1

I'm trying to make a tuner. 3 leds are connected to the Arduino Uno board, each one corresponding to one situation (too high, low or correct height). Python handles the detecting of a note according to the mic input, and determines which led should be turned on, but as it's a live tuner, Python sends the information pretty fast. I've figured out how to turn a led on one at a time and keep it on as long as the input doesn't change, but it only works at a low speed when I do it manually, with a Python program like this :

code=1
while code!=0:
    code=input("Code?")
    ser.write(code.encode('utf-8')) 

If I try it with a Python code such as :

code= '5'
while 1:
    ser.write(code.encode('utf-8'))

then the LEDs just stay off.

Here is my Arduino Code :

int hauteur = 0;
void setup() {
    pinMode (2, OUTPUT); //red pin
    pinMode (6, OUTPUT); //green pin
    pinMode (5, OUTPUT); //yellow pin
    Serial.begin(9600);
}

void loop() {
    if(Serial.available ()) {
        hauteur = Serial.parseInt();

        while (hauteur==2) {
            (digitalWrite(2,HIGH));
            if (Serial.available ()) {
                hauteur=Serial.parseInt();
            }
        }
        digitalWrite(2,LOW);

        while (hauteur==5){
            (digitalWrite(5,HIGH));
            if (Serial.available ()) {
                hauteur=Serial.parseInt();
            }
        }
        digitalWrite(5,LOW);

        while (hauteur==6){
            (digitalWrite(6,HIGH));
            if (Serial.available ()) {
                hauteur=Serial.parseInt();
            }
        }
        digitalWrite(6,LOW);

        Serial.flush();
    }
}

If 2, 5 or 6 are sent by Python with enough time in between them, then the board does what it's supposed to do and turns on the according LED. However sent too fast nothing happens anymore. How can I reduce that necessary lapse of time to get a real time change of lights according to what's sent by Python?

001
  • 13,291
  • 5
  • 35
  • 66
sheyy_dt
  • 11
  • 2

2 Answers2

0

I don't think the Arduino should have an issue with how fast you send the data. Serial data is kind of slow. At 9600 baud that's only about 960 bytes/sec (8 bits plus start/stop bits).

Also note, on the Arduino, digitalWrite can be slow. For faster results see: https://www.arduino.cc/en/Reference/PortManipulation

Try this:

// Create an array so we can use a loop
// Another advantage is you can easily add leds
int leds[] = {2,5,6};
const int num_leds = sizeof(leds)/sizeof(leds[0]); // = 3
void loop()
{
    if (Serial.available()) {
        hauteur = Serial.parseInt();
        // Turn hauteur ON and others OFF
        for (int i = 0; i < num_leds; i++) {
            digitalWrite(leds[i], leds[i] == hauteur ? HIGH : LOW);
        }
    }
}
001
  • 13,291
  • 5
  • 35
  • 66
0

The Arduino is recieving from the Python program. In order for it to not lag behind, it needs to be polling the serial line faster than Python sends the commands.

In other words, you need to slow down the Python serial commands as the Arduino can't keep up (yes you are flushing the line on the Arduino side, but it is better to just always be waiting for any incoming data).

So I would re-write your Python code with some time.sleep calls:

while 1:
    #code to modify the value of `code`...
    ser.write(code.encode('utf-8'))
    time.sleep(0.1)

As for the Arduino side, I think you have a mis-understanding of how the digitalWrite function works. Once you set a pin on or off, it remains in that state until you toggle it to the other state. This means you do not need to constantly tell it to stay on in a while loop, you can just tell it once what state it should be in.

This simplifies your code to:

int hauteur;
void setup() {
    pinMode(2, OUTPUT); //red pin
    pinMode(6, OUTPUT); //green pin
    pinMode(5, OUTPUT); //yellow pin
    Serial.begin(9600);
}

void loop() {
    if (Serial.available()) {
        hauteur = Serial.parseInt();
        digitalWrite(2, hauteur == 2);
        digitalWrite(5, hauteur == 5);
        digitalWrite(6, hauteur == 6);
        Serial.flush()
    }
}

So instead of using any unnecessary ifs or whiles, you can just set the state of each LED to the evaluation of whether the received integer is equal to that pin.

Joe Iddon
  • 20,101
  • 7
  • 33
  • 54