当然ながら、「データ」そのものにXもYもないので、あるデータがXなのかYなのかを判別する手段を別途設けてやらなければいけません。
一番単純なのは、先にXを送り、つぎにYを送るという規則でしょうが、何らかの原因(ノイズなど)でデータを一回受信し損ねたり、あるいは単に送信側受信側のプログラムの起動の関係がずれたりしただけでどちらが先でどちらが後かなんてわからなくなってしまいます。
なら、例えば、XとYは連続して(具体的に決めるなら10ms以内とか)送る、Yと次回のXの間は100ms以上空ける、という規則をつくればXとYを弁別できますね。
あるいは、XとYに「ありえないパターン」はあるでしょうか? もし、XとYはどちらも0にはならない、という規則があったら、XとYの組の間に必ず0を送る、という規則を設けることも考えられます。X Y 0 X Y 0...とするわけです。
そういう都合のいい(使われない)データもない、とすると...
100%の検出はできませんが、例えば X Yに続いてその和(の下位8bit)を送信することにしてみては。1バイト受信して仮のX, もう1バイト受信して仮のYとします。次の1バイトを受信して、それがX+Yの値になっていたら仮定がただしかったということ。もし違っていたらこれまでの仮のYを仮のX, 新しい1バイトを仮のYと置き換えてつぎの1バイトを受信してさてそれは和になっているでしょうか...というのを調べていきます。余程ノイズの多い厳しい環境でない限り、一度正しい順番をみつければその後は概ね安定して通信ができるでしょう。
しかし、一番普通に行われることは、バイナリではなく「数字」に変換して(複数バイトで)通信することです。0x15の1バイトを送るのではなく、'2''1'という数字を送ります。当然ながら数字でない文字は「付加情報」であることが明らかになるので、この前に例えば'X', 後ろに','をつければ"X21,"を受信したらX,"Y123,"を受信したらYの値とすればいいという話になります。
通信量は増えますが、いろいろな意味で「扱いやすい」データになります。
ちょっと思い出したので追記。
シリアル通信の通信の単位は1バイトで、それ以上でも以下でもありません。
pythonでSerial.write(文字列)という関数がありますが、決して「文字列」がなにか一つの単位として送られるわけではなく、単に文字列を一文字ずつ送っているだけだ、ということに注意してください。
言い換えれば、受信する側がその文字列をまとめて受信する保証はまったくないということです。
もちろん、一つの関数で順次送るのであれば時間的には密着するので、この回答の最初で言ったような「時間的な配置」として塊で受信できてしまう可能性は大きくなります。しかし、それは(ちゃんとその時間関係を設計するのでないかぎり)保証されたものではない、ということに留意。
もう少し具体的にいうと、送る側で"X21,Y123,"を送ったから受信で9文字受信の指示をしたら"X21,Y123,"が受信できる、と期待してはいけません。X21,y12で一旦切れてしまうかも知れない、あるいは前回切れた切れ端が頭にくっついて3,X21,Y12の9文字が受信できてしまうかもしれない、そういうのにちゃんと対応出来て初めてまともなUART通信のプログラムと言えます。