user59122: I got an Arduino UNO today, and I am just writing a basic blink program. I have 3 LEDS on the arduino. Those LEDS are connected to Pin 1, 2, and 3.
Now I can control those LED by writing octal values 0 to 7 to the /dev/ttyUSB0.
The code I have written so far is:
# pragma GCC optimize ("Ofast")

# define LED1 1
# define LED2 2
# define LED3 3

char buf[4] ;
unsigned char inp, len ;

void setup() {
    pinMode(LED1, OUTPUT) ;
    pinMode(LED2, OUTPUT) ;
    pinMode(LED3, OUTPUT) ;
    
    Serial.begin(9600) ;
}

void loop() {
    len = Serial.readBytes(buf, 3) ;
            
    if (len) {
        buf[3] = '\0' ;
        inp = atoi(buf) ;

        // Illuminate LEDs
        digitalWrite(LED1, 1 & inp ? HIGH : LOW) ;
        digitalWrite(LED2, 2 & inp ? HIGH : LOW) ;
        digitalWrite(LED3, 4 & inp ? HIGH : LOW) ;
    }
}

So when I write:

0 turns off all the LEDS
1 turns on LED on pin 1
2 turns on LED on pin 2
3 turns on LED on pin 1 and 2
4 turns on LED on pin 3
5 turns on LED on pin 1 and 3
6 turns on LED on pin 2 and 3
7 turns on all the LEDS.

The problem is that, when I write 7 for example, it takes up to 1 second to turn on the LEDS. If I write 0, it takes another second to turn off the LEDS.
Is there way to control the LEDS in close to real-time?

user313: You're calling Serial.readBytes() when there may or may not be 3 bytes available. If there aren't 3, the call waits for them to arrive or for a timeout. That's the delay you are seeing.
If you really want 3 bytes at a time, check whether there are 3 before you try to read them:
if( Serial.available >= 3 )
   len = Serial.readBytes(buf, 3);

When the if fails - because there aren't three bytes available - you won't waste any time waiting for them.

user42015: When sending multiple bytes which together form a single message it is best to use a delimiter character and read the data until there. That way you don't run into timeouts and you can be sure, that the received data represents a full message.
In the cases where the LEDs need 1s to react you are most likely sending less than 3 bytes, which causes the Serial.readBytes() function to time out after the default 1s. I guess you are currently always sending only 1 byte (though you are trying to read 3 byte in your code).
To use a delimiter character there are multiple ways. The easiest fix would be using Serial.readStringUntil('\n'). The newline character (which I used as a parameter here) is a common delimiter character. You would then need to aways send the newline character at the end of a full message.
Just setting the timeout very low is not a very good solution. With a low baudrate as 9600 that can easily mean, that the message is chopped up into multiple parts, because the transmission takes longer than the timeout.

Besides that: I don't really understand, why you need to receive 3 bytes for turning on or off 3 LEDs. One byte (even, when you are just using single digits) has a big enough data space for more than these 3 LEDs. Also you are not really using octal numbers. atoi() is expecting a string representation of a decimal number. There is nothing octal in your code. And then you are using the first 3 bits of the resulting number for controlling the LEDs.
All in all this seems quite complicated for a very basic task. Maybe there is some reason for that, which you didn't write about.

59122: <p>I got an Arduino UNO today, and I am just writing a basic blink program. I have 3 LEDS on the arduino. Those LEDS are connected to Pin 1, 2, and 3.</p>
<p>Now I can control those LED by writing octal values 0 to 7 to the <code>/dev/ttyUSB0</code>.</p>
<p>The code I have written so far is:</p>
<pre><code># pragma GCC optimize (&quot;Ofast&quot;)

# define LED1 1
# define LED2 2
# define LED3 3

char buf[4] ;
unsigned char inp, len ;

void setup() {
    pinMode(LED1, OUTPUT) ;
    pinMode(LED2, OUTPUT) ;
    pinMode(LED3, OUTPUT) ;
    
    Serial.begin(9600) ;
}

void loop() {
    len = Serial.readBytes(buf, 3) ;
            
    if (len) {
        buf[3] = '\0' ;
        inp = atoi(buf) ;

        // Illuminate LEDs
        digitalWrite(LED1, 1 &amp; inp ? HIGH : LOW) ;
        digitalWrite(LED2, 2 &amp; inp ? HIGH : LOW) ;
        digitalWrite(LED3, 4 &amp; inp ? HIGH : LOW) ;
    }
}
</code></pre>
<p>So when I write:</p>
<ul>
<li>0 turns off all the LEDS</li>
<li>1 turns on LED on pin 1</li>
<li>2 turns on LED on pin 2</li>
<li>3 turns on LED on pin 1 and 2</li>
<li>4 turns on LED on pin 3</li>
<li>5 turns on LED on pin 1 and 3</li>
<li>6 turns on LED on pin 2 and 3</li>
<li>7 turns on all the LEDS.</li>
</ul>
<p>The problem is that, when I write 7 for example, it takes up to 1 second to turn on the LEDS. If I write 0, it takes another second to turn off the LEDS.</p>
<p>Is there way to control the LEDS in close to real-time?</p>
 313: <p>You're calling <code>Serial.readBytes()</code> when there may or may not be 3 bytes available. If there aren't 3, the call waits for them to arrive or for a timeout. That's the delay you are seeing.</p>
<p>If you really want 3 bytes at a time, check whether there are 3 before you try to read them:</p>
<pre><code>if( Serial.available &gt;= 3 )
   len = Serial.readBytes(buf, 3);
</code></pre>
<p>When the <code>if</code> fails - because there aren't three bytes available - you won't waste any time waiting for them.</p>
 42015: <p>When sending multiple bytes which together form a single message it is best to use a delimiter character and read the data until there. That way you don't run into timeouts and you can be sure, that the received data represents a full message.</p>
<p>In the cases where the LEDs need 1s to react you are most likely sending less than 3 bytes, which causes the <code>Serial.readBytes()</code> function to time out after the default 1s. I guess you are currently always sending only 1 byte (though you are trying to read 3 byte in your code).</p>
<p>To use a delimiter character there are multiple ways. The easiest fix would be using <code>Serial.readStringUntil('\n')</code>. The newline character (which I used as a parameter here) is a common delimiter character. You would then need to aways send the newline character at the end of a full message.</p>
<p>Just setting the timeout very low is not a very good solution. With a low baudrate as 9600 that can easily mean, that the message is chopped up into multiple parts, because the transmission takes longer than the timeout.</p>
<hr />
<p>Besides that: I don't really understand, why you need to receive 3 bytes for turning on or off 3 LEDs. One byte (even, when you are just using single digits) has a big enough data space for more than these 3 LEDs. Also you are not really using octal numbers. <code>atoi()</code> is expecting a string representation of a decimal number. There is nothing octal in your code. And then you are using the first 3 bits of the resulting number for controlling the LEDs.</p>
<p>All in all this seems quite complicated for a very basic task. Maybe there is some reason for that, which you didn't write about.</p>
