There's no flow control on the Uno and Nano serial and you are sending fast enough that bytes are being dropped, and there's no way your protocol or lack of one demarcates separate messages (separate numbers).
This will become more clear if you write your numbers in hexadecimal:
Dec |
Hex |
61805 |
0xf16d |
61937 |
0xf1f1 |
28013 |
0x6d6d |
61937 |
0xf1f1 |
Adding a delay between messages can serve to separate the messages if the receiving side makes use of a timeout and can prevent the receiving side from being overwhelmed with data.
If you don't want to use time to slow down and separate your data, you can change what is sent instead. One idea is to have the receiver actively request data when it's ready to receive some. The receiver should expect only entire messages between requests, and if anything gets garbled, it can just read whatever data has come in and throw it out before the next request.
Your messages can also be separated by some characters that aren't part of the messages themselves. A common way to do that is just to encode your numbers as separate text lines, the line terminator \n
serving as the separator between messages.
I have not tested these yet, but here are some very minimal modifications to your code that approach having a protocol with fewer of these problems:
Sender:
void setup () {
Serial.begin(9600);
}
void loop() {
// await message request
while(Serial.read() != '.') {
}
//
const unsigned int s = 61805;
Serial.write(highByte(s)) ;
Serial.write(lowByte(s));
}
Receiver:
void setup() {
Serial.begin(9600);
}
void loop () {
// request message
Serial.write('.');
// await two-byte response
const unsigned long request_sent = millis();
while (Serial.available() < 2 && millis() - request_sent < 1000) {
}
if (Serial.available() != 0) {
if (Serial.available() == 2) {
// two byte response receive
const unsigned upperByte = Serial.read();
const unsigned lowerByte = Serial.read();
const unsigned r = (upperByte << 8) + lowerByte;
Serial.println(r);
} else {
// Something went wrong, too or too few bytes received;
// throw them out and start over.
delay(100);
while (Serial.read() != -1) {}
}
}
}
It's a long way from doing it properly, but it should behave at least better than what you started with. There's a lot to designing even simple protocols. Typically there are start and end frame bytes, a checksum or CRC, a message number counter, etc.