How To Do Big Strings in Arduino

Arduino makes it pretty easy to store & use character strings, but those strings compete with your variables, so you can’t do as much. Here’s how to put big strings into read-only program memory and use them.

Lots of sketches can have big strings in them. Maybe you’ve built a little command-line interface or you’re storing small web pages (for net-connected Arduinos). Normally you do something like this:

char hellostr[] =  "<html><head><title>hello world</title></head>"
                   "<body><p align=center><h1>hello world</h1></p>
                   "</body></html>";

// and then sometime later

Serial.println( hellostr );

The problem with this is that “hellostr” is stored in RAM along with your variables. The ATmega chip in Arduino only has 1kB of RAM. If your code is getting complex, and you’re using big strings, and lots of libraries, you may start having mysterious problems. Arduino can’t warn you if your sketch starts using too much RAM.

Instead, you can use PROGMEM, or PROGram MEMory, to store your strings. That is, the flash ROM memory that your code lives in. Using PROGMEM strings can be tricky, but here’s a little function called “printProgStr()” to make it almost as easy.

const char hellostr[] PROGMEM = "...";     // notice added 'const' and 'PROGMEM'

// given a PROGMEM string, use Serial.print() to send it out
void printProgStr(const prog_char str[])
{
  char c;
  if(!str) return;
  while((c = pgm_read_byte(str++)))
    Serial.print(c,BYTE);
}

// and then at some point

printProgStr( hellostr );

If you have another use for the string that isn’t “Serial.print()”, just create your own function and put whatever per-character handling function in there instead.

“WiiChuck” Wii Nunchuck Adapter Available

Want to hook up a Wii Nunchuck to an Arduino but don’t want to cut up the cord on your Nunchuck? Yeah me too. So I made some of these:

wiichuck_adapter1.jpg

wiichuck_adapter2.jpg

It’s a small PCB that adapts the Wii Nunchuck connector to standard 4-pin header. I call it the “wiichuck adapter”. It plugs directly into the Arduino, no wiring necessary. You can get one too for $4.

Available from the following wonderful shops:
FunGizmos.com. FREE DOMESTIC SHIPPING. International shipping for $1 more.
Little Bird Electronics (Australia)
SparkFun. Ships domestic & internationally. Be sure to order header pins too!
– and just about any SparkFun distributor

Continue reading ““WiiChuck” Wii Nunchuck Adapter Available”

In Processing, size() matters for Serial ports

Mark Allen of Machine Project is teaching an Arduino course using some of the notes from my Bionic Arduino class. He and his students were seeing in Windows XP & 2000, when trying to getting Processing to talk to Arduino, the cryptic error:

  gnu.io.PortInUseException: Unknown Application
               at
  gnu.io.CommPortIdentifier.open(CommPortIdentifier.java:354)

Both his class and Mark and I separately spent a lot of time trying to figure out what the problem was. Eventually we discovered that it’s because the sketch I had written had a setup() like this:

  void setup() {
    port = new Serial(this, portname, 19200);
    size(400,400);
  }

but instead should have been like this:

  void setup() {
    size(400,400);
    port = new Serial(this, portname, 19200);
  }

Yes, size() must come before new Serial() on Windows or it will not work. There is a bug report describing a similar problem and is marked RESOLVED, INVALID because as the reference documentation for size() states, “The size() function must be the first line in setup()”.

I’ve been using Processing for a long time and I found this feature of size() surprising. I always figured size() to be just a dimensioning function, not a critical part of sketch startup. I’ve seen many sketches that apparently function correctly where size() is located outside of setup() or is not the first statement in setup(). Perhaps the Processing sketch parser should check the sketch before running it to make sure not statements come before size().

I apologize to any Windows users attempting to use the Processing sketches I wrote for Bionic Arduino. I’ve updated the sketches appropriately so the above issue doesn’t come up.

SpiroExplorer, a Spirograph toy

So I’ve written a tool that can turn any parametric equation into a series of Roomba movement commands. Mostly, anyway. The parametric equations I’m predominately focusing on are the hypotrochoid series of equations used in a Spirograph.

To explore the space of hypotrochoid curves I created SpiroExplorer, a simple Processing applet that lets you to adjust the equation parameters in real-time. You can do the following things while it’s drawing:

– left/right arrows change “r”, the radius of the inner moving circle
– up/down arrows change “d”, the pen’s distance from center of the moving circle
– ,/. changes “R”, the radius of the big fixed outer circle
– +/- changes scale
– [/] changes “dtheta”, the increment size (resolution, essentially)
– space bar randomizes parameters
– return key clears the screen

Click the below to play with SpiroExplorer:

spiroexplorer

RoombaComm library, release 0.95

RoombaComm is Java library for communicating and controlling the Roomba. It works on any operating system that RXTX supports. This includes Mac OS X, Linux, and Windows. It also works with Processing. It will soon work with Flash and Max/MSP.

It’s been a work in progress for several months and has gotten a little better as I work through improving it for the book.

Several bugs have been fixed, particularly with respect to Bluetooth on Windows. See the README for some info on that.

Tested systems:
– Mac OS X 10.4 (Tiger) : usb serial & bluetooth
– Mac OS X 10.3 (Panther) : usb serial & bluetooth
– Windows 2000 : usb serial & bluetooth
– Gumstix Linux : built-in serial

Tested adapters:
Homemade RS-232 adapter
Homemade Bluetooth adapter
RooStick USB adapter

Demo command-line programs include:
– DriveRealTime — Drive your Roomba with cursor keys
– RTTTLPlay — Play monophonic ringtones on your Roomba
– Spiral — Roomba drives in ever expanding spiral
– Waggle — Roomba wags like a dog
– BumpTurn — Roomba drives around by itself, avoiding things
– Spy — Read your Roomba’s mind while it works
– Tribble — Roomba purrs and sometimes barks
– RoombaCommTest — Roomba GUI remote control panel (not command-line)

Processing demos include:
– RoombaTune — Play your Roomba like a musical instrument
– RoombaRing — Play RTTTL ringtones on a Roomba
– RoombaView — Full instrument panel and remote control

This is what RoombaView looks like:

roombaview

Download:
– full package: roombacomm-0.95.zip
– Processing library: roombacomm-processing-0.95.zip

Docs:
javadoc
README-0.95
the source tree

RoombaComm: Roomba Control & Communications API, release 0

Update:
new version of RoombaComm released

As mentioned previously, I’ve started on a library to make Roomba-to-host-computer interfacing easier. This is the zeroth release of such a library.

The goals of this library are:

  • provide full access to the entire Roomba SCI protocol
  • provide a set of higher-level functionality on top of the SCI protocol
  • create a library that is as cross-platform as possible
  • provide interfaces to high-level languages/environments like Java, Flash, Processing, Max/MSP, etc.
  • allow someone who’s not an expert programmer utilize a rapid development environment like Processing to quickly manipulate the Roomba.

Java was chosen as a language, since the RXTX serial library seems well-developed on many platforms and has been tested thouroughly in Processing. Java also has good network connectivity, making it possible to create a net-to-serial adapter for the other languages.

And so the RoombaComm API:

RoombaComm In Use
In both Java and Processing, usage is very similar. Here is an example in Processing, which also forms the core of one of the Java examples:

RoombaCommSerial roombacomm = new RoombaCommSerial(this);

if( roombacomm.connect("/dev/cu.KeySerial1") ) {
    println("connected!");
    roombacomm.startup();

    println("Playing some notes");
    roombacomm.playNote( 72, 10 );
    roombacomm.pause( 200 );
    roombacomm.playNote( 79, 10 );
    roombacomm.pause( 200 );
    roombacomm.playNote( 76, 10 );
    roombacomm.pause( 200 );

    println("Spinning left, then right");
    roombacomm.spinLeft();
    roombacomm.pause(1000);
    roombacomm.spinRight();
    roombacomm.pause(1000);
    roombacomm.stop();

    println("Going forward, then backward");
    roombacomm.goForward();
    roombacomm.pause(2000);
    roombacomm.goBackward();
    roombacomm.pause(2000);
    roombacomm.stop();

    println("Disconnecting");
    roombacomm.disconnect();
}
else {
  println("could not connect! :(");
}

If all goes well with the above, you should see and hear something like this:

The API functions used above allow for a very Logo-like programming experience. The API has also more detailed commands, including the ability to read the Roomba’s sensors. As there is no documentation, see the examples and source for now.

Expect a new version of this API with more examples and documentation within a week or so.