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!
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.
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
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)
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..
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.
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
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:
?!? 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:
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.