Hello, I am making a project where my arduino reads a value entered into the serial monitor via xbee. Currently the problem is not the xbee but the conversion from a char to an integer. I tried putting - '0' after Serial.read and that works fine but only for single digit values.
I'm not sure why it isn't working and there's more than one possible.
Is your serial monitor running at 9600?
A good thing is to put a line in setup that prints the program name (or Hello World) to show it's working.
Is it including a carriage return or newline or both at the end of sent lines?
int pos = 0;
#include <Servo.h>
Servo myservo;
void setup()
{ // when the open and close brackets are on the same indent level, it is much easier to check
Serial.begin( 9600 );
Serial.println( "\nHello World!\n" ); // the '\n' makes a new line
myservo.attach( 9 );
}
void loop()
{
if ( Serial.available() > 0 )
{
if (( pos >= '0' ) && ( pos <= '9' ) // now only digits get used
{
pos = Serial.read() - '0';
myservo.write( pos );
}
}
}
My eyes are old. I threw in some spaces to make it easier to read quickly and correctly. Bunched up typing is a great way to end up glossing over little mistakes.
Below is some servo test code that has a method of converting characters to a number for use as a servo command.
// zoomkat 12-25-13 serial servo test
// type servo position 0 to 180 in serial monitor
// or for writeMicroseconds, use a value like 1500
// Send an a to attach servo or d to detach servo
// for IDE 1.0.5 and later
// Powering a servo from the arduino usually *DOES NOT WORK*.
#include <Servo.h>
String readString; //String captured from serial port
Servo myservo; // create servo object to control a servo
int n; //value to write to servo
void setup() {
Serial.begin(9600);
myservo.writeMicroseconds(1500); //set initial servo position if desired
myservo.attach(7, 500, 2500); //the pin for the servo control, and range if desired
Serial.println("servo all-in-one test code 12-25-13"); // so I can keep track of what is loaded
Serial.println();
}
void loop() {
while (Serial.available()) {
char c = Serial.read(); //gets one byte from serial buffer
readString += c; //makes the string readString
delay(2); //slow looping to allow buffer to fill with next character
}
if (readString.length() >0) {
Serial.println(readString); //so you can see the captured string
// attach or detach servo if desired
if (readString == "d") {
myservo.detach(); //detach servo
Serial.println("servo detached");
goto bailout; //jump over writing to servo
}
if (readString == "a") {
myservo.attach(7); //reattach servo to pin 7
Serial.println("servo attached");
goto bailout;
}
n = readString.toInt(); //convert readString into a number
// auto select appropriate value
if(n >= 500)
{
Serial.print("writing Microseconds: ");
Serial.println(n);
myservo.writeMicroseconds(n);
}
else
{
Serial.print("writing Angle: ");
Serial.println(n);
myservo.write(n);
}
bailout: //reenter code loop
Serial.print("Last servo command position: ");
Serial.println(myservo.read());
Serial.println();
readString=""; //empty for next input
}
}
When you use conversion functions, be sure that either your data is pre-checked for correctness (if numbers, make sure it's all digits somehow) or you write error handling for mistypes or transmission faults, otherwise some time your program will deliver erroneous results whether you notice or not.
What can I say? Interfacing people to computers teaches a lot about what can go wrong. Good user I/O takes a bit more code. It's not good to assume flawless data unless your code constricts input to be always flawless. You can do that to some extent with character-terminals (Hyperterminal) where you have instant interaction with the user but not with Serial Monitor that doesn't get the characters until a whole line is sent, which limits interaction and forces data to be re-entered.
I have found that time spent making better than the standard I/O functions pays back well later on.
Thank you all, it sounds a bit to complicated for me right now. I would really like to know more about the coding and electronics, and if anyone knows of any good books or resources that would help, it would be greatly appreciated.
isaac868:
Thank you all, it sounds a bit to complicated for me right now. I would really like to know more about the coding and electronics, and if anyone knows of any good books or resources that would help, it would be greatly appreciated.
/*
* Read ascii serial input and convert to decimal.
* Serial input must end with a newline or a carriage return and a newline.
* So we know when input is ended.
*
*/
char inChar;
int inVal;
void setup()
{
Serial.begin ( 9600 );
Serial.println ( F ( __FILE__ ) );
Serial.println ( F ( "Read serial ascii input and convert to integer." ) );
} // setup
void loop ()
{
while ( Serial.available () > 0 )
{
inChar = Serial.read ();
switch ( inChar )
{
case '\n': // end of data input, inVal is an integer, use as needed
// print to serial out as demo
Serial.println ( inVal );
// reset inVal for next input
inVal = 0;
break;
case '0' ... '9': // capture the numeric ascii input and convert to integer
inVal = ( inVal * 10 ) + ( inChar - '0' ); // ascii -> integer
break;
} // switch
} // while Serial.available
} // loop