SerialRead More than One Number

hi, i want to give a price to my variable from serial, for example 2103. But Serial.Read reads only one number per time, in my example the number "2". How can I give directly form serial.read the whole number to my variable?

How can I give directly form serial.read the whole number to my variable?

You can't. But, this might help.

http://jhaskellsblog.blogspot.com/2011/05/serial-comm-fundamentals-on-arduino.html

This issue only gets asked once a week or so, so we can see that you did a great job of searching first.

char price[10];
int num;
int i;
//Variables

while(price[i]){
  price[i] = 0;
  i++;
}
i=0;
//Clear the array

While(Serail.available()){ //If there is stuff to be read,
  price[i]=Serial.read();
  i++;
}
//Save the data

num=0;
boolean multiplier;
boolean dataPiece;
while(price[i]){
  num+=(price[i]*pow(10,datapiece));
  i--;
  dataPiece++;
}
//Turn the array into an integer

This should work. It saves the numbers into an array as they come in, then turns them from an array to an integer.

Onions.

This should work.

Did you try it? Did you even compile it?

while(price[i]){
  price[i] = 0;
  i++;
}

It isn't necessary to put a NULL in every position. Put a NULL in the first position, and then add a NULL after every character is added.

In any case, this is a bad way to to put the NULLs in the array. This code will quite happily run past the end of the price array, and stomp all over other data.

While(Serail.available()){ //If there is stuff to be read,
  price[i]=Serial.read();
  i++;
}

while, not While.

Serial data arrives slowly. This loop will read any data that has arrived. If half the number string has arrived, this code will read half a number, and assume it has the whole number.

boolean dataPiece;
while(price[i]){
  num+=(price[i]*pow(10,datapiece));
  i--;
  dataPiece++;
}

dataPiece is defined as a boolean, not initialized, and used as a number. byte is the same size, and implies that the variable being defined IS a number, while boolean does not.

pow is a very expensive function to use. It is also inappropriate, as it uses all float arguments, and returns a float. pow(10,2) will return 3.999999999999999999, which is 3 when stored in an int.

If price were properly NULL terminated (and complete), atoi() could be used to convert the array to a value, without the issues involved using pow (it's smarter than that).

If price were properly NULL terminated (and complete), atoi() could be used to convert the array to a value, without the issues involved using pow (it's smarter than that).

I knew of atoi(), but not how to use it. I decided to use pow() instead, although it is not something I have needed to use before...

Did you try it? Did you even compile it?

Nope :blush:

It isn't necessary to put a NULL in every position. Put a NULL in the first position, and then add a NULL after every character is added.

I've never thought of that, but it is a brilliant idea!

while, not While.

:blush:

dataPiece is defined as a boolean, not initialized, and used as a number. byte is the same size, and implies that the variable being defined IS a number, while boolean does not.

I have absolutely no idea why I declared it as a boolean; as you say, declaring it as a byte would actually work (unlike boolean), without taking up any more RAM.

Serial data arrives slowly. This loop will read any data that has arrived. If half the number string has arrived, this code will read half a number, and assume it has the whole number.

This calls for delay() !

Onions.

This calls for delay() !

It most certainly does not. It calls for the sender to send some end-of-packet marker. If the sender sends 1234, the Arduino can read any available character, storing it in the array (followed by a NULL) if it is not a . If it is a , the the sketch should call atoi() with the array, use the value returned, and reset for the next batch of serial data.

Read the blog I first posted a link to.

PaulS:

This calls for delay() !

It most certainly does not. It calls for the sender to send some end-of-packet marker. If the sender sends 1234, the Arduino can read any available character, storing it in the array (followed by a NULL) if it is not a . If it is a , the the sketch should call atoi() with the array, use the value returned, and reset for the next batch of serial data.

Read the blog I first posted a link to.

My mistake. I thought you meant a call to serial read will stop the arduino from reading any data and accept any bits it has already received as the final number.
I assume for atoi() you pass it a char array, and the return value is the integer?

num = atoi(price[]);

Onions.

I assume for atoi() you pass it a char array, and the return value is the integer?

Yes, but the brackets are not supposed to be there.

int num = atoi(price);

Here is some working code then:

char startChar = '

The method is simple; type in $ followed directly by a number (E.G. $12345) then press enter. The arduino will print out the number you typed in. It works, but has one strange flaw... It types out each individual digit on a new line, then the whole number. E.G. 0 4 45 459

Where have these extra numbers come from!?

Onions.; // or '!', or whatever your start character is char endChar = '\r'; char buffer[10]; boolean storeString = false; //This will be our flag to put the data in our buffer int index; int num;

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

void loop(){   while(!Serial.available());  //This means the program will only send an output when you send an input. It prevents long lists of numbers coming out when you are not doing anything, but should be deleted in a normal program.   while(Serial.available()>0){     char incomingbyte = Serial.read();     if(incomingbyte==startChar){       index = 0;  //Initialize our index variable       storeString = true;       break;     }     if(storeString){       if(incomingbyte==endChar){         buffer[index] = 0; //null terminate the C string         //Our data string is complete.  Parse it here         storeString = false;       }       else{         buffer[index++] = incomingbyte;       }     }   }   num=atoi(buffer);   Serial.println(num); } ```

The method is simple; type in $ followed directly by a number (E.G. $12345) then press enter. The arduino will print out the number you typed in. It works, but has one strange flaw... It types out each individual digit on a new line, then the whole number. E.G. 0 4 45 459

Where have these extra numbers come from!?

Onions.

Where have these extra numbers come from!?

You printed them:

  num=atoi(buffer);
  Serial.println(num);

You only want to convert and print the number when incomingbyte == endChar. After converting and printing, you need to initialize the array.

Simple servo test code that probably has what is needed.

// zoomkat 11-27-10 serial servo test
// type servo position 0 to 180 in serial monitor
// for writeMicroseconds, use a value like 1500
// for IDE 0019 and later
// Powering a servo from the arduino usually DOES NOT WORK.

String readstring; //string to be captured from serial port
#include <Servo.h> 
Servo myservo;  // create servo object to control a servo 

void setup() {
  Serial.begin(9600);
  myservo.attach(7);  //the pin for the servo control 
  Serial.println("servo-test-21"); // so I can keep track of what is loaded
}

void loop() {

  while (Serial.available()) {
    delay(10);  
    if (Serial.available() >0) {
      char c = Serial.read();  //gets one byte from serial buffer
      readstring += c; //makes readstring from the single bytes
    } 
  }

  if (readstring.length() >0) {
    Serial.println(readstring);  //so you can see the captured string 
    char carray[readstring.length() + 1]; //determine size of the array
    readstring.toCharArray(carray, sizeof(carray)); //put readstringinto an array
    int n = atoi(carray); //convert the array into an Integer 
    myservo.writeMicroseconds(n); // for microseconds
    //myservo.write(n); //for degees 0-180
    readstring="";
  } 
}