Category Archives: Arduino

The first Internet of Things Bay Area Meetup and the Air Quality Egg…

Last night, I met with Nanode creator Ken Boak and Chris Jefferies from tinajalabs.com at Cafe Actual in Berkeley for the inaugural IoTBayArea meetup. IoT groups are already going strong in many cities like London, Amsterdam, and NYC, but now that Ken is operating here in the SF Bay Area, he wanted to get a group going here.

The current big project being developed by these groups is the Air Quality Egg: a crowd sourced air quality sensor network based upon open source technology. It’s a new Kickstarter based project too (which I have decided to back)!

Air Quality Egg



Beyond the fact that it uses some cool technology, I like this project mostly because the data it gathers will enable people to understand something about the world that they live in day to day. In the Bay Area, we have the Bay Area Air Quality Management District, a government group established in 1955 by the California legislature to monitor air quality in the nine SF Bay counties. This is the government agency that is responsible for (among other things) the Spare the Air day program, which warns citizens of days with particularly unhealthy air pollution, and urges them to take personal action to reduce the problem. It’s a great program, and they produce some interesting real time data on air quality in different areas, as well as forecasts. The air quality index (AQI) that they report measures ground-level ozone, airborne particles, carbon monoxide, sulfur dioxide and nitrogen dioxide.

So, if the government is doing such a good job, why do we need a citizen network to monitor the same things?

First of all, this data may not be accurate for your neighborhood. If your home or business is located near sources of pollution (such as busy streets or some industrial polluters) in spite of the fact that the overall air pollution in your city is reasonable, you might be experiencing high levels of these pollutants. Or it could simply be a matter of geography: I live in a fairly smallish valley, which might be more isolated from the offshore winds that might blow pollutants away. It would be interesting to understand how the pollution in my relatively suburban environment compared with other locations.

Secondly, an open source archive of raw sensor data opens up opportunities for research. Instead of just getting a single AQI number, we’ll end up with a bunch of spatially distributed raw readings for individual pollutants. Perhaps ozone is the dominant pollutant in your area. Or perhaps burning of yard waste causes particulates to spike in certain areas at certain times of the year. Perhaps we can see the daily variation in carbon monoxide as traffic peaks and ebbs in certain locations.

Third, it encourages citizen participation in thinking about air pollution. Just as “Spare the Air” days challenge us to consider ways to change our behavior to improve air quality, participation in an air quality monitoring network turns something that is easy to take for granted into something that we can understand and improve.

Oh, and it involves cool software and hardware too. 🙂

If any of this interests you, you might try following Ken (@monsonite) on Twitter. The IoTBayArea is just beginning, but I suspect we’ll see some rapid growth. We are shooting for regular meetings, with the next one tentatively set for the last weekend in April (but subject to change, stay tuned). Even if the Air Quality Egg project doesn’t thrill you, if you are still interested in the world of Internet connected devices, I urge you to try to come to the next one, you’ll find like minded people and good conversation.

Thanks to Ken and Chris.

Arduino Hole Dimensions Drawing

I’ve been kind of busy and distracted lately, so I haven’t had much time to get any embedded microcontrollers. I did dust off an Arduino FIO that I never played with, and charged up a 1000maH LiPo battery to power it. While it was blinking, I dug out my Xbees and started thinking of a project that I put off a while ago (more details later) and realized that while the Arduino FIO is cheap, compact, and includes an Xbee socket, it does have one kind of annoying problem: no mounting holes. While pondering this, I decided to try to dig out the dimensions for the standard hole pattern used on the Arduino. Like many things regarding the Arduino, the answer could be found on the Adafruit weblog:

Arduino Hole Dimensions Drawing from adafruit industries blog.

Breadboarding a Tellymate for the Arduino…

The microcontrollers of today are in many ways superior to the simple eight bit computers that I learned to program as a teenager, but one way in which most of them are decidedly inferior is that they have only a very limited number of actual peripherals. After all, even my simplest Atari 400 back in 1980 could be hooked to a television and display text and graphics. But there is something good about these microcontrollers: they are quite a bit faster than these old chips, and they are lots cheaper.

This means that it’s possible to generate video not by the usual method of having dedicated computer hardware, but by “bit-banging” the video signal directly with carefully written code with timing. Many Arduino users have seen the “TV out” library for the Arduino, which does precisely this, if you haven’t check out this old video of mine where I demonstrate it.


But that library has two major problems. It’s very low resolution, and it’s hard to use with libraries that may screw up it’s video timing (such as the library that allows you to read PS/2 keyboards).

But there is another cool idea: use a separate Atmel AVR chip as a dedicated processor to generate video. This is the approach that the Batsocks Tellymate Shield uses. If you want, you can buy a kit from them for an Arduino shield, which would be very convenient. It basically implements a simple serial terminal which implements VT-52 like command codes, which makes it very simple to program. And because it is entirely separate from the main Arduino, it generates stable video without any of the timing problems that using TVout can have. Oh, and because it is very cleverly written, it can do higher resolution video (25 lines of 38 characters).

A very cute gadget. What’s even more awesome is that you can breadboard one of these things very, very simply. I had an old ATmega88 sitting in a drawer. If you don’t need full RS232 voltage levels (like, for instance, driving it from the Arduino serial ports) then the only thing you need are two resistors, two diodes, and a smattering of capacitors. I programmed my Arduino to serve as the ISP, flashed the firmware into the chip (the authors nicely include versions for a wide variety of Arduino chips), reprogrammed the fuses to use the external crystal, and then breadboarded it up. And then, after powering it up, well, nothing. I hauled out my scope. Was serial data going to the board? Yep. Anything like a signal coming out? Nope. Wait, it looks like something varying from 4.5 to 5.5 volts? Ooops. Loose ground wire. Fixed that. Working? Nope. Recheck pins. Doh! Outputs are on pins 15 and 17, not 16 and 18. Fixed that, and….

It works.

If you need a simple video interface for an Arduino project, you can easily build this interface on a breadboard, a chunk of protoboard, or you can get various version with differing capabilities from the creators. But try it out: it’s a cool little gadget.

Examining the output of a simple remote-keyless-entry transmitter…

Yesterday I was looking (sadly unsuccessfully) for some BPW32 photodiodes that I know I have somewhere, when I ran across some of 434 Mhz transmitter modules from Sparkfun (now a retired part) that I had never used. These little $4 transmitters are commonly used for remote-keyless access or similar applications. They have just four pins: power, ground, a data pin, and an antenna, so they are easy to interface. I thought that they might be useful as backup low power beacon transmitter aboard a high altitude balloon payload, but I had never unpacked them, never tried them out. It dawned on me that I might also be able to use them with my code which I had previously written to send Hellschrieber telemetry. But to start out, I just made a simple program that sent the string “BEACON” at 1 second intervals and fed it to the data pin.

But how to receive it? I fired up my FT-817 and tuned it roughly to 433.920 Mhz (the nominal frequency) and even without an antenna, I could clearly hear the buzzy signal with a 1 second period. In fact, I could still hear it over 50Khz away from the nominal frequency. The signal was very, very wide. That got me curious so I dug out my Funcube Dongle Pro, hooked up a simple wire whip antenna, and tuned it in.

Here’s a picture of 96Khz surrounding 433.920:

Bleh. Really wide, really ugly, and really unpleasant sounding in the earphone. The horizontal lines coincide with the transmissions, the long harmonic laden regions in between are the “dead times”.

I suppose that if you were only using these intermittently in a key fob kind of situation, I could justify using something like this, but for the kind of application I was envisioning, they just seem gratuitously poor. Still, it was fun getting my Funcube Dongle out of the box and playing with it again.

Addendum: they also don’t work as a Hellschrieber transmitter. I hooked up my “Hellduino” code, but the resulting spray of noise didn’t provide any useful decodes. I think that the transmitter has an upper limit on how long pulses can be, and is also sending AM modulated signals, rather that keyed CW.

A simple beacon keyer for the ATtiny13

Roger, G3XBM built a simple beacon for light communication using a K1EL beacon keyer chip and a handful of other components. I didn’t have any of those chips around, but I did have some Atmel ATtiny13s lying around. I hacked this simple program together to send Morse code in two different ways: on pin PB1 (pin six) there is a simple on/off keying signal. On pin PB0 (pin five) there is the same signal, modulated with an 800 hz signal. Roger used a similar output to send a modulated version of his call. I hardcoded this program to transmit slow Morse with three second dits (QRSS3). I loaded this onto an ATtiny13 tonight, and hooked a small white led the PWM output pin through a current limiting resistor. Using a primitive receiver I built before, a solar cell hooked into a Radio Shack powered speaker, I tested it out, and it seemed to work rather well: the 800hz tone was clear and audible. I’ll be playing with this some more, but for now, here’s the code:

[sourcecode lang=”cpp”]
/*
* beaker.c
*
* A simple beacon beeper for the ATtiny13
*/

// #define F_CPU 1200000UL
#define F_CPU 9600000UL

#include <inttypes.h>
#include <avr/io.h>
#include <avr/sleep.h>
#include <util/delay.h>

#define FREQ (800)
#define DIT_MS (3000)

#define OUTPUT PB0 /* 800 Hz PWM signal, OC0A */
#define KEY PB1 /* Just a keying output */
#define SWITCH PB4 /* a switch between 12 WPM and QRSS3 */

void
dit()
{
/* on */
TCCR0A |= _BV(COM0A0) ; /* enable OC0A */
PORTB |= _BV(KEY) ;
_delay_ms(DIT_MS) ;

/* off */
TCCR0A &= ~_BV(COM0A0) ; /* disable… */
PORTB &= ~_BV(KEY) ;
_delay_ms(DIT_MS) ;
}

void
dah()
{
/* on */
TCCR0A |= _BV(COM0A0) ;
PORTB |= _BV(KEY) ;
_delay_ms(3*DIT_MS) ;

/* off */
TCCR0A &= ~_BV(COM0A0) ;
PORTB &= ~_BV(KEY) ;
_delay_ms(DIT_MS) ;
}

void
space()
{
_delay_ms(2*DIT_MS) ;
}

void
ioinit()
{
DDRB = _BV(KEY) | _BV(OUTPUT) | _BV(SWITCH) ;
PORTB &= ~_BV(OUTPUT) ;

TCCR0A = _BV(COM0A0) | _BV(WGM01) ;
TCCR0B = _BV(CS01) | _BV(CS00) ;
OCR0A = 93 ;
}

int
main(void)
{
ioinit() ;

for (;;) {
dah() ; dit() ; dah() ; space() ;
dah() ; dit() ; dit() ; dit() ; dit() ; space() ;
dit() ; dit() ; dit() ; dit() ; space() ;
dah() ; dit() ; dit() ; dah() ; space() ;
space() ; space() ;
}

return 0 ;
}
[/sourcecode]

More on ATtiny programming…

Last night’s hacking adventure was inspired by a couple of recent posts from Roger, G3XBM having to do with light based communication. The first was his simple beacon design: it’s just a keyer chip, a MOSFET, a voltage regulator, and some (beefy) current limiting resistors. Roger used this beacon to do some non-line-of-sight communications via “cloudbounce”.

It’s inspiring, so I’ve been thinking about trying some similar experiments. As it would happen, I have some reasonably high power LEDs floating around, and rigging up the transmitter really wouldn’t be too hard. I don’t have any of the K1EL chips that he used, but I do have a few of the Atmel ATtiny13s floating around, so I figured I’d go ahead and write up a simple beacon program to send my call via QRSS3 and (if a switch is tossed) 12wpm Morse. After my ATtiny powered Halloween Pumpkin and my ATtiny13 powered Christmas hat, I figured it would be a snap. I fetched an Arduino, programmed it with the AVRISP sketch, and then went to wire up the Arduino to program the code (did I mention I wrote some code?) to an ATtiny13 which I stuck on a breadboard.

And that’s when I realized that I didn’t take very good notes about how I did it last time, and refinding the necessary connections and commands was both difficult and some sources didn’t even have the information correct.

So I’ll remember, here’s the list of connections you need:

  • ATtiny pin 4 goes to ground.
  • ATtiny pin 8 goes to 5V.
  • ATtiny pin 1 goes to Arduino pin 10.
  • ATtiny pin 5 goes to Arduino pin 11.
  • ATtiny pin 6 goes to Arduino pin 12.
  • ATtiny pin 7 goes to Arduino pin 13.
  • Many sources say that for Unos, you must put a 10uF cap between the RESET and GROUND on the Arduino. I had one, so I did it. I’ve used older Arduinos (such as the NG) which have different reset circuits (you must manually reset them to program them) and for those it isn’t necessary. Your mileage may vary.

Lastly, you need the right avrdude command. It took me an embarrassingly long time to come up with the right command, mostly because it appears that I needed to manually set the baud rate to 19200 (what the AVRisp sketch expects). Archived for posterity:


avrdude -v -c avrisp -p t13 -P /dev/tty.usbserial-A800eKtX -b 19200 -U flash:w:beaker.hex

I discovered a couple of things: while the previous versions of the ATtiny I used seemed to have fuses set so that the internal oscillator (nominally 9.6Mhz) would be divided by 8, this one did not. I sorted this out by defining F_CPU appropriately, but it was late and I didn’t get my PWM code (which generates the 800hz sidetone) working properly. Tonight, I’ll dust it off and hook it to the scope and see what’s going on.

When this is done, it should be fairly simple to get the rest of the prototype transmitter together. Roger used a 4″ or so lens as the collimating optic for his transmitter. As it happens, I have a dusty 6″ Newtonian telescope that I purchased for a pittance, whose mirror really isn’t up to the kind of standards I appreciate. I think I can mount a high power LED into a 35mm film can and insert that into the telescope eyepiece, and it should make an excellent collimator (I may need an auxillary lens if the cone from my LED is too broad, I think the telescope is around f/5 or so). Perhaps by this weekend, I’ll have the transmitter setup, and I can start working on the (much harder) receiver.

Hope this article saves someone some time. I know I’ll be referring back to it in the future.

Web-based control of an RGB LED via the Nanode, an Arduino compatible microcontroller

Okay, I finally got some time to record a video about a simple little webserver project I hacked together earlier this week. My wife Carmen got me a Nanode kit from Wicked Device around Christmas. These are Arduino compatible development boards which include a Microchip ENC28J60 Ethernet device to enable web connectivity. One slight drawback is that they are not compatible with the Ethernet shields which are based upon the Wiznet 5100 chipsets, so you’ll need different drivers and different code. I’ve been experimenting with the Jeelabs EtherCard drivers, which seem to work well and are well supported, although they are limited in their TCP implementation (it limits TCP responses to just a single TCP/IP packet). Nevertheless, I implemented a simple webserver to control the I/O pins of the Nanode, based upon the ideas (but not the code) of Jason Gullickson’s RESTduino. I then did a short demo of how you could use it to control a strip of RGB LEDs from a simple jQuery based interface. Watch:



Here’s the sketch. Feel free to swipe it and any ideas for any web enabled projects you need (nothing here is worth copyrighting or licensing at all, consider it public domain).

[sourcecode lang=”cpp”]
#include <EtherCard.h>
#include <NanodeUNIO.h>

//
// remote by Mark VandeWettering
//
// a reimplementation of the "RESTduino" idea, first published at:
// http://jasongullickson.posterous.com/restduino-arduino-hacking-for-the-rest-of-us
//
// I decided to rewrite this application because:
// 1. originally, it was written for the Wiznet based Ethernet Shield, but I have
// mostly Nanodes, based upon the ENC28J60
// 2. It was ported to the Ethershield library by Andrew Lindsay, but Andy has decided
// that he’s decided not to continue development of that library, deferring to the
// EtherCard library being developed by JeeLabs
// 3. I thought there was a lot of cool additions that could be made! Okay, I haven’t
// implemented any at the moment, but I will!
//

#define DEBUG 1
#define BUFFER_SIZE (900)

byte Ethernet::buffer[BUFFER_SIZE] ;
BufferFiller bfill;

char okHeader[] PROGMEM =
"HTTP/1.0 200 OK\r\n"
"Content-Type: text/html\r\n"
"Pragma: no-cache\r\n"
"\r\n" ;

char responseHeader[] PROGMEM =
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n"
"Access-Control-Allow-Origin: *\r\n"
"\r\n" ;

void
homepage(BufferFiller& buf)
{
buf.emit_p(PSTR(
"$F"
"<html>"
"<head>"
"<title>webserver remote</title>"
"<style type=\"text/css\">"
"body { width: 640px ; }"
"</style>"
"</head>"
"<body>"
"<h1>webserver remote</h1>"
"<p>"
"This webserver is running on a <a href=\"http://nanode.eu\">Nanode</a>, an "
"Arduino-compatible microcontroller with web connectivity. It uses the <a"
"href=\"https://github.com/jcw/ethercard\">EtherCard library</a> written by "
"<a href=\"http://jeelabs.net/projects/cafe/wiki/EtherCard\">JeeLabs</a>. "
"Inspired by Jason Gullickson’s <a href=\"http://www.youtube.com/watch?v=X-s2se-34-g\">RESTduino</a>."
"</p>"
"<hr/>"
"<p style=\"text-align: right;\">Written by Mark VandeWettering</p>"
"</body>"
"</html>"
), okHeader) ;
}

#define CODE_ERROR (-1)
#define CODE_WRITE (0)
#define CODE_READ (1)
#define CODE_ANALOG_WRITE (2)
#define CODE_INDEX (3)

int
cmdparse(const char *cmd, int &pin, int &val)
{
const char *cp = cmd+4 ;

if (*cp++ == ‘/’) {
if (*cp == ‘ ‘) {
return CODE_INDEX ;
} else if (isdigit(*cp)) {
pin = atoi(cp) ;
while (isdigit(*cp)) cp++ ;
if (*cp == ‘ ‘) {
return CODE_READ ;
} else if (*cp == ‘/’) {
cp++ ;
if (isdigit(*cp)) {
val = atoi(cp) ;
while (isdigit(*cp)) cp++ ;
if (*cp == ‘ ‘)
return CODE_ANALOG_WRITE ;
else
return CODE_ERROR ;
} else if (strncmp(cp, "HIGH", 4) == 0) {
cp += 4 ;
if (*cp == ‘ ‘) {
val = 1 ;
return CODE_WRITE ;
} else
return CODE_ERROR ;
} else if (strncmp(cp, "LOW", 3) == 0) {
cp += 3 ;
if (*cp == ‘ ‘) {
val = 0 ;
return CODE_WRITE ;
} else
return CODE_ERROR ;
}
} else
return CODE_ERROR ;
} else {
return CODE_ERROR ;
}
} else {
return CODE_ERROR ;
}
}

void
setup()
{
byte mac[6] ;

Serial.begin(9600) ;
Serial.println("\nbrainwagon remote webserver\n") ;

NanodeUNIO unio(NANODE_MAC_DEVICE) ;
unio.read(mac, NANODE_MAC_ADDRESS, 6) ;

if (ether.begin(sizeof Ethernet::buffer, mac) == 0) {
Serial.println("Failed to access Ethernet controller.") ;
for (;;) ;
}

if (ether.dhcpSetup()) {
ether.printIp("IP: ", ether.myip) ;
ether.printIp("GW: ", ether.gwip) ;
ether.printIp("DNS: ", ether.dnsip) ;
} else {
Serial.println("DHCP failed.\n") ;
for (;;) ;
}
}

void
loop()
{
word len = ether.packetReceive() ;
word pos = ether.packetLoop(len) ;
int pin, val ;

if (pos) {
bfill = ether.tcpOffset() ;
char *data = (char *) Ethernet::buffer + pos ;
Serial.println(data) ;
switch (cmdparse(data, pin, val)) {
case CODE_READ:
pinMode(pin, INPUT) ;
bfill.emit_p(PSTR(
"$F"
"{\"$D\" : \"$S\"}"),
responseHeader,
pin, val ? "HIGH" : "LOW") ;
break ;
case CODE_WRITE:
pinMode(pin, OUTPUT) ;
digitalWrite(pin, val ? HIGH : LOW) ;
bfill.emit_p(PSTR(
"$F"), responseHeader) ;
break ;
case CODE_ANALOG_WRITE:
pinMode(pin, OUTPUT) ;
analogWrite(pin, val) ;
bfill.emit_p(PSTR(
"$F"), responseHeader) ;
break ;
case CODE_INDEX:
homepage(bfill) ;
break ;
case CODE_ERROR:
default:
bfill.emit_p(PSTR(
"HTTP/1.0 404 Not Found\r\n"
"Content-Type: text/html\r\n"
"\r\n"
"<html><body><h1>404 Not Found</h1></body></html>")) ;
break ;
}
ether.httpServerReply(bfill.position()) ;
}
}
[/sourcecode]

maniacbug is an Arduino wizard…

Ken Boak was nice enough to gift me with a pair of Nanodes when he was out visiting last month. Much to my embarrassment, I haven’t had much time to play with them, so tonight I tried to do a bit more research to figure out how I could use them in some more advanced projects. Previously I had found the Ethercard library which was developed by Jeelabs. It works okay for many things, but has a web server implementation which is too limited for many uses: all web pages must fit in a single TCP/IP packet. I was digging around trying to find a TCP/IP implementation that could handle larger ones. I knew about Adam Dunkel’s uIP stack for microcontrollers which has been ported to many microcontrollers, but the first link I found to an implementation on the Nanode didn’t seem to have any example web server code. But then I ran across this posting on maniacbug’s blog describing a complete webserver using uIP. He’s got his own github repository which seems to have a lot more complete examples fleshed out. I downloaded and tested the code, and it appears to work pretty well. I’ll be digging into it over the next few days, and perhaps making my own webserver application to run on the nanode.

He’s also got a huge number of other rather sophisticated postings on stuff he’s done with the Arduino. Check them all out, I know I will be too.

maniacbug | AVR Microcontroller Projects

Interesting “feature” re: _delay_ms in avr-libc

A couple of my projects have used the tiniest of the Atmel ATtiny chips: the ATtiny13. I have written one or two programs in assembler for these chips, but I prefer to work with avr-gcc whenever possible. What’s amazing is that you actually can use a sophisticated C compiler to generate code for such a tiny chip (only room for 512 instructions).

Yesterday’s project was to implement a small QRSS beacon controller, similar to one’s sold by Hans Summer as part of his QRSS kits. He actually published his code, so I could just use that, but I found it a little bit obscure, and thought I could do something, well, if not better, at least less obscure to me. I wanted to retain the basic interface (Hans’ chip provides a sidetone on one pin, a key on another, and uses three pins as an input to select one of eight speeds). The basic loop fetches a pattern of dots and dashes, looks up the speed from the input switches, and then sends the pattern of dots and dashes. Easy peasy. I’ve written similar Arduino code before. Toggle pin high, delay, toggle pin low, delay, out goes a dot or dash.

But when I tried to use the _delay_ms() macro, I found that the codesize I had used grew enormously. It appeared to be dragging in a bunch of floating point arithmetic routines. I had used this function on my Christmas tree hat project without incident: what was going on?

Well, first of all, it appears that _delay_ms takes a floating point value as an argument. The compiler is smart enough that if the value passed to the function is a constant, it unfolds the code into a simple integer only loop. But if you use a variable as the argument (as I do, since the dit times are varying in length) you end up dragging all the floating point baggage into your code. It seems ridiculous to use floating point in this situation.

I got around this by noting that in my case, all my delays were multiples of 100ms. So, instead of just calling _delay_ms(n*100), I implemented the delays as a simple loop which executes _delay_ms(100) multiple times. Code is small, all is well.

You would think that a small, integer only delay would be possible. Oh well.

A $.33 MAX232CPE, or a $0.01 2N3904?

In response to my previous post, @xek replied:

https://twitter.com/#!/xek/status/163442298456260608

Well, the fact is I had heard of doing that. It’s not really hard to rig something that will convert the RS232 level from the GPS into TTL levels for the Arduino. It just takes a single transistor inverter: you rig an 10K resistor from the RS232 signal to the base, a 1K resistor from 5v to the collector, and then ground the emitter. Tap the transistor on the emitter side, and voila! It works. I rigged this up on the breadboard and checked it on the scope, and sure enough: 5v and 0v. I then coded up a simple sketch which used the SoftwareSerial library: it instantiates a serial port, then copies bytes when available to the normal Serial output device. Once I remembered that my GPS output at 4800 baud, the program worked flawlessly.

After I got this working, I gave the other direction a tiny amount of thought. I couldn’t think of a good, simple way to convert the TTL level to the negative levels without using some kind of charge pump, or a negative supply. But there is a cute trick you can use, that I discovered while surfing for alternative circuits: check it out. The trick is that if you are operating half duplex (only one side of the transmission transmits at the same time), the transmit line will go to the negative state. So, if you need to output a negative value, you simply swipe the voltage from Tx side of the RS232 line. That just takes a PNP transistor. Very cute.

Addendum: the receive circuit looks the same as mine, except they add a diode. Novice that I am, I don’t get why it is necessary or desirable. My circuit seems to work fine without it: can someone with experience tell me why it’s a good idea?

Addendum2: The MAX232s aren’t wasted: I am using it as an opportunity to learn Eagle and design a simple but still useful PCB. I’ll still be working on that.

Tinkering with an old GPS receiver…

I used to be an electrical engineer like you, then I took an arrow in the knee.

(If you don’t get this, google for “arrow in the knee”, and guess what Xbox game I spent the morning and afternoon playing instead of working on something cool.)

I’ve had a number of projects that could benefit from adding a GPS to an Arduino. I’ve got a few old GPSes lying around: in addition to the normal handheld and car windshield Garmin models, I have an old Garmin 18 and an ADS-GM1 from Argent Data Systems. They are the guys that make the Open Tracker (have one of those kicking around somewhere too). It’s a pretty respectable little GPS, and since I wasn’t using it for anything else, I thought it would be great to hook one up.

Except, well, it doesn’t use TTL signal levels for it’s serial connection. I double checked it by hooking it up to my scope, and have a peek:

Yep, -6v to 6v will not do. So, a few days ago, I ordered some Maxim MAX232CPE drivers from Tayda Electronics (great price, only $.33 each). I also intended to order some PCB mount DB-9 connectors that would mate with these, and do a small PCB that could be plugged into a breadboard, and then the DB-9 on the ADS-GM1 wouldn’t need to be modified. But sadly, I ordered the wrong part, and so that project is a teensy bit on the back burner. But pretty soon, I’ll get that all sorted out and a number of my Arduino projects will be able to benefit from accurate position and time.

High Frequency Precision Sine Wave Synthesis for the Arduino by Adrian Freed

While researching something completely different, I found Adrian Freed’s very cool page with code to generate high quality sine waves using PWM on the Arduino. This code could serve as an audio frequency signal generator, or as the basis of a computer music project. It also demonstrates some non-trivial Arduino wizardry in dealing with PWM interrupts and the like. Bookmarked for future reference!

Arduino sketch for high frequency precision sine wave tone sound synthesis | Adrian Freed: arduino, oscillator and open sound control expertise

An Arduino powered IBM PS/2 Morse Keyboard

I’ve been trying to do a bit more Arduino programming and interfacing lately. Nothing too difficult, but just trying to expand my junkbox and my skills so that I can quickly prototype new ideas and expand the kind of projects that I can tackle in the limited time that I seem to have for playing around.

I have written programs to use an Arduino to blink or beep Morse code before, but the programs were meant to control beacons, where they might just send the same message over and over, which I just compiled into the program. Today’s experiment did two things: it reads and buffers keystrokes from an old IBM PS/2 keyboard which I rescued from exile in my garage, and it actually keys my ham radio transmitter (a Yaesu FT-817ND) using a 4N31 optoisolator.

Most keyboards that you get today are interfaced via the Universal Serial Bus (USB). That’s kind of cool, but it’s also a bit of a travesty, since they require a lot more code (and a lot more knowledge) to interface what is ultimately a pretty simple device. Back in the old IBM AT days, keyboards were equipped with a large 5 pin DIN connector, and would transmit “scan codes” represent each character along a simple serial bus. The IBM PS/2 shrunk the connector to a six pin mini-DIN connector, but retained almost all the other features.

But if you want to do a tidy job, you’ll need some extra bits and pieces to hook them to your Arduino. Luckily, Sparkfun has a couple of cheap bits that will make it easy. I ordered some 6 pin MiniDIN connectors from them, along with a tiny $0.95 breakout board which you can tack together along with some header pins to make a little breadboard friendly connector. You need four connections: 5V, ground, and a clock and data line, which I connected to pins 3 and 4 on my Arduino.

You’ll also need a library. Yes, you could roll your own, but that would have added hours to this simple project. Instead, I chose this one, more or less at random from a number of possibilities. It seemed to work fine, and compiled properly even with my Arduino 1.0 setup. The code actually comes from the guys who make the Teensy, but the code works fine on regular Arduinos.

Then, I wrote the code. I wanted the user to be able to type ahead of the sending, so I needed to implement a ring buffer to store chars (currently up to 128) which I coded up from scratch in the simplest way possible. The way I used to do Morse sending was to set the output pin to be HIGH, then delay(), then set it to LOW. But we want to process new keystrokes and add them to the buffer as soon as you can. So, I implemented my own “delay” function, which loops to find new characters and inserts them in the buffer while waiting for the timeout. This seems to work pretty well.

Without further explanation, here’s the code:

[sourcecode lang=”cpp”]
#include <PS2Keyboard.h>

// _____ _ _ _ _ __ __
// |_ _| |_ ___ /_\ _ _ __| |_ _(_)_ _ ___ | \/ |___ _ _ ___ ___
// | | | ‘ \/ -_) / _ \| ‘_/ _` | || | | ‘ \/ _ \ | |\/| / _ \ ‘_(_-</ -_)
// |_| |_||_\___| /_/ \_\_| \__,_|\_,_|_|_||_\___/ |_| |_\___/_| /__/\___|
//
// _ __
// | |/ /___ _ _ ___ _ _
// | ‘ </ -_) || / -_) ‘_|
// |_|\_\___|\_, \___|_|
// |__/
//
// Version for the PS2 Keyboard
// using the library from http://www.pjrc.com/teensy/td_libs_PS2Keyboard.html
//
// Written by Mark VandeWettering K6HX
//
// This is just a quick Morse keyer program.
//

////////////////////////////////////////////////////////////////////////
//
// Here is a queue to store the characters that I’ve typed.
// To simplify the code, it can store a maximum of QUEUESIZE-1 characters
// before it fills up. What is a byte wasted between friends?
//
////////////////////////////////////////////////////////////////////////

#define QUEUESIZE (128)
#define QUEUEMASK (QUEUESIZE-1)

int aborted = 0 ;
int qhead = 0 ;
int qtail = 0 ;
char queue[QUEUESIZE] ;

void
queueadd(char ch)
{
queue[qtail++] = ch ;
qtail &= QUEUEMASK ;
}

void
queueadd(char *s)
{
while (*s)
queueadd(*s++) ;
}

char
queuepop()
{
char ch ;
ch = queue[qhead++] ;
qhead &= QUEUEMASK ;
return ch ;
}

int
queuefull()
{
return (((qtail+1)%QUEUEMASK) == qhead) ;
}

int
queueempty()
{
return (qhead == qtail) ;
}

void
queueflush()
{
qhead = qtail ;
}

////////////////////////////////////////////////////////////////////////

int pin = 13 ; // blink the LED for now…
int tpin = 10 ; // tone pin

#define WPM (20)
int ditlen = 1200 / WPM ;

PS2Keyboard kbd ;

inline void
ps2poll()
{
char ch ;
while (kbd.available()) {
if (queuefull()) {
Serial.print("") ;
} else {
switch (ch=kbd.read()) {
case ‘\033’:
queueflush() ;
Serial.flush() ;
Serial.println("== FLUSH ==") ;
aborted = 1 ;
break ;
case ‘%’:
queueadd("CQ CQ CQ DE K6HX K6HX K6HX K\r\n") ;
break ;
default:
queueadd(ch) ;
break ;
}
}
}
}

void
mydelay(unsigned long ms)
{
unsigned long t = millis() ;
while (millis()-t < ms)
ps2poll() ;
}

#define FREQ (700)

void
scale()
{
long f = 220L ;
int i ;

for (i=0; i<=12; i++) {
tone(tpin, (int)f) ;
f *= 1059L ;
f /= 1000L ;
Serial.println(f) ;
delay(300) ;
}
noTone(tpin) ;

}

void
dit()
{
digitalWrite(pin, HIGH) ;
tone(tpin, FREQ) ;
mydelay(ditlen) ;
digitalWrite(pin, LOW) ;
noTone(tpin) ;
mydelay(ditlen) ;

}

void
dah()
{
digitalWrite(pin, HIGH) ;
tone(tpin, FREQ) ;
mydelay(3*ditlen) ;
digitalWrite(pin, LOW) ;
noTone(tpin) ;
mydelay(ditlen) ;
}

void
lspace()
{
mydelay(2*ditlen) ;
}

void
space()
{
mydelay(4*ditlen) ;
}

void
setup()
{
pinMode(pin, OUTPUT) ;
pinMode(tpin, OUTPUT) ;
Serial.begin(9600) ;
kbd.begin(4, 3) ;
Serial.println("Morse Code Keyboard by K6HX") ;
}

////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////

char ltab[] = {
0b101, // A
0b11000, // B
0b11010, // C
0b1100, // D
0b10, // E
0b10010, // F
0b1110, // G
0b10000, // H
0b100, // I
0b10111, // J
0b1101, // K
0b10100, // L
0b111, // M
0b110, // N
0b1111, // O
0b10110, // P
0b11101, // Q
0b1010, // R
0b1000, // S
0b11, // T
0b1001, // U
0b10001, // V
0b1011, // W
0b11001, // X
0b11011, // Y
0b11100 // Z
} ;

char ntab[] = {
0b111111, // 0
0b101111, // 1
0b100111, // 2
0b100011, // 3
0b100001, // 4
0b100000, // 5
0b110000, // 6
0b111000, // 7
0b111100, // 8
0b111110 // 9
} ;

void
sendcode(char code)
{
int i ;

for (i=7; i>= 0; i–)
if (code & (1 << i))
break ;

for (i–; i>= 0; i–) {
if (code & (1 << i))
dah() ;
else
dit() ;
}
lspace() ;
}

void
send(char ch)
{

if (isalpha(ch)) {
if (islower(ch)) ch = toupper(ch) ;
sendcode(ltab[ch-‘A’]) ;
} else if (isdigit(ch))
sendcode(ntab[ch-‘0’]) ;
else if (ch == ‘ ‘ || ch == ‘\r’ || ch == ‘\n’)
space() ;
else if (ch == ‘.’)
sendcode(0b1010101) ;
else if (ch == ‘,’)
sendcode(0b1110011) ;
else if (ch == ‘!’)
sendcode(0b1101011) ;
else if (ch == ‘?’)
sendcode(0b1001100) ;
else if (ch == ‘/’)
sendcode(0b110010) ;
else if (ch == ‘+’)
sendcode(0b101010) ;
else if (ch == ‘-‘)
sendcode(0b1100001) ;
else if (ch == ‘=’)
sendcode(0b110001) ;
else if (ch == ‘@’) // hardly anyone knows this!
sendcode(0b1011010) ;
else
return ; // ignore anything else

if (!aborted) {
Serial.print(ch) ;
if (ch == 13) Serial.print((char) 10) ;
}
aborted = 0 ;
}

////////////////////////////////////////////////////////////////////////

void
loop()
{
ps2poll() ;

if (!queueempty())
send(queuepop()) ;
}
[/sourcecode]

To key the transmitter, I used a 4N31 optoisolator. This code uses pin 13 to key the transmitter, so I wired it to pin 1 on the optoisolator, passing through a 1K current limiting resistor, and pin 2 ground. Pins 4 and 5 are wired to the tip and shield of a 3.5mm socket, which I then connected to the FT-817 key input using a 3.5mm stereo cable I had lying around. I could have used a little NPN transistor to do the keying, but the optoisolator keeps any current from the radio from circulating in the Arduino (and vice versa) which is a nice little insurance that nothing will zap either my radio or my microcontroller.

Here’s the resulting project:



Feel free to drop me a line if you find this code to be useful. Let me know how you adapted it to do something cool in your shack or lab.

Addendum: Friends Atdiy and Whisker of the tymkrs empire made a similar project a while ago, except that they used a board based upon a Propeller board, which does a lot of what my project does as well. If you like the Propeller instead (and if you’ve been following my blog and reading about WA0UWH’s beacon, why wouldn’t you?) you might check out their video:



Nice new breadboard and power supply from TAUTIC.com

This is just a plug for a cute little pair of gadgets that I got the other day.. If you are like me and use solderless breadboards to experiment with stuff on the Arduino, you end up with the Arduino and the breadboard connected by a hodge podge of wires, and if you accidently tug on a power supply cord or the USB cord, half connections come undone. Or, you do all this experimenting on the dining room table, and when you have to clear it away for dinner, all sorts of wires become undone. Frustrating. Even annoying.

So, I took out an insurance policy against annoyance and frustration and ordered a protyping board for the Arduino Uno from TAUTIC.com. TAUTIC Electronics LLC is one of those cool little bootstrapped companies that have chosen to embrace the Open Source Hardware ideas and offer products of interest to tinkerers like myself. This prototype board is basically just a solderless breadboard bonded to a blue plastic backer, with the holes properly drilled to attach an Arduino Uno and the necessary hardware. He also makes version for the chipKit microcontrollers manufactured by Diligent.

While I placed that order, I decided to also give one of his dual output breadboard power supplies a try. For $9, you get a nice little board that plugs into a prototype board and provides 5V on the top rail, and 3.3V on the bottom rail. Very spiffy. The boards were shipped to me literally on the day I ordered them, great customer service. Jayson has a number of other cool boards, including some thermocouple boards and a PIC based development board. Check his store out and see if there is something that catches your eye.

The downside of Arduino…

First of all, I really like the Arduino. There are lots of reasons: great community, relatively inexpensive, wide hardware availability and variety, and often a good “impedance” match to projects. But there are a few design choices (both hardware and software) that can be a nuisance, especially as you try to push the limits of what can be done on such inexpensive and low power hardware.

First of all, there is the basic software philosophy. I love the fact that it is a single download: this simplifies installation, and whether you are an expert or a novice doesn’t matter, that’s simply more convenient. But using the program editor provided is simply not that desirable for experts who might be more used to Eclipse, or to an old fashioned kind of guy like myself for whom vi and Makefiles is more reasonable. With a little work you can find out where avr-gcc, avr-libc and avrdude are installed and add them to your search path, but you still have some work to build a Makefile which can compile your sketch from the command line. That’s a little annoying.

But more annoying are the design choices of the libraries themselves.

High among them are the heavy use of delay and the relative invisibility of interrupts. This may simplify short programs, but it provides no help to more sophisticated programs, and may in fact hinder them. Consider my experiments of last night (which fueled the rant of this morning). I merely wanted to implement a serial terminal using the TVout library and some serial communications library. The idea would be “read from serial, print to TVout”, voila, should be simple.

TVout generates NTSC video on the fly, and it basically works great. To do so, it uses regular timer interrupts. and if you dig into the library itself, you might find out that it uses Timer1. At regular interval, the timer 1 counter overflows, and the library knows that it’s time to bitbang out the video using some carefully constructed code. It also appears to use Timer2 to generate audio tones. Hmmm. The AVR chip that underlies the normal Arduino has only three timers… is that going to be a problem? How can I tell if another library also uses those timers?

You won’t find it in the documentation to any library. Arduino programming is supposed to be easy, and remove the need to understand how the underlying hardware works. Except that when you try to use two libraries together, and they happen to both use the same underlying timer resources, it doesn’t work right. There are no compile issues, it’s just one or both of the modules fail.

Which it did of course last night. You’d think that a loop like:

[sourcecode lang=”cpp”]
void
loop()
{
TV.print((char)Serial.read()) ;
}
[/sourcecode]

might have a chance of working, but it doesn’t. It drops and mangles characters horribly. While you might be able to poll some switches, apparently typing is something that is simply beyond the realm of expectation.

Some of you are probably going to leap to TVout’s defense, claiming that “You’re not doing it right! There is an example sketch which shows you the right way to do Serial and TVout!” Let’s have a look at that little sketch, shall we?

[sourcecode lang=”cpp”]
#include <TVout.h>
#include <pollserial.h>
#include <fontALL.h>

TVout TV;
pollserial pserial;

void setup() {
TV.begin(_NTSC,184,72);
TV.select_font(font6x8);
TV.println("Serial Terminal");
TV.println("– Version 0.1 –");
TV.set_hbi_hook(pserial.begin(57600));
}

void loop() {
if (pserial.available()) {
TV.print((char)pserial.read());
}
}
[/sourcecode]

Okay, we have some new library, which we never heard of before. It’s apparently part of the TVout download. Documentation? No. It calls a function I haven’t seen before, “set_hbi_hook”. Is that documented? No. I am pretty sure it’s a hook which will get called at the end (or the beginning?) of a horizontal blanking interrupt (this isn’t my first rodeo) but what’s really going on here. The pserial.begin call must return a function… time to crack open the source code.

And, it’s about what you expect. There is a hook function that gets called on every line, right before the line is rendered. My guess is that it’s bad if the timing of the hook function is in anyway indeterminate, because then the rows will start at odd intervals. But each render routine starts with a line which waits… for some length…. maybe there is some amount of time (undocumented, different for PAL/NTSC, maybe just the front part of each scanline, read more code) that if you don’t exceed, you’ll be fine. What does pollserial do? Well, it snoops at the serial data registers (polling!) to see if a new character has arrived. It then puts it in a ringbuffer, so that it can be made available to the read call later. Okay, I understand.

But did I mention the reason I didn’t use this code in the first place? It’s that pollserial didn’t compile on my Arduino 1.0 setup (most libraries that aren’t part of the core don’t out of the box yet, in my experience). I could probably figure that out (has something to do with inheriting from the Print class and a prototype mismatch) but in my real, ultimate application, I wanted to read from a PS/2 keyboard. It will of course have the same (but differing in details) issues, and I’ll have to tweak their driver code to make it work with TVout too. Sigh.

Ultimately, I guess I disagree with one part of the Arduino philosophy: that programming can ever really be simple. Writing a program to blink an led, or read a switch isn’t hard, no matter what language or processor you use. Simple programs are simple, but the virtue of computers is that they can do things which are complex. If your software environment doesn’t give you sufficient help in organizing and doing complex actions, then you are missing out a great deal of the purpose of computers.

Addendum: While trying to fix the compile errors in pollserial, I found this fragment:

[sourcecode lang=”cpp”]
int pollserial::read() {
if (rxbuffer.head == rxbuffer.tail)
return -1;
else {
uint8_t c = rxbuffer.buffer[rxbuffer.tail];
//tail = (tail + 1) & 63;
if (rxbuffer.tail == BUFFER_SIZE)
rxbuffer.tail = 0;
else
rxbuffer.tail++;
return c;
}
}
[/sourcecode]

Can you spot the problem? Hints: BUFFER_SIZE is defined to 64, and rxbuffer.buffer is malloced to be BUFFER_SIZE bytes long.