Digital RGB LED Strip + Bluetooth modules

Hi to everyone!
I'm working on a project involving a digital rgb led strip (LPD8806, 160pixel) and a bluetooth module.
I'm using my MacBook Pro with the internal bluetooth to communicate with a bluetooth module that is connected to an Arduino, which is controlling the LED strip. Actually, I divided the LED Strip which was 5m long in 10 strips long 50cm each (16pixel).
I'm using them to form a grid, in which every strip is connected to another, here a image to give the idea:

I'm using Processing with a simple sketch to send the height of the grid through bluetooth, here is the sketch:

/* Lorenzo Gasparini joined@me.com 2013 */
/* Codice Processing per gestione striscia LED da remoto con */
/* i moduli Bluetooth Bluetooth */

//Importo la libreria per la comunicazione seriale
import processing.serial.*;
Serial myPort;

void setup() 
{
  //Imposto dimensione finestra
  size(400, 600);
  frameRate(10);
  noStroke();
  //Apro la porta seriale corrispondente al modulo BT
  myPort = new Serial(this, "/dev/tty.HC-05-DevB", 115200);
}

void draw()
{
  //Calcolo la posizione verticale del mouse rispetto alla finestra e la mappo
  //con numeri da 0 a 16
  int c = (int) ((mouseY / 600.0) * 17.0);
  //Stampo per debug
  println(c);
  //Invio alla striscia tramite seriale bluetooth
  myPort.write((byte)c);
}

And the Arduino Uno with the bluetooth module has this sketch:

/* Lorenzo Gasparini joined@me.com 2013 */
/* Codice Arduino per gestione striscia LED con dati ricevuti */
/* da Bluetooth */

//Librerie per gestione striscia LED RGB
#include "LPD8806.h"
#include "SPI.h"


int tmp;
//Griglia di boolean rappresentante i pixel (on/off)
boolean grid[16][10];

//Striscia LED con 160 LED RGB (10 pezzi * 16 led)
LPD8806 strip = LPD8806(160);

void setup()
{
  //Inizializzazione seriale
  Serial.begin(115200);
  
  //Inizializzazione striscia LED
  strip.begin();

  //Reset iniziale pixel
  strip.show();
}


void loop()
{
  //Aspetto di ricevere qualcosa
  while (!Serial.available()) ;
  
  //Ricezione dati
  while (Serial.available())
  {
    tmp = Serial.read();
    
    //Riempimento fino all'altezza "tmp"
    Fill(tmp);
    
  }
  
  //Aggiornamento striscia
  showStrip();

}

//Riempimento griglia fino ad altezza "m"
void Fill(int m)
{
  //Scorro le colonne
  for (int k=0; k<10; k++)
  {
    //Scorro le righe
    for (int i=0;i<16;i++)
    {
      //Riempio fino all'altezza stabilita
      if (i < m) 
      {
        grid[i][k] = true;
      }
      else grid[i][k] = false;
    }
  }
}

//Funzione che restituisce in che colonna della griglia un certo pixel va
int col(int n)
{
  return 10-(int)(n/16.0-0.05);
}

//Funzione che restituisce in che riga della griglia un certo pixel va
int riga(int n)
{
  if (col(n) % 2 == 0)
  {
    if (n % 16 == 0) return 1;
    else return 17 - (n % 16);
  } else {
    if (n % 16 == 0) return 16;
    else return (n % 16);
  }
}

//Update e display della striscia
void showStrip()
{
  int r,c;
  
  //Scorro tutti i pixel
  for (int i=0; i<160;i++)
  {
    //Trovo la riga e la colonna del pixel corrente
    r = riga(i+1)-1;
    c = col(i+1)-1;
    
    //Se il pixel va acceso
    if (grid[r][c])
    {
      //Colore del pixel in base alla riga
      strip.setPixelColor(i, Wheel((r/16.0)*384));
    }
    else
    {
      strip.setPixelColor(i, strip.Color(0,0,0));
    }
  }
  
  //Aggiorno la striscia LED
  strip.show();
}

//Funzione degli esempi della libreria per striscie LED LPD8806 che
//Dato un numero tra 0 e 384, restituisce un colore (stile "arcobaleno")
uint32_t Wheel(uint16_t WheelPos)
{
  byte r, g, b;
  switch(WheelPos / 128)
  {
    case 0:
      r = 127 - WheelPos % 128;   //Red down
      g = WheelPos % 128;      // Green up
      b = 0;                  //blue off
      break; 
    case 1:
      g = 127 - WheelPos % 128;  //green down
      b = WheelPos % 128;      //blue up
      r = 0;                  //red off
      break; 
    case 2:
      b = 127 - WheelPos % 128;  //blue down 
      r = WheelPos % 128;      //red up
      g = 0;                  //green off
      break; 
  }
  return(strip.Color(r,g,b));
}

Sorry for the comments in Italian but I think it's quite understandable!
The problem is that the refreshing speed is too low.. I think it's due to the bluetooth communication but it sounds strange to me because the connection should be at 115200 bps. I'm sending just a byte every time! Have you got any idea?
If you need any other info.. just tell me!

Oh, forgot to mention.. I'm using this bluetooth modules:
http://www.usconverters.com/downloads/bluetooth-module-btm5-datasheet.pdf

Thanks!

This line in the Processing sketch is setting the sample rate to 10 per second:

  frameRate(10);

Says here the default is 60: frameRate() / Reference / Processing.org

I would experiment with increasing this setting to see if it helps.

Good luck with your project,

-br

Unlike loop() on the Arduino, draw() is not called as fast as possible. There is a frame rate that determines when the next call to draw() happens.

I don't think that the problem involves the amount of data being sent. Rather, it involves how often data is sent.

Look at the Processing documentation for frame rate. Or, create a while loop in draw() to send more data per invocation of draw().

PaulS:
Unlike loop() on the Arduino, draw() is not called as fast as possible. There is a frame rate that determines when the next call to draw() happens.

I don't think that the problem involves the amount of data being sent. Rather, it involves how often data is sent.

Look at the Processing documentation for frame rate. Or, create a while loop in draw() to send more data per invocation of draw().

Thank you both, but the problem isn't the low frameRate.
In fact, I can esclude the "draw" and do

void setup()
{
..
while (true) myPort.write((byte) (int)random(16));
}

But I can say that it surely doesn't go over 3-4 fps.

EDIT: Tried with this

while (true)
  {
    myPort.write((byte) count);
    if (count==16) count = 0;
    else count++;
  }

and the FPS turns out to be exactly 4 (16 pixels updats in 4 seconds).

while (true) myPort.write((byte) (int)random(16));

Maybe you need a cast to a float in there, too.

Disconnect all the LED strips. Connect one LED. Turn the LED on or off every time a byte arrives. I'm willing to bet that you get more than 4 bytes per second.

PaulS:

while (true) myPort.write((byte) (int)random(16));

Maybe you need a cast to a float in there, too.

Disconnect all the LED strips. Connect one LED. Turn the LED on or off every time a byte arrives. I'm willing to bet that you get more than 4 bytes per second.

Okay, tried with this:

void loop()
{
  while (!Serial.available()) ;
  
  while (Serial.available())
  {
    tmp = Serial.read();
    
    if (t)
    {
      strip.setPixelColor(1, strip.Color(127,0,0));
      t = false;
    }
    else
    {
      strip.setPixelColor(1, strip.Color(0,0,0));
      t = true;
    }
  }
  
  strip.show();
}

Aaaaand.. the pixel blinks 2 times per second :frowning:

EDIT: Message received, the (int) casting isn't necessary.. Instead, the (byte) one is necessary because in this way I send 1 byte vs 4 bytes (int)

Tried with this code on the Arduino:

boolean temp = false;
void setup() {
 
  Serial.begin(115200);
  pinMode(3,OUTPUT);
}
void loop() {
  while (Serial.available())
  {
    int t = Serial.read();
    
    if (temp)
    {
      digitalWrite(3,HIGH);
      temp = false;
    }
    else 
    {
      digitalWrite(3,LOW);
      temp = true;
    }
  }
}

with a LED connected on pin 3, and the Processing sketch continuously sending bytes.. it blinks only 2 times per second!
How can this be possible?

EDIT: I even tried with "Serial tools" sending random characters and the max speed is 2 blinks per second.. I'm really confused..

I'm really confused..

So am I. What is "Serial tools"? How fast does it actually send data?

Since you are not setting the pin state based on what you are reading, the LED should toggle faster than you can see it change.

PaulS:

I'm really confused..

So am I. What is "Serial tools"? How fast does it actually send data?

Since you are not setting the pin state based on what you are reading, the LED should toggle faster than you can see it change.

Serial tools is a terminal for the serial port that I'm using in OSX. It is set to 115200 bps. If i send bytes continuously (i.e. keeping one key pressed) the led blinks 2 times per second. If i press repeatedly one key i can't get over 2 times per second of blinking..

If you use the Serial Monitor, and enter a string of characters, then hit send, what do you see happening? More than 2 characters per second?

PaulS:
If you use the Serial Monitor, and enter a string of characters, then hit send, what do you see happening? More than 2 characters per second?

If I write "1", the led turns on (or off). If i write "11" the led blinks 1 time but very 'fast'. If i write "111" the led turns on (or off). And so on..

If i write "11" the led blinks 1 time but very 'fast'.

Faster than 1/2 a second?

What you describe tells me that the Serial Monitor is able to send data to the Arduino faster than 2 bytes per second. So, there is no reason that Processing should not be able to do the same.

Processing is able to read the data that the Arduino sends to the serial port. So, forget about the LED strips for a while. When the Arduino gets a byte from the serial port, Serial.println(millis()); and have Processing read and display the serial data, using the bufferUntil() method of the Serial class and overriding the serialEvent() function.

Show us what you get in Processing.

PaulS:

If i write "11" the led blinks 1 time but very 'fast'.

Faster than 1/2 a second?

What you describe tells me that the Serial Monitor is able to send data to the Arduino faster than 2 bytes per second. So, there is no reason that Processing should not be able to do the same.

Processing is able to read the data that the Arduino sends to the serial port. So, forget about the LED strips for a while. When the Arduino gets a byte from the serial port, Serial.println(millis()); and have Processing read and display the serial data, using the bufferUntil() method of the Serial class and overriding the serialEvent() function.

Show us what you get in Processing.

First, thank you for the help you are giving me. Here the sketch I've tried following your advices.
Arduino sketch

void setup() {
 
  Serial.begin(115200);
}
void loop() {
  while (Serial.available())
  {
    Serial.read();
    
    Serial.println(millis());
  }
}

Processing code:

import processing.serial.*;
Serial myPort;

void setup() 
{
  size(400, 600);
  frameRate(60);
  myPort = new Serial(this, "/dev/tty.HC-05-DevB", 115200);
  myPort.bufferUntil(10);
}

void draw()
{
  myPort.write((byte)1);
}

void serialEvent()
{
  println(myPort.readString());
}

Result: nothing printed on the console..

The serialEvent() function has a specific signature:

void serialEvent(Serial thePort)
{
}

When the correct COM port for windows, and use the correct signature, I get:

187789

187805

187822

187838

187854

187872

187888

That's roughly 16 milliseconds per byte, including the time needed to generate the response. Far faster then twice a second.

PaulS:
The serialEvent() function has a specific signature:

void serialEvent(Serial thePort)

{
}



When the correct COM port for windows, and use the correct signature, I get:


187789

187805

187822

187838

187854

187872

187888



That's roughly 16 milliseconds per byte, including the time needed to generate the response. Far faster then twice a second.

Corrected the signature, result:

78295

78544

78794

79044

79295

79546

79796

80046

80297

It works like this:
-Processing send a byte via bluetooth serial port to the bluetooth module
-The bluetooth module sends millis() as response

When I ran your code, I was using a cable. Your considerably higher intervals clearly indicate that your bluetooth module is slower than molasses in January.

PaulS:
When I ran your code, I was using a cable. Your considerably higher intervals clearly indicate that your bluetooth module is slower than molasses in January.

But how do you explain that if I use this code in Arduino:

void setup()
{
  Serial.begin(115200);
}
void loop()
{
  Serial.println(millis());
}

and this code in Processing:

import processing.serial.*;
Serial myPort;

void setup() 
{
  size(400, 600);
  frameRate(60);
  myPort = new Serial(this, "/dev/tty.HC-05-DevB", 115200);
  myPort.bufferUntil(10);
}

void draw()
{
}

void serialEvent(Serial p)
{
  println(p.readString());
}

The console shows this:

34072

34073

34073

34074

34074

34075

34076

34076

34077

34077

?!? It seems that the communication is slow only sending data from the Macbook to the BT module..

Note: Again, I'm not communicating directly from Arduino to processing, the Arduino Serial port is interfaced with the BT module, which is interfaced with the Macbook BT module.

EDIT: Okay, I made a new test and it's quite interesting..
I used this code in Processing:

import processing.serial.*;
Serial myPort;

void setup() 
{
  size(400, 600);
  myPort = new Serial(this, "/dev/tty.BTMod", 115200);
}

void draw()
{
  myPort.write((byte)1);
  println(millis());
}

And the console shows:

2285
2302
2554
2804
3054

So it seems that the real problem is sending data from the MacBook BT serial port!

I'm going mad.. Tried even switching the BT module baud rate to 57600bps, no luck.

I think this has something to do with the module.. but I cant debug it :confused:

The module is this one, it it can help:

So I should simply give up without knowing the real problem?

The thing I love about electronics & this kind of stuff is that checking everything you can always debug an error and know the real cause of the issue..

I'm really frustrated about this because I almost completed my project and I have only this small fu**ing irritating problem in the slow speed of the BT module! I don't want to change the communication way: bluetooth was just perfect, integrated in my MacBook!
And if I buy another BT module I need to wait something like a month to receive it from HK and there's the possibility that it won't work anyway.

Sorry for the outburst but I'm really irritated!