Pages: 1 2 3 [4] 5 6   Go Down
Author Topic: Messenger library  (Read 20936 times)
0 Members and 1 Guest are viewing this topic.
Canada
Offline Offline
Jr. Member
**
Karma: 0
Posts: 75
I Love Arduino!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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):

Code:
#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];
  */
  
}
Logged

Thomas Ouellet Fredericks

0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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!
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 54
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 http://www.arduino.cc/playground/Code/Messenger?
For example to send an array or string like (114,134,144,116,84,126,143)
Thanks!
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 4
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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 http://www.arduino.cc/playground/Code/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.
Logged

Canada
Offline Offline
Jr. Member
**
Karma: 0
Posts: 75
I Love Arduino!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi diode and bigRed,

Quote
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 http://www.arduino.cc/playground/Code/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:

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

  
}
Logged

Thomas Ouellet Fredericks

0
Offline Offline
Newbie
*
Karma: 0
Posts: 7
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

Code:
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
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 2
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I find find it really helpful smiley
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 7
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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!

Code:
#define MESSENGERBUFFERSIZE 64

changed to

Code:
#define MESSENGERBUFFERSIZE 128

duh!
Logged

Enschede - The Netherlands
Offline Offline
Jr. Member
**
Karma: 0
Posts: 75
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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/.

Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 18
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Im new to arduino and loving it!
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 36
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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


Using the example checkstring  I can turn the led on and off fine smiley  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 ?






 
Code:
// 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() );


}
Logged

Nova Scotia, CA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 64
A world that runs on bits and bytes!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This library came in handy for me and thought that I would share a nifty function addition (checkSubString).

In this project's case the serial port is used to send data and to receive poll and configuration settings commands.

For example;

Poll Commands (e.g. send a poll command to Arduino to receive data from a client computer over serial):
M0!
where:
- M0 is message type 0

M1!
where:
- M1 is message type 1


Configuration Settings:
SET01nn
where:
- nn set the sample interval in seconds (01-60)
.
.
.
SET08nn
where:
 - nn = 96 sets the serial port's baud-rate to 9600
 - nn = 38 sets the serial port's baud-rate to 38400

Code:
Messenger.h (Public)
uint8_t checkSubString(char *subString, char *string, uint8_t length);

Messenger.cpp
// alpha implementation, may be a more efficient method
// instead of calling strncpy
uint8_t Messenger::checkSubString(char *subString, char *string, uint8_t length) {
      if (next()) {
            if ( strcasestr(subString,current) == 0 ) {
                  // return remaining chars after subString
                  int nChars = strlen(current) - strlen(subString);
                  strncpy(string, current + strlen(subString), nChars);
                  string[nChars] = '\0';
                        if ( strlen(string) > length ) return 0;
                  dumped = 1;
                  return 1;
            } else {
                  return 0;
            }
      }
}

Here is a usage example - simply add the following snippet example to the checkString example.

Code:
char buffer[32]; // global buffer


    } else if ( message.checkString("M0!") ) {
       // send message 0 data
    } else if ( message.checkSubString("SET01", buffer, 2) ) {
      Serial.print("Sample Interval: ");
      Serial.println(buffer);
     //
     // store sample interval...
    } else if ( message.checkSubString("SET08", buffer, 2) ) {
      Serial.print("Baud-Rate: ");
      Serial.println(buffer);
     //
     // store serial port baud-rate..
    } else {
      return;
    }

Enjoy!

Eric




« Last Edit: July 22, 2010, 01:32:37 pm by LAVco » Logged

Common sense is not so common...

Nova Scotia, CA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 64
A world that runs on bits and bytes!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey luke123

Take a look at my post.  Simply add an "else" statement to return if no matches are found.

Cheers..

Eric
Logged

Common sense is not so common...

Nova Scotia, CA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 64
A world that runs on bits and bytes!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Update to my previous post for checkSubString.

Code:
uint8_t Messenger::checkSubString(char *subString, char *string, uint8_t length) {
      if (next()) {
            //if ( strcasestr(subString,current) == 0 ) {
            if ( strstr(current, subString) != NULL ) {
                  // return remaining chars after subString
                  int nChars = strlen(current) - strlen(subString);
                  strncpy(string, current + strlen(subString), nChars);
                  string[nChars] = '\0';
                  if ( strlen(string) > length ) return 0;
                  dumped = 1;
                  return 1;
            } else {
                  return 0;
            }
      }
}

Cheers,

Eric
Logged

Common sense is not so common...

0
Offline Offline
Newbie
*
Karma: 0
Posts: 45
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?

here's my code
http://download.growcontrol.com/arduino/usbmessenger.pde
« Last Edit: August 02, 2010, 01:48:03 am by lorenzop » Logged

Pages: 1 2 3 [4] 5 6   Go Up
Jump to: