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
}
}