Help for Seral.read()

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:

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. :):slight_smile:

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

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.

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

For a single digit number you can use this function

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 :slight_smile:

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. :):slight_smile:

stunito0o0:
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. :):slight_smile:

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.

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

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

Why?

AWOL:

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

for (myAngle = 10; myAngle <= 170; myAngle++)

and i found out that when i make them eaven

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 :smiley:

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>" )

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() )

stunito0o0:
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:

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.

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. :slight_smile:

stunito0o0:
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.

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

I think this one is superfluous:

}
 keyboardValue=data+70;

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

i fixed it :cold_sweat:

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 :frowning: what am i doing wrong now

for (myAngle = keyboardValue; myAngle <= keyboardValue; myAngle++)

Think about what your're trying to accomplish with this statement, because no matter what the value of keyboardValue, this loop will only run once.

( I already highlighted that one)

Any good reason for not using the servo library?

AWOL:
( I already highlighted that one)

Any good reason for not using the servo library?

I heard that it can controll only 2 servos at once i need 4 ,but that doesn't matter anyway i fixed it .I just had to put one "for" cicle in setup function XD .THX for the quick help guys you are the best. In Bulgarian forums everyone just ignore you just because you are new at this. :X .THX again gyus you save my day :).If i have any other questions i'will write again. :slight_smile:

I heard that it can controll only 2 servos at once

Not so. Up to 12 with a standard board

I heard that it can controll only 2 servos at once

That's the second time someone has said that this week. Where does that come from? It quite clearly says twelve on the Servo library reference page.