Read byte from Serial to 6 LEDS

My first post. Please correct me if I´m doing something wrong.

I´ve made this program that reads info from serial and writes the value binary to 6 LEDs. I don´t feel that it´s the easiest or the fastest way though and that is what I´m really looking for. My code looks like this:

boolean enable = false;

void setup()
{
  for (int i = 2; i < 8; i++)
  {
    pinMode(i, OUTPUT);
  }
  Serial.begin(9600);
}

void loop()
{
  if (Serial.available() > 0)
  {
    enable = true;
  }
  if (enable)
  {
    while (Serial.available() > 0)
    {
      byte b = Serial.parseInt();
      b = constrain(b, 0, 63);
      byte val = b;
      for (int i = 7; i >= 2; i--)
      {
        if (pow(2, (i-2)) <= val)
        {
          digitalWrite(i, HIGH);
          val -= pow(2, (i-2));
        }
        else
        {
          digitalWrite(i, LOW);
        }
      }
    }
    enable = false;
  }
  delay(100);
}

A valid code example would be nice. I´ve tried using PORTD but it does not work. I've also posted this on stackoverflow arduino - Read byte from Serial - Stack Overflow. The arduino I have is an 2560 Mega which I have bought.

You haven't set the serial line speed.

  if (pow(2, (i-2)) <= val)

Don't use "pow" for integers.
bitSet and bitClear are easy starting points for bit manipulation

Ohh I have set the Serial line speed. For some reason it have been removed here. Il make an edit to show that it´s there. I´l look into bitSet and bitClear. Have PORTD been removed? I just wonder since it seemed very easy and fast.

I don't see PORTD in your code.

The 'enable' has no function, since 'available' already returns if something is available.
Calling 'available' twice can be avoided.
Walking the bits can be done with the bitRead().
http://arduino.cc/en/Reference/BitRead

So you want to send the decimal value in ascii text ?
Like "16" or "22".

I have not tested the code below, but I hope you find it easy to read.

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

  for (int i = 2; i < 8; i++)
  {
    pinMode(i, OUTPUT);
  }
}

void loop()
{
  if (Serial.available() > 0)
  {
    // Some serial input is detected.
    // The parseInt function waits for the reception of characters,
    // until a non-decimal character is received.
    // So it is not needed to wait for the characters here.
    int x = Serial.parseInt();
    x = constrain(i, 0, 63);

    for (int i = 7; i >= 2; i--)
    {
      // This can be done in a single line.
      // digitalWrite(i, bitRead(x, i));
      // But that is not easy to read.
      // Below is a normal if.. else.
      if (bitRead(x, i))
      {
        digitalWrite(i, HIGH);
      }
      else
      {
        digitalWrite(i, LOW);
      }
    }
  }
  // A delay is possible, but not needed.
  // delay(10);
}

Added: Something very wrong with that code.
The Serial.parseInt() could be waiting for a long time until a non-decimal character is received. And if it reads a CR of a LF, it returns zero.
My guess is that the leds turn immediately off, if the CR or LF is received.
Checking for CR or LF would read a character from the stream and Serial.parseInt() can no longer be used.
Solution: Use a start character. Like 'L' (as in Led). If you transmit "L22\r\n" you can search the stream for the 'L' and do a Serial.parseInt() after that.

Thank you, I´l try that out. :slight_smile:

The Serial.parseInt() could be waiting for a long time until a non-decimal character is received.

Actually, it has a timeout built in (one second, if memory serves), so it won't block forever.

Examples of reading from serial: http://www.gammon.com.au/serial