How to write to serial a byte array with dynamic array?

Hi,

I started programming with esp8266. Everything is okey but I have a problem with serial write.

I want to write to serial port for communicate with microcontroller. I’ll send data like this format:

Total 5 Byte : “Header”[3] + PinNo[1] + Value[1];

I want to send 5 bytes to microcontroller. I’ll use it for extend the esp8266 ports.

Now, there is a problem.

When I assign an int variable to byte array item, Its printing bad character.

But when i assign a hex value directly , its working fine.

CODE :

		int lightPin = data[0].toInt(); // 0-255
		int lightValue = data[1].toInt(); // 0-1

		byte msg2[5];
		msg2[0] = 'M'; //1.Header Byte
		msg2[1] = 'K'; //2.Header Byte
		msg2[2] = 'B'; //3. Header Byte
		msg2[3] = 0x31; // PinNo
		msg2[4] = 0x32; // Value

		Serial.write(msg2, 5);
		Serial.println();

How can i solve this?

Thank u.

2 good.png

int is a signed 16-bit value.

byte is an unsigned 8-bit value.

The hex values in your example are in the range of 0-255.

Serial.write() sends the bits out exactly as-is. Hex value 0x31 is the char '1' which is very different than the byte value 1. Serial.print() converts values into their ascii representation.

i would use lowByte(lightPin);but just for future reference try casting to (byte) rather than (char) also.
char is a signed 8-bit value believe it or not

Perehama:
int is a signed 16-bit value.

byte is an unsigned 8-bit value.

The hex values in your example are in the range of 0-255.

I dont understandt, is a byte value range of 0-255? When I assign a signed 16-bit int to byte , isnt it converting and casting automatically to ranged 0-255?

blh64:
Serial.write() sends the bits out exactly as-is. Hex value 0x31 is the char '1' which is very different than the byte value 1. Serial.print() converts values into their ascii representation.

So do you say , 0x31 is not equal to int 1 ?

Moostapha:
I dont understandt, is a byte value range of 0-255? When I assign a signed 16-bit int to byte , isnt it converting and casting automatically to ranged 0-255?

So do you say , 0x31 is not equal to int 1 ?

Casting is you telling the compiler you know the expected behavior of the conversion and not to raise any warning of invalid conversion.
int value 1 is 0x0001.

ehm yes i was going from the point of view that data[0].toInt()==49 which is the same as 0x31 but if data[0].toInt()==1 well that is the same as 0x01
So if you want to send the header and have the 2 bytes following it will not be directly readable to you in a Serial monitor, but you will actually send the bytes you want, where as if you assign the HEX value, you get the visual result you want, but the message will not be sent correctly. In a way “what is the problem ?”

Perehama:
Casting is you telling the compiler you know the expected behavior of the conversion and not to raise any warning of invalid conversion.
int value 1 is 0x0001.

how do you advise me to send data as 5 size byte array?

Is this true way?

 int lightPin = data[0].toInt(); // 0-255
 int lightValue = data[1].toInt(); // 0-1

 byte msg2[5];
 msg2[0] = (uint8_t)'M'; //1.Header Byte
 msg2[1] = (uint8_t)'K'; //2.Header Byte
 msg2[2] = (uint8_t)'B'; //3. Header Byte
 msg2[3] = (uint8_t)lightPin; // PinNo
 msg2[4] = (uint8_t)lightPin; // Value

 Serial.write(msg2, 5);

Dynamic arrays are not a good idea in the small memory of an Arduino. Just allocate a fixed array that is big enough for the biggest piece of data.

...R

Deva_Rishi:
ehm yes i was going from the point of view that

data[0].toInt()==49

which is the same as 0x31 but if

data[0].toInt()==1

well that is the same as 0x01
So if you want to send the header and have the 2 bytes following it will not be directly readable to you in a Serial monitor, but you will actually send the bytes you want, where as if you assign the HEX value, you get the visual result you want, but the message will not be sent correctly. In a way "what is the problem ?"

Ohh finaly, thank you, :slight_smile:

then is this true code?

 int lightPin = data[0].toInt(); // 0-255
 int lightValue = data[1].toInt(); // 0-1

 byte msg2[5];
 msg2[0] = lowByte('M'); //1.Header Byte
 msg2[1] = lowByte('K'); //2.Header Byte
 msg2[2] = lowByte('B'); //3. Header Byte
 msg2[3] = lowByte(lightPin); // PinNo
 msg2[4] = lowByte(lightValue); // Value

 Serial.write(msg2, 5);
 Serial.println();

Moostapha:
how do you advise me to send data as 5 size byte array?

Is this true way?

 int lightPin = data[0].toInt(); // 0-255

int lightValue = data[1].toInt(); // 0-1

what are the values of data[0] & data[1] and how do you want to send them ?
if data[0] is ‘1’ then data[0].toInt(); assigns 49 to lightpin, if you want ‘1’ to come out the other end you should use

msg2[3] = char(lightPin+48);

is that what you meant to do ?

Robin2:
Dynamic arrays are not a good idea in the small memory of an Arduino. Just allocate a fixed array that is big enough for the biggest piece of data.

At least according to the original code posted, the OP misunderstands / misused the term 'Dynamic' (at least in the memory allocation context). The array shown is statically allocated.

 msg2[0] = lowByte('M'); //1.Header Byte
 msg2[1] = lowByte('K'); //2.Header Byte
 msg2[2] = lowByte('B'); //3. Header Byte
 msg2[3] = lowByte(lightPin); // PinNo
 msg2[4] = lowByte(lightValue); // Value

No ! it is not, first and finally what do you want to send and how do you want to receive that ?

msg2[0] ='M'; //1.Header Byte
 msg2[1] = 'K'; //2.Header Byte
 msg2[2] = 'B'; //3. Header Byte

was fine, it will send the characters and if you test for them at the other end you can confirm that you sent them.Now for the final 2 values (since they are actually values) it depends, data[0] how do you obtain the value ? this is where your code is incomplete, and the same for data[1] what is the range ? and how do you want to interpret them at the other end ?

Deva_Rishi:
what are the values of data[0] & data[1] and how do you want to send them ?
if data[0] is '1' then data[0].toInt(); assigns 49 to lightpin, if you want '1' to come out the other end you should use

msg2[3] = char(lightPin+48);

is that what you meant to do ?

Actually I dont want to send '1' character.

  1. Read data[0] as string
  2. Convert to int;
  3. Send int value as DEC,

Example

  1. data[0] = "80";
  2. Convert to int = 80
  3. Send 80 DEC to serial. Not Char 'P'. Decimal 80. Character doesn't matter.

Moostapha:
Example

  1. data[0] = "80";
  2. Convert to int = 80
  3. Send 80 DEC to serial. Not Char 'P'. Decimal 80. Character doesn't matter.

but you send only one character for the value so the value will be between 0-9 otherwise you need to send 2 characters (or more) so then your whole method will need separators and terminating characters and your Array will need to be bigger, you could send 3 bytes for data[0] and fill it up with character '0' if the value is below 100 and/or 10 , this is not a very elegant method, also since you would anyway have to decode it at the other end.

 int lightPin = data[0].toInt(); // 0-255
 int lightValue = data[1].toInt(); // 0-1

Why are you making this so difficult? The range of values that you indicate here would CLEARLY indicate that lightPin and lightValue should be bytes. Why are they NOT?