Help with Processing and serial communication

I have been having a very annoying problem recently with some code I am writing. The general idea is that I have some firmware on the Arduino that is constantly checking the USB serial connection for commands (Gcodes actually). When it finds a command it processes that command and then sends a handshake.

The whole time this is happening, I have a processing program that is reading Gcodes from a file and sending them 1 by 1 to the Arduino via the serial connection. Each time is sends a command it waits for the handshake saying the Arduino is done processing the command before it sends the next command.

The problem I am having is that my initial 2-3 handshakes don't seem to work. I have had to resort to sending 2 or 3 commands regardless of if it sees a return handshake and then after those commands are sent, the rest of the handshakes work as normal. I have a feeling I am just doing something wrong or out of order, but I have been unable to figure out what it is. I was thinking maybe something to do with clearing the serial buffer between commands or maybe waiting for available serial connection before sending the handshake...??? Not sure. I am still using a colon ":" as the end of command character because originally I was using the Arduino Serial Monitor to send commands which does not send a carriage return after each command. Might have something to do with the problem. So if anyone has any ideas I would really appreciate some help! The code is below.

Processing Code
import processing.serial.*;

Serial myPort;  // Create object from Serial class
String[] lines; // file array
int index;
int conf = 1;
boolean handshake = true; // allow it to send 1st command

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.
  
  
  lines = loadStrings("test.txt");
  println(Serial.list()); // print list of available serial ports
  String portName = Serial.list()[1]; // change this to correct com port ([0] = COM1, etc)
  myPort = new Serial(this, portName, 9600); 
  
  println("File is " + lines.length + " lines long");
}

void draw() {
  //myPort.write("M201 :");
  
  if (index < lines.length) {
    
    myPort.write(lines[index]);
    println("Line " + index + ": " + lines[index]);
    index = index + 1;
    if (index < 2){
      delay(2000);
      handshake = true;
    }
    else
      handshake = false;
    
    while (handshake == false){ // wait for confirmation
      if ( myPort.available() > 0) {  // if data is available,
        conf = myPort.read();         // read it and store it
        if (conf == 'A'){
          println("  handshake received!");
          handshake = true;
        }
      }
    }
    
    
  }
  
  
}
Arduino Code
const int ledpin = 13;

boolean comment_mode = false;

// comm variables
const int max_cmd_size = 100;
char buffer[max_cmd_size]; // buffer for serial commands
char serial_char; // value for each byte read in from serial comms
int serial_count = 0; // current length of command
char *strchr_pointer; // just a pointer to find chars in the cmd string like X, Y, Z, E, etc
int codenum;
// end comm variables


void setup() // initialization loop for pin types and initial values
{
  pinMode(ledpin, OUTPUT); // debuggingg, delete later
  digitalWrite(ledpin, LOW);
  
  Serial.begin(9600); // initialize serial interface for debugging
  
  clear_buffer();
  
  
}

void loop() // input loop, looks for manual input and then checks to see if and serial commands are coming in
{
  
  get_command(); // check for Gcodes
  
}




void get_command() // gets commands from serial connection and then calls up subsequent functions to deal with them
{
  if (Serial.available()) // each time we see something
  {
    serial_char = Serial.read(); // read individual byte from serial connection
    
    if (serial_char == ':') // end of a command character, should change to \n in future for sending gcode files
    { 
      process_commands(buffer, serial_count);
      clear_buffer();
      comment_mode = false; // reset comment mode before each new command is processed
    }
    else // not end of command
    {
      if (serial_char == ';') // semicolon signifies start of comment
      {
        comment_mode = true;
      }
      
      if (comment_mode != true) // ignore if a comment has started
      {
        buffer[serial_count] = serial_char; // add byte to buffer string
        serial_count++;
        if (serial_count > max_cmd_size) // overflow, dump and restart
        {
          clear_buffer();
          Serial.flush();
        }
      }
    }
  }
}


void clear_buffer() // empties command buffer from serial connection
{
  serial_count = 0; // reset buffer placement
}


void process_commands(char command[], int command_length) // deals with standardized input from serial connection
{
  if (command[0] == 'M') // M code
  {
    codenum = (int)strtod(&command[1], NULL);
    switch(codenum)
    {
      case 201: // M201, turn light on
        //Serial.println("M201: turn light on");
        digitalWrite(ledpin, HIGH);
        break;
      case 202: // M202, turn light off
        //Serial.println("M202: turn light off");
        digitalWrite(ledpin, LOW);
        break;
    }
  }
  
  // done processing commands
  if (Serial.available() <= 0) {
    Serial.print('A', BYTE);   // send a capital A
  }

}

Like the loop function on the Arduino, the draw method, in a Processing sketch, is called over and over again in an infinite loop. I don't see anything being done in the draw method other than sending and receiving serial data.

That all could (and, I think in this case should) be done in setup.

In the processing code, you open a serial port connection. That causes the Arduino to reset. The reset on the Arduino is not instantaneous. The Arduino is not ready to receive serial data, but you send it some anyway.

After the Arduino is ready to read some data, it does so, and then sends the string that says it is ready for more.

Change the Arduino code so that it sends the "I'm ready, what's the holdup?" message in setup.

Change the Processing code so that it doesn't send anything until the Arduino says it's ready.

Keep the code in the Arduino sketch that sends the "I'm ready, what's the holdup?" message after it is done processing the command.

I did not realize the Arduino actually resets after you open a serial connection. Thanks for the pointer. I will change the code to have some kind of a initialize_connection function where the Processing waits to hear that the Arduino has restarted and is ready to play. I'll report back with my results.

In the meantime, I am always up for constructive criticism on either of the codes if someone out there sees a better way to accomplish what I am trying to do

That seems to have solved the problem! So does the Arduino reset anytime something tries to initialize a serial connection to it? I'm still not fully sure why the Arduino does this, but the results show that it definitely takes some time after the connection is initialized to reboot.

The Arduino DOES reset every time a serial connection is made. There have been many arguments for and against the restart. The main argument for is that lots of stuff needs to happen to establish communications. Doing that in the middle of loop would interfere with timers and interrupts, etc. Doing it in setup, before the timers are started and interrupts enabled makes sense.

WoW :frowning:

LOL I was all this day suffering, cuz I couldn't understand why Global Variables reseted to false :S, and some time later I put a Blink at Setup() and I saw this :S Arduino resets when Sketch is executed (Serial Port Open) and resets again when process is closed :frowning:

There is nothing to do to avoid Arduino's reset??

Thanks :frowning:

There is nothing to do to avoid Arduino's reset??

I think it depends on which board you've got, but on the 2009 there's a track you can cut to disable this feature.
Check your board's documentation.

Not sure if this was covered elsewhere already.

Wouldn't it be possible to disable the resetting of the arduino (mega) on comport-(de)init by a command/define or something? I think in my case, where the arduino will keep track of a relative position/speed in the world, i'd rather be in charge of resetting than the 'auto-reset' like it does now.

Wouldn't it be possible to disable the resetting of the arduino (mega) on comport-(de)init by a command/define or something

No, not really - it's a feature of the hardware outside the AVR.

Ok thx, it's no biggy though.

There is info stating that a certain valur resistor can be placed between the +5v pin and reset pin to prevent the reset. I think the reset is actually a function of the FTDI chip and the and the IDE sending a dtr/rts type signal to the board reset circuit.

By IDE i assume you mean the Arduino sketch-writing thingy, when i (de)-init the comport from my own (higher 'brain') software the reset still happens so it's not the Arduino software causing the reset. Can only assume it's a window's API causing it.
If it would cause an issue later on i'll dig into the hardware-resistor stuff, just a resistor should be easy (when going easy on coffee as well) ...

If it would cause an issue later on i'll dig into the hardware-resistor stuff, just a resistor should be easy (when going easy on coffee as well) ...

I believe it's a 150 ohm resistor between ground and reset that disables the auto-reset feature. The auto-reset feature is required by the Arduino IDE so that it can activate the bootloader program in the AVR chip after compiling but prior to uploading.

You can in theory defect auto-reset in the PC if you can configure the comm port driver (or OS API?) to not touch the DTR and RTS control signals, but the details vary with OS being used.

Some Arduino clone boards use a simple switch or jumper clip to enable or disable the auto-reset feature, a nice feature to have.

Lefty