problem with readStringUntil and atoi functions

I want to read numbers which go onto a string(cause readStringUntil needs a String right?) from my bluetooth module and convert them to numbers.

This is more or less the piece of code giving errors :

String SpinIN ;
unsigned int pinIN;

Serial.begin(9600); 
if (Serial.available() > 0)

SpinIN = Serial.readStringUntil('\n');	
                        pinIN = atoi(CpinIN);

I get the followinng error :

Sketch_Tesi.ino: In function 'void loop()':
Sketch_Tesi:119: error: cannot convert 'String' to 'const char*' for argument '1' to 'int atoi(const char*)'
Sketch_Tesi:137: error: ambiguous overload for 'operator=' in 'CmodeIN = Serial.HardwareSerial::read()'
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino/WString.h:86: note: candidates are: String& String::operator=(const String&)
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino/WString.h:87: note: String& String::operator=(const char*)
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino/WString.h:88: note: String& String::operator=(const __FlashStringHelper*)

Can someone help me? :cry:

The String class (note the uppercase 'S') does not work with character array data directly. If the largest input you expect is, say, 20 characters, try defining SpinIN as a char array:

char SpinIN[21];    // Need space for null termination character

and try something like:

// whatever code is above...
int charsRead;

if (Serial.available() > 0) {
   charsRead = Serial.readBytesUntil('\n', SpinIN, 20);  // Read up to 20 chars max or newline
   SpinIN[charsRead] = '\0';                             // Make it a string
   pinIN = atoi(SpinIN);                                 // Convert to int

}

You may find useful examples in serial input basics.

...R

Nope it doesn't work, with tht code it reads just the first byte that I send

Serial input tutorial.

see if that helps.

But that example doesn't use the read until function... I already have a lot of cases in my program and iwanted to keep it the simplest i could :slight_smile: isn't there a way to make it work with that?

Ok I managed to fix somehow the proble, the only thing is that he doesn't wait for the terminating character but he like "gives some timme to type" so if I type slowly 3 numbers he'll get them separate, and if i type fast 123 he gets the number 123 ... lol

this is my code, and I'm using a bluetooth module connected to a smartphone to send the numbers

char CpinIN [10] ; 
unsigned int pinIN =0;


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

void loop(){
  
  if (Serial.available() > 0){     

Serial.readBytesUntil('\n',CpinIN,9);	
//                     
                       pinIN = atoi(CpinIN);	
                       Serial.println (pinIN);
  }
}

Alarikka:
But that example doesn't use the read until function... I already have a lot of cases in my program and iwanted to keep it the simplest i could :slight_smile: isn't there a way to make it work with that?

It tells you how to read serial input without blocking execution of the sketch. That's what it's about.
You can't have read until and do other things at the same time too.

I just read digits in as they arrive and accumulate a value without copying any of it into a buffer.
My code has the value before it hits the end of word delimiter, where convert buffered text hasn't started.

You can read text as fast as it arrives. Learn state machines. Nick shows a start on them in that blog.

Ok GoForSmoke I tried to use your advice Now this is my code :

const unsigned int MAX_INPUT = 20;
unsigned long int dataout;

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

void process_data (const char * data)
  {
  dataout = atoi(data);
  Serial.println (dataout);
  }  // end of process_data
  

void processIncomingByte (const char inByte)
  {
  static char input_line [MAX_INPUT];
  static unsigned int input_pos = 0;

  switch (inByte)
    {

    case '\n':   // end of text
      input_line [input_pos] = 0;  // terminating null byte
      
      // terminator reached! process input_line here ...
      process_data (input_line);
      
      // reset buffer for next time
      input_pos = 0;  
      break;

    case '\r':   // discard carriage return
      break;

    default:
      // keep adding if not full ... allow for terminating null byte
      if (input_pos < (MAX_INPUT - 1))
        input_line [input_pos++] = inByte;
      break;

    }  // end of switch
   
  } // end of processIncomingByte  

void loop()
  {
  while (Serial.available () > 0)
    processIncomingByte (Serial.read ());
    
  }

The problem is now that if I send up to 5 characters all goes well ( if I type 12345 I get 12345) , but when I try to type 6 or more characters it just gives me random numbers like -->> 123456 = 423476650.
What am I doing wrong?

atoi returns an int. Try atol.

Thak you! :grinning: :grinning:

This is more like I mean. dataout is calculated as each digit comes in, the value is interpreted before the delimiter is read, not interpret after and with no buffer or need to include string.h either. I've been coding I/O that way since the 80's when you really had to work to make fast programs.

unsigned long dataout;

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

void processIncomingValue(const char inByte)
{
  static unsigned int input_pos = 0;

  switch (inByte)
  {

  case '\n':   // end of text terminator reached!
    Serial.println(dataout);
    dataout = 0;
    break;

  case '\r':   // discard carriage return
    break;

  default:
    if ( inByte >= '0' && inByte <= '9' )
    {
      dataout *= 10UL;
      dataout += inByte - '0';
    }
    else // anything but '\n', '\r' or a digit ends numeric interpretation
    {
      Serial.println(dataout);
      dataout = 0;
    }
    break;

  }  // end of switch

} // end of processIncomingByte  

void loop()
{
  if ( Serial.available() > 0 )
    processIncomingValue( Serial.read() );

}