Messenger library

Great library, thanks very much for sharing this...

I've added a few things in my own class CmdMessenger which extend from Messenger. Had to make a few small changes to the origional Messenger which I've included here along with my CmdMessenger class if its useful to anyone else.

Basicly with CmdMessenger sub class you can attach more than 1 messenger handler, which get called according to the first string (cmd) in a message. If a valid message for the command hasn't been attached then the single default message handler of Messenger is called.

http://www.arduino.cc/playground/uploads/Code/CmdMessenger.zip

The zip file contains the orgional Messenger with my small changes, the new CmdMessenger class and two sample programs (one runs on Arduino the other on a TouchShieldSlide) connected via hardware Serial1. If your using softwareSerial, which dosn't have the Serial.available() method then you will need to change the feedinSerialData() mehod.

Neil

Not very experienced with Java. I am a maxmsp whiz. This library seems like what I want (firmata is too bloated), but maybe it can't do this?

I just want to route messages, like in the example but parse numbers that follow the message name. ie send a value over max-messanger like this:

dimmer1 $1
dimmer2 $1

Sorry if this is obvious.

I started using the library with the message callback function similar to the one from the examples (CheckString):

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);
    }
  }
}

I found out that there is one danger with this. It you sent any message that doesn't match the strings which you are checking against, you get stuck in an endless while loop, because the message is never removed from the stack.

This problem became apparent when i was using 2 modules communicating with XBee on the same network. They both listen to different messages and so every message would get either one of hem to hang.

I solved this by simply adding an

else{
message.readInt();
}

at the end of the function. This way if the message doesn't match with any of the strings, it is removed and the loop continues with the next.

It would be helpful if this caveat is mentioned in the examples. Maybe it would be elegant to have an explicit method for skipping an element in the message stack?

I'm trying to use the Messenger library in Processing.

First of all I'm missing the string functions, I guess they're just not implemented yet?

So I want to match strings, or at least combinations of ascii characters manually. It seems so simple but I cannot figure it out.

I want to match something like "BFOO". The only way to access these characters seems to be readChar(). The first call returns 'B', but then the rest seems to be thrown away, and I don't know how to get to the remaining characters.

The reference says:

char readChar()

Returns the element as a character. If the character is part of a word, the whole word is removed from the completed message.

So this seems to be correct, but I don't understand the idea behind it. How is that useful, and how can I access those other characters?

I'm having trouble sending out a array of values from Processing to Arduino. Can anyone guide on how to do this?

Can this library even do this?

Thanks!

As usual, could you be more specific and provide an example?
What are the specifics or the array sent? Size, update speed, data size, etc...

hello!

i am trying to use Messenger to receive a 2d array from my PC. the message looks like this:

2,3,4 32,0,0, 3,16,16....<<60 more sets like this>>...32,32,32 [crg rtrn]

Messenger reads this in copyString seems to work, but when i try to access the stored Message as an array, i can only seem to access it as one long character string.

i thought the [space] character broke the incoming string into Elements (of an array) - is this not the case?

if it IS the case...how do i go about finding the individual space-separated groups once i copy the incoming message?

or am i missing something? maybe i have to build my own array of character arrays?

any thoughts? i can post an example if it would help..

thanks!
-josh

i thought the [space] character broke the incoming string into Elements (of an array) - is this not the case?

The space character does break the string into elements... but your example "2,3,4 32,0,0, 3,16,16.." shows commas and not strings as separators. You can configure Messenger to work with commas instead if you wish.

Even if you sent "2 3 4 32 0 0 3 16 16...", you could not use copyString to retrieve the individual elements (because copyString copies everything as a string as its name implies). You would use readInt instead to read each integer separately.

ah! yes - sorry for the confusion ...

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?

thanks!

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.

thanks so much!

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.

Hi diode and bigRed,

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');
  

  
}

Hi!

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?

BTW: MAXSIZE is 255.

Thanks for a great library!

Stefan

I find find it really helpful :slight_smile:

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!

#define MESSENGERBUFFERSIZE 64

changed to

#define MESSENGERBUFFERSIZE 128

duh!

Hi, just for your information.

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.

http://www.kasperkamperman.com/blog/arduino-flash-communication-as3-messenger/.

Im new to arduino and loving it!

Hey thanks for posting this library ! Im having a problem though ..

Using the example checkstring I can turn the led on and off fine :slight_smile: 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() );


}