Lesson 1: Errors are your friend.
I’ve been working on closing up my serial port experiments (so that I can move on to do something interesting with it) and I ran into a big snag. Whenever I tried to read from the file descriptor the read function returned an error. After much wailing and gnashing of teeth I did the right thing and added a line of code (perror) that would print out what was happening on the standard error output. The error was “Resource temporarily unavailable”. So, despite being able to successfully open the file descriptor I couldn’t read from it for some reason. The problem wound up being pretty funny (in hindsight). I was opening the file descriptor in “non-blocking” mode, which means that read() won’t wait for data to come in before returning. I had anticipated this and expected read() to return 0 if nothing was there (and keep trying until something was there). What was happening, however, was that error. It turns out that when you open a file descriptor to a serial port a certain signal is set that (if supported) will reset the device on the other end of the serial connection. This means my Arduino was rebooting at the same time I was calling read() since read() happened right after opening the file descriptor! What’s funny is that I was enjoying all the blinking my Arduino board was doing when I ran this program (who doesn’t enjoy the blinking?) and it turns out that blinking means “I’m rebooting!”. The fix was to add a fraction of a second delay between opening the file descriptor and reading from it.
Lesson 2: UNIX terminal programming is hard, but that’s ok.
Really, it is hard. I’ve been beating myself up about it, but I’m realizing that it’s only hard because it’s so old. There is an astounding amount of flexibility combined with a crazy amount of flags and modes to set because this interface had to support a zillion types of hardware and software devices over the years that all had their own way of doing things.
I started this project exactly one month ago, and I’m only now able to read on my PC what my Arduino is spitting out via the serial connection. This seems like an unacceptable amount of time to do something so simple, but if I think about it I think I’ve only spent about five or six hours total on this, and that includes reading my Unix books, studying source code online, and writing my own programs to tease out the behavior. This translates to me spending one or two hours a week on this over the past month. I shouldn’t be so hard on myself – the problem isn’t that I’m having a hard time with implementing the concepts, it’s that I don’t have a lot of time to actually sit down and do it.
I have about another hour of work that needs to be done cleaning up the code and commenting it, but then I’ll try to write up a line-by-line explanation and go into the caveats and pitfalls I discovered along the way. It’s going to be the tutorial I wish I had found a month ago.