I want to send character "3" before accessing servos program, but it is not working.
here my code
#include <Servo.h>
String readString, servo1, servo2;
Servo myservo1; // create servo object to control a servo
Servo myservo2;
int result;
void setup() {
Serial.begin(9600);
myservo1.attach(8); //the pin for the servo control
myservo2.attach(7);
Serial.println("test"); // to keep track of what is loaded
}
void loop() {
if(Serial.available()){
result = Serial.read();
if (result== '3'){
while (Serial.available()) {
Serial.println("xxx"); //just make sure that the program have entered the if loop
delay(5); //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
servo1 = readString.substring(0, 3); //get the first three characters
servo2 = readString.substring(3, 6); //get the next three characters
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.write(n1);
myservo2.write(n2);
readString="";
servo1="";
servo2="";
}
}
}
}
I use serial monitor, and the the program is fail to read the 6 character for moving the servos.
If your requirement can't be met by sending single characters to control every option then you need to develop a more sophisticated strategy for sending data that will work in every case. As @PaulS suggests, a good idea is to receive all the characters until some end-marker is detected and then analyse what was received to decide what needs to be done. A simple end-marker is a Carriage Return. You can get the Arduino Serial Monitor to add one automatically.
Another good strategy is to separate the function for getting data from the PC from the function that acts on that data. Then both functions will be easier to debug and extend to meet future requirements.
How to process incoming serial data without blocking
You really should look at the State machine part as it directly addresses what you are doing.
snip--
State Machine
Another way of processing incoming data, without blocking, is to set up a "state machine". Effectively this means looking at each byte in the input stream, and handling it depending on the current state.
As an example, say you had this coming into the serial port:
R4500S80G3
Where Rnnn is RPM, Snnnn is speed, and Gnnnn is the gear setting.
The state machine below switches state when it gets a letter "R", "S" or "G". Otherwise it processes incoming digits by multiplying the previous result by 10, and adding in the new one.
When switching states, if first handles the previous state. So for example, after getting R4500 when the "S" arrives, we call the ProcessRPM function, passing it 4500.
This has the advantage of handling long messages without even needing any buffer, thus saving RAM. You can also process message as soon as the state changes, rather than waiting for end-of-line.
the link that Nick gave is very helpful, I will use this the method, but for a moment I am using this code an working but not to well.
the different just moving the delay(5) to the place before while (Serial.available()) {
Here is the code:
#include <Servo.h>
String readString, servo1, servo2;
Servo myservo1; // create servo object to control a servo
Servo myservo2;
int result;
void setup() {
Serial.begin(9600);
myservo1.attach(8); //the pin for the servo control
myservo2.attach(7);
Serial.println("test"); // so I can keep track of what is loaded
}
void abc () {
while (Serial.available()) {
delay(5); //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
servo1 = readString.substring(0, 3); //get the first four characters
servo2 = readString.substring(3, 6); //get the next four characters
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.write(n1);
myservo2.write(n2);
readString="";
servo1="";
servo2="";
}
}
void loop() {
if(Serial.available()){
result = Serial.read();
if (result== 'g'){
Serial.println("xxx");
delay(30);
abc();
}
}
}
Is STILL a bullshit bandaid solution that sometimes work for some baud rates. If you don't want to learn to read serial data properly, you will continue to have (intermittent) problems. Bite the bullet; learn to send and receive serial data properly.
void abc () {
Get real. This function name says NOTHING about what the function does.
Get real. This function name says NOTHING about what the function does.
I probably wouldn't have expressed myself with the same clarity, but I agree 100%.
You should use names for variables and functions and organize your code so that you will understand it with a single read-through after not seeing it for 6 months.
Is STILL a bull$#!+ bandaid solution that sometimes work for some baud rates. If you don't want to learn to read serial data properly, you will continue to have (intermittent) problems. Bite the bullet; learn to send and receive serial data properly.
The Nick Gammon blog, if learned and understood teaches that very well.
I just hope that the OP gains proficiency at C/Arduino quickly.
One rule I learned right at the start: Everything Counts. Every last letter or symbol, anything out of place WILL cause the code to either stop or do what you did not want. Double and triple check on the slightest doubt or even lack of strong certainty.
Back in my day we had no internet but we could get books and load them with bookmarks. Now with the net I keep browser tabs to whatever references I need, the Arduino site has many and web pages make the rest. Even after years of coding I still look up commands because I hate wasting time doing to fix what I didn't do right.
DON'T be guessing. Every time you check first, you reinforce the correct knowledge where if you don't then you do not learn but your knowing fades a little in doubt and shadow-poking.