I'm doing research sketches for an upcoming project that will use a RaspberryPi as a master and some form of Arduino as an LED pixel strip control. The RPI will also be controlling eight servos via a i2c breakout and four seperate channels of sound generation. It will be a busy Pi. I've chosen to write the master program on the Pi in Python.
My current stage of learning is setting up the Pi/Arduino serial interface. I'm writing the Python on my Mac and communicating using pyserial to a Mega 2560 via USB. The Arduino sketch is set up to divide a 150 pixel strip into three sections which can be controlled individually or in parallel. It takes a comma separated list of two fields; the first identifying which section of the strip, the second identifying the position on the strip. This code works great when I am just giving commands via the Serial Monitor.
In the Python I'm just running a for loop to send out simple position information. When I send out a '0,position', which runs all three sections in paralell it works fairly well, with only a little jitter and rarely skipping and LED. When I start to send separate sections commands, '1,position''2,position''3,position' it starts to get really jittery and will go totally haywire after a few loops.
I'm asking for advice on how to optimize the communication between the two devices. I know I'm missing something in the timing, because sometimes it runs smoother when I'm having Python print it's internal position marker to the shell.
Here's the Arduino code:
#include <Adafruit_NeoPixel.h>
#define PIN 2
#define numPix 150
// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 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)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(numPix, PIN, NEO_RGB + NEO_KHZ800);
int positions[3];
int index;
void setup(){
Serial.begin(9600);
strip.begin();
strip.show();
}
void loop(){
if(Serial.available()>0)
{
//look for index
index =Serial.parseInt();
if (Serial.read()== ','){
int tempPos=Serial.parseInt();
switch (index)
{
//the parallel case
case 0:
positions[0]=tempPos;
positions[1]=100-tempPos;
positions[2]=100+tempPos;
break;
//the individual cases
case 1:
positions[0]=tempPos;
break;
case 2:
positions[1]=100-tempPos;
break;
case 3:
positions[2]=100+tempPos;
break;
}//end switch
}//end if serial.read = ','
}//end serial ava
//this section turns a single pixel in each section on according to position data, and turns all others off
for (int i = 0; i<numPix;i++){
if(i==positions[0]||i==positions[1]||i==positions[2])
{
strip.setPixelColor(positions[0],255,255,255);
strip.setPixelColor(positions[1],255,255,255);
strip.setPixelColor(positions[2],255,255,255);
}
else if (i!=positions[0]&&i!=positions[1]&&i!=positions[2])
{
strip.setPixelColor(i,0,0,0);
}
}
strip.show();
delay(20);
}//end loop
And here is the simple Pyserial loop:
import serial,time;
ser = serial.Serial('/dev/tty.usbmodemfa131',9600)
ser.write('0,0') ##my wakeup call to the Mega
print ser.readable()##its response
time.sleep(1) ##everybody get ready
print "begin"
while 1: ##go
for i in range(0,50):
##the parallel section:
ser.write('0'+','+str(i)+'\n') ## this works the best
##the individual section with some variations on the ser.write
## send1='1' +','+str(i)+'\n'
## send2='2' +','+str(i)+'\n'
## send3='3' +','+str(i)+'\n'
## ser.write(send1+send2+send3)
###### or
## ser.write(send1)
##
##
## ser.write(send2)
##
##
## ser.write(send3)
## print send1+send2+send3
I'm not really a very good nuts and bolts programmer, I'm more a 'code by the seat of my pants holy s@%$ it works don't touch it' sort of guy. I realize with this project I'm going to have to dig a little deeper but I'm not sure where to start. Any advice you can give other than 'give up and run away' would be helpful. (We already signed the contract)
Mostly I'm guessing that it has to do with how I've got the timing set up in the Python, but I'm sure there's optimizations I don't know about in the Arduino too. Thanks for your time.