Sending char by serial strange result

Hi,

hopefully this is the right category.

I am actually trying to just send an uint8 from one device to the other. Besides the RX / TX cables I also added a common ground, and the results are always the same. So it is not related to the hardware setup.
Edit: Sending and receiving of the uint8 is done by Serial1. Serial is only used for debugging.

I have one device sending an uint8. Only important code snippets here:

void SerialHid::SendByte(uint8_t byte)
{
	string message{"Sending "};
	message.append(NumericToString(byte));
	MsgOutMessage(message.c_str()).Send();
	Serial1.write((char)byte);
	#ifdef DEBUGGING_PC
		Serial.println(message.c_str());
	#endif
}

This also was tested with print instead of write. In parallel I send the passed value so I am sure the right one is printed.

On the other device I want to read exact that byte:

bool SerialReader::Process() {
	int mSize = Serial1.available();
	if  (mSize > 0) {
		int mLastValue = Serial1.read();
		#ifdef DEBUGGING_PC
			Serial.print("Received ");
			Serial.println(mLastValue);
			Serial.print("Size ");
			Serial.println(mSize);
		#endif
		return true;
	}
	return false;
}

Now here are some serial debug lines according to the passed in value (MsgOutMessage gives out the correct number here, which is then directly passed in to the write):

7:

Received 252
Size 2
Received 0
Size 1

11:

Received 252
Size 2
Received 0
Size 1

53:

Received 28
Size 2
Received 252
Size 1

254:

Received 224
Size 1

My assumption was that I only get a size of 1 with a single byte I can cast into my uint8 back after checking for .1 (no data received). Instead I get sometimes two bytes, and I do not see the reason or how to cast..

Then why mess around with Strings and chars ?

As your topic does not relate directly to the installation or operation of the IDE it has been moved to the Programming category of the forum

1 Like

This is all you need:

uint8_t c = some_value;
Serial.write(c);

Instead I get sometimes two bytes

That is very likely correct. Post ALL the code and forum members will explain why.

Sorry, have edited the question: Serial1 is the connection from one device to the other, Serial is only for debugging (as well as MsgOut).

I am using write / print, and the result is what is listed above.

Also here sorry: Serial1 is the device connection on both sides, Serial and MsgOut is only for debugging

That is very bad manners. Now the replies to it may not make any sense so never do it again

Ah sorry I thought putting an "Edit:" in front of the edited line makes it clear. Next time I will repost.

I still don't understand why you cast it to char instead of just writing the byte. Have you checked how many bytes you recieve ?

It does not matter if casted or not, I just kept it.
Even without casting I get that I have listed in the opening post:
Sending a 7 gives me a size of 2 at the receiver, containing 252 and 0
Sending an 11 gives me a size of 2 at the receiver, containing 252 and 0
Sending a 53 gives me a size of 2 at the receiver, containing 28 and 252
Sending a 254 gives me a size of 1 at the receiver, containing 224

The issue is in the code you did not share as Serial1.write(byte); does only send one byte.

Are you calling the SendByte() function multiple times ?

There is no call to Serial1 besides the code snippet.
Each time SendByte() is called I get a message by MsgOutMessage which I can see in NodeRed - there is only one call with the number I have posted..
Even If it would be triggered multiple times (which I am sure it is not, but however): I cannot see the 7 or 11 or whatever I pass in in a single byte which is received..

Btw, casting to char does not make a difference on Serial1.write(). But If I use Serial1.print, casting to char makes a difference. If I f.e. print() a uint8 with number 254 and do not cast, I receive

Received 224
Size 5
Received 224
Size 4
Received 28
Size 3
Received 224
Size 2
Received 252
Size 1

Of course it does. Serial.print() is for ASCII output, formatted in different ways, depending on what type of variable is being printed. Use Serial.write() to avoid formatting and send binary values.

All this is described in the Arduino Reference Guide.

1 Like

So can we see the code of those functions / clases

message.append(NumericToString(byte));
MsgOutMessage(message.c_str()).Send();

➜ NumericToString()
➜ MsgOutMessage and Send()

And the NodeRed stuff

You may think to change the title of the thread to:
Sending "uint8_t byte" by serial -- strange result!

1. Which Arduino are you using - MEGA, ESP32?
2. If using two MEGA, then make connection as per Fig-1.
3. To send an uint8_t type data (say; unint8_t y = 0x23;) at 1-sec interval from MEGA1 to MEGA2 over Serial1 Port, You may upload sketches similar to the following into Sender (MEGA) and Receiver (MEGA2).


Figure-1:

Tested on Two UNOR3 using Software UART Ports:
Sender Sketch:

#include<SoftwareSerial.h>
SoftwareSerial SUART(8, 9);

uint8_t y = 0x95;

void setup()
{
  Serial.begin(9600);
  SUART.begin(9600);
}

void loop()
{
  Serial.print("Sending data: "); Serial.println(y, HEX);
  SUART.write(y); //0x95 is sent as 10010101
  Serial.println("==============================");
  delay(1000);
}

Receiver Sketch:

#include<SoftwareSerial.h>
SoftwareSerial SUART(8, 9);
uint8_t y;

void setup()
{
  Serial.begin(9600);
  SUART.begin(9600);
}

void loop()
{
  byte n = SUART.available();  //check if a car as come form Sender
  if (n != 0)
  {
    y = SUART.read();  //y = 0x95
    Serial.print("Data Received: "); Serial.println(y, HEX);
  }
}