0
votes

I am trying to control a total of 6 LEDS with python. I was using pyserial to send arduino some data but I have encountered several problems with it.

The first problem I have encountered was:

According to the code I have written on arduino, the LEDS should blink for 1 second for several amount of times a specific data received. (This is later explained below.) However, the LEDS stay on the number of seconds they should blink. Meaning if the LEDS are supposed to blink for 10 times. The LEDS stay on for 10 seconds and turn off.

The second problem was:

The if conditions I have put in the code was not in order. As you can see in the arduino code, the if conditions are in order. However, this is what happens when I run the code.

The first LED lights up for 10 seconds, the second one lights up for 10 seconds as well. And later on the fifth one lights up.

To explain a little more of the code:

I am storing lists inside a list inside of python. There is a for loop that sends each list with a delay of 1 second. The list has 6 elements.( This is for later experimentation.) However, in this work only the first two of elements of each list matter.

In order to negate the auto reset on arduino, I put 10 microfarad capacitor between the ground and reset. After that I run the python code to send the data.

I think I have explained the situation with details, however I am open to suggestions and will answer questions on the comments.

The Python Code:

import time

import serial

 
incomingByte2=[[1,20,200,300,400,500],[2,30,24,63,200],[3,5,400,500,100,200],[4,10,1,1,1,1],[5,10,1,1,1,1],[6,10,1,1,1,1]]

uzunluk= len(incomingByte2)


def close():

#    arduino=serial.Serial("COM4",9600)

   

    arduino = serial.Serial(

            port='COM3',\

            baudrate=115200,\

            parity=serial.PARITY_NONE,\

            stopbits=serial.STOPBITS_ONE,\

            bytesize=serial.EIGHTBITS,\

            timeout=0)


    print("connected to: " + arduino.portstr)
   
    for i in range(0,uzunluk):

        arduino.write(str.encode(str(incomingByte2[i])))
    
        time.sleep(1)

The Arduino Code:

int ledPins[] = {2,3,4,5,6,7,8,9};
int incomingdata[6];
int ilkled,ikinciled,ucunculed,dordunculed,besinciled,altinciled;
void setup() {
  // put your setup code here, to run once:
int index;
Serial.begin(115200);
for(index = 0; index <= 7; index++)
{
pinMode(ledPins[index],OUTPUT);
}
}
void loop() {
  // put your main code here, to run repeatedly:
if(Serial.available()){
    for (int a=0; a < 6; a++) { 
      incomingdata[a] = Serial.parseInt();
      delay(100);
      ilkled=incomingdata[0];
      ikinciled=incomingdata[1];
      ucunculed=incomingdata[2];
      dordunculed=incomingdata[3];
      besinciled=incomingdata[4];
      altinciled=incomingdata[5];
      
}
}

if (ilkled==1){
  for (int x=0;x<ikinciled;x++){
  digitalWrite(ledPins[0],HIGH);
  delay(1000);
  digitalWrite(ledPins[0],LOW);
  }
}
if (ilkled==2){
  for (int x=0;x<ikinciled;x++){
  digitalWrite(ledPins[1],HIGH);
  delay(1000);
  digitalWrite(ledPins[1],LOW);
}
}
if (ilkled==3){
  for (int x=0;x<ikinciled;x++){
  digitalWrite(ledPins[2],HIGH);
  delay(1000);
  digitalWrite(ledPins[2],LOW);
}
}
if (ilkled==4){
  for (int x=0;x<ikinciled;x++){
  digitalWrite(ledPins[3],HIGH);
  delay(1000);
  digitalWrite(ledPins[3],LOW);
}
}
if (ilkled==5){
  for (int x=0;x<ikinciled;x++){
  digitalWrite(ledPins[4],HIGH);
  delay(1000);
  digitalWrite(ledPins[4],LOW);
}
}
if (ilkled==6){
  for (int x=0;x<ikinciled;x++){
  digitalWrite(ledPins[5],HIGH);
  delay(1000);
  digitalWrite(ledPins[5],LOW);
}
}
}
1

1 Answers

1
votes

I think your read loop is broken. It should close after delay(100), no?

for (int a=0; a < 6; a++) { 
  incomingdata[a] = Serial.parseInt();
  delay(100);
}

Personally I would not string encode the data in Python. Send it as raw bytes, then read it as raw bytes into your int array.

Serial.readBytes( incomingData, 6 ); // assumes 8 bit ints.

That would do away with the loop completely.

Your LED staying on instead of flashing because you missed the line I added below.

for (int x=0;x<ikinciled;x++){
  digitalWrite(ledPins[5],HIGH);
  delay(1000);
  digitalWrite(ledPins[5],LOW);
  delay(1000); // <<<< Hold the LOW time

}

Otherwise it will be set LOW for only a few microseconds.

You may also run into synchronous issues with your Serial read versus how much time you spend in "delay()" during the LED flashing. Your python looks like it's sleeping only for 1 second, but your code responding to that will take many seconds as it delays in delay().

The Serial buffer will overflow and data will be lost/overwritten and when you call your next "parseInt" or "readBytes" there is no guarantee where the next bit of data in the buffer starts. Highly likely not at the next block of 6 ints.

You could send the data less often or send it based on how long the flashing will take. Alternatively you could implement an interrupt system to flash the LEDs... and the solutions get more complex from there up.

Welcome to the world of low level communications protocols.

PS, get rid of these

if (ilkled==6){

Just use it directly.

digitalWrite(ledPins[ilkled-1],HIGH);