Hello,
I want to be able to control a RGB led over serial by writing different Analog values.
The problem is that Serial.read() only returns one value a time.
What would be the best method to process data which is sent like:
r=0
g=255
b=255
Hello,
I want to be able to control a RGB led over serial by writing different Analog values.
The problem is that Serial.read() only returns one value a time.
What would be the best method to process data which is sent like:
r=0
g=255
b=255
What would be the best method to process data which is sent like:
One character at a time.
PaulS:
What would be the best method to process data which is sent like:
One character at a time.
Yes, I could save these characters in a buffer, but how will I be able to convert the buffer to a int which can be used for PWM.
null terminate it and use atoi
You can capture the values as a string, and then convert the string into a number. The below shows how to capture a string and convert it into a number for use for servo control. If you can attach a delimiter to each value sent to keep the values seperate (like using a comma, 254,128,200,90,), then possibly simpler code can be used.
// zoomkat 12-13-11 serial servo (2) test
// for writeMicroseconds, use a value like 1500
// for IDE 1.0
// Powering a servo from the arduino usually DOES NOT WORK.
// two servo setup with two servo commands
// send eight character string like 15001500 or 14501550
// use serial monitor to test
#include <Servo.h>
String readString, servo1, servo2;
Servo myservo1; // create servo object to control a servo
Servo myservo2;
void setup() {
Serial.begin(9600);
myservo1.attach(6); //the pin for the servo control
myservo2.attach(7);
Serial.println("two-servo-test-1.0"); // so I can keep track of what is loaded
}
void loop() {
while (Serial.available()) {
delay(3); //delay to allow buffer to fill
if (Serial.available() >0) {
char c = Serial.read(); //gets one byte from serial buffer
readString += c; //makes the string readString
}
}
if (readString.length() >0) {
Serial.println(readString); //see what was received
// expect a string like 07002100 containing the two servo positions
servo1 = readString.substring(0, 4); //get the first four characters
servo2 = readString.substring(4, 8); //get the next four characters
Serial.println(servo1); //print to serial monitor to see parsed results
Serial.println(servo2);
int n1 = servo1.toInt();
int n2 = servo2.toInt();
Serial.println("the numbers are :");
Serial.println(n1); //print to serial monitor to see number results
Serial.println(n2);
myservo1.writeMicroseconds(n1); //set servo position
myservo2.writeMicroseconds(n2);
readString="";
}
}
'readString' was not declared in this scope
How to solve it?
thenamefirst:
'readString' was not declared in this scope
How to solve it?
You probably messed something when selecting / coping, here it works out of the box.
Personally, I would use strtok. Read and buffer the entire line, then parse it, something like this (untested...):
char buffer [32];
int cnt = 0;
boolean ready = false;
int rgbval, red, green, blue;
void ParseLine
{
char key[8];
char value[8];
key = strtok(buffer, "="); // Everything up to the '=' is the color name
value = strtok(NULL, "\n"); // Everything else is the color value
if ((key != NULL) && (value != NULL))
{
rgbval = atoi(value);
switch (toupper(key))
{
case 'R'
red = rgbval;
break;
case 'G'
green = rgbval;
break;
case 'B'
blue = rgbval;
break;
}
}
}
void loop()
{
if (ready)
{
ParseLine();
ready = false;
} else while (Serial.available())
{
char c = Serial.read();
buffer[cnt++] = c;
if ((c == '\n') || (cnt == sizeof(buffer)-1))
{
buffer[cnt] = '\0';
cnt = 0;
ready = true;
}
}
}
thx
The examples in serial input basics should do what you need.
...R
why i adapt this code to use like this:
#include <Servo.h>
#include <SPI.h>
#include <SD.h>
const int chipSelect = 4;
File myFile;
String readString, servo1, servo2;
void setup() {
Serial.begin(9600);
while (!Serial)
{
; //
}
Serial.print("Initializing SD card...");
if (!SD.begin(chipSelect)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
myFile = SD.open("FIRST1.txt");
if (myFile)
{
Serial.println("FIRST1.txt:");
}
else
{
Serial.println("error opening test.txt");
}
}
void loop() {
myFile = SD.open("LL.txt");
if (myFile){
delay(3); //delay to allow buffer to fill
if (myFile.available() >0) {
char c = myFile.read(); //gets one byte from serial buffer
readString += c; //makes the string readString
}
if (readString.length() >0) {
Serial.println(readString); //see what was received
}
}
}
and my SD card have 12345678 data
but the result was
1
11
111
1111
11111
111111
1111111
thenamefirst:
why i adapt this code to use like this:
What do you mean by "this" ? What was the original code before you changed it?
...R
Greetings.
Try this code
#define red 9
#define green 10
#define blue 11
int tblue = 0;
int tgreen = 0;
int tred = 0;
void setup() {
pinMode(blue, OUTPUT);
pinMode(red, OUTPUT);
pinMode(green, OUTPUT);
Serial.begin(115200);
color(255,0,0);
}
void loop() {
if(Serial.available()>0){
tred=Serial.parseInt();
tgreen=Serial.parseInt();
tblue=Serial.parseInt();
color(tred,tgreen,tblue);
Serial.println("red " + (String)tred + " green " + (String)tgreen + " blue " + (String)tblue);
}
}
void color(int cred, int cgreen, int cblue) {
analogWrite(red, cred);
analogWrite(green, cgreen);
analogWrite(blue, cblue);
}
Sending 0,255,255 for r,g,b
the original code is #4 i change it to read data from SD card.
my SD card data is 12345678
but when i use #10 code the result is
1
11
111
1111
11111
111111
myFile = SD.open("LL.txt");
if (myFile){
delay(3); //delay to allow buffer to fill
if (myFile.available() >0) {
That delay is just plain stupid. The SD.open() function doesn't return until the associated buffer has been filled.
Then, you read one character from the file, append it to the String instance, print the string, end loop(), and open the file again.
The if in the snippet above needs to be a while, to read the whole file.
I would suggest using Serial.readStringUntil("\n")
which waits until the carriage return character is read or the end of the timeout.
foadsf:
I would suggest usingSerial.readStringUntil("\n")
which waits until the carriage return character is read or the end of the timeout.
Error:
invalid conversion from 'const char*' to 'char' [-fpermissive]
Need to use single instead of double quotes for only one character, this works:
String inputString = Serial.readStringUntil('\n');
See too:
foadsf:
I would suggest usingSerial.readStringUntil("\n")
which waits until the carriage return character is read or the end of the timeout.
I would advise not to promote the use of String (capital S) objects; there is the risk of memory fragmentation which might result in unpredictable run time behaviour. readBytesUntil is a far better option and Robin's Serial Input Basics tutorial is far preferred.
Note
This thread is 7 years old