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...

  • 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 '15 at 0:49
  • I'll give that a shot – Eddie Sherman Nov 12 '15 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 } } } – Eddie Sherman Nov 12 '15 at 1:11
  • Entering 4 ... it outputs 4 -49 So it's somehow jumping and setting ledState before I enter anything. – Eddie Sherman Nov 12 '15 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 '15 at 1:46
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;
    }
  }    

}
  • 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. – Eddie Sherman Nov 12 '15 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.

  • 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... – Eddie Sherman Nov 12 '15 at 0:22
  • I've updated my post...so you can see the output and new code. – Eddie Sherman Nov 12 '15 at 0:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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