Hi guys, not sure if this is the right place to post this, but I figured maybe somebody had some experience with this here...
I'm trying to send messages to an LCD screen via applescript and a Uno. The problem is that I can write to the serial buffer using Serial PortX, but I can't seem to get it to send a newline or carriage return. I'm using those signals to detect the end of a string to transmit via Xbee to another arduino.
Tranmission is no problem, and newline detection doesn't seem to be either. I can easily use the serial monitor to accomplish this goal. But when I run my applescript, I can get data into the serial buffer, but I don't see it on the LCD until I open the serial monitor and hit enter, sending a newline. Then it pops right up! Here is my applescript:
set portRef to serialport open "/dev/cu.usbmodem1d21" bps rate 9600 data bits 8 parity 0 stop bits 1 handshake 0
if portRef is equal to -1 then
display dialog "could not open port "
serialport close "/dev/cu.usbmodem1d21"
else
serialport write "Hello World" to portRef
serialport write (ASCII character 10)
end if
If anyone here is done this before, I thank you in advance for your help.
Here is my arduino code, in case my newline detection isn't correct. I've tried it with newline and carriage return. I've tried to detect both '/n/r' and ascii code 10 and 13, no avail.
#include <SoftwareSerial.h>
SoftwareSerial LCD(2, 3); // RX, TX
String inputString = ""; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
void setup(){
Serial.begin(9600);//start serial
LCD.begin(9600);//Start software serial
LCD.write(12); // clear the screen
LCD.write(17); //turn on backlight
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
}
void loop(){
if (stringComplete){ //Wait for string to finish
//delay(1000); //LCD.write(12);
//delay(1000);
LCD.println(inputString); //print text. Couldn't be easier!
inputString = ""; //gotta clear that bitch
stringComplete = false;
}
}
void serialEvent() {
while (Serial.available()) { // get the new byte:
char inChar = (char)Serial.read(); // add it to the inputString:
inputString += inChar; // if the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (inChar == 10) {
stringComplete = true;
Serial.flush();
}
}
}
Well, actually, you might try \r and \n, rather than /r and /n.
I can get data into the serial buffer, but I don't see it on the LCD until I open the serial monitor and hit enter, sending a newline.
It matters not, I'm guessing, what you actually send. It's that opening the Serial Monitor corrects the way that the serial port is opened, allowing data to actually flow to the Arduino. You might try other (non-standard) options, or other values for handshake, to see if you can open the serial port the same way that the Serial Monitor app does.
Yeah, Mistyped. I was using \r and \n. Doesn't seem to matter what I send over. Do you mean to say I should using something other than a carriage return or newline as a detection signal?
Its a good idea at the early stage of a project to use printable characters for delimiters so you can see what is happening. When you have the system working then you can switch to non-printing characters.
I think @PaulS is referring to the fact that the Arduino resets every time the Serial connection is opened and it then spends a few seconds in the bootloader before it starts running your sketch. Your PC program has to allow for this. The easiest way is to get the Arduino to print something in setup() - such as Serial.println("I'm ready") - and have the PC wait until it receives that message before doing anything else. (I use PC to include Mac, Windows and Linux).
So, I'm using Applescript and Serialport X to stream data from a computer to an arduino, and display it on a LCD after taking a wireless journey through Xbee. Everything seems to be working, except that after some amount of time, the serial port RX and TX lights come on solid on the arduino that is receiving data from the computer, and the serial port seems to lock up. Resetting the arduino with the reset button seems to not work, only after force quitting the script, and unplugging the arduino can I run the program again.
It seems that the amount of delay I put in the applescript between each serial write affects the serial port, the longer the delay the more reliable it is. but I can't seem to get it to work all the time. Am I writing to the serial port incorrectly? Or am I reading it wrong? Or could this be a problem with SerialPortX? Below is the code I've written, both in applescript and arduino. Thanks in advance!
set portRef to serialport open "/dev/cu.usbmodem1d21" bps rate 14400 data bits 8 parity 0 stop bits 1 handshake 0
if portRef is equal to -1 then
display dialog "could not open port "
serialport close "/dev/cu.usbmodem1d21"
else
repeat 800 times
tell application "Boom Recorder"
set current_TC to get timecode
set current_state to get state
end tell
serialport write current_TC to portRef
serialport write " " to portRef
serialport write current_state to portRef
serialport write (ASCII character 10) to portRef
delay 0.3
end repeat
serialport close portRef
display dialog "Done!"
end if
#include <SoftwareSerial.h>
SoftwareSerial XbeeTX(2, 3); //RX, TX
String inputString = ""; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
int testLedPin = 13;
void setup() {
Serial.begin(14400);// initialize serial
XbeeTX.begin(19200); //startup Software Serial
//LCD.begin(9600);//SoftwareSerial
//LCD.write(12); //Clear the screen
//LCD.write(17); //turn on backlight
pinMode(testLedPin, OUTPUT);
digitalWrite(testLedPin, LOW);
// reserve 200 bytes for the inputString:
inputString.reserve(400);
}
void loop() {
//XbeeTX.println("Balls");
// print the string when a newline arrives:
if (stringComplete) {
XbeeTX.println(inputString);
Serial.println(inputString);
// clear the string:
inputString = "";
stringComplete = false;
//XbeeTX.write(220);
}
}
/*
SerialEvent occurs whenever a new data comes in the
hardware serial RX. This routine is run between each
time loop() runs, so using delay inside loop ca
n delay
response. Multiple bytes of data may be available.
*/
void serialEvent() {
while (Serial.available()) {
digitalWrite(testLedPin, HIGH);
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (inChar == 10) {
stringComplete = true;
XbeeTX.write(12);
//XbeeTX.write(220);
//Serial.flush();
}
}
}
Actually, there is a very valid reason to avoid anything that performs dynamic memory allocation in a limited resource space like a micro-controller. The AVRs that are in Arduinos use a Heap-based implementation for memory.
The heap method suffers from a few inherent flaws, stemming entirely from fragmentation. Like any method of memory allocation, the heap will become fragmented; that is, there will be sections of used and unused memory in the allocated space on the heap. A good allocator will attempt to find an unused area of already allocated memory to use before resorting to expanding the heap. The major problem with this method is that the heap has only two significant attributes: base, or the beginning of the heap in virtual memory space; and length, or its size. The heap requires enough system memory to fill its entire length, and its base can never change. Thus, any large areas of unused memory are wasted. The heap can get "stuck" in this position if a small used segment exists at the end of the heap, which could waste any magnitude of address space, from a few megabytes to a few hundred.
Memory fragmentation in a platform with only 2K on a 328 (e.g. Uno) to 8K on a 2560 (e.g. Mega) can cause problems fairly quickly. String class is fine on something running a modern OS that have built-in protection against memory fragmentation (it would probably be fine on the Linux side of the YUN), but it just isn't appropriate for anything more than a dead simple Arduino sketch. Probably not even that just so someone doesn't get in the habit of using it. Better to learn how to use c-strings on simple Arduino sketches to learn how to use them.
Well, I am having a seperate issue with the serial buffer now, I actually recieved help from here that allowed me to solve my previous issue. Always something else, however.
Hey, guys, I figured it out! So I was sending the incoming data to the UART serial port (not the soft serial) for diagnostic purposes, and had forgotten about it. For whatever reason, not doing that was the key. It's quite reliable now! Haven't had an issue since. Not really sure why that would cause this, but it solved the issue.
Wanted to pass the info along for whomever it might help, but also, anybody know why this would cause a problem?
can someone please post the final configuration and updated code?
This is a very interesting topic and a good rare examples for whoever is testing the same OS x - Arduino interfaces.