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...
2 Answers 2
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– Eddie Sherman2015年11月12日 02:53:46 +00:00Commented Nov 12, 2015 at 2:53
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– Eddie Sherman2015年11月12日 00:22:11 +00:00Commented Nov 12, 2015 at 0:22
-
I've updated my post...so you can see the output and new code.Eddie Sherman– Eddie Sherman2015年11月12日 00:38:09 +00:00Commented Nov 12, 2015 at 0:38
if(ledState == 0)
not'0'
. same for'1'
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.