I have Processing and Arduino communicating over COM port just fine. COM port is through USB and attached to Arduino Mega 2560, all on Win XP. There is a LCD with serial controller BV4618, attached to Arduino. The LCD's serial controller is using pins 4 & 5 for serial RX/TX. Communication between Arduino and LCD is set to 9600 baud, otherwise I get some silly Korean characters.
I wrote this simple Processing test program which just sends few strings down and Arduino happily receives them and displays them on LCD. Now I tried speeds up to 57600 baud and it all works fine.
But problem is that I need to put a delay(900); statement into Processing code, otherwise Arduino stops receiving data. In other words, if Processing delay is 900 or higher, than Arduino shows received data on the LCD. If I drop Processing delay to even 800, Arduino immediately stops showing any data received data, although a little RX led on Arduino blinks as sign that something went in.
Now, all this is just testing. Then end product needs to be a Processing/Arduino code that works as fast as possible, without a delay that is almost one second long. I do not know much about how Serial works. How can I avoid having this delay(900) on the Processing side?
Here is Processing code:
/**
* v1.00.a
*
* This sketch illustrates how to send commands with parameters to an Arduino sketch. Commands
* need to be terminated with LF or CR. This Processing sketch is made to work with Arduino
* sketch:
*
* Arduino_LCD_Serial_ByVac_BV4618_and_Serial_Com
*
* Arduino needs to have LCD display attached and configured. The above Arduino sketch is using
* the HD44780 LCD (4x20) controller with ByVac BV4618 serial controler.
*
*
* Updates:
*
* 15:37 9.5.12 - v1.00.a = Initial code.
*
*/
import processing.serial.*;
// The serial port:
Serial myPort;
int i = -1; // Counter for switch() statement must start from -1, not 0, as one
// would imagine.
void setup() {
// List all the available serial ports:
println(Serial.list());
// Just pick up the serial port to which Arduino is hooked, or find where Arduno
// sits in Control Panel > System > Device Manager > USB Ports.
myPort = new Serial(this, "COM6", 57600);
}
void draw() {
/*
* It was found through experimentation that Processing wants to execute only one write()
* statement per loop. If you try to execute two write()'s it freezes, it doesn't even reset
* Arduino, what is otherwise normal at a begining of Processing sketch run!
*
* Processing's switch() statement, on other hand, wants to start itterator from -1, not 0,
* as it would be logical.
*
* For multiple write() statements, sending multiple commands to Arduino, just stuck them up,
* like: "servox 472\nsrx 2437\n", by using '\n' as command delimeter.
*/
switch (i) {
case 0:
// Line must be terminated either '\n' or '\r' characters.
myPort.write("servox 1379\n"); break;
case 1:
myPort.write("servoy 20\r"); break;
case 2:
// Comands can be stuck up, one after another, like this:
myPort.write("srx 640\nsry 480\n"); i = -1; break;
}
i++;
// HUGE DISCOVERY!!! Only send one write() statement per loop. Trying this second one, blocks
// the Processing code, at a runtime, and it doesn't even reset Arduino!
///myPort.write("servoy 20\n");
delay(900);
}
Here is Arduino code:
/**
* v1.00.a
*
* Sending characters and words, via terminal like Serial Monitor, to Arduino and displaying
* them on the attached ByVac BV4618 serial interface. ByVac BV4618 is attached to Negative
* Black LCD Display HD44780 4x20 (YMFC-C2004).
*
* Modified the original example file by removing all that looked like keypad instruction.
*
* Circuit:
*
* - ByVac BV4618, the HD44780 LCD controller with Serial, RS232 and I2C interface,
* http://doc.byvac.com/index.php5?title=Product_BV4618
*
* - LCD Display HD44780 4x20 Black NEG Backlight (YMFC-C2004),
* http://www.ebay.co.uk/itm/LCD-Display-HD44780-4x20-chr-20x4-Black-NEG-Backlight-/170440872374?pt=Bauteile&hash=item27af1151b6
*
* - power from Arduino, Vcc= +5.0V (red wire) and Gnd (black wire),
* - 2.7kOhm resistor between LCD's Gnd (1st pin) and Vo (3rd pin),
* - Ard.PWM.pin #4 - Ard's TX pin, to BV4618's RX pin, white wire,
* - Ard.PWM.pin #5 - Ard's RX pin, to BV4618's TX pin, green wire,
*
* Usage:
*
* Settings:
*
* - Terminal program of choice, like Arduino IDE's Serial Monitor, must be set to:
*
* - Baud rate ........... 57,600
* - Line termination .... Newline
*
* - If instructions are sent via serial port from another program, like Processing, than
* lines must be terminated with '\n' or '\r'. For example, these are good ones:
*
* "servox 1375\n" or "SRY 12\r"
*
* Space or ' ', is not used as delimeter. Space ' ' is treated just as any other character.
*
* Input:
*
* - Type in: 'test1' (without quotes), than press return. Line termination must bed done
* with LF and CR. If you want to use ' ' or char(32) for line termination, you must change
* code.
* - Output to above will be 'test1,' (without quotes), etc. All outputs will follow
* each other like: test1,test 2,test3,test4 etc.
*
* This Arduino sketch is made to work with Processing sketch:
*
* Processing_Serial_Write_Command_Line_1
*
* Updates:
*
* 15:37 9.5.12 - v1.00.a = Initial code.
*
*/
#include <BSerial.h>
#include <bv4618_S.h>
#define rxPin 5
#define txPin 4
BV4618_S lcdByVacSerial(rxPin, txPin);
boolean blnLCDRefresh = true;
char incomingChar = 0; // Arduino receiving incoming serial data into int variable.
const int SERIAL_INPUT_BUFFER_SIZE = 32; // Input line lenght up to 31 characcters.
char arrChrBuffer[SERIAL_INPUT_BUFFER_SIZE];
int i;
void setup() {
// 9600 Baud, 0 delay, '*' as ACK
lcdByVacSerial.begin(9600,50,'*');
// N.B. puts() is for arrays of char-s, or char*, but not Sting-s, putch() for individual Char-s.
// 4 x 20 display
lcdByVacSerial.puts("\e[4L\e[20c");
// clear screen, needs a delay
lcdByVacSerial.puts("\e[2J"); delay(50);
// cursor on, as a static underline.
lcdByVacSerial.puts("\e[?25h");
// Start up our serial port, we configured our XBEE devices for 38400 bps.
Serial.begin(57600);
}
void loop() {
// Only print to LCD if there is a new stuff to show. Otherwise LCD characters blink anoyingly.
if (blnLCDRefresh) {
///lcdByVacSerial.puts("Awaiting input:");
// Set LCD's cursor to line 2, column 1.
///lcdByVacSerial.puts("\e[2;1H");
blnLCDRefresh = false;
}
// If character was received, show it on LCD display.
while (Serial.available() > 0) {
// Read the received bytes:
incomingChar = Serial.read(); // Incoming char will become int ASCII ordinal.
// Write into the character array all characters, except line termination ones, like: LF
// and CR.
if (incomingChar != '\n' && incomingChar != '\r') {
arrChrBuffer[i] = arrChrBuffer[i] + incomingChar;
i++;
} else {
// This break enables stucking up of multiple commands together, like: "srx 640\nsry 480\n"
// Individual commands just need to be separated by '\n' characters. When first '\n' is met,
// character array that was extracted up to that point is processed. But the rest of multi-
// command is still in the serial buffer and it is extracted in the next loop. Voila!
break;
}
}
// LF and CR are used for line termination.
if (incomingChar == '\n' || incomingChar == '\r') {
// Output to LCD.
// N.B. puts() is for arrays of char-s, or char*, but not Sting-s, putch() for individual Char-s.
lcdByVacSerial.puts(arrChrBuffer); lcdByVacSerial.putch(',');
// Move LCD's cursor up one place.
///lcdByVacSerial.puts("\e[1A");
// Set LCD's cursor to line 2, column 1.
///lcdByVacSerial.puts("\e[2;1H");
// After printing to LCD, reset all the auxiliary variables.
for (int j=0;j < SERIAL_INPUT_BUFFER_SIZE;j++) { arrChrBuffer[j] = '\0'; }
i = 0; incomingChar = '\0';
}
// Catch a breath.
delay(100); // Wait a bit.
}
Please have a look.