Serial input ang receive int question

Hi all.
the Robin2's Example 2 - Receiving several characters from the Serial Monitor at:

works well for char, how to receive integer then?
I added: int dateget = receivedChars; got errors.

Thanks
Adam

// Example 2 - Receive with an end-marker

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;


int dateget = 0;

void setup() {
    Serial.begin(9600);
    Serial.println("<Arduino is ready>");
}

void loop() {
    recvWithEndMarker();
    showNewData();
}

void recvWithEndMarker() {
    static byte ndx = 0;
    char endMarker = '\n';
    char rc;
    
    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
            dateget = receivedChars;
        }
        else {
            receivedChars[ndx] = '\0'; // terminate the string
            ndx = 0;
            newData = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        newData = false;
    }
}
Arduino: 1.8.19 (Windows 7), Board: "ESP32 Dev Module, Disabled, Disabled, Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS), 240MHz (WiFi/BT), QIO, 80MHz, 4MB (32Mb), 921600, Core 1, Core 1, None, Disabled"


C:\Users\HUA.DELLV-PC\Documents\Arduino\Robin_Example2_A\Robin_Example2_A.ino: In function 'void recvWithEndMarker()':

Robin_Example2_A:35:22: error: invalid conversion from 'char*' to 'int' [-fpermissive]

             choice = receivedChars;

                      ^~~~~~~~~~~~~

exit status 1

invalid conversion from 'char*' to 'int' [-fpermissive]


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

The code you posted does not contain that line.

1 Like

The data is coming as ASCII characters. The simplest way to convert ASCII back into an integer number is the atoi function.

I'd normally give you a link there but I don't have it right now. Just Google atoi.

1 Like

Hi @shanren,

usually characters are transmitted via Serial. They are ASCII representatives of letters like "A", "x" or numbers like "1", "0" etc.

If you want them to form binary numbers like integers or float again you have to convert the strings into the wanted type.

There are different ways to do that see here for example:

https://circuits4you.com/2018/03/09/how-to-convert-int-to-string-on-arduino/

You can use String objects which is the easiest way but generally not recommended due to possible memory problems in the Arduino world. You use an ESP32 which has a lot of memory so that you could use Strings ...

The recommended way is to use C strings and the function atoi() like you see in the examples.

It is also possible to send the data binary without conversion using Serial.write() instead of Serial.print(). To do this you have to send the data byte by byte and restore the data type again at the receiving side. That's mostly required if you have to send lots of data in short time.

With binary transmission you cannot easily distinguish data from control characters (like Newline, Carriage Return) as these data may be binary content.

So if not necessary the ASCII transmission is the easiest to handle (especially because you can directly read what comes over the line).

Good luck!

1 Like

Thanks.
sorry about.
it was: int dateget = receivedChars; or int dateget = 0; in head.
and also tested by: int dateget = receivedChars;
same result.

Thanks.
the reason I used that way is based on the example below of:

but that can only receive single digital.
anyway, I'll check your link first.

I used:

 int result = atoi(receivedChars);
    int dateget = result;

got what I need.

Thank you again ec2021.

char incomingByte = 0;
int choice = 0;

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

void loop()
{
  if(Serial.available()>0)
  {
     incomingByte = Serial.read();
     choice = incomingByte - '0';
    Serial.println(choice);

    switch(choice)
   { 

   }

  }
}

Do you understand how it works? Does it make sense? Can you imagine multiplying that digit by ten and then adding in the next digit you find?

1 Like

Thanks.
I just got a idea from there that the input number can be changed into 'int',
now I got the tool to do it and got what I expected from ec2021 's reply.

The example you mentioned is limited to the transmission of ASCII digits. Unfortunately it does not handle characters other than numbers.

The "trick" used is to subtract the ASCII value of the character for zero from any char received.

The characters (letters) for 0 to 9 are coded with the bytes 48 to 57. just google for "ASCII table".

The calculation is like this

received char value - char value '0' = result

'0' - '0' = 48 - 48 = 0
'1' - '0' = 49 - 48 = 1
'2' - '0' = 50 - 48 = 2
etc.

For other received characters you get values that are not implicitly understandable...

And as @Delta_G mentioned you only get the value of a single digit not the decimal number in total. To restore that you have to do something like this

  • value = 0
  • Repeat for all digits
    • decode a single digit (from left to right) as "digit"
    • value = value*10
    • value = value + digit
  • Print or use value

To be on the save side you had to handle characters outside the numbers and negative values ('-') and make sure that value is of correct type to handle the range (integer, long, signed or unsigned). Or even floating point numbers.

That's an interesting and educational task to solve! :wink:

1 Like

Great!
that's why there is a: choice = incomingByte - '0'; in my link's code.
I'll replenish my code.

and also one of Delta_GKarma: 1500+'s asking may implicit the trick that I didn't understand yet.

Thank you.

You are welcome ... Here a sketch that solves the input of integer data with the " Minus '0' character method":

/*
  Forum: https://forum.arduino.cc/t/serial-input-ang-receive-int-question/1188479
  Wokwi: https://wokwi.com/projects/381293653101267969
*/

constexpr char LF = 10;  // ASCII for Line Feed
constexpr char CR = 13;  // ASCII for Carriage Return

char incomingByte;
long value;
boolean valid;

void setup()
{
  Serial.begin(57600);
  message();
}

void loop()
{
  if (Serial.available())
  {
    incomingByte = Serial.read();

    switch (incomingByte)
    {
      // digits are decoded and added to value
      case '0' ... '9':
        valid = true;
        value = value * 10 + incomingByte - '0';
        break;
     // In case of LF or CR and after in minimum one valid input 
     // value is printed. Then the input message is called
     // where also value and valid are reset   
      case LF:
      case CR:
        if (valid) {
          Serial.println(value);
          message();
        }
        break;
      // If any other characters are detected an error message is printed,
      // the Serial buffer is cleared and the input message is called   
      default:
        // all other characters lead to an error message
        Serial.print("Error: You used a non-digit character:\t");
        Serial.println(incomingByte);
        SerialClear();
        message();
        break;
    }
  }
}

void message(){
  Serial.println("Please input an integer value:");
  value = 0;       // Reset the sum
  valid = false;   // Reset validity
}

void SerialClear(){
  while (Serial.available()) {
    char garbage = Serial.read();
  }
}

You can check it out on Wokwi:

Good luck and have fun!

1 Like

Thanks.
very useful, I actually used to ESP32 unit.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.