i suppose some background of my larger project would be helpful...
i've built an RGB LED Matrix and found some code to write colors to each of 64 LEDs. it works great, but now i would like to send constantly updated color values from my PC to display on the matrix LEDs. i though it would be best to send them as a group of 64 at a time - a whole '64 pixel frame' if you will..
SO, my message actually contains spaces AND commas:
2,3,4 -space- 32,0,0 -space- etc.
so each element is supposed to be a 3 value set of integers. once i have these sets in an array, i want to parse them using the commas and probably strtok_r. so, basically i am hoping to store a 2 dimensional array from Messenger. still possible?
Messenger is probably not the best solution if you are sending all that data at a high interval. For 64 leds, each controlled through three numbers separated by commas, you are looking at at least 384 bytes of data! This should definitely cause some Messenger overflows. Even without the overflow, you would expect an update speed between 15 and 5 "images" per second.
The best solution is to simply send a bunch of bytes without the help of Messenger. Here is partial code (I did not test it):
#define VALUES 192 //64*3
byte leds[VALUES];
unsigned long lastTime;
int writeindex;
void setup() {
Serial.begin(57600);
lastTime = millis();
writeindex = 0;
}
void loop() {
// Read serial data
while ( Serial.available() ) {
// if ever there is more than 10ms between two bytes,
// this indicates the start of a new series
if( millis() - lastTime > 10) {
writeindex = 0;
}
lastTime= millis();
leds[writeindex] = (byte) Serial.read();
writeindex = (writeindex + 1) % VALUES;
}
/*
For example, you want to retrieve the value of led i
red = leds[i*3];
green = leds[(i*3)+1];
blue = leds[(i*3)+2];
*/
}
oh right...well i was just trying to see if it would work at all - then was going to try to optimize it or use other techniques to get it going faster. but you have a great point - keeping the data stream lean from the get go will save alot of overhead and make everything faster for sure.
i guess i started with Messenger because my host software sending from the PC easily spits out strings, but i had a harder time getting it to send raw ascii bytes - as strange as that may sound. i'll try retooling it and give it a go with your code as an example.
Hi Tof,
This looks really interesting. Could you perhaps outline what the best method and format of sending a combined message from Processing would be, to match your Arduino receiving example at Arduino Playground - Messenger?
For example to send an array or string like (114,134,144,116,84,126,143)
Thanks!
Hi Tof,
This looks really interesting. Could you perhaps outline what the best method and format of sending a combined message from Processing would be, to match your Arduino receiving example at Arduino Playground - Messenger?
For example to send an array or string like (114,134,144,116,84,126,143)
Thanks!
I also have this question, I've tried writing to the serial port that the arduino is hooked up to, but that doesn't work very well.
Could you perhaps outline what the best method and format of sending a combined message from Processing would be, to match your Arduino receiving example at Arduino Playground - Messenger
Well, the simplest solution would be to instantiate a Serial object and then write the data as ASCII ints to it.
For example, this is the Processing code that would send the array {114,134,144,116,84,126,143} to the Messenger enabled Arduino:
import processing.serial.*;
Serial serial; // Create object from Serial class
int[] data = {114,134,144,116,84,126,143};
void setup()
{
size(200, 200);
// I know that the first port in the serial list on my mac
// is always my FTDI adaptor, so I open Serial.list()[0].
// On Windows machines, this generally opens COM1.
// Open whatever port is the one you're using.
for ( int i=0; i < Serial.list().length ; i ++ ) {
println("Port: \t"+Serial.list()[i]);
}
String portName = Serial.list()[0];
serial = new Serial(this, portName, 115200);
frameRate(20);
}
void draw() {
// Send the data.
// The data can not be formed of more than 64 ASCII characters.
for (int i=0; i < data.length ; i++ ) {
serial.write(str(data[i])); // Write the data as an ASCII character
serial.write(' '); // Write the word separator: an ASCII space character
}
// Write the message terminator: an ASCII carriage return.
serial.write('\r');
}
I am communicating between PC and Arduino using your messenger protocol and so far it is great. But now I am trying to send a whole text-array and found something strange:
Whenever I send a message from PC to Arduino that has 64 or more characters the message gets lost. Just so you can have some fun looking at my 'totally awesome' coding skills, here is what I'm using:
void messageCompleted() {
// This loop will echo each element of the message separately
byte i;
byte j;
while ( message.available() ) {
message.copyString(MsgrString,MAXSIZE);
// Serial.print(MsgrString); // Echo the string
// Serial.println(); // Terminate the message with a carriage return
if (!strcmp(MsgrString,"?")) { // Somebody wants us to SEND data
while ( message.available() ) {
message.copyString(MsgrString,MAXSIZE);
// Serial.print(MsgrString); // Echo the string
// Serial.println(); // Terminate the message with a carriage return
if (!strcmp(MsgrString,"RoomName")) { // We need to send the RoomName array
//Serial.println("Sending RoomName array");
for (i=0; i<8; i++){
//Serial.print(i, DEC);
Serial.print(RoomName[i]);
Serial.print(" ");
}
Serial.println();
}
if (!strcmp(MsgrString,"Mode")) { // We need to send the Mode byte
//Serial.println("Sending Mode");
Serial.print("Mode=");
Serial.println(Mode, DEC);
}
}
}
if (!strcmp(MsgrString,"!")) { // Somebody wants us to RECEIVE data
while ( message.available() ) {
message.copyString(MsgrString,MAXSIZE);
//Serial.print(MsgrString); // Echo the string
//Serial.println(); // Terminate the message with a carriage return
if (!strcmp(MsgrString,"RoomName")) { // We need to receive the RoomName array
//Serial.println("Receiving RoomName array");
i=0;
while ( message.available() ) {
message.copyString(MsgrString,MAXSIZE);
//Serial.print(MsgrString); // Echo the string
//Serial.println(); // Terminate the message with a carriage return
for (j=0; j<10; j++){
RoomName[i][j] = MsgrString[j];
}
Serial.print(i, DEC);
//Serial.println(RoomName[i]);
i++;
}
Serial.println("RoomName array:");
for (i=0; i<8; i++){
Serial.print(i, DEC);
Serial.print(" ");
//Serial.println(RoomName[i]);
}
}
else if (!strcmp(MsgrString,"Mode")) { // We need to receive the Mode byte
while ( message.available() ) {
Serial.println("receiving Mode");
Mode = message.readInt();
Serial.print("I received: ");
Serial.println(Mode, DEC);
}
}
}
}
}
Is there a 64 character limitation? Or is the problem somehow on my side?
Never mind about the 64 character limit. I found the offending code after all of about 30 seconds search. Sometimes using your own eyes is perfectly sufficient!
I've made a description in how to send serial data from and to Flash with the Messenger library. The file can be used with the basic_communication sketch in the Messenger library examples folder.
Hey thanks for posting this library ! Im having a problem though ..
Using the example checkstring I can turn the led on and off fine but if i type some random letters ect it will confuse it and will stop it working totally the next time i type "on" ect.
I need this to ignore anything other than "on" or "off" ect ?
// This example demonstrates Messenger's checkString method
// It turns on the LED attached to pin 13 if it receives "on"
// It turns it off if it receives "off"
#include <Messenger.h>
// Instantiate Messenger object with the message function and the default separator
// (the space character)
Messenger message = Messenger();
// Define messenger function
void messageCompleted() {
// This loop will echo each element of the message separately
while ( message.available() ) {
if ( message.checkString("on") ) {
digitalWrite(13,HIGH);
} else if ( message.checkString("off") ) {
digitalWrite(13,LOW);
}
}
}
void setup() {
// Initiate Serial Communication
Serial.begin(115200);
message.attach(messageCompleted);
pinMode(13,OUTPUT);
}
void loop() {
// The following line is the most effective way of
// feeding the serial data to Messenger
while ( Serial.available() ) message.process( Serial.read() );
}// This example demonstrates Messenger's checkString method
// It turns on the LED attached to pin 13 if it receives "on"
// It turns it off if it receives "off"
#include <Messenger.h>
// Instantiate Messenger object with the message function and the default separator
// (the space character)
Messenger message = Messenger();
// Define messenger function
void messageCompleted() {
// This loop will echo each element of the message separately
while ( message.available() ) {
if ( message.checkString("on") ) {
digitalWrite(13,HIGH);
} else if ( message.checkString("off") ) {
digitalWrite(13,LOW);
}
}
}
void setup() {
// Initiate Serial Communication
Serial.begin(115200);
message.attach(messageCompleted);
pinMode(13,OUTPUT);
}
void loop() {
// The following line is the most effective way of
// feeding the serial data to Messenger
while ( Serial.available() ) message.process( Serial.read() );
}
I'm having some trouble with bad commands. the correct commands for my project work great, but if I enter a command wrong it seems to lock up and the pin 13 led comes on. my code is still pretty simple and I don't see how it could cause this, and I don't see how the library could do it directly either. could it be an overflow someplace?
I think I fixed the problem. it took me forever to trace down the actual root, and it turns out pretty simple.
in the example basic_communication, I change line 21:
while ( message.available() ) {
to this:
if(messenger.available()){
this seems to fix my problems. no more lock ups caused by an endless loop. the incoming serial data is sent to the messenger class one character at a time anyway, so it can never have 2 separate commands in buffer at the same time. so no need to use a "while" loop.