Tiny glitches in serial communications.

I made a simple arduino&processing project, that sends values from processing to arduino, to PWM some leds.

The problem I have is that the leds keep blinking randomly when they shouldn’t.
It seems to be in the communications side of things.

Arduino’s side looks like this

´/* Led Pixel script - www.anthonymattox.com
 * recieves input from processing script  */

int redPin=9;
int greenPin=10;
int bluePin=11;
int redVal=0;
int greenVal=0;
int blueVal=0;

byte buff[]= "00000000";

void setup() {
  Serial.begin(9600);
  pinMode(redPin,OUTPUT);
  pinMode(greenPin,OUTPUT);
  pinMode(bluePin,OUTPUT);
}

void loop() {

  while (Serial.available()>=2) {
    for (int i=0; i<10; i++) {
      buff[i]=buff[i+1];
    }
    buff[10]=Serial.read();
    if (buff[10]=='R') {
      redVal=int(buff[9]);
    }
    if (buff[10]=='G') {
      greenVal=int(buff[9]);
    }
    if (buff[10]=='B') {
      blueVal=int(buff[9]);
    }
     
  analogWrite(redPin,redVal);
  analogWrite(greenPin,greenVal);
  analogWrite(bluePin,blueVal);

  }
}

And Processing has:

 import krister.Ess.*;        // import audio library
import processing.serial.*;  // serial communication library


FFT myfft;           // create new FFT object (audio spectrum)
AudioInput myinput;  // create input object
int audioScale;      // variable to control scaing

float redvalue =0;
float greenvalue = 0;
float bluevalue = 0;

int redavag = 0;
int redavagcount = 0;
int redavagraw = 0;
int redInt = 0;
float redIntensity = 0.6;

int greenavag = 0;
int greenavagcount = 0;
int greenavagraw = 0;
int greenInt = 0;
float greenIntensity = 1;

int blueavag = 0;
int blueavagcount = 0;
int blueavagraw = 0;
int blueInt = 0;
float blueIntensity = 1.5;

int redoverload = 0;
int greenoverload = 0;
int blueoverload = 0;

float highfreq = 0;

int bufferSize=1024;
int sampleRate = bufferSize;
int sampleZoom = 3;
int sampleAverage = 256;
int sampleAverageSize = (bufferSize / sampleAverage) * sampleZoom ;
int sampleStart = 0;
int sampleFreqText = sampleAverageSize;
int sampleOffset = 30;

int speccell = 0;

slider s1;   // create two slider objects
slider s2;

Serial port;

void setup() {
  size(140,315);
  frameRate(30);
  background(255);
  noStroke();
  fill(0);
  noSmooth();
  textAlign(RIGHT);  

  Ess.start(this);  // start audio
  myinput=new AudioInput(bufferSize); // define input
  myfft=new FFT(bufferSize*2);        // define fft
  myinput.start();

  myfft.equalizer(false);
  //myfft.limits(.005,.01);
  myfft.limits(.02,.1);
  //myfft.noLimits();
  myfft.averages(sampleAverage);      // controls number of averages
  myfft.envelope(0);
  myfft.smooth=false;

  println("Available serial ports:");  // define 'port' as first
  println(Serial.list());              // ...available serial port
  port = new Serial(this, Serial.list()[0], 9600);

  s1=new slider(25,25,255, color(200,150,80)); // define slider objects
  s2=new slider(75,25,255, color(200,150,80));
  s1.p=100;   // default position of sliders
  s2.p=190;
}

void draw() {
  
  audioScale=s1.p*10; // adjust audio scale according to slider
  myfft.damp(map(s2.p,0,255,1,.0)); // adjust dapming
 
redvalue = ( ( ( (myfft.averages[0] + myfft.averages[1])*audioScale) / 2 ) * redIntensity);
greenvalue = ( ( ( (myfft.averages[2] +myfft.averages[3] + myfft.averages[4])*audioScale) / 3 ) * greenIntensity );
bluevalue = (((( myfft.averages[7] + myfft.averages[8] + myfft.averages[9] + myfft.averages[10] + myfft.averages[11] + myfft.averages[12])*audioScale) / 6 ) * blueIntensity );

  redInt = int(redvalue);
  greenInt = int(greenvalue);
  blueInt = int(bluevalue);

  if (redInt > 255) { redInt = 255; redoverload++;}
  else if (redInt < 2) redInt = 0;
  if (greenInt > 255) { greenInt = 255; greenoverload++;}
  else if (greenInt < 2) greenInt = 0;
  if (blueInt > 255) { blueInt = 255; blueoverload++;}
  else if (blueInt < 2) blueInt = 0;
  
  drawGUI();
  
      // draw led intensity bars
    fill(255,0,0);
    rect(100,300,10,-redInt);    
    fill(0,255,0);
    rect(110,300,10,-greenInt);    
    fill(0,0,255);
    rect(120,300,10,-blueInt);    

    fill(0,0,0) ; 
  
     text(s1.p, 35, 300);
     text(s2.p, 85, 300); 
  sendSerial();
  
}


// FUNCTION CALLS


// sets up audio input
public void audioInputData(AudioInput theInput) {
  myfft.getSpectrum(myinput);
}

void drawGUI() {
  
    background(255);
    fill(0,0,0);
    
//Render Sliders
  pushStyle();
  s1.render();  // render sliders
  s2.render();
  popStyle();
    
}

//SEND THE SERIAL DATA
void sendSerial() { 
    
  port.write(redInt);
  port.write('R');
  port.write(greenInt);
  port.write('B');
  port.write(blueInt);
  port.write('G');

}

The weird thing is, that the problem is still there, green and blue led’s flashing every few seconds, randomly, with this code:

  port.write(redInt);
  port.write('R');
  port.write(0);
  port.write('B');
  port.write(0);
  port.write('G');

I’m guessing the problem is simply the way I send and read the data in the first place, but I wasn’t successful at my attempts to fiddle with buffers or bits.

[EDIT]
Here is a quick video of the problem, it isn’t very easy to see, but the green and blue leds flash occasionally, even though I should be sending “0” to them all the time.

    for (int i=0; i<10; i++) {
      buff[i]=buff[i+1];
    }
    buff[10]=Serial.read();

…is very likely overrunning the buffer corrupting whatever happens to be beyond the end but it is impossible to say for certain because, when you tried to post your entire sketch, something went wrong.

I left the rest out intentionally, but I’ll put the whole code up.
I’m just embarrassed about my coding style :stuck_out_tongue:

[EDIT]
Now that you mentioned the ‘overrunning’, I tackled the problem from a slightly different angle; minimizing the data and buffer.
So instead of sending 6 packets with 3 identifiers, and basically bruteforcing the reading, I went with 4 packets with a start identifier.

This seems to have fixed the blinking problem :slight_smile:

Here are the revised snippets:

Arduino:

byte buff[] = "0000";

void loop() {
  
// send data only when you receive data:
  if (Serial.available() > 0 ) { 
    incomingByte = Serial.read();
    
//Lock to the start of the stream; check if misaligned
    if (incomingByte == 'S') {
      buffSlot = 0;
    }
    
//store the data in the buffer
    buff[buffSlot] = incomingByte;

//read static buffer positions    
    redVal = buff[1];
    greenVal = buff[2];
    blueVal = buff[3];
    
    buffSlot++;      
    if (buffSlot == 4) buffSlot = 0;
  }
}

And Processing:

  port.write('S');
  port.write(dim_curve[redInt]);
  port.write(0);
  port.write(0);