Reputation: 6215
So, I'm in a bit over my head, and I feel like I'm very close to a solution, but it's just not working quite yet. Here's my situation:
I'm working with an Arduino microcontroller, and I'm attempting to write two Bash scripts (right now running in Mac OS X 10.6) which will (a) print all serial data coming out of the Arduino unit to the standard output, and (b) allow me to send serial data to the Arduino unit. These scripts will then be called using Adobe AIR's NativeProcess API to allow a tight integration between the Arduino unit and a Flex Adobe AIR application.
My two scripts are very simple -
Here's my WriteToSerial.sh script:
echo $1 > $2
($1 is obviously my string, $2 is the location of the serial port - currently /dev/tty.usbserial-A800eIUj)
And here's my ReadSerialOutput.sh script:
tail -f $1
($1 is the location of my serial port, currently /dev/tty.usbserial-A800eIUj)
When I call either of these scripts (or even if I just type the commands directly into the Bash console), my computer just hangs - I can type characters, but nothing happens until I Ctrl + C out of the process.
However, if I open the Arduino IDE and turn on the Serial Monitor, then tail -f
the port, close the serial monitor, and then echo "test" > serial port, everything works just great.
This suggests to me that opening the Serial Monitor within the Arduino IDE is somehow initializing the serial port, which in turn allows me to tail it with no problem. This in turn suggests to me that I'm simply failing to input some sort of initialization command. However, I've been searching high and low for days and can't seem to find anything that addresses this issue.
What is the solution?
Upvotes: 28
Views: 64647
Reputation: 184
A one-liner Something that works really well for datalogging, and acting on data:
Summarythe following timestamps and sends to stdout
cat /dev/cu.usbmodem1421 | awk '{ for (i=0; i<NF; i++) printf $i + system("echo , `date`")}'
Sample Output:
This method can even be adapted to monitor and act upon the data in real time:
cat /dev/cu.usbmodem1421 | awk '{ for (i=0; i<NF; i++) printf $i + system("echo , `date`)}'
more examples here: https://github.com/gskielian/Arduino-DataLogging/tree/master/Bash-One-Liner
Upvotes: 0
Reputation: 531
I get the same problem too. I use Arduino Uno with Ubuntu 12.04. After a few hours of searching and trying, I find out that Arduino will reset when the serial device is opened for the first time,but will not reset when the serial device is opened again.
So, run command - echo "input string" > /dev/ttyXXX in bash will reset Arduino and send "input string" immediately. Arduino need take some time to initialize, and is not quick enough to receive this string. cat /dev/ttyXXX will reset Arduino too.
When /dev/ttyXXX is opened in somewhere firstly, these commands will work.
Here is my solution:
1) open /dev/ttyXXX by redirecting /dev/ttyXXX to file description 3
exec 3<> /dev/ttyXXX
2) wait for Arduino's initialization
sleep 1
3) communicate with Arduino
echo "input something" >&3
cat <&3
4) close /dev/ttyXXX
exec 3>&-
Upvotes: 34
Reputation: 12481
On Linux, you need to call setserial to configure your serial port options (baud rate, parity, flow-control, etc.) before you can read/write the port correctly.
You need to find a way to do this with your Mac OS X Bash system.
Or you could write a Python script to do this.
Upvotes: 2
Reputation: 12481
Try using the tool stty:
stty -F /dev/my_serial_port <baud_rate> cs8 cread clocal
As always, read the manpage before applying the above. cread
allows you to receive data. You may want to omit clocal
if you are using flow control. If you aren't sure what the above settings are, ask, and I can write up a more complete answer.
Upvotes: 14
Reputation: 61
I struggled with this problem also, trying no end of stty settings and tricks to cat my files to /dev/tty.usbserial-FTF7YNJ5 (in my case) whilst standing on one toe, etc.
Then I did an ls /dev and noticed /dev/cu.usbserial-FTF7YNJ5 -- oh, what's this? Apparently, a 'calling unit' version of the device that doesn't expect or provide any flow control. Dumps bytes to the port. Exactly what I needed.
So just do: cat super_file.bin > /dev/cu.usbserial-XXXXX
Hope this helps. And only now that I know the answer, I found this: http://stuffthingsandjunk.blogspot.com/2009/03/devcu-vs-devtty-osx-serial-ports.html
Upvotes: 4
Reputation: 1
There's also Apple's SerialPortSample command line tool that allows you to set arbitrary baud rates:
// from: SerialPortSample/SerialPortSample.c
// ...
// Starting with Tiger, the IOSSIOSPEED ioctl can be used to set arbitrary baud rates
// other than those specified by POSIX. The driver for the underlying serial hardware
// ultimately determines which baud rates can be used. This ioctl sets both the input
// and output speed.
// ...
For more information see: http://www.arduino.cc/playground/Interfacing/Cocoa
Another piece of Cocoa sample code that shows you how to talk to the Arduino microcontroller over a serial connection is objective-candarduino (hosted on Google code).
Upvotes: 0
Reputation: 1
Check to see if sending data to / receiving data from the Arduino unit is working by using a different app such as Cornflake (serial terminal for Mac OS X) - instead of using the Arduino IDE & the Serial Monitor.
In addition, you may want to check out if you could benefit from switching to Xcode (in terms of debugging features, etc.).
See: Setting up Xcode to Compile & Upload to an Arduino ATMega328 (Duemilanove)
Upvotes: 0
Reputation: 1
Try / modify ttyecho:
http://www.humbug.in/2010/utility-to-send-commands-or-data-to-other-terminals-ttypts/
Upvotes: 0
Reputation: 11
Maybe try some serial command line tool similar to serial-1.0.
See: Serial port loopback/duplex test, in Bash or C? (process substitution)
Upvotes: 1
Reputation: 1
Try adding an ampersand (&) to the end of the commands to put the process in the background. If the console is hanging up, then that means the script or process is still running on your current terminal, and you won't be able to input or click on anything until the process or script is done.
You can also try running the command in 1 terminal window, and open a new terminal window/tab, and try tailing from there.
Upvotes: 0