Arduino + LCD + Max5 (Max/MSP)

Hi there,

I am having trouble with connecting the Arduino to an LCD while sending/receiving serial data to Max/MSP.

I got the LCD to work (hooked up a potentiometer to analog in 0 and it displays on the LCD).

I got the connection to Max/MSP to work (receiving values from analog/digital pins to Max/MSP).

Here is the thing. If I try to do both at the same time, it acts weird. The LCD kind of freezes and I can't do anything. I can sometimes get it to work if I reconnect a couple of times quickly after each other. :-?

Here is my code:

#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12); //16x2 standard LCD screen hooked up to the arduino,
// using this tutorial: Arduino Tutorial - connecting a parallel LCD
int x = 0;

int a = 0;
int y = 0;
int a_old = 0;

void setup()
{
lcd.begin(16, 2);
Serial.begin(9600);
delay(600);
}

void loop()
{
if (Serial.available() > 0){
if (Serial.read() == 'r') { // If an 'r' is received then read the pins and send them to max/msp AND
// write "serial received" to the LCD
for (int pin= 0; pin<=5; pin++){ // Read and send analog pins 0-5
x = analogRead(pin);
sendValue (x);
}

Serial.println(); // Send a carriage returnt to mark end of pin data.
delay (5);

lcd.clear(); // Displaying "serial received" on line 2 of the LCD if there is
lcd.setCursor(0, 1); // incoming data from the serial connection
lcd.print("serial received");
// lcd.print(analogRead(0));
}
}
else
{
a= analogRead(0); // This is what happens by default. Seeing if the value of Ain0 changes
y = (a + a_old)*0.5; // and if it does, diplaying it's value on line 1 of the LCD

if (abs(y - a_old) > 0){
lcd.clear();
delay(5);
lcd.setCursor(0, 0);
lcd.print("my number: ");
lcd.print(y);
delay(4);
}

a_old = y;
}

}

void sendValue (int x){ // function to send the pin value followed by a "space".
Serial.print(x);
Serial.print(32, BYTE);
}


I uploaded a video showing what happens: - YouTube
I would really like to understand what is wrong...
thanks a lot.

You might want to check whether your code works used from the Serial monitor in the Arduino first.

If that does - and Max/MSP still doesn't work - then it is possible the problem could be due to different serial port initializations of Max/MSP vs. the Serial monitor in the IDE.

I had a similar problem in Linux; for instance, to intialize a serial port, it is usually enough to call stty 115200 </dev/ttyUSB0; and then in principle you can call cat /dev/ttyUSB0 in order to read from the Arduino / the USB serial port.

Now, this for me happens not to work (for some code) immediately after programming the Arduino; immediately after programming, calling stty / cat will cause cat to exit after reading only a few bytes. And then, I usually have to use screen /dev/ttyUSB0 115200 in order to 'initialize' the port properly - only after a screen session, will cat start to work.

I can, however, use stty -a in Linux to see all serial port settings after programming of Arduino - and after screen is used; and compare the differences:

# after programming

$ stty -a -F /dev/ttyUSB0 
speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^H; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 0; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt
-echoctl -echoke

# after screen /dev/ttyUSB0 115200:
$ stty -a -F /dev/ttyUSB0 
speed 115200 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^H; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 100; time = 2;
-parenb -parodd cs8 -hupcl -cstopb cread clocal -crtscts
-ignbrk brkint ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig -icanon iexten -echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke

So, the difference taken into account, the complete initialization that screen does, would be done through stty as:

stty 115200 min 100 time 2 brkint ignpar -inpck ixon iexten echoe echok echoctl echoke </dev/ttyUSB0

(although, for me, to get this running it is enough to just specify min 100 time 2 with stty...)

Don't know if this is applicable to your case - but maybe you can somehow check the serial port setting when things work, and when they don't (maybe Max/MSP can read them?) and see if that makes a difference?

Cheers!

PS: Saw your video - you are using the Mac serial port name as argument of 'serial' (i.e. "serial ~usbserial...."); I believe, for Max/MSP you should always use the "internal" serial port names, like "a", "b", "c" - as when it gives you the list in response to 'print' command - when you work with 'serial' object (i.e. "serial a ....").

In any case, things seem to start working when you start using these 'internal' names as argument of 'port' command, i.e. "port a"; maybe this is also the reason why you have to click twice to initialize it properly?

Thanks a lot for your input.

Everything works fine in Arduino's serial monitor, so I think you are right, that it is maybe Max/MSP that can't initialize properly.

I don't really understand the stty/cat/screen commands, and how to use them. From where would you call the code? As far as I understand, the idea would be to try to get more exact serial port settings (when it is working), and then initialize the "serial" object in Max/MSP with some more specific settings...?

I have tried using both the "a", "b", "c" shortcut arguments and the actual port names when initializing "serial" in Max/MSP... they seem to give the same result.

Thanks again...

Hi bitsandbobs,

Everything works fine in Arduino's serial monitor, so I think you are right, that it is maybe Max/MSP that can't initialize properly.

Ok, that's good to have confirmed.

I have tried using both the "a", "b", "c" shortcut arguments and the actual port names when initializing "serial" in Max/MSP... they seem to give the same result.

Ok - not good that it's the same result - but good that we know this isn't the problem...

As far as I understand, the idea would be to try to get more exact serial port settings (when it is working), and then initialize the "serial" object in Max/MSP with some more specific settings...?

Exactly - the thing is to discover what are the differences in serial port initialization between Arduino IDE serial reader (which works) and Max/MSP (which doesn't) - and then try to initialize Max/MSP with the (hopefully working) settings from Arduino IDE's serial reader..

I don't really understand the stty/cat/screen commands, and how to use them. From where would you call the code?

You would call the code (programs, rather) from your terminal in Mac OSX.

The thing is - you use Max/MSP to read and write to the serial port (which represents the Arduino).

Since I don't - I use cat to just read the serial port (since cat can only read a file, simply); and alternatively, I use screen to both read and write to the serial port (since it can do both).

Those cat / screen are not that relevant for your case - so far, I believe you should just use stty to read the serial port settings (after IDE's serial reader; and after Max/MSP) so that you can compare them.

I found some examples for use of stty on Mac, but nothing really a tutorial:

These say that, possibly, the syntax for stty is not the same for Mac and Unix - but try it.

Note that to retrieve the serial port settings, I do in Linux (the $ below indicates the command line prompt - don't type that):

$ stty -a -F /dev/ttyUSB0

Above, '-a' means "read all settings", and '-F /dev/ttyUSB0' means "from the device /dev/ttyUSB0" - change this accordingly for the device name on your Mac.

Note that if you just type 'stty -a' - without specifying a device - you will retrieve the settings of your current Terminal (command line) - which is also a tty device :slight_smile:

Then, to set the serial port settings, the syntax on Linux is a bit different:

$ stty 9600 min 100 time 2 </dev/ttyUSB0

The stty program will automatically interpret the lone 9600 as the speed to set the serial port to - and then you add any other parameter you may want to set (such as 'min 100' and 'time 2') after it ...

In essence, doing a 'stty 9600 </dev/ttyUSB0' would be the same as when the 'serial a 9600' object first runs in Max/MSP...

Note that to specify the serial port, this time you don't use '-F /dev/ttyUSB0' - but instead you use a so-called "file descriptor redirection" with the left angle bracket (<) (see I/O Redirection).

To make sure whether you have set the settings succesfully, you would then call 'stty -a -F ...' again.

To get to the stty documentation, you should be just able to type 'man stty' in your Terminal - and you get it shown after pressing [ENTER] (and you exit it by pressing 'q'); however, it can be a bit difficult to read.

Cheers!