Serial port communication keeps disconnecting for unknown reason

I have a Mac Mini hooked up to 3 arduinos ( a mega 2560 and 2 UNO R3s) sending and receiving messages back and forth with processing.

The 3 arduinos control up to 34 relays that control the venue lighting, and one of the arduinos has 6 sensors attached that sends the inputs back to processing. (two touch sensors, two buttons, one accelerometer and one motion sensor).

However, every time i startup the installation, it works for about 10-15 seconds, I see that processing stops receiving the serial data from arduino, and when i try to restart the programs, it says the port is busy.

I tried unplugging and plugging the arduinos, didn't work.

I tried restarting the computer, but seems that the busy port is preventing the computer from shutting down, so I could only shut it down by holding on to the power button. It works again after i restart the machine but the serial communication drops again after 10-15 seconds.

I have no idea what could be the issue, just a few wild guesses.

  1. maybe something was short circuited, however after checking visually a few times i haven't noticed any shortages so far.
  2. maybe because the USB cable to the arduino(the one with the sensors) is too far away, about 10m, so maybe i should try a booster or try to shorten the range.

I am in desperate need of help and would really appreciate if anyone could point out what could be the problem.

Thanks

Does your Processing program open and close the serial ports or do they remain open ? Opening a serial port attached to most Arduinos will cause them to reset and begin the program again. You can see this behaviour when you open the Serial monitor from the IDE.

Maybe one or more of the Arduinos has run out of ram and crashed.

Pete

I'm not sure I fully understand how it all works.

For communications from Processing to Arduino, processing opens 3 serial ports, with the same port (9600), but with different names (according to the serial port name like "tty......1411" ), the serial ports remain open as long as the program runs.

For communications from Arduino to processing, actually only one arduino is sending out messages, with the "Serial.begin(9600)" way of doing it.

The communications are really frequent, sending a lot of messages back and forth, I don't know if that is an issue or not.

@ Pete

Hmm.. I dont really remember coding anything complicated enough that could crash the arduino, maybe because of a program bug, but it seemed to be working fine when I tested it individually without the lights though.

Maybe ill need to take another look at the code.

Here is the code for the arduino that receives 6 sensors and controls 10 relays.

int delay_time    = 30;
int letter_first  = '#';
int letter_last   = ';';
int output_pins[] = {
  // Left [A-F]
    12,11,10,9,8,7,
  // Right [G-J]
    6,5,4,3
};
int input_pins[]  = {
  A0, A1, A2, A3, A4, A5
};
String  send_data;
char    receive_data[(sizeof(output_pins)/sizeof(int))];
boolean start_receive;
int     curr_char;
int     data_length;

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

void loop()
{
  readArduino();
  readProcessing();
  delay(delay_time);
}

void readArduino()
{
  int i = 0;
  send_data  = "";
  send_data += "#";
  for(i = 0; i < (sizeof(input_pins)/sizeof(int))-1; i++)
  {
    send_data += String(digitalRead(input_pins[i]));
    send_data += ",";
  }
  send_data += String(analogRead(input_pins[(sizeof(input_pins)/sizeof(int))-1]));
  send_data += ";";
  Serial.println(send_data);
}

void readProcessing()
{
  if(Serial.available())
  {
    curr_char = Serial.read();
    if(curr_char == letter_first)
    {
      start_receive  = true;
      data_length    = 0;
      resetReceiveData();
    }
    else if(curr_char == letter_last)
    {
      start_receive  = false;
      processData(String(receive_data), data_length);
    }
    else
    {
      if(start_receive)
      {
        receive_data[data_length]  = char(curr_char);
        data_length++;
      }
    }
  }
}

void processData(String data, int len)
{
  int i = 0;
  if(data.indexOf('0') > -1)
  {
    allLight(false);
  }
  else if(data.indexOf('1') > -1)
  {
    allLight(true);
  }
  else
  {
    allLight(false);
    for(i = 0; i < data.length(); i++)
    {
      digitalWrite(output_pins[data.charAt(i) - 'A'], HIGH);
    }
  }
}

void allLight(boolean on)
{
  int i = 0;
  for(i = 0; i < (sizeof(output_pins)/sizeof(int)); i++)
  {
    digitalWrite(output_pins[i], on);
  }
}

void setVariable()
{
  int i = 0;
  for(i = 0; i < (sizeof(output_pins)/sizeof(int)); i++)
  {
    pinMode(output_pins[i], OUTPUT);
  }
  start_receive  = false;
  data_length    = 0;
  send_data      = "";
}

void resetReceiveData()
{
  memset(receive_data, 0, (sizeof(receive_data)/sizeof(receive_data[0])));
}
String  send_data;

Stop that crap right there. First, there is no reason to collect all the data into one variable before sending it. The receiving end can’t tell you did that, and wouldn’t care if it could. Second, there is no reason to wrap the char array that actually holds the data.

void setVariable()

That’s about the dumbest name for a function I’ve seen all week.

Sorry, since I’m really noob at this.

So I should just a use Serial.print() and Serial.println() to send the data?

In your opinion, which part of the code might be crashing the arduino?

So I should just a use Serial.print() and Serial.println() to send the data?

Yes.

In your opinion, which part of the code might be crashing the arduino?

All that String crap.

Thanks.

I'll try it out.

For communications from Processing to Arduino, processing opens 3 serial ports, with the same port (9600)

Are you sure about this ? I am not familiar with Processing but 9600 sounds suspiciously like the baud rate to me and it matches the baud rate in the Arduino code. How are the three serial ports in Processing connected to the single one on the Arduino ?

Sorry I think i misunderstood the code, you are right about it.

I checked some examples actually it should be this

arduino = new Arduino(parent, name, rate);

So basically 9600 is not the port but the transfer rate, and the "name" is the port. So its actually 3 different serial ports that use the same baud rate.

So its actually 3 different serial ports that use the same baud rate.

How many serial ports on the Arduino are they connected to and how ?

UKHeliBob:

So its actually 3 different serial ports that use the same baud rate.

How many serial ports on the Arduino are they connected to and how ?

I have a Mac Mini hooked up to 3 arduinos ( a mega 2560 and 2 UNO R3s) sending and receiving messages back and forth with processing.

Sounds like three arduinos with one serial port per arduino.

cynricng: In your opinion, which part of the code might be crashing the arduino?

Are you sure that it is the Arduino which is crashing, and not the PC/Laptop/Processing code which is crashing - could it be that processing is not processing (!) the incoming data fast enough, and you are getting some sort of receive-buffer-overflow ??

Sorry for the late reply.

Changed the setup to just 1 mega and 1 Uno instead of 3,
I also modified the entire program, changing all the data transfer to just short bytes, and only sending when there is a status change.

The only long message I’m sending around is the arduino UNO sending back to Processing, which goes like this:
#00000,000;”
First and last char is for verifying whether there are left out characters.
2nd - 6th char are I/O indicators of different sensors switches such as motion sensors, buttons, touch sensors
8-10 char is the value of the accelerometer
The arduino has a 30 millisecond delay between each loop. The message sends out whenever there is change in any of the sensors, however since the accelerometer values bounce around quite a lot even when it sits still, it pretty much sends out messages on every loop, even if I have already averaged out the values.

Here is the processing code for receiving the arduino message

String[][] ard = matchAll(from_arduino, "#(.*?);");
    if(ard != null)
    {
      for(i = 0; i < ard.length; i++)
      {
        if(ard[i][1].indexOf('#') < 0 && ard[i][1].indexOf(';') < 0)
        {
          //Do something with message ard[i][0]
        }
      }
    }

As for messages sent from the Processing to Arduinos, its just bytes like “201” with a “255” at the end, so arduino recognises its the end of the message.
The first digit is the phase of the program such as “sleep phase” “initiate phase” “active phase”
The others are just I/0 indicators of which phase the lights should be in.

The processing code is as below

if(curr_a != prev_a)
{
  prev_a      = curr_a;
  for(j = 0; j < curr_a.length(); j++)
  {
    arduino[0].write(curr_a.charAt(j)-'0');
  }
}
if(curr_b != prev_b)
{
  prev_b = curr_b;
  for(j = 0; j < curr_b.length(); j++)
  {
    arduino[1].write(curr_b.charAt(j)-'0');
  }
}

And the arduino code is as below

while(Serial.available() > 0)
  {
    data = Serial.read();
    if(data == 255)
    {
      if(curr != 3){
        curr = 0;
        return;
      }
      curr = 0;
      
      if(light_stage==0 && data_group[0] == 1){
        flash_time_curr = flash_time_max;
      }
      
      light_stage = data_group[0];
      light_flash = false;
      
      if(data_group[1] == 0) // If second char is 0
      {
        light_touch = false;
      }
      else if(data_group[1] == 1) // If second char is 1
      {
        light_touch = true;
        touch_count = speed_normal;
      }
      if(data_group[2] == 0) // If second char is 0
      {
        light_button = false;
      }
      else if(data_group[2] == 1) // If second char is 1
      {
        light_button = true;
        button_count = speed_normal;
      }
    }
    else // Dataset collection
    {
      data_group[curr]  = data;
      curr++;
    }

It seems to work fine with my mac book pro running osx 10.7.5, but the machine that I’m supposed to run it on is a Mac Mini 10.9 and just keeps disconnecting after a few seconds and clogging up the port.

On the laptop, it still disconnects once in a while but not that often, but the port releases back out just fine when I close the program. However when I tried using a USB hub with external power, and matched the port names, it disconnects just like the mac mini which is strange.

I actually brought the Mac mini to an apple technician to ask what could potentially be the problem, he said that the ports seem fine, and said maybe the OS has collided the port addresses, and he could downgrade it 10.8.5 for us to see if it works.

I'm suspicious that because the arduino that sends the sensor data to processing is the same one that is receiving data form processing. Therefore the messages are colliding into each other and freezing the serial port