Python Serial to run NeoPixels on Arduino UNO

I need to create an iterative light sequence. This project will be interfacing with a camera via Python hence the need to use Python and have the Arduino act as a NeoPixel driver.

I am trying to configure the Arduino to read the serial port and then run the code if it is flagged to do so. However, I am unsure on what's going wrong here - it simply won't run when inside the Serial.available() > 0 loop.

Arduino UNO Code:

// NeoPixel program showing use of the WHITE channel for RGBW
// pixels only (won't look correct on regular RGB NeoPixel strips).

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1:
#define LED_PIN     6

// How many NeoPixels are attached to the Arduino?
#define LED_COUNT  6

// NeoPixel brightness, 0 (min) to 255 (max)
#define BRIGHTNESS 10 // Set BRIGHTNESS to about 1/5 (max = 255)

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRBW + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 3 = Pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)

void setup() {
  // put your setup code here, to run once:
  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(BRIGHTNESS);

  // Open serial connection.
  Serial.begin(9600);
  Serial.write('1');  
}

void loop() {
  // put your main code here, to run repeatedly:
//  colorWipe(strip.Color(  0,   0,   0, 255), 50); // True white(not RGB white)
  if(Serial.available() > 0){ 
    colorWipe(strip.Color(  0,   0,   0, 255), 50); // True white(not RGB white)
    Serial.write('0');
  }
}

// Fill strip pixels one after another with a color. Strip is NOT cleared
// first; anything there will be covered pixel by pixel. Pass in color
// (as a single 'packed' 32-bit value, which you can get by calling
// strip.Color(red, green, blue) as shown in the loop() function above),
// and a delay time (in milliseconds) between pixels.
void colorWipe(uint32_t color, int wait) {
  for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
    strip.clear();                         // Clear after every iteration. 
    strip.setPixelColor(i, color);         //  Set pixel's color (in RAM)
    strip.show();                          //  Update strip to match
    delay(100);                            //  Pause for a moment
  }
}


Python Code

#Import the necessary packages.
import serial
import time

#Establish a serial connection with the Arduino.
arduino = serial.Serial(port='COM5', baudrate=9600, timeout=0.1)

#Boolean variable that will represent whether or not
#we are connected
connected = False

#Loop until we are connected 
while not connected: 
    serial_in = arduino.read()
    connected = True 

#Tell the arduino to begin the light sequence. 
arduino.write(1)

#Wait until the arduino tells us it is finished.
while arduino.read() == '1':
    arduino.read()

#Close the port and end the program
arduino.close()

@purplebottle2023 I pulled the pieces that communicate between Python and Arduino so that you can play around with the code and make sure it does what you want. The start of the data exchange I used two arrows "<>" instead of the character "1" it's entirely up to you if you decide to go back to "1"

Arduino snippet

void setup() {
   // put your setup code here, to run once:
  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(BRIGHTNESS);

  // Open serial connection.
  Serial.begin(9600);
  Serial.println("<>");
}

void loop() {
  while (Serial.available() > 0) {
  char signal=Serial.read();
  if (signal=='1')
  {
  colorWipe(strip.Color(  0,   0,   0, 255), 50); // True white(not RGB white)
  Serial.println('0');  
  }
  
  }
}

Python snippet

#Import the necessary packages.
import serial
import time

#Establish a serial connection with the Arduino.
arduino = serial.Serial(port='COM3', baudrate=9600, timeout=0.1)

sync_signal=''

while not '<>' in sync_signal:
	sync_signal=arduino.readline().decode()

print("Started")

while True:
		arduino.write("1".encode('utf-8'))
		if arduino.in_waiting >0:
			if arduino.readline().strip().decode("utf-8")=="0":
				print("Finished")
				break

#Close the port and end the program
arduino.close()
import serial, time
from time import sleep

Arduino = serial.Serial("/dev/ttyACM0", "9600", timeout=1)
Arduino.setDTR(False)
sleep(1)
Arduino.flushInput()
Arduino.setDTR(True)
num = 0

while True:

    if (Arduino.isOpen() == False):
        Arduino.open()
    if Arduino.inWaiting() > 0:
        try:
            incomeChar = Arduino.read().decode().strip()
            num = int(incomeChar)
        except:
            pass
    if num == 1:
        Arduino.write(b'0')
    if num == 0:
        Arduino.write(b'1')
    time.sleep(1)
#include <Adafruit_NeoPixel.h>
#define LED_PIN     6
const int LED_COUNT = 6;
#define BRIGHTNESS 10 // Set BRIGHTNESS to about 1/5 (max = 255)

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRBW + NEO_KHZ800);

void setup() {
  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.clear();  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(BRIGHTNESS);

  Serial.begin(9600);
  Serial.print('1');
}

void loop() {
  if (Serial.available() > 0) {
    byte c = Serial.read();
    if (c == 1) {
      colorWipe(strip.Color(  0,   0,   0, 255), 50); // True white(not RGB white)
      Serial.print('0');
    }
  }
}

void colorWipe(uint32_t color, int wait) {
  for (int i = 0; i < LED_COUNT; i++) { // For each pixel in strip...
    strip.clear();                         // Clear after every iteration.
    strip.setPixelColor(i, color);         //  Set pixel's color (in RAM)
    strip.show();                          //  Update strip to match
    delay(100);                            //  Pause for a moment
  }
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.