views:

170

answers:

7

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 MacOS 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 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)

The problem I'm having is that 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 control-C out of the process.

HOWEVER, if I open the Arduino IDE and turn on the Serial Monitor, then tail -f the port, then close the serial monitor, 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.

And so this brings me to you, Stack Overflow. Please, if you have any idea what I'm talking about by all means weigh in - if only to tell me that I'm not crazy. And if you can help me figure this out, I'll happily tell everyone what a great person you are.

Cheers, and in the meantime I'm going back to Google. myk

A: 

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.

bm7150
Yeah, I've got multiple terminal windows so I don't think that's the problem - I mean, even echo "Test" > SERIAL is freezing up, and that should be a single process that runs and stops. It's the fact that they're hanging that's confusing me.
Myk
+1  A: 

Maybe try some serial command line tool similar to serial-1.0.

See: Serial port loopback/duplex test, in Bash or C? (process substitution)

dan
A: 

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 MacOS bash system.

Or you could write a python script to do this.

sheepsimulator
Yeah, I've got a python script working, actually. But I'd like to not have the python runtime as a dependency on host machines if I can avoid it. ><
Myk
...if it were just the native Python install I'd be ok with it, but it also need PySerial installed in order to run so that makes it a bit more complex. If I can't figure this out then that's what I'll do, but I feel like there HAS to be a way to make this work!
Myk
@Myk - Since you want to avoid python, You might be able to get the same effect you observed (I can use my own tools when the Arduino IDE is open) by writing a small C program that uses tcsetattr() that sets the port options first. The easiest way is to figure out the CLI command to set serial port options on your Mac.
sheepsimulator
@Myk - Please see my new answer. stty is the traditional command in *nixes for adjusting serial port options.
sheepsimulator
Yeah, I am almost thinking a C program is the way to go - I'm tempted to just reverse-engineer serproxy to make it output to standard output rather than a socket, and then bam.
Myk
+1  A: 

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 are using flow control. If you aren't sure what the above settings are, ask, and I can write up a more complete answer.

sheepsimulator
Yeah, I've been messing around with the stty thing. In MacOS it seems like I can't use -F, I have to use -f (same command, just different syntax). Other than that sure, I will input a command like that and get no errors - but then it still hangs when I try to echo "TEST" > /dev/tty.usbserial-XXX
Myk
I'm almost starting to wonder if it's this computer - I have only tested it here, I will have to try a dif system when I get home tonight.
Myk
@Myk - I kinda doubt a different computer will change this. Something that might block a send might be a flow-control issue - if the CTS line isn't high, no data will be sent. You can get around this in hardware by looping the RTS pin back to the CTS pin. Or by setting clocal.
sheepsimulator
If it's not too much trouble, what's flow-control and CTS? I tried setting clocal as per your advice above, but no dice. Sadly I'm sort of a *nix noob - learning fast, but there's much I don't know.
Myk
CTS is one of the serial port's signals, usually used together with RTS for hardware flow control. Flow control is using some sort of protocol to tell the other end to stop transmitting until we have processed the data we have already received.
ninjalj
@Myk: can you run `stty -a < /dev/tty.usbserial-A800eIUj` while you have the serial port working on the Arduino IDE? That would give you the settings to use.
ninjalj
You might want to see this: http://electronics.stackexchange.com/questions/5167/set-rs232-port-options-from-macos-x-cli/5175#5175
sheepsimulator
I switched my approach to solving this problem - I'm rolling with Python, which reads my serial port in two lines of code. Still, though, this answer was the most helpful and links in the comment to the other question so I'm going to go ahead and accept this. Thanks for your help!
Myk
A: 

Try / modify ttyecho:

http://www.humbug.in/2010/utility-to-send-commands-or-data-to-other-terminals-ttypts/

tilo
I don't think that's it, since echo works just fine once I've initialized the serial port using the Arduino IDE. Both my echo and my tail -f do EXACTLY what I want them too once I actually have access to the port.
Myk
A: 

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)

tol
A: 

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).

ceeit