hello everyone,
I realize this is probably a question that has been asked a lot, but I have researched it and still don't quite understand the solution. my problem is theat i want to drive 2 servos from the arduino, which is receiving their positions from a Processing sketch. however, I don't understand how to differentiate between the 2 servo's values, e.g. how to add a 'marker' to the string being sent, how to interpret the marker, and remove the marker so the number is by itself again. I have tried to look it up, but I just didn't really get it. Thanks.
The serial data will be read by the Arduino one byte at a time. So, if Processing sent a string like 190 followed by a carriage return the Arduino could read byte one, interpret it as referring to servo 1 then read bytes until the carriage return and interpret the number received as an angle to move to. To move servo 2 to an angle of 150 degrees the string would be 2150 followed by carriage return. This would work for up to 10 servos. Note that this uses C style strings rather than Strings.
Have a look at http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=11425&page=1 to see how to read bytes and put them in an array for processing. To convert the string into a number to use to set the servo angle look at the atoi() function.
thanks for the link, but is this processing or arduino code? in processing the code gets the error unexpected token: typedef
(line 5), and in arduino it doesnt return correct values, if it returns anything at all. I understand how to send serial data, but i dont know how to break it down into different values for separate outputs.
This appears to be a fine example to me... And exactly what I was looking for to process some data received from a BT transceiver for a Holtek HT1632 scrolling display..
void processIncomingByte (const byte c)
{
if (isdigit (c))
{
currentValue *= 10;
currentValue += c - '0';
} // end of digit
else
{
// The end of the number signals a state change
handlePreviousState ();
// set the new state, if we recognize it
switch (c)
{
case 'R':
state = GOT_R;
break;
case 'S':
state = GOT_S;
break;
case 'G':
state = GOT_G;
break;
default:
state = NONE;
break;
} // end of switch on incoming byte
} // end of not digit
} // end of processIncomingByte
???
Doc
so how do you take the values you receive from the serial connection and apply those to the value of a servo/led/etc. ? docedison's code has the switch that differentiates between R/S/B, but you obviously don't want to make a switch with 255 cases for the brightness of an led, or 180 for the position of a servo. what I want to know is how to receive values A,B, and C and make them the value of variables X,Y and Z.
Servo test code for controlling more than one servo where the servo commands are separated by a , comma..
//zoomkat 11-22-12 simple delimited ',' string parse
//from serial port input (via serial monitor)
//and print result out serial port
//multi servos added
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
}
}
}
zoomkat: The serial monitor always says: writing Angle: 0
what settings do i need on the COM window? i have 9600 baud, newline.
what exactly do i have to type? i am trying a45,
and all different values.
Ta_anders:
what exactly do i have to type? i am tryinga45,
and all different values.
In Zoomcat's example you are expected to type the angle, followed by a letter to identify the servo, followed by a comma. You are entering these in the wrong order.
thank you so much to everyone! this is exactly what i needed! time to rule the world!