Freezing/peripheral problems with serial communication (Arduino)
I am using an Arduino Duemilanove and some pots / buttons to control a Max patch. However, for seemingly no reason, there are some times that either Max freezes up as I open the serial connection, or one of my peripherals (mouse or keyboard, USB and bluetooth) stop communicating with my computer. The latter problem seems to indicate that it's the serial connection that is the issue.
I'm using almost exactly the suggested Arduino to Max patch, modified only to allow for more inputs (attached). The problem occurs when using the attached patch both by itself and as a subpatch.
I am on Mac OS 10.7, with Max 5.1.7, on a 2010 (possibly?) iMac. I'm not certain what other information I can include, but if any more is needed, please ask.
To reproduce problem:
1. Plug in Arduino through USB port.
2. Send Arduino the attached code.
3. Once code is fully received by Arduino, hit the top toggle in the attached Max patch.
At this point, Max would sometimes freeze, with the toggle remaining in the off position. (Max would then fail to start up again, even with the shift-click trick. It would get as far as showing the bold "MaxMSP" menu header in the top left of the screen, but would get stuck with the spinning beach ball.)
At other times, my mouse or keyboard would cease to work, but the controller would continue working (if my memory is correct: I can't seem to reproduce the bug at this moment, of course... :) ). Some times, the mouse or keyboard would start working again once Max was quit; other times, a restart fixed it.
here is the Arduino code:
int sm_buttonPin = 2;
int bg_buttonPin = 3;
int potPin_1 = A0;
int potPin_2 = A1;
int potPin_3 = A2;
int potPin_4 = A3;
int potPin_5 = A4;
void setup()
{
pinMode(sm_buttonPin, INPUT);
pinMode(bg_buttonPin, INPUT);
Serial.begin(9600);
}
int small_read = 0;
int big_read = 0;
void loop()
{
Serial.print(digitalRead(sm_buttonPin));
Serial.print(" ");
Serial.print(digitalRead(bg_buttonPin));
Serial.print(" ");
Serial.print(analogRead(potPin_1));
Serial.print(" ");
Serial.print(analogRead(potPin_2));
Serial.print(" ");
Serial.print(analogRead(potPin_3));
Serial.print(" ");
Serial.print(analogRead(potPin_4));
Serial.print(" ");
Serial.println(analogRead(potPin_5));
}
Hi
intermittent problems like this are unlikely to be reproducible on other systems. If the patch occasionally works as expected, I can't see anything glaringly obviously wrong with the code or the patch. I'm not sure starting the [qmetro] and opening the serial port at exactly the same time is necessary. Try using just [metro] in place of [qmetro] and manually starting each ([serial] then [metro]) in turn; your port argument to the serial object is enough. I don't see any real need to be constantly switching metro on and off and opening and closing the serial port.
Brendan
Hello n00b_meister,
Thanks for the reply. Yeah, I have a penchant for ending up with seemingly unsolvable intermittent problems which are unreproducible. Oh well.
However, I was more wondering if there was some sort of lower-level stuff I could do, rather than hoping for someone to be able to reproduce the bug, since it seems to my novice mind that my computer is just getting its serial ports mixed up.
I'll try out that modification.
I have the same problem, intermittent behaviour
USB turned off
sometimes keyboard and trackpad turned off
I'm working on serial communication between Arduino and Max
did you find a solution or the problem is the Board?
Thanks
I had problems too using this kind of arduino code. I think the problem is that there are more datas sent over the serial port than Max can read them.
In some cases, I introduce a small delay()
into the main loop. In others, I send the datas every few ms, calling in the mail loop a function like this one:
void serialOut (int x1, int x2, int x3, int x4, int x5, int x6)
{
static unsigned long currentTime = 0;
if (abs (millis() - currentTime) > 50)
{
Serial.print(x1);
Serial.print("_");
Serial.print(x2);
Serial.print("_");
Serial.print(x3);
Serial.print("_");
Serial.print(x4);
Serial.print("_");
Serial.print(x5);
Serial.print("_");
Serial.print(x6);
Serial.println();
currentTime = millis();
}
}
The best way to make sure you don't overflow either buffer is to make sure both the Arduino and Max are ready for new serial information. In the Arduino IDE, look at File>Examples>Communication>SerialCallAndResponse. There's a max patch at the bottom which illustrates this "Handshake" method of communication.
Hi there,
same problem here on OSX 10.6.8 USB/MAX freezes after 10 - 15min.
I use an USB to serial adapter an USB Midi-Interface and Enttec USB DMX Pro.
On Windows XP emulated with VMWare Fusion I have no problems.
Tested on both OS with MAX 5 and 6.
i had the same freezing, under win7/64bit.
i manged to stabilize the system, using some of the tips above and a mishmash of three arduino core examples (blinkWithoutDelay,serialCallResponse, smoothing)
note the choice of NOT using delay but a delta between prevTime and currentTime. this doesnt hang the arduino and allows for continues sampling (or whatever else you want to do with no delay).
in following code arduino side will sample an analog pin and pass it to max.
max patch
m
arduino code
////////////////////////////////////////////////////////
const int numReadings = 50; //my sensor is very noisy
//you can take it down to something that work for you.
int readings[numReadings];
int index = 0;
unsigned long total = 0;
int average = 0;
int inputPin = A0;
unsigned long previousMillis = 0;
void setup()
{
// initialize serial communication with computer:
Serial.begin(19200);
Serial.println("init");
for (int thisReading = 0; thisReading < numReadings; thisReading++)
readings[thisReading] = 0;
establishContact(); // send a byte to establish contact until receiver responds
}
void loop() {
average = smoother(analogRead(inputPin));
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > 10) {
previousMillis = currentMillis; // save the last time you blinked
if (Serial.available() > 0) // if we get a valid byte
Serial.println(average, DEC);
}
}
void establishContact() {
while (Serial.available()
Serial.print('A'); // send a capital A
delay(300);
}
}
// converted smoothing example into a function
// dont use it twice as it uses globals.
unsigned long smoother(int newVal){
total= total - readings[index];
readings[index] = newVal;
total= total + readings[index];
index = index + 1;
if (index >= numReadings)
index = 0;
return total / numReadings;
}
/////////////////////////////////
`