1

I have 8 LED's connected to a shift register on my arduino uno r3. I am trying to write a Python3 script that will prompt a user to select one of the LED's and then prompt to toggle on or off.

Should be pretty basic but I cant seem to get this working.

I have already botched my code trying to get this running:

the jist of my python script is

import serial
import os
import time

os.system('clear')

ser = serial.Serial('/dev/cu.usbmodem1431', 9600)

while True:
    led = input("Which LED do you wish to operate? (press x to quit): ")

    if led >= '0' and led <= '7':
        print("Operating LED # %s" % led)
        ser.write(str.encode(led)) # sends the choice of led to arduino'
        on_or_off = input("Do you want to turn it on or off (press 0 for off and 1 for on): ")

        if on_or_off == '0':
            #send command to arduino to turn off the selected LED
            print("Command sent to arduino to turn OFF LED %s" % led)
            ser.write(str.encode(on_or_off))
        elif on_or_off == '1':
            #send command to arduino to turn on the selected LED
            print("Command sent to arduino to turn ON LED %s" % led)
            ser.write(str.encode(on_or_off))
        else:
            print("Please enter 0 or 1 to operate the LED. ")

    elif led == 'x':
        ser.close()
        break
    else:
        continue

For some reason Arduino is only dealing with the first input...

HEre is my loop code on the arduino

void loop() {
  if(Serial.available() > 0){
    led = Serial.read(); // from python script the led to operate
    led = led - '0';
    if(led >= '0' && led <= '7'){
      if(Serial.available() > 0){
        ledState = Serial.read(); // expects the led state next
        ledState = ledState - '0';
        if(ledState == '0'){
          shiftWrite(led,LOW);
        }else if(ledState == '1'){
          shiftWrite(led,HIGH); 
        }
      }
    }
  }
}

shiftWrite is a function I wrote because there are 8 LEDS hooked to a shiftRegister

update:

I tried the state machine suggestion and it didnt work...

  void loop() {
  while(Serial.available()){
    led = Serial.read();
    led = led - '0';
    if(led>= 0 && led <= 7){
      state = 1; //We've received the LED # go to state 1
      Serial.println(led);
      Serial.println(state);
      Serial.println(ledState);
      continue;
    }
    if(state == 1){
      ledState = Serial.read();
      ledState = ledState - '0';
      if(ledState == '0'){
        shiftWrite(led,LOW);
      }else if(ledState == '1'){
        shiftWrite(led,HIGH);
      }
      state = 0; //Ended the operation return to state 0
    }
  }
}

With the serial monitor in the arduino IDE open (not running the python script) I tried this input: 4,1

This is my output on the serial monitor:

4
1
0
1
1
0

Any ideas? Basically the same problem as before...I actually thought the state machine idea would work...

7
  • You actually didn't follow exactly my solution, you're assuming that '0' is 0 and '1' is 1 while in fact, '0' = 48 and '1' = 49. You have to write if(ledState == 0) not '0'. same for '1'
    – Ikbel
    Nov 12, 2015 at 0:49
  • I'll give that a shot Nov 12, 2015 at 1:06
  • void loop() { while(Serial.available()){ led = Serial.read(); led = led - '0'; if(led >= 0 && led <= 7){ state = 1; //We've received the LED # go to state 1 Serial.println(led); } if(state == 1){ ledState = Serial.read(); ledState = ledState - '0'; Serial.println(ledState); if(ledState == 0){ shiftWrite(led,LOW); }else if(ledState == 1){ shiftWrite(led,HIGH); } state = 0; //Ended the operation return to state 0 } } } Nov 12, 2015 at 1:11
  • Entering 4 ... it outputs 4 -49 So it's somehow jumping and setting ledState before I enter anything. Nov 12, 2015 at 1:12
  • I figured it out, check your Serial Monitor, you must set it to No Line Ending. There is nothing wrong with the code, it's just the Serial Monitor, when you press Enter, it sends another character which makes the loop go crazy.
    – Ikbel
    Nov 12, 2015 at 1:46

2 Answers 2

1

Try this code, it is working as intended:

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

int state = 0; 
int led;
int ledState;

void loop() {  

  while (Serial.available())
  {
    if (state == 0)
    {

      led = Serial.read() - '0';
      if(led >= 0 && led <= 7)
      {
        state = 1;
        Serial.println("Got LED number: " + String(led)); 
        break;      
      }
    }
    if (state == 1)
    {
        ledState = Serial.read() - '0';
        if(ledState == 0)
        {
          Serial.println("LED n " + String(led) + " is now OFF");
        }
        else if(ledState == 1)
        {
          Serial.println("LED n " + String(led) + " is now ON");
        }
        state = 0;
    }
  }    

}
1
  • This makes sense. I haven't tried it against my python code...but breaking from the loop once the LED is chosen should fix my issue. I will update you tomorrow if this works. Nov 12, 2015 at 2:53
1

You're assuming that the microcontroller is going to wait until you choose LED state, which is wrong. Try this:

int state = 0; 
int led;
int ledState;

void loop() {  
  while (Serial.available())
  {
    if (state == 0)
    {
      led = Serial.read() - '0';
      if(led >= 0 && led <= 7)
      {
        state = 1; // Here we have got the LED number, go to state 1
        continue; 
      }
    }
    if (state == 1)
    {
        ledState = Serial.read() - '0';
        if(ledState == 0)
        {
          shiftWrite(led,LOW);
        }
        else if(ledState == 1)
        {
          shiftWrite(led,HIGH); 
        }
        state = 0; // Here we ended the operation, return back to state 0
    }
  }    

}

You need what we call a state machine, here I use state=0 for the state corresponding to choosing LED number, state=1 is for the state that waits for the operation ON/OFF.

2
  • I tried that, but its still not working. To debug I've got the serial monitor on the arduino ide communicating...and printing out what the arduino is receiving... I'll post a response so you can see my code... Nov 12, 2015 at 0:22
  • I've updated my post...so you can see the output and new code. Nov 12, 2015 at 0:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.