Receiving numbers via Serial in hex, decimal, or binary

Hi, is there a good way to receive a number via Serial onto an Arduino when it is sent from Serial Monitor, and store the number in an unsigned int variable? I would like to make a basic framework to use in a variety of sketches and use these features:
If the number begins with 0x it is interpreted as hex
If the number begins with B it is interpreted as binary
If the number begins with 1-9 it is interpreted as decimal
If the number is too big to fit in an unsigned int, or if other characters received, discard and start over or send an error message via Serial Monitor back to the PC

Does anybody have an elementary example, which already does some of this, to get me started down the right path?

Search the forum for 'serial input basics'. You will find a thread that should help.

Thanks, I see that thread from Robin2, I think that is just what I needed.

That's it. I would have given a link, but it is difficult to copy and paste on my little tablet.

For the convenience of others Serial Input Basics

...R

That is a great thread. I have the serial part understood now.

The other part of the problem is doing stuff with the received data, such as parsing it before running it through strtol so I can use hex as my preferred default number translation but still offer decimal and binary as options, and perhaps process a couple of non-number commands.

Here is a code snippet of the sort of thing I’m doing (successfully) so far; I know how to do this sort of thing with String object, but afraid I don’t know how to do it with char arrays. substring and startsWith and stuff like that. Is this sort of thing a good case for using String and converting back and forth to char arrays, or is there a forum thread or tutorial which would be good for me to visit?

    if (inputString.startsWith("num", 0)  &&
        (inputString.substring(3, 4) >= "0" && inputString.substring(3, 4) <= "9" )) {
      Serial.println("decimal number");
      base = 10;
      inputString = inputString.substring(3);
    }
    else if (inputString.startsWith("bin", 0) &&
             (inputString.substring(3, 4) >= "0" && inputString.substring(3, 4) <= "1" )) {
      Serial.println("binary number");
      base = 2;
      inputString = inputString.substring(3);
    }
    else if (inputString.startsWith("0X", 0) || inputString.startsWith("0x", 0) &&
             ((inputString.substring(2, 3) >= "0" && inputString.substring(2, 3) <= "9" ) ||
              (inputString.substring(2, 3) >= "A" && inputString.substring(2, 3) <= "F" ) ||
              (inputString.substring(2, 3) >= "a" && inputString.substring(2, 3) <= "f" ))) {
      Serial.println("hex number");
      base = 16;
    }
    else if ((inputString.substring(0, 1) >= "0" && inputString.substring(0, 1) <= "9" ) ||
             (inputString.substring(0, 1) >= "A" && inputString.substring(0, 1) <= "F" ) ||
             (inputString.substring(0, 1) >= "a" && inputString.substring(0, 1) <= "f" )) {
      Serial.println("hex number");
      base = 16;
    }

Later on in the code I convert the String to char array and process it with strtol using the correct base as a parameter.

The code in Serial Input Basics won't understand
inputString.startsWith() etc
because it deliberately does not use Strings (capital S) which do not work well in the limited memory of the Arduino.

Post your complete program.

...R

This is the whole program. It works fine to get characters into a String object and parse them to decide if hex, decimal, or binary was intended by the user, and works regardless of CR/LF, CR, or no line ending. It then converts the String to a char array to finish the processing of the number with strtol. I would like to avoid String object and use nothing but char array if I knew how to do substring and comparison type operations with char array instead. That is a weak area for me.

String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete

void setup() {
  // initialize serial:
  Serial.begin(115200);
  //  while (!Serial) {
  //  } // wait until serial connects to run sketch
  Serial.println("\nReset");
  // reserve 200 bytes for the inputString:
  inputString.reserve(200);
}

void loop() {
  byte base = 0;
  // print the string when a newline arrives:
  if (stringComplete) {
    Serial.print("String: ");
    Serial.println(inputString);

    if (inputString.startsWith("num", 0)  &&
        (inputString.substring(3, 4) >= "0" && inputString.substring(3, 4) <= "9" )) {
      Serial.println("decimal number");
      base = 10;
      inputString = inputString.substring(3);
    }
    else if (inputString.startsWith("bin", 0) &&
             (inputString.substring(3, 4) >= "0" && inputString.substring(3, 4) <= "1" )) {
      Serial.println("binary number");
      base = 2;
      inputString = inputString.substring(3);
    }
    else if (inputString.startsWith("0X", 0) || inputString.startsWith("0x", 0) &&
             ((inputString.substring(2, 3) >= "0" && inputString.substring(2, 3) <= "9" ) ||
              (inputString.substring(2, 3) >= "A" && inputString.substring(2, 3) <= "F" ) ||
              (inputString.substring(2, 3) >= "a" && inputString.substring(2, 3) <= "f" ))) {
      Serial.println("hex number");
      base = 16;
    }
    else if ((inputString.substring(0, 1) >= "0" && inputString.substring(0, 1) <= "9" ) ||
             (inputString.substring(0, 1) >= "A" && inputString.substring(0, 1) <= "F" ) ||
             (inputString.substring(0, 1) >= "a" && inputString.substring(0, 1) <= "f" )) {
      Serial.println("hex number");
      base = 16;
    }


    Serial.print("length: ");
    Serial.println(inputString.length());

    int stringlength = inputString.length() + 1;
    char char_array[stringlength];
    inputString.toCharArray(char_array, stringlength);
    if (base != 0) {
      char * pEnd;
      long val1 = strtol(char_array, &pEnd, base);
      Serial.print("val dec: ");
      Serial.println(val1);
      Serial.print("val hex: ");
      Serial.println(val1, HEX);
      Serial.print("val bin: ");
      Serial.println(val1, BIN);
    }
    // clear the string:
    inputString = "";
    stringComplete = false;
  }

#define SERIALTIMEOUT 3000
  static unsigned long serTimeoutCounter;
  if (Serial.available()) {
    char inChar = (char)Serial.read();
    if (inChar == '\n') {
      stringComplete = true;
    }
    else {
      if (inChar > 31) {
        inputString += inChar;
        serTimeoutCounter = millis();
      }
    }
  }
  if (millis() > SERIALTIMEOUT &&
      serTimeoutCounter < millis() - SERIALTIMEOUT &&
      inputString != "") {
    stringComplete = true;
  }

}

This Cplusplus link should answer your questions.

I strongly believe you will find your code easier to manage if you put the receiving code into a function in the way it is done in Serial Input Basics. My idea in writing that tutorial was that users would simply include one of my functions into their project.

...R

Yes, thanks. I intend to use functions and will use one to receive. I plan to make a function that will receive in much the same manner as I have done in my code, allowing for a timeout and/or end of line character, and use a char array instead of String object.

String object definitely makes working with strings more friendly, and I realize it is a crutch. I will need to do lots of homework to get the same functionality out of char arrays, and that work will be best handled by functions as well. It would be nice to find some examples of how people are using char arrays to do things similar to what I'm doing in the if statements in my code.

Everybody learns differently, some visually, others by example, and other by the book. I have the book and do study it, and I am making slow progress, as I learn better with examples. I also have formal education on C and C++, although char arrays have always been my weak spot. I am just not good at it yet. In fact, I'm exceptionally bad at it. I got a D- in those chapters and in pointers and reference types! If you know of any posts, blogs, books, etc. which cover specifically converting common String object use cases to char array, please let me know.