Go Down

Topic: Help for Seral.read() (Read 944 times) previous topic - next topic

Jun 01, 2012, 04:04 pm Last Edit: Jun 01, 2012, 05:13 pm by stunito0o0 Reason: 1
Hi gyus,
I have a little problem with my code.I found out that when you  send somethng to   "Serial.read () ;" it receives  number's position in ASCII table.For example if i send 1 it receives 49.Do you now  I can make it to receive the number  I send, not its ASCII position?Here is my code:
Code: [Select]
int escPin = 2;
int myAngle;
int pulseWidth;
int keyboardValue=0;
int incomingByte=0;
void setup ()
{
Serial.begin(9600);
pinMode (escPin, OUTPUT);
}
void servoPulse (int escPin, int myAngle)
{
pulseWidth = (myAngle * 10) + 600;
digitalWrite (escPin, HIGH);
delayMicroseconds (pulseWidth);
digitalWrite (escPin, LOW);
}
void loop ()
{
if (Serial.available() > 0) {
               incomingByte = Serial.read();
                Serial.print("I received: ");
                Serial.println(incomingByte, DEC);

}

keyboardValue=incomingByte+70;
for (myAngle = keyboardValue; myAngle <= keyboardValue; myAngle++)
{
servoPulse (escPin, myAngle);
delay (20);
}
}

PS.Sorry for my bad english hope you understand my question. :):)

Grumpy_Mike

Quote
I can make it to receive the number  I send,

Is it a single digit number or a multi digit number?

For a single digit number you can use this function
Code: [Select]

int convertFromHex(int ascii){
  if(ascii > 0x39) ascii -= 7; // adjust for hex letters upper or lower case
  return(ascii & 0xf);
}

call it with the value read from Serial.read and it returns the key as a number. Note this will not only work for decimal numbers but for hex values sent as upper case or lower case.


Is it a single digit number or a multi digit number?

For a single digit number you can use this function
Code: [Select]

int convertFromHex(int ascii){
 if(ascii > 0x39) ascii -= 7; // adjust for hex letters upper or lower case
 return(ascii & 0xf);
}

call it with the value read from Serial.read and it returns the key as a number. Note this will not only work for decimal numbers but for hex values sent as upper case or lower case.



It wil be from 0 to 100 .O I am sorry ,but can u fix my code i'm bad with english and cant understand you fully.Thx in advance :)

James C4S

It is a bad idea to use incomingByte in the way you did, because it gets used whether it has been updated or not.  Seems like everything should be within the if-statement.
Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com


It is a bad idea to use incomingByte in the way you did, because it gets used whether it has been updated or not.  Seems like everything should be within the if-statement.

I'm not sure i uderstand you write,but i need it to be that way because i need to spin the motor without stopping,+ that when incomingbyte is 0 the esc is in neutral possition.But thx for the anser i will have it in mind next time. :):)

James C4S


I'm not sure i uderstand you write,but i need it to be that way because i need to spin the motor without stopping,+ that when incomingbyte is 0 the esc is in neutral possition.But thx for the anser i will have it in mind next time. :):)


Quote
Code: [Select]
if (Serial.available() > 0) {
               incomingByte = Serial.read();
                Serial.print("I received: ");
                Serial.println(incomingByte, DEC);

}
keyboardValue=incomingByte+70;

keyboardvalue will be changed whether there was a new character from serial or not.
Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

Oh I think I understand you this time.You mean that it has to be someting like this :
Code: [Select]

if (incomingByte!=0)
{
keyboardValue=incomingByte+70;
for (myAngle = keyboardValue; myAngle <= keyboardValue; myAngle++)
{
servoPulse (servoPin, myAngle);
delay (20);
}
}

AWOL

Code: [Select]
for (myAngle = keyboardValue; myAngle <= keyboardValue; myAngle++)
Why?
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.


Code: [Select]
for (myAngle = keyboardValue; myAngle <= keyboardValue; myAngle++)
Why?

Actualy I am not sure too.When i started to test it  the motor was spining for a second then stops then spin again.It was setted like this
Code: [Select]
for (myAngle = 10; myAngle <= 170; myAngle++)
and i found out that when i make them eaven 
Code: [Select]
for (myAngle = 170; myAngle <= 170; myAngle++)
it the motor spins without stopping.The speed is controled by changing the numbers from 70 to 170.The only problem i have is that i cant  make  the serial function to reseave what i send not the ASCII table.
I am not sure you understand me :D

michael_x

Quote
For example if i send 1 it receives 49.Do you know how I can make it to receive the number I send, not its ASCII position?

I think one main problem is your idea about ascii / binary and serial transmission.

If you use Serial Monitor , enter a "1" and press Send, the text being sent to Arduino consists of that character '1' which shows up as a decimal number 49. Similarly, cou could send an 'A' and would receive a 65.

You might have different code on the sending side, directly sending a single byte with a value of 0 to 100, but that's not Serial Monitor.
Rather make it to interpret the characters you send: "100"  are 3 ascii characters, plus hopefully a newline character that indicates the end of the number.

See Nick Gammon's hints on dealing with Serial input ( He prefers visible markers to indicate start and end of numbers like "<100>"  )

Quote
Oh I think I understand you this time.You mean that it has to be someting like this :
  if (incomingByte!=0)

You're on the way. Unfortunately, incomingByte is not 0 any more after you received anything. You might set it to 0 whenever your loop restarts, or in an else { } banch of if( Serial.available() )

Arrch

#10
Jun 01, 2012, 05:13 pm Last Edit: Jun 01, 2012, 05:44 pm by Arrch Reason: 1
The only problem i have is that i cant  make  the serial function to reseave what i send not the ASCII table.

You have a couple options. Since you're not sure exactly how many digits the user is going to send, the most common is to use a start and/or stop byte. Everything between is processed as part of the number. Simple example:

Code: [Select]
const char STOP_BYTE = '\n'; // In the serial monitor, you will need to select the appropriate drop down to append the newline char
char buffer[20]; // stores the characters to be converted to an int
...
void loop() {
 static byte i=0;
 if (Serial.available() > 0) {
   char inByte = Serial.read();
   if (inByte==STOP_BYTE) { // We've received the end of our input
     buffer[i] = '\0'; // null terminate the string
     int data = atoi(buffer);
     // Do something with the data int
     i=0; // reset the index
   } else {
     buffer[i++] = inByte; // add character to buffer and increment index
   }
 }
}


What this does is stores every character received into a char array. When it received the newline character it null terminates the array (making it a string) and calls the atoi function which converts a string to an int. You then do what you want with the int and reset the index. The important thing to note is that you need to send a newline after you're done inputting the number. If using the Arduino serial monitor, change the appropriate drop down in the bottom right.

Hey again guys I hope i am not too cheeky,but can u help a little bit more i am not sure what i do wrong.
Code: [Select]
int escPin = 2;
int myAngle;
int pulseWidth;
int keyboardValue=0;
int incomingByte=0;
const char STOP_BYTE = '\n'; // In the serial monitor, you will need to select the appropriate drop down to append the newline char
char buffer[20]; // stores the characters to be converted to an int
void setup ()
{
Serial.begin(9600);
pinMode (escPin, OUTPUT);
}
void servoPulse (int escPin, int myAngle)
{
pulseWidth = (myAngle * 10) + 600;
digitalWrite (escPin, HIGH);
delayMicroseconds (pulseWidth);
digitalWrite (escPin, LOW);
}

void loop() {
  static byte i=0;
  if (Serial.available() > 0)
  {
    char inByte = Serial.read();
    if (inByte=='\n') // We've received the end of our input
    {
      buffer[i] = '\0'; // null terminate the string
      int data = atoi(buffer);
      // Do something with the data int
      i=0; // reset the index
    }
    else {
      buffer[i++] = inByte; // add character to buffer and increment index
    }
  }
}
keyboardValue=data+70;
for (myAngle = keyboardValue; myAngle <= keyboardValue; myAngle++)
{
servoPulse (escPin, myAngle);
delay (20);
}
}

errors:
1 expected constructor,destructor,or type of conversion before '='token
2 expected unqualified-id befor 'for'
3 expected constructor,destructor,or type of conversion  before '<=' token
4 expected constructor,destructor,or type of conversion  before '++' token
5 expected declaration before '}' token
Thx in advance. :)

Arrch


Hey again guys I hope i am not too cheeky,but can u help a little bit more i am not sure what i do wrong.

Too many/too little curly braces. This is where proper formatting helps a great deal. Do yourself a favor and use the auto format tool in the Arduino IDE (Tools > Auto Format) and it should be more apparent.

dxw00d

Unfortunately, Auto-format just tells you that there are too many close braces.

I think this one is superfluous:
Code: [Select]
}
keyboardValue=data+70;


You are then left with data being out of scope on that line.

i fixed it  :smiley-roll-sweat:
Code: [Select]
int escPin = 2;
int myAngle;
int pulseWidth;
int keyboardValue=0;
int incomingByte=0;
const char STOP_BYTE = '\n'; // In the serial monitor, you will need to select the appropriate drop down to append the newline char
char buffer[20]; // stores the characters to be converted to an int
void setup ()
{
Serial.begin(9600);
pinMode (escPin, OUTPUT);
}
void servoPulse (int escPin, int myAngle)
{
pulseWidth = (myAngle * 10) + 600;
digitalWrite (escPin, HIGH);
delayMicroseconds (pulseWidth);
digitalWrite (escPin, LOW);
}

void loop() {
 static byte i=0;
 if (Serial.available() > 0)
 {
   char inByte = Serial.read();
   if (inByte=='\n') // We've received the end of our input
   {
     buffer[i] = '\0'; // null terminate the string
     int data = atoi(buffer);
     // Do something with the data int
     i=0; // reset the index
      keyboardValue=data+70;
     
for (myAngle = keyboardValue; myAngle <= keyboardValue; myAngle++)
{
servoPulse (escPin, myAngle);
delay (20);
}
   }
   else {
     buffer[i++] = inByte; // add character to buffer and increment index
   }
 }
}

but the esc doesnt even arm  :( what am i doing wrong now

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy