serial write data format uint16

void loop() {

 if (Serial.available() > 0) {
                incoming = Serial.readString();
      }
 delay (100);
 if (Serial.available() > 0){
              
                digitalWrite(8, HIGH);
                uint16_t message[]={0x02,0x03,0x04,0x12,0x16,0x00,0x0A,0xAD,0x88};
                testcrc = ModRTU_CRC(message[],sizeof(message));
  //              uint8_t message[]={0x02,0x03,0x04,0x12,0x16,0x00,0x0A,0xAD,0x88};
                Serial.write(testcrc, sizeof(testcrc));
                delay (100);
                digitalWrite(8, LOW);
 }

The code above send the following error:

Arduino: 1.8.3 (Windows 10), Board: "Arduino/Genuino Uno"

C:\Users\ammar.surti\Documents\Arduino\MODBUS2\MODBUS2.ino: In function 'void loop()':

MODBUS2:22: error: call of overloaded 'write(uint16_t&, unsigned int)' is ambiguous

                 Serial.write(testcrc, sizeof(testcrc));

                                                      ^

C:\Users\ammar.surti\Documents\Arduino\MODBUS2\MODBUS2.ino:22:54: note: candidates are:

In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Stream.h:26:0,

                 from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h:29,

                 from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:232,

                 from sketch\MODBUS2.ino.cpp:1:

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:57:12: note: size_t Print::write(const char*, size_t) <near match>

     size_t write(const char *buffer, size_t size) {

            ^

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:57:12: note:   no known conversion for argument 1 from 'uint16_t {aka unsigned int}' to 'const char*'

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:56:20: note: virtual size_t Print::write(const uint8_t*, size_t) <near match>

     virtual size_t write(const uint8_t *buffer, size_t size);

                    ^

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:56:20: note:   no known conversion for argument 1 from 'uint16_t {aka unsigned int}' to 'const uint8_t* {aka const unsigned char*}'

exit status 1
call of overloaded 'write(uint16_t&, unsigned int)' is ambiguous

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Can someone help out why isnt the serial print printing uint16 data format. if i try this with uint8_t. it works fine

Can someone help out why isnt the serial print printing uint16 data format.

Because write != print.

If you want to write a uint16_t, cast the pointer to a pointer to uint8_t

Why do you want to use uint16_t?

Serial comms is always done with 8-bit data types. If you want to send 16 bit data, you normally split it into 2 8-bit data values before transmission, then reverse that process after receiving at the other end.

Hint: have a look at the highByte(), lowbyte() and word(h, l) functions

Because write != print.

I tried both writing and printing

If you want to write a uint16_t, cast the pointer to a pointer to uint8_t

Can i get an example how to do that?

Why do you want to use uint16_t?

Serial comms is always done with 8-bit data types. If you want to send 16 bit data, you normally split it into 2 8-bit data values before transmission, then reverse that process after receiving at the other end.

Hint: have a look at the highByte(), lowbyte() and word(h, l) functions

I have to do 16 bit for modbus, and i cannot break that because on the other end i have a PLC. i dont have the flexibility to merge data in there or do anything else for that matter. I can be flexible with this program.

What do you need to go out on the wire? ASCII or Binary?

It has to be hex. That is what modbus protocol works on. I am calculating the CRC here and that has to be 16bit for modbus. No other way unfortunately

ammarqs:
It has to be hex. That is what modbus protocol works on. I am calculating the CRC here and that has to be 16bit for modbus. No other way unfortunately

Have a look at this page:

you are right, CRC is 16bits (2 bytes). however based on the info one that page I think it is safe to say that you can send the CRC as 2 seperated bytes using serial.write();

likely that you would need to send the lower byte first then the upper byte but it could be the reverse! I'm just guessing here! :slight_smile:

ammarqs:
It has to be hex.

Let me rephrase the question. The data on the wire WILL be binary, by definition. The question is do you want those bits to be a straight binary representation of the number you're sending -- 8 bits for a byte, 16 bits for and int, etc? Or do you want it to be an ASCII representation of your number in hex?

Have a look at this page:
Modbus serial protocol decoding

you are right, CRC is 16bits (2 bytes). however based on the info one that page I think it is safe to say that you can send the CRC as 2 seperated bytes using serial.write()

Thank you.
Can you guide me to a split command that i can use here to break the uint16 to two uint8.

Let me rephrase the question. The data on the wire WILL be binary, by definition. The question is do you want those bits to be a straight binary representation of the number you're sending -- 8 bits for a byte, 16 bits for and int, etc? Or do you want it to be an ASCII representation of your a hex number?

Yes straight binary representation and NOT ASCII.

  Serial.write((byte) testcrc);
  Serial.write((byte) (testcrc>> 8));

This sends in the correct order for most MODBUS systems I am aware of.