Serial.write() error

I'm getting a consistent error "call to overloaded 'write(int)' is ambiguous". The code in my subroutine, where the compiler thinks 0x00 is an integer, is here:

void send_token(byte un) {   // send the token to a unit
    Serial.write(0xAA) ;     // start byte
    Serial.write(un) ;       // unit
    Serial.write(0x21) ;     // "21" is a token
    Serial.write(0x00) ; 
    Serial.write(0x00) ; 
    Serial.write(0x04) ;     // end byte

If 0x00 is replaced with "un" or any non-zero byte, eg, 0x12, the error goes away.

Seems to me that 0x00 should compile as a byte and 0x0000 should compile as an int.

In a related issue, it puts the beak* on me when I code Serial.print(0x03, HEX) and I get “3” instead of “03”. The same goes for printing using BIN. I can accept the fact that integers and floating point numbers don’t print leading zeros, since they would have to be formatted for field width, but when HEX or BIN is coded, I think the coder ALWAYS wants to see all the bits, even the leading zeros. So, if printing HEX, if the variable is a byte, you get two characters and if it’s an int, you get 4, etc.

I suggest that this ought to be fixed.

  • this is a military term for one’s blood pressure coming up…

Dr_Quark:
Seems to me that 0x00 should compile as a byte and 0x0000 should compile as an int.

I believe that literal integer constants are int by default (for AVR anyway). And, that's true regardless of the radix you use to express them.

Dr_Quark:
So, if printing HEX, if the variable is a byte, you get two characters and if it’s an int, you get 4, etc.

When I need to print in Hex (usually for register-level debugging), I use something like below. You may adjust the formatting to suit your needs.

template<typename IntType>
void printHex(IntType val, Print *ptr = &Serial) {
  ptr->print("0x ");
  for (int8_t shift = 8 * sizeof(val) - 4; shift >= 0; shift -= 4) {
    uint8_t hexDigit = (val >> shift) & 0xF;
    ptr->print(hexDigit, HEX);
    if (((shift & 0xF) == 0) && (shift > 0)) {
      ptr->print(" ");
    }
  }
}

template<typename IntType>
void printlnHex(IntType val, Print *ptr = &Serial) {
  printHex(val, ptr);
  ptr->println();
}

void setup() {
  uint8_t x = 0x2;
  uint16_t y = 0x3A;
  uint32_t z = 0xCC;

  Serial.begin(116200);
  delay(1000);

  printlnHex(x);
  printlnHex(y);
  printlnHex(z);
}

void loop() {
}

Output:

0x 02
0x 003A
0x 0000 00CC

Thanks. I've been using my own code, something like yours, but as an old machine language programmer I think there is something special about BIN and HEX and WORDs and BYTEs that should be honored. I'll let the kids deal with FLOATs and whole numbers. (I can feel an "OK, Boomer" coming already)

Dr_Quark:
Thanks. I’ve been using my own code, something like yours, but as an old machine language programmer I think there is something special about BIN and HEX and WORDs and BYTEs that should be honored. I’ll let the kids deal with FLOATs and whole numbers. (I can feel an “OK, Boomer” coming already)

WORDs and BYTEs are whole numbers.

Their capitalisation suggests they’re macros too.

Did you really use “machine language”, or do you really mean “assembler”?

Both. Loaded code using Altair 8080 panel switches and used assembler on a Z-80 (and other) systems using audio cassette AFSK storage. Boy, in comparison, do I love Arduinos. :slight_smile:

Capitalization only used for emphasis in plain text. If it was in code, I'd agree re: macros. Except, I don't agree that words and bytes are whole numbers. They could represent switch positions or other discrete input data. A switch position represented by a bit can be manipulated as a digit, but not usually.

Dr_Quark:
I'm getting a consistent error "call to overloaded 'write(int)' is ambiguous".

Not me. This compiles without any error or warning for Arduino UNO or Nano.

void setup()
{
  Serial.begin(115200);
}


void send_token(byte un) {   // send the token to a unit
    Serial.write(0xAA) ;     // start byte
    Serial.write(un) ;       // unit
    Serial.write(0x21) ;     // "21" is a token
    Serial.write(0x00) ;
    Serial.write(0x00) ;
    Serial.write(0x04) ;     // end byte
}


void loop() {}

Perhaps you have a mistake in the part of the code you didn't think we needed to see. Or maybe you are using one of the more exotic Arduino boards that uses a different core. Or maybe you are using some kind of "Arduino Compatible" which uses a third-party core. Hard to see from here.

Thanks, John. I'm just using the (see edit below). The error was consistently generated until I stuck the "un" (defined as a byte) in place of the 0x00.

on edit: Oops, I forgot. I was using the Arduino Web Editor and the Nano 33 IOT processor. This may be limited to that core.

johnwasser:
Not me. This compiles without any error or warning for Arduino UNO or Nano.

Try again with Leonardo.
The error occurs when you are using USB serial.

HardwareSerial has these write() methods

    virtual size_t write(uint8_t);
    inline size_t write(unsigned long n) { return write((uint8_t)n); }
    inline size_t write(long n) { return write((uint8_t)n); }
    inline size_t write(unsigned int n) { return write((uint8_t)n); }
    inline size_t write(int n) { return write((uint8_t)n); }
    using Print::write; // pull in write(str) and write(buf, size) from Print

while USB serial has these

    virtual size_t write(uint8_t);
    virtual size_t write(const uint8_t*, size_t);
    using Print::write; // pull in write(str) and write(buf, size) from Print

That write(int) in HardwareSerial removes any ambiguity.
The ambiguity arises from the fact that 0 is also a null pointer constant.

This is all well and good, but is essentially worthless to self-taught DIY programmers. I've gone all the way from machine code, assembler, Fortran, Algol, Ada, Visual Basic, Forth, and now C. Having to dive this deep to "understand" the print function is counterproductive to actually coding. If you're a pro, doing intensive coding, fine. But not for the average user of the Arduino IDE.

In a word, thbbbbtttttt.

But I do appreciate your faith in us flatworms down here at the bottom. :slight_smile: