Help with strtoul() function.

Hello all.

New to world of Arduino and as a electronic hardwear engineer this programing side is all new to me but learning fast thanks to the forums :).

Ok, i would like to use the function strtoul() but i don't fully understand how to use it so would like your help in understanding how to use the function correctly.

I have a ASCII string for example,

"41 05 1C 7B" (received over the serial)

but i'm only interested in the "1C 7B" and would like to convert it to HEX to get something like "0x1C7B" stored to a unsigned long. So if anyone could show/explain this to me it will be a great help.

Look forward to your replies, thanks.

The following code assumes that you save the whole ASCII string into a character array (reading from serial is usually a slow process with characters arriving one after another).

char buffer[12]; //your message with a trailing '\0'

// read from serial and maybe check if message has the correct length

char * pch;
uint32_t nResult= 0;
byte nPos= 0;
pch= strtok(buffer, " ");
  if(nPos > 1) // ignore first and second hex value
    nResult= (nResult << 8) | (strtoul(pch, NULL, 16) & 0xff);
  pch= strtok(NULL, " ");

The code is not efficient or fail save. Basically your string is divided into smaller substrings and in the loop the first two “bytes” are skipped and the following bytes are combined to the result by reading a single byte (result from stroul is 32 bit, hence the mask to 8 bit) and shifting the previous value of the result by 8 bits and placing the read byte into this now free space.

Another approach would be to modify the buffer directly to get those two bytes of interest together without the space in between and then use strtoul().

1 Like

Something like this?

char str[] = {'4','1','0','5','1','C','7','B','\0'};
unsigned long result = strtoul(str, NULL, 16); 
unsigned int result_int;
result = result &0xFFFF; //getting rid of 0x4105
result_int = result &0xFFFF; //getting rid of 0x4105

Should work. :) I haven't compiled it... so chances are that this may put out some errors.

Thanks for the replies an will have a look at them. From searching around i came up with the below, whould that not work do you think?

define NULL '\0'

char serialrx[16]; char buffer[8];

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

void loop() { byte i = 6; serialrx[6]; //start conversion from the 6th byte while(serialrx != NULL) buffer[i++] = strtoul (serialrx, NULL, 16); i = 6;


Please use the code tags (button # above the smilies).

Concerning the code you posted:

#define NULL '\0'

This one is not necessary.

char serialrx[16];
char buffer[8];

void setup() {

Serial.flush() changed in Arduino 1.0. Before it cleared the receive buffer. Since v1.0 it waits for the transmit buffer to be empty / the transmission to be finished. Not really necessary in setup().

void loop() {
  byte i = 6;
  serialrx[6];                                                     //start conversion from the 6th byte

This line does nothing.

  while(serialrx != NULL)
  buffer[i++] = strtoul (serialrx, NULL, 16);
  i = 6;

And this code is bogus. serialrx is a pointer to an array of characters. serialrx[pos] means one of the characters in the array. This looks like a try in using pointer arithmetics or maybe some very old code for reading the serial receive buffer. The way it is now serialrx is never NULL because it is defined as a global array - the pointer to the array stored in serialrx is not NULL.

From my point you need to learn some of the C programming basics and some C++ to use libraries supplied with Arduino.

Lets go through all step by step. Let us assume all input via serial connection looks like your example string - four hex coded values with spaces between and at the end of the command an "return" ("\n" or "\n\r"). First step is to get the input from Serial. All data arrives bytewise and the ATmega328 on the Arduino is a lot faster than the transmission via Serial. You could use a buffer for the incoming data and when a "return" arrives the whole string is evaluated. While reading data you could filter the spaces out and ignore any '\r' only looking for '\n'. This helps for the second step using strtoul like bubulindo did in his post. For the reading you need some kind of a loop which collects and filters incoming data.

  boolean bWaitingInput= true;
    uint8_t nBufferPos= 0; // position in the array where a new character is saved
    if(nBufferPos >= BUFFER_MAX) // is the buffer full?
      serialrx[BUFFER_MAX - 1]= '\0'; // make a valid string by setting the last buffer character to '\0'
      Serial.print("buffer overflow: ");
      Serial.println(serialrx); // transmit what the buffer holds for debugging
      nBufferPos= 0; // reset the buffer
    if(Serial.available()) // something arrived via serial connection?
      char c=; // read the new character
        case '\r':
        case ' ':
          break; // do nothing with space or '\r'
        case '\n':
          serialrx[nBufferPos++]= '\0'; // a string must have 0 at the end, so we add it here
          bWaitingInput= false; // we have data for evaluation
        default: // all other characters go into the buffer
          serialrx[nBufferPos++]= c;
  Serial.print("received: ");

Now strtoul could be used on serialrx (no spaces to interfere are in the buffer). BUFFER_MAX is a define for the buffer size. Search for "post increment" to understand the filling of the buffer with the position variable. This is for a start. If you have no idea what's going on then use Serial.println() to show you results in the serial monitor. PaulS proposes to use a pen and paper and think of what you would do step by step to get your problem solved - I like this idea.