I found some really useful code online to allow me to read multiple digit integers from the Serial monitor.
But i want to make it work with multiple multi-digit numbers seperated by a comma and stored in different variables.
here's the code:
void setup() {
Serial.begin(9600);
}
int integerValue=0;
// Max value is 65535
char incomingByte;
void loop() {
if (Serial.available() > 0) { // something came across serial
integerValue = 0; // throw away previous integerValue
while(1) { // force into a loop until 'n' is received
incomingByte = Serial.read();
if (incomingByte == '\n') break; // exit the while(1), we're done receiving
if (incomingByte == -1) continue; // if no characters are in the buffer read() returns -1
integerValue *= 10; // shift left 1 decimal place
// convert ASCII to integer, add, and shift left 1 decimal place
integerValue = ((incomingByte - 48) + integerValue);
}
Serial.println(integerValue);
}
}
How would i go about to doing so?
Say the Serial Monitor input is : 123,456
i want it to be stored in two values so that
Var1 = 123
Var2 = 456
Instead of using 2 variables, you should use an array and a counter instead. Then you can check if the incoming value is not a comma, store it into the array, if it is a comma, increment the counter.
The program you posted does not actually use the Serial.parseInt() function so I am intrigued by the thread title.
As it stands the program stops reading input when a Newline character is received. As a strart to answering your question you could perhaps change
if (incomingByte == '\n') break; // exit the while(1), we're done receiving
to exit the (very clumsy) while(1) loop if either a Newline or a comma is received. You could then increment a counter to give you a value to test to determine which variable the number received should be stored in. As has been suggested this could usefully be in an array but that is up to you.
Note that the above suggestion is based on your current code which is not the best way to do what you want. Why, for instance have the while(1) loop when the loop() function provides the same mechanism ?
You could read all of the input at one time using Serial.readByteUntil('\n', buffer, maxLenght) and then use strtok() to pull out the individual numbers.
Thank you guys!
The while loop is so only that part of the code runs until the arguments are fufilled and then it breaks out and runs the rest of the code .
I dont quite understand what you mean by using a counter.
lele_gricc:
Thank you guys!
The while loop is so only that part of the code runs until the arguments are fufilled and then it breaks out and runs the rest of the code .
You could do stuff outside of the loop() function once the appropriate conditions are met. Doing it that way you can also do other things in the loop() function that would be impossible using while(1) because that would prevent other code being executed.
I dont quite understand what you mean by using a counter.
Initialise a variable to use as a counter to zero before reading the input. Every time you finish reading in a value that you want to save, use the value of the counter to decide where to save it and increment the counter ready for the next input and the next storage decision. The counter can conveniently be used as the index to an array of that is what you decide to use.
int cnt = 0
void setup() {
Serial.begin(9600);
}
int integerValue=0;
char storedData[2];
// Max value is 65535
char incomingByte;
void loop() {
if (Serial.available() > 0) { // something came across serial
integerValue = 0; // throw away previous integerValue
while(1) { // force into a loop until 'n' is received
incomingByte = Serial.read();
if (incomingByte == '\n') break;
if (incomingByte == ','){
cnt++;
break;
} // exit the while(1), we're done receiving
if (incomingByte == -1) continue; // if no characters are in the buffer read() returns -1
integerValue *= 10; // shift left 1 decimal place
// convert ASCII to integer, add, and shift left 1 decimal place
integerValue = ((incomingByte - 48) + integerValue);
}
storedData[cnt] = integerValue;
Serial.println(storedData[cnt]);
}
}
Try this amended version based on your code. I have commented the changes that I made
int cnt = 0; // <<<<<<<<< added the semi colon
int integerValue=0;
int storedData[2]; //<<<< the value to be stored is an int but only space for 2 of them as written
// Max value is 65535
char incomingByte;
void setup()
{
Serial.begin(115200);
}
void loop()
{
if (Serial.available() > 0) { // something came across serial
integerValue = 0; // throw away previous integerValue
while(1) { // force into a loop until 'n' is received
incomingByte = Serial.read();
if (incomingByte == '\n' || incomingByte == ',') //<<<<<<<<< break on Newline or comma
{
break;
} // exit the while(1), we're done receiving
if (incomingByte == -1) continue; // if no characters are in the buffer read() returns -1
integerValue *= 10; // shift left 1 decimal place
// convert ASCII to integer, add, and shift left 1 decimal place
integerValue = ((incomingByte - 48) + integerValue);
}
storedData[cnt] = integerValue;
Serial.println(storedData[cnt]);
cnt++; //<<<<<<<<<<<<<<<increment index after storing and printing
}
}
The below code does something similar to what you might want to do.
//zoomkat 11-12-13 String capture and parsing
//from serial port input (via serial monitor)
//and print result out serial port
//copy test strings and use ctrl/v to paste in
//serial monitor if desired
// * is used as the data string delimiter
// , is used to delimit individual data
String readString; //main captured String
String angle; //data String
String fuel;
String speed1;
String altidude;
int ind1; // , locations
int ind2;
int ind3;
int ind4;
void setup() {
Serial.begin(9600);
Serial.println("serial delimit test 11-12-13"); // so I can keep track of what is loaded
}
void loop() {
//expect a string like 90,low,15.6,125*
//or 130,hi,7.2,389*
if (Serial.available()) {
char c = Serial.read(); //gets one byte from serial buffer
if (c == '*') {
//do stuff
Serial.println();
Serial.print("captured String is : ");
Serial.println(readString); //prints string to serial port out
ind1 = readString.indexOf(','); //finds location of first ,
angle = readString.substring(0, ind1); //captures first data String
ind2 = readString.indexOf(',', ind1+1 ); //finds location of second ,
fuel = readString.substring(ind1+1, ind2+1); //captures second data String
ind3 = readString.indexOf(',', ind2+1 );
speed1 = readString.substring(ind2+1, ind3+1);
ind4 = readString.indexOf(',', ind3+1 );
altidude = readString.substring(ind3+1); //captures remain part of data after last ,
Serial.print("angle = ");
Serial.println(angle);
Serial.print("fuel = ");
Serial.println(fuel);
Serial.print("speed = ");
Serial.println(speed1);
Serial.print("altidude = ");
Serial.println(altidude);
Serial.println();
Serial.println();
readString=""; //clears variable for new input
angle="";
fuel="";
speed1="";
altidude="";
}
else {
readString += c; //makes the string readString
}
}
}
This source is the same length as zoomkat's, but compiles to about half the memory.
A simple "atoi" would convert the strings to integers that could then be compared.
No mucking about with nasty Strings.
In my code the sent characters are captured as a String and not a c-string. The below link has the String functions detailed out. Your "fuel was more than angle" is not very clear. With the String functions character strings can be compared. If what you want to compare are numerical values, then the captured numerical character string would need to be converted into a number and the usual numeric comparison functions >, <, ==, etc. could be used.
I found this simple code on a book I am reading for learning
int led = 13;
void setup(){
pinMode(led, OUTPUT);
Serial.begin(9600);
}
void loop(){
if (Serial.available()){
char com = Serial.read();
// Act according to the value received
if (com == 'x'){
// Stop the LED
digitalWrite(led, LOW);
}
else if (com == 'a'){
// Start the LED
digitalWrite(led, HIGH);
}
else if (com == 'b'){
// Blink with a delay corresponding to the value received after 'b'
if (Serial.peek() > '0' && Serial.peek() <= '9'){
digitalWrite(led, HIGH);
delay((Serial.read() - 48) * 100); // 48 is ASCII for '0'
digitalWrite(led, LOW);
}
}
}
}
I tried with my board but doesn't work...
I changed it after a lot of googling, like this.
int led = 13;
int x;
String str;
void setup() {
pinMode(led, OUTPUT);
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0)
{
str = Serial.readStringUntil('\r');
x = Serial.parseInt(char 'b');
}
// Act according to the value received
if (str == "x") {
// Stop the LED
digitalWrite(led, LOW);
Serial.println(str);
str = "c"; //change value of str to avoid endless printing of x
}
else if (str == "a") {
// Start the LED
digitalWrite(led, HIGH);
Serial.println(str);
str = "c"; //change value of str to avoid endless printing of a
}
else if (str == "b") {
digitalWrite(led, HIGH);
delay(x * 100);
digitalWrite(led, LOW);
Serial.print(str);
Serial.println(x);
str = "c"; //change value of str to avoid endless printing of b
}
// }
}
But still I cannot get my led blink.
Can anyone help me?
Why the first sketch does not work in the first place?
Thank you anyway.
lele_gricc:
For zoomkat how would i go about comparing the numbers recieved ?
Say i wanted to check that fuel was more than angle... how would i do so since they are strings?
Servo test code that receives a string numeric value as a String, and converts the numeric value into a number for a servo command. In your situation you could extract the numeric value, convert to a number, then make the greater/less than comparison.
//zoomkat 11-22-12 simple delimited ',' string parse
//from serial port input (via serial monitor)
//and print result out serial port
//multi servos added
// Powering a servo from the arduino usually *DOES NOT WORK*.
String readString;
#include <Servo.h>
Servo myservoa, myservob, myservoc, myservod; // create servo object to control a servo
void setup() {
Serial.begin(9600);
//myservoa.writeMicroseconds(1500); //set initial servo position if desired
myservoa.attach(6); //the pin for the servoa control
myservob.attach(7); //the pin for the servob control
myservoc.attach(8); //the pin for the servoc control
myservod.attach(9); //the pin for the servod control
Serial.println("multi-servo-delimit-test-dual-input-11-22-12"); // so I can keep track of what is loaded
}
void loop() {
//expect single strings like 700a, or 1500c, or 2000d,
//or like 30c, or 90a, or 180d,
//or combined like 30c,180b,70a,120d,
if (Serial.available()) {
char c = Serial.read(); //gets one byte from serial buffer
if (c == ',') {
if (readString.length() >1) {
Serial.println(readString); //prints string to serial port out
int n = readString.toInt(); //convert readString into a number
// auto select appropriate value, copied from someone elses code.
if(n >= 500)
{
Serial.print("writing Microseconds: ");
Serial.println(n);
if(readString.indexOf('a') >0) myservoa.writeMicroseconds(n);
if(readString.indexOf('b') >0) myservob.writeMicroseconds(n);
if(readString.indexOf('c') >0) myservoc.writeMicroseconds(n);
if(readString.indexOf('d') >0) myservod.writeMicroseconds(n);
}
else
{
Serial.print("writing Angle: ");
Serial.println(n);
if(readString.indexOf('a') >0) myservoa.write(n);
if(readString.indexOf('b') >0) myservob.write(n);
if(readString.indexOf('c') >0) myservoc.write(n);
if(readString.indexOf('d') >0) myservod.write(n);
}
readString=""; //clears variable for new input
}
}
else {
readString += c; //makes the string readString
}
}
}