Writing integer values using Serial.read()

OK, I give up. How can I write, using the built in hyperterminal or any other method (VB.Net), an actual integer value, e.g. 255, or 100, or 34 without the Arduino converting it to ASCII? I want to type in a number (x) and have the PWM IO's set to analogWrite(PinNum, x). Everything I've tried so far just writes the ASCII code for the first character entered. HELP!!!

Tom.

It isn't actually being converted to ASCII, it is ASCII. Anything entered is, by definition, ASCII, and only ASCII. Code is needed to convert the entered ASCII characters to an integer suitable for analogWrite(). One possibility would be to use the atoi() function.

No. If I type '255' into the serial monitor and send it, the arduino receives the ASCII value of 2, which is 50. It doesn't do anything with the last 2 numbers in '255', only the 2 is processed and it is sent to the PWM output as the ASCII value of 50.

If I type '255' into the serial monitor and send it, the arduino receives the ASCII value of 2, which is 50. It doesn't do anything with the last 2 numbers in '255', only the 2 is processed and it is sent to the PWM output as the ASCII value of 50.

That's because your sketch is incomplete.
It is also invisible.
Jack Christensen was quite correct.

Consider how exceedingly stupid computers are (including that subset we know and love, microcontrollers). They need to be told just about how to do everything :wink:

ASCII characters are received one character (or byte, since in this case characters are 8 bits, same as a byte) at a time via the serial interface. Every time Serial.read() is called, it returns the next character, unless there are none, in which case it returns -1. (Note that Serial.read() actually returns an int, which is 16 bits, but let's ignore that for now.)

Now we humans will type numbers as a string of ASCII characters. Consider some of the problems the processor has in interpreting the input. All these need to be addressed* in the code that processes the incoming characters. (1) How will the start and end of the number be determined? I might want to enter the number 42. I might type the 2 one second after the 4, or, if the phone rings, several minutes after the 4. How shall we interpret the "-1" condition? (2) Can I just enter "42", or is "0042" allowed? Is "42.00" allowed? (3) What shall we do if I type "00A2"? (4) Note that up until now, the unspoken assumption has been that the number is entered as a base 10 number. What if I want to enter a hexadecimal number? (may not be a consideration for your example). (5) What if I want to enter more than one number (ditto).

*Addressed may mean simply making an assumption, or it may mean complex and robust coding.

Now I've made it more complicated than it absolutely has to be, but the point is to appreciate that interpretation of typed input is not necessarily a trivial problem. In general, we need to check syntax, possibly the range of the entered value, and react accordingly. Assumptions can be made that will simplify the coding considerably, but the code may be more error-prone as a result. In this case we could assume the number is always typed as exactly three characters, and that all those characters are digits, 0-9. There are several failure modes here. If more or less than three characters are entered, we may not get the intended value. If letters are entered, we may get an error or invalid value. With three digits, we can enter values that are inappropriate for analogWrite(). But for a first pass in a testing situation, these assumptions may be perfectly fine.

Hope that helps. Not to brighten your day too much, but consider that people have died as a result of mishandling of human input by the code in computer-controlled radiation therapy machines. Google "Therac 25".

Now we humans will type numbers as a string of ASCII characters

And in the dim and distant past, we typed numbers in as a stream of EBCDIC characters.
That's a measure of how far we have progressed in the last thirty years.

LOL, I was pretty much an ASCII guy, the EBCDIC guys were down the hall. But I could translate :wink: Actually spoke with Bob "Yes, I am the Father of ASCII" Bemer a few times, although I'm not sure I entirely realized who he was at the time. So that's my claim to fame, hahaha.

No. If I type '255' into the serial monitor and send it, the arduino receives the ASCII value of 2, which is 50. It doesn't do anything with the last 2 numbers in '255', only the 2 is processed and it is sent to the PWM output as the ASCII value of 50.

Well, below is some simple servo code I use that converts a typed string to a number that night help you.

// zoomkat 10-4-10 serial servo test
// type servo position 0 to 180 in serial monitor
// for writeMicroseconds, use a value like 1500
// for IDE 0019 and later
// Powering a servo from the arduino usually DOES NOT WORK.

String readString;
#include <Servo.h> 
Servo myservo;  // create servo object to control a servo 

void setup() {
  Serial.begin(9600);
  myservo.attach(7);  //the pin for the servo control 
  Serial.println("servo-test-21"); // so I can keep track of what is loaded
}

void loop() {

  while (Serial.available()) {
    delay(1);  
    if (Serial.available() >0) {
      char c = Serial.read();  //gets one byte from serial buffer
      readString += c; //makes the string readString
    } 
  }

  if (readString.length() >0) {
    Serial.println(readString);  //so you can see the captured string 
    int n;
    char carray[6]; //converting string to number
    readString.toCharArray(carray, sizeof(carray));
    n = atoi(carray); 
    myservo.writeMicroseconds(n); // for microseconds
    //myservo.write(n); //for degees 0-180
    readString="";
  } 
}

Thanks Zoomkat.
Sorry about the "invisible" sketch. Here it is. I think I can now muddle my way through it.

int ledPin = 9;      // LED connected to digital pin 9
int val = 125;         // variable to store the read value

void setup()
{
  pinMode(ledPin, OUTPUT);   // sets the pin as output
  Serial.begin(9600);
  //writeSpeed(val);
}

void loop()
{
  while (Serial.available() < 1)
  {
  }
  int speed = Serial.read();
  writeSpeed(speed);
}
void writeSpeed(long x)
  {
   analogWrite(ledPin, x);
   Serial.println(x);
  } 
void doSomething(int y)

  {
   switch(y)
  {
    case 'f':
    val = val + 5;
    if (val > 255)
     {
      val = 255;
     }
    writeSpeed(val);
    break;
    case 's':
    val = val - 5;
    if (val < 10)
      {
        val = 10;
      }
    writeSpeed(val);
    break;
  }
  }