Pages: [1]   Go Down
Author Topic: Help needed splitting up serial messages from Max.  (Read 388 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 6
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,

I'm pretty new to writing for Arduino and using the boards and this is my first post here. I'm trying to make a foot controller for use with Max/MSP. The idea being that I can get my computer out of the way during performances. The buttons on the foot controller will activate parts of my max patch. Max will send data back to an LCD display on the foot pedal to give me some visual feedback.

I've been playing with the LCD 'SerialDisplay' example:
Code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup(){
    // set up the LCD's number of rows and columns:
  lcd.begin(16, 2);
  // initialize the serial communications:
  Serial.begin(9600);
}

void loop()
{
  // when characters arrive over the serial port...
  if (Serial.available()) {
    // wait a bit for the entire message to arrive
    delay(10);
    lcd.clear();
    // read all the available characters
    while (Serial.available() > 0) {
      // display each character to the LCD
      lcd.write(Serial.read());
    }
  }
}

I can happily send text from Max to the first line of my 16x2 LCD but what I would really like to be able to do would be to program the arduino to understand messages sent from Max/MSP like this:

'1 hello' - prints 'hello' to the first row of the LCD
'2 goodbye' - prints 'goodbye' to the second row of the LCD

later on i'd like to add led's to my foot-switches so I'd like to extend my message system like this:

'3 1 1' - turn led 1 on
'3 1 0' - turn led 1 off

I've been searching around for a couple of days to find some answers but I've not found much (maybe I don't know what exactly i'm looking for)....

Any advice or pointers would be greatly appreciated.

Cheers,

John.

« Last Edit: October 07, 2009, 05:44:04 pm by leafcutter » Logged

0
Offline Offline
God Member
*****
Karma: 0
Posts: 572
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, as a starting point, you'd need to define a "buffer" to hold the incoming message.

Then you read what charachter is available on the serial port, and add that to the next position in the buffer. Keep doing this until there is nothing left on the serial port.

Then you could to a compare, like saying if the first charachter in the buffer is == 'h", print "hello" to the LCD screen.

Later on you could test if the buffer contained numbers, if so, convert the string to a number of type int or long or whatever, then use this number to manipulate the high/low status of the digital pins.
Logged

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

Thanks trialex,

I had a dig around and came up with this:
Code:
// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

#define STRLEN 20
int updateLCD = 1;
char buffer[STRLEN];
int  bufferIndex = 0;
int charCount = 0;
int timeCount = 0;

void setup()
{
  // set up the LCD's number of rows and columns:
  lcd.begin(16, 2);

 
  // initialize the serial communications:
  Serial.begin(9600);
}

void loop()
{
  if( Serial.available())
  {

    char ch = Serial.read();
    charCount ++; // count characters coming through serial
    // delay(1);
    if( ch == '^')  // is this the terminating carriage return
    {

      buffer[ bufferIndex ] = 0; // terminate the string with a 0
      bufferIndex = 0;  // reset the index ready for another string
      updateLCD = 1;

      if (updateLCD == 1 && buffer[0] == '1') {

        lcd.setCursor(0,0);
        for(int i = 0; i <  STRLEN; i++) {
          lcd.write(32); // erase row by writing spaces into all colls.
        }

        lcd.setCursor(0,0);
        for(int i = 2; i <  charCount - 2; i++) {
          lcd.write(buffer[i]); // write from buffer into first row of LCD
        }
      }

      if (updateLCD == 1 && buffer[0] == '2') {

        lcd.setCursor(0,1);
        for(int i = 0; i <  STRLEN; i++) {
          lcd.write(32);  // erase row by writing spaces into all colls.
        }
        lcd.setCursor(0,1);
        for(int i = 2; i <  charCount - 2; i++) {
          lcd.write(buffer[i]); // write from buffer into second row of LCD
        }
      }
      charCount = 0;
      updateLCD = 0;

    }
    else
      buffer[ bufferIndex++ ] = ch; // add the character into the buffer
  }
}




So sending the message '1 hello ^' prints 'hello' into the first row of the LCD and sending '2 goodbye ^' prints 'goodbye' into the second row of the LCD. You can use the serial monitor to test or use the following Max/Msp patch.
Code:
max v2;
#N vpatcher 304 60 1564 916;
#P origin 0 -103;
#P toggle 92 58 15 0;
#P window setfont "Sans Serif" 9.;
#P window linecount 1;
#P newex 92 80 58 196617 metro 100;
#N counter 2 0 127;
#X flags 0 0;
#P newobj 197 121 83 196617 counter 2 0 127;
#N counter 0 0 127;
#X flags 0 0;
#P newobj 92 121 83 196617 counter 0 0 127;
#P newex 197 290 95 196617 prepend slider_2 =;
#P newex 197 313 54 196617 prepend 2;
#P slider 197 147 15 128 0 1;
#P newex 92 291 95 196617 prepend slider_1 =;
#P newex 92 349 64 196617 speedlim 50;
#P newex 92 314 54 196617 prepend 1;
#P slider 92 148 15 128 0 1;
#P newex 92 385 47 196617 append ^;
#P newex 92 409 51 196617 tosymbol;
#P newex 92 432 166 196617 spell;
#P newex 92 457 71 196617 serial a 9600;
#P connect 14 0 13 0;
#P connect 13 0 11 0;
#P connect 11 0 4 0;
#P connect 4 0 7 0;
#P connect 7 0 5 0;
#P connect 5 0 6 0;
#P fasten 9 0 6 0 202 344 97 344;
#P connect 6 0 3 0;
#P connect 3 0 2 0;
#P connect 2 0 1 0;
#P connect 1 0 0 0;
#P fasten 13 0 12 0 97 106 202 106;
#P connect 12 0 8 0;
#P connect 8 0 10 0;
#P connect 10 0 9 0;
#P pop;

It all seems to work well, but as it's my first bit of Arduino code I'm sure there are some things I could do better - Any advice?

I also came across a really strange problem with running the LCD and using 'Serial.println' in the same program. I've boiled it down to the following:
Code:
// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // get rid of this line and it works?!?

void setup()
{
Serial.begin(9600);  
}

void loop(){
Serial.println("Hello World!");
delay(1000);
}

I would expect this to print out 'Hello World!' but it does not. I get 'Hello Wold!' (misses out the letter 'r') in the serial monitor.

If i get rid of the 'LiquidCrystal lcd(12, 11, 5, 4, 3, 2);' line I get the expected output, but of course I cant use my LCD display then.

Can anyone tell me what is going on here?

Arduino 0017 w/Roboduino Duemilanove board.

Cheers,

John.


Logged

Pages: [1]   Go Up
Jump to: