Go Down

Topic: Buffer and serial input (Read 1 time) previous topic - next topic

Jassper

Jan 20, 2009, 03:40 pm Last Edit: Jan 20, 2009, 03:41 pm by Jassper Reason: 1
relevant code;
Code: [Select]

while(Serial.available())
       {  
       c = Serial.read();
       if(c < '0' || c > '9') return;
       S_buffer[iReceived++] = (char)c;
       }
   iValue = atoi(S_buffer);


The buffer is defined as;
char S_buffer[] = "000";

If I send "142" to the code, iValue is returned as 142, ok no issue there, but I want to be able to send a string from "60" to "600". So what do I need to change in the code so when I send "63" iValue is 63 and when I send "432", i Value is 432?

As it is now, I have to send "063" to get iValue to equal 63.

mem

#1
Jan 20, 2009, 04:07 pm Last Edit: Jan 20, 2009, 06:39 pm by mem Reason: 1
You do need some method of determining the end of the string. Always sending 3 characters (as in "063") is perfectly acceptable way to achieve this.

Other solutions are to have a terminating character (a carriage return or 0 for example) that your receive routine could detect. Or you could send the number of characters as the first byte of the string.

But simplest is what you are doing - pad your string with leading zeros so its always three characters.

Jassper

Thanks for the info.

The serial is comeing from a touch panel user interface, I was hoping to avoid the need to insert a null infront if the number wass less than 99, but I guess it is just as easy.

westfw

Code: [Select]

 iValue = 0;
 while(Serial.available()) {  
    c = Serial.read();
    if (c < '0' || c > '9')
      return;
    iValue = iValue * 10 + (c - '0');
  }
 return;
This is a very "standard" algorithm for reading numbers from text.  Note that you'll need to make sure that all the data has been received BEFORE this piece of code runs; serial data arrives much more slowly than ardunio code executes.

Jassper

Thanks, I'll check this out, but don't I need to change the c to an actual number first or does it do that by subtracting the 0x30?

halley

#5
Jan 21, 2009, 08:57 pm Last Edit: Jan 21, 2009, 08:58 pm by halley Reason: 1
In ASCII, all the digit characters are in order, and in the range 0x30 to 0x39.  This is intentional.  Subtracting 0x30 from the character will give you the value of the digit.  Adding 0x30 from a value will give you the appropriate digit (assuming values 0-9).

The C language shortcuts this, so you can type '0' to refer to the 0x30 value.  It makes it quite readable:  an expression (ch - 'A') tells you how far into the alphabet a character is, from 0 to 25;  an expression (ch - '0') tells you the numeric value of a digit character.  To convert upper to lowercase, ch = ch + ('a'-'A').  Etc.

Jassper

#6
Jan 21, 2009, 09:32 pm Last Edit: Jan 21, 2009, 09:34 pm by Jassper Reason: 1
Quote
In ASCII, all the digit characters are in order, and in the range 0x30 to 0x39.  This is intentional.  Subtracting 0x30 from the character will give you the value of the digit.  Adding 0x30 from a value will give you the appropriate digit (assuming values 0-9).

The C language shortcuts this, so you can type '0' to refer to the 0x30 value.  It makes it quite readable:  an expression (ch - 'A') tells you how far into the alphabet a character is, from 0 to 25;  an expression (ch - '0') tells you the numeric value of a digit character.  To convert upper to lowercase, ch = ch + ('a'-'A').  Etc.


Yep, I figured that out. But thanks!! - see, I'm learning  8-)

actually I learned all this before, but that was about 20 years ago

drspectro

Since this is a human interface you dont have to always enter 3 characters or use a termination char.  You can also wait until you have not received any input for a second (or half sec.).    

If the user enters more than 2-3 chars, you decide whether to keep the first 3 or the last 3 entered.   Or you could decide more than 3 chars signals a mistake and ignore all input until there is a 1 sec pause.

Think about setting time on a digital clock.  

Go Up