A Byte of Serial

Hi Folks,

I'm struggling with something which I just can't get to the bottom of. When I use Serial.read I can't find a way to read a group of characters together. For example if I upload the following code to Arduino:

int incomingByte = 0;
void setup() {
      Serial.begin(9600);
}
void loop() {
      if (Serial.available()) {
            // read the incoming byte:
            incomingByte = Serial.read();
            Serial.println(incomingByte, DEC);
      }
}

..how can I force the arduino to read say 3 characters typed into the Serial Monitor as one whole number?

I'm in the process of establishing communication between a great authoring program called Runtime Revolution and the Arduino and so far I can read sensors and switch things on and off but I can't get PWM to work because of the above problem. For example I need to be able to send 255 as a whole number to get a full PWM and 123 to get half. However at the moment if I send 255 via the Serial Monitor or Runtime Revolution arduino sets the PWM to 2 then 5 and then 5.

Any help or advice greatly appreciated.

This post follows on from http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1228694318 Mikal Hart helped me a great deal but I didn't want to be any more demanding of his time so I dropped the subject.

Jim H

// a memory area large enough for our largest expected input token
// plus an extra char for a '\0' string terminator that we'll add
char buffer[4];
int received;

void setup()
{
    Serial.begin(9600);

    // empty (and terminate) the buffer
    received = 0;
    buffer[received] = '\0';
}

void loop()
{
    if (Serial.available())
    {
        // receive a character at the end of our buffer
        // (and terminate the buffer again so it's a string)
        buffer[received++] = Serial.read();
        buffer[received] = '\0';

        // what do we have so far?
        Serial.print("buffer contains: [");
        Serial.print(buffer);        Serial.println("]");

        // filled the buffer?
        if (received >= (sizeof(buffer)-1))
        {
            Serial.print("key received... ");
            if (0 == strcmp("EDH"))
                Serial.println("unlocked!");
            else
                Serial.println("invalid! try again");

            // empty the buffer or we'll overflow
            received = 0;
        }
    }
}
buffer contains: [a]
buffer contains: [ab]
buffer contains: [abc]
key received... invalid! try again
buffer contains: [E]
buffer contains: [ED]
buffer contains: [EDH]
key received... unlocked!

If you want the input to be treated as a number instead of a literal string like a PIN or PASSCODE, then you can use the standard function atoi() to turn the current buffer string into a numerical value. However, you'll need to know when the user is done typing a number, usually by having the user type a NON-DIGIT afterwards, or making the user type leading zeroes to ensure all input has a fixed number of digits. Otherwise, you'd never be able to enter values like 3 or 62.

Blimey, Thankyou! That looked frighteningly complicated to me but by some sort of miracle I've managed to work it out:

#include <stdlib.h>     // needed for atoi
char buffer[4];
int received;
int ledPin = 9;
void setup()
{
    Serial.begin(9600);
    received = 0;
    buffer[received] = '\0';
}
void loop()
{
    if (Serial.available())
    {
        buffer[received++] = Serial.read();
        buffer[received] = '\0';
        if (received >= (sizeof(buffer)-1))
        {
            Serial.print(buffer);
int myInt = atoi(buffer); 
    analogWrite(ledPin, myInt);
            received = 0;
        }
    }
}   }
}

"Leading zeros" - wow that's a brilliant idea and so simple! I intended to ask about terminating characters in my original question but didn't want to complicate things.

Thanks a million.

Jim H

Outstanding, Jim! That's a very nice solution. Sorry I lost track of that other thread. :smiley:

Good luck!

Mikal