Category Archives: Arduino

Arduino based projects and resources

April Fools

About a week ago, Sparkfun posted a great prank in their weekly new product video. As April 1 was coming up, and I thought the kids would enjoy it, I ordered the bits that I didn’t have, and managed to pull it off.  Sparkfun didn’t give many details, so I thought I’d share my implementation.First here’s a video showing my wife getting pranked. She was a super good sport, (even not minding posting a video of her in her bathrobe!)

NOTE: Someone on google+ pointed out that at 8 amps, these horns could seriously heat up the li-po, and a hot li-po is not a good thing (fires/explosions!) so do this at your own risk. I only pulse the horns for 1 second at a time (twice per activation) so the battery never gets hot, but if you had a programming error, and it was stuck on, look out! Another good reason for the cutout switch and testing without the horns connected.

[youtube]http://www.youtube.com/watch?v=Hn6xDEUDoMw[/youtube]

Here’s what you’ll need for this prank:

  1. Arduino
  2. Accelerometer: I used this one from ModernDevices
  3. Digitally controlled relay. I used the same one they used in the Sparkfun prank
  4. The Horns!
  5. A (nearly) 12V lightweight battery. Sparkfun has this nice 1500 MAH 11.1 LIPO for a good price
  6. A compatible charger. Sparkfun recommends the IMAX B6 This can also be found on Amazon
  7. Wires, connectors, a good way to connect all the parts together

.

Here I wired the battery to power the Arduino, one leg of power went directly to both horns, and the other switched through the relay. I also put a toggle switch inline  with the power to the horns so I could shut off the horns for testing (The relay has an led and also clicks, so you can tell if it’s operating).

I had a proto-screw-shield on hand which was convenient for hooking up both the accelerometer and connecting to the relays.

Here it’s almost all hooked up. The relay connections are made to the analog side of the arduino to simplify wire routing. (Both 5V ground and io pins together.)

I use the button and LED on the protoshield to arm the device and indicate it’s status.

The bolts on the horns were too short to go through 1/4 ” plywood, so I used the supplied mounting plates to offset mount the horns.

Here it is all put together.  Here’s the Arduino sketch, but I recommend you try to program this yourself!

We Interrupt our regular programming….

I made an attempt to improve the SoftwareSerial library to make it possible to use Pin Change Interrupts in conjunction. I made some progress, but it’s not working yet. I’ll share what I’ve learned, and spell out a simple (though Kludgy) workaround.

 

Implementing asynchronous serial without hardware isn’t an easy task, and the Software Serial library is a pretty cool hack. It takes processor resources to implement that protocol though, especially with any speed, and as always there’s often competition for resources.

 

The limitations of Software Serial are widely discussed in various Arduino forums, and there are alternatives such as  Paul Stoffregen’s AltSoftSerial which looks very promising but comes with it’s own set of tradeoffs (it uses one of the timer’s so disables PWM on some of the pins)

 

The limitations of SoftSerial that comes with the Arduino IDE appear to be 2:
  1. Interrupts are disabled during transmit so you can’t transmit and receive at the same time, and it may cause you to miss other interrupts. (Paul’s library deals with this)
  2. It uses Pin Change interrupts in such a way as to eliminate their use for anything else.

 

It  is this second limitation that my friend Justin Shaw of Wyolum labs and I were discussing, and I thought I’d take a look to see if it could be remedied.

 

 There’s one pin change interrupt vector per port (and a mask register as well)
That means if you are using more than one pin from a port for pinchange interrupts, the interrupt handler for that port has to determine what to do.
Interrupts are covered in many fine pages on the web, so I won’t go into details here, but there are two kinds on the arduino:
1. Dedicated external interrupts – tied to pin 2 and 3 each with their own interrupt vector.
2. Pin Change Interrupts – allow’s you to use any IO pin. There are registers to tell which pin(s) you want to watch in each port, and a vector for each set of IO pins (Ports) on an Atmega 328, there are three: Port B, C and D.

 

There are libraries (such as PinChangeInt.h) that handle setting up these handlers, but SoftwareSerial doesn’t use them. It has it’s own interrupt handling routine, and uses the Interrupt service vectors in a very selfish way. It points all the port interrupt vectors to it’s own routine, even if it’s only using a couple of pins from a single port.

 

The code below from SoftwareSerial.cpp sets the interrupt handler for all the ports that are defined (by processor type)
PCINT0 is for Port B (PB0-PB7)
PCINT1 is for Port C (PC0-PC6)
PCINT2 is for Port D (PD0-PD7)
PCINT3 isn’t defined for atmega328p
#if defined(PCINT0_vect)
ISR(PCINT0_vect)
{
  SoftwareSerial::handle_interrupt();
}
#endif
#if defined(PCINT1_vect)
ISR(PCINT1_vect)
{
  SoftwareSerial::handle_interrupt();
}
#endif
#if defined(PCINT2_vect)
ISR(PCINT2_vect)
{
  SoftwareSerial::handle_interrupt();
}
#endif
#if defined(PCINT3_vect)
ISR(PCINT3_vect)
{
  SoftwareSerial::handle_interrupt();
}
#endif

 

So, if you are using PB5 as a softserial rx,
you could comment out the code for PCINT1-PCINT3.
If you are using the PinChangeInt.h library, you’d also want to add:
 #define NO_PORTB_PINCHANGES 
Ahead of your #include PinChangeInt.h
so it doesn’t try to hook the vector softserial is using.

LCDBootDrive: Selectable Files!

New toy (o-o-o)

After I showed the BootDrive on the Adafruit Show and Tell, I watched their weekly “Ask an Engineer” show where they showcased a new product, an LCD shield with an RGB backlight. The really cool thing is that the LCD AND 5 buttons only need 2 IO pins on the Arduino, because the shield is designed with an I2C expander. I ordered it the next day (close to 5pm) selected UPS ground shipping and it was at my house the next day!

Here’s a quick video before I go through the blow-by-blow:

[youtube]http://www.youtube.com/watch?v=w5jPm3thkWo[/youtube]

I soldered the micro-sd breakout onto an Adafruit Proto Shield, and a 6 pin right angle header to connect an FTDI cable. Adafruit also had a pre-made 6pin-6pin female cable that was perfect for this project!

I wired it with fine wire-wrap wire on the bottom

The wiring is almost identical to the original BootDrive, except I changed the reset pin assignment:

Digital Pin5  –> FTDI Pin 6 (CTS)
GND                –> FTDI Pin 1 (GND)
Digital Pin1 (RX) –>FTDI Pin 4 (TX)
Digital Pin2 (TX)–>FTDI Pin 5 (RX)

SD Card Interface:
Digital Pin 10 –> SD-breakout CS
Digital Pin 11  –>  SD breakout DI
Digital Pin 12  –> SD breakout DO
Digital Pin 13  –> SD breakout CLK
GND                    –> SD breakout GND
5V                       –> SD breakout 5V

Debugging

I incorporated the directory listing code from the SD library examples, and instead of listing all the files, I did an openNextFile() each time the “down” button was pressed. It would be nice to be able to scroll up and down, but I’m pretty tight on memory as it is, so I didn’t want to cache the directory, or do some kludgy re-reading the whole directory to get to the file we are on.

The first problem I ran into was it worked fine until you scrolled through what turned out to be 25 names (actually the same 3 names 8+ times) and then it started repeating the same name over and over. When I realized it was always 25, I knew it wasn’t some overflow, and I finally figured out the example code had a bug in it! They list the directory by opening each file (with openNextFile() to get the name, but they never close it! If you try the listfiles example with more than 25 files on the card, you’ll see only the first 25. Easy enough to fix, as I’m scrolling I close the file after I get it’s name. I reopen it if you press the “select” or program button.

The next problem was a bit harder. The hex programs seemed to work on some boards but not others, even though there were apparently no errors. I created new test programs and suddenly they didn’t work either. Since the writing to flash seemed to be working, I figured that there must be some corruption of data. I read back the programmed AVR code from the target arduino (with avrdude  <programmer parameters….> -U f:r:readfile.hex:i) and compared it with the file I was sending to be programmed. It turns out I was advancing to the next “line” of 16 bytes even when I read less. Files that ended in shorter lines were getting placed ahead of where they needed to be and so the program was corrupt. Probably on some, the data that was already there was harmless, or the program didn’t actually execute that part of it’s memory, but in some cases it clearly was. Fixed, putback to github!

Have fun and let me know if you try it!

https://github.com/osbock/Baldwisdom/tree/master/LCDBootDrive

Precious Memory

There are two kinds of memory(well three including EEPROM, but we won’t deal with that here) you can run out of when doing an Arduino project (or any embedded project):

  1. Flash Memory: For a lot of applications, the Arduino has a fairly big flash memory (the UNO and all atmega328 based Arduinos give you 32k flash.) The Arduino IDE will also tell you if your program size exceeds the amount of flash in the particular Arduino you have selected.
  2. Static RAM: Atmega328 in the UNO gives you 2k of RAM. This is the most precious commodity in Arduino programming, and it’s often surprising how fast you can run out. The bad thing is,  the IDE won’t warn you, and your program can go from working to behaving really weirdly by doing something as simple as adding an additional debug print statement. This post will attempt to explain this, and give you a few tips for understanding your RAM use.

Where Did it All Go?
When you run out of SRAM, your program can just stop working, for reasons ranging from one data structure overwriting another (so your program does something based on the wrong value) to overflowing into the stack. When that happens, generally, your program dies a horrible death, because returning from subroutines can cause the processor to jump to random places in memory. If you make an innocuous change to your code (like adding another debug statement) and your program suddenly behaves very differently, chances are you have run out of SRAM.

It’s obvious if you declare large variable arrays like:

int valueArray[1024];

would instantly overflow memory because int’s occupy 2 bytes in atmega land. You also need to leave room for stack, and any other variables your libraries, and the Arduino software itself uses.

What’s Harvard got to do with it?
Not so obvious is the fact that:

Serial.println("Hello");
const char constantString[] = {"Hello"};

both  occupy 6 bytes in both flash memory and in SRAM (c-strings are terminated with a Null, or 0x00 byte).  The reason is AVR 8 bit microcontrollers use a Harvard architecture addressing scheme. This means that when an instruction addresses memory, there are two versions, one that addresses program memory (flash), and another to address RAM. Most routines like Serial.println use regular RAM, as they don’t know if you’ll be passing in constant info or stuff that you’ve constructed. As a result, even static strings (with a const declaration) are copied from flash to SRAM at system startup. It’s possible to write routines to only use flash (using the PROGMEM attribute) and it’s definitely useful, but that’s covered elsewhere.

I ran into this porting the avrdude stk500 routines to Arduino, blindly converting the printfs into Serial.print statements. In order to get enough RAM I ended up using numeric codes for errors (I’ll probably eventually get around to PROGMEM-ing them).

So, how do you tell if you are nearly running out, or have already? The IDE won’t tell you, so you have to dig in a little.

The build process for arduino produces an “ELF” file or Executable and Linkable File. This is used to create the actual HEX file for programming, but still has memory segment information embedded in it.

First find your build directory. On Windows 7 this is \users\<youruser>\AppData\Temp\build<a bunch of numbers>.tmp

Now, assuming you have the avrdude files somewhere in your path, use the command:

avr-size -C --mcu=atmega328p <yourelf-file.elf>

For example, the current version of Bootdrive gives me:

avr-size -C --mcu=atmega328p BootDrive.cpp.elf
 AVR Memory Usage
 ----------------
 Device: atmega328p
Program: 19272 bytes (58.8% Full)
 (.text + .data + .bootloader)
Data: 1340 bytes (65.4% Full)
 (.data + .bss + .noinit)

It’s probably best not to go beyond 95% full for your Data (that’s the SRAM part) to save room for your stack, and even less if you pass big variables on the stack or have deep call chains.

BootDrive for Arduino

Announcing the formal release of BootDrive for Arduino. If you’ve been reading the blog, you know that I’ve been working with Justin Shaw of Wyolum labs to enable their I2SD (Arduino clone with a micro-sd card) to bootload a program onto another Arduino. After battling several issues, mostly related to porting avrdude code to the Arduino (assumptions about infinite memory, etc!) it’s working well enough people can fool around with it.

Right now the code looks for a single file (“program.hex”) and waits 5 sec and then blasts it into the target arduino. Details about setting up to try this yourself follow the video.

Here’s a demo of it in action:

[youtube]http://www.youtube.com/watch?v=i4wJ4kRO80E[/youtube]

If you’d like to try this with a couple of Arduinos, you’ll also need an SD card (or micro-sd) interface such as the Adafruit Micro-SD breakout. This board is great because it has onboard 3.3v conversion so it’s safe to use with 5V (stock) Arduinos. Download the code from github: https://github.com/osbock/Baldwisdom/tree/master/BootDrive
or a zipped version here

Hook up your Arduinos like this:

I

The basic setup is:

Arduino Control:
Master Digital Pin6  –> Target reset
GND                                –> GND
MASTER Digital Pin1 –>Target Digital Pin2
MASTER Digital Pin2 –>Target Digital Pin3

SD Card Interface:
 Master Digital Pin 10 –> SD-breakout CS
Master Digital Pin 11  –>  SD breakout DI
Master Digital Pin 12  –> SD breakout DO
Master Digital Pin 13  –> SD breakout CLK
Master GND                    –> SD breakout GND
Master 5V                       –> SD breakout 5V

Optional debugging serial interface (This lets you see error messages and the like)
Master GND    –> FTDI cable Pin 1 (GND)
Master Digital Pin 4 –> FTDI cable Pin 5 (diagram is wrong, but you can change it in the code if you need to)

Here are the defines you can change to swap the pins around:

#define BOOT_BAUD 115200 // This is the Arduino UNO’s bootloader baud rate. Other boards are different!
#define DEBUG_BAUD 19200 // for software serial debugging
#define txPin 4
#define rxPin 5 // not really used…
#define rstPin 6

Also if you want to put your SD card on a different line (or are using a shield that uses a different chip select) change this:

const int chipSelect = 10;

Action!

Right now, 5 seconds after initialization, the program blasts a file called “program.hex”. You can add your own user interface to select amongst multiple programs.
Just call:

void programArduino(char *filename)

with the filename, e.g.”

programArduino("program2.hex");

You can build new hex files by grabbing them from the Arduino build directory. Make sure you have the IDE set up for your target board and press the “compile/verify” button.

From http://arduino.cc/en/Hacking/BuildProcess:

The .hex file is the final output of the compilation which is then uploaded to the board. During a “Verify” the .hex file is written to /tmp (on Mac and Linux) or \Documents and Settings\<USER>\Local Settings\Temp (on Windows). During upload, it’s written to the applet sub-directory of the sketch directory (which you can open with the “Show Sketch Folder” item in the Sketch menu)

Note on Windows7, the base directory is \users\<USER> \appdata\local\Temp\build<some bunch of numbers>.tmp\<sketchname>.cpp.hex

Note that if you want to load an Arduino other than UNO, you’ll need to change the baud rate. You can find that in “hardware/arduino/boards.txt” in the arduino directory. This won’t work on MEGA based Arduinos as they use the stk500v2 protocol (thanks westfw!)

Everything You Always Wanted to know about Arduino Bootloading but Were Afraid to Ask

Breaking through!

It’s been a while since the last update, but some progress has been made. I discovered that SoftwareSerial library doesn’t work really well at 115200 baud, so I switched the wiring around to use software serial for debugging, and the hardware uart pins (Arduino pins 1 and 2) to talk to the bootloader on the target. This is a little bit of a pain, as you have to unplug the connection to the target to download code to the “programmer” but it does work now.

I had a little trouble getting sensible responses from the bootloader until I put in a delay after resetting. In retrospect this makes sense as the AVRdude code reminded me that there are capacitors on the Arduino reset line. I was probably trying to talk too soon.

What bootloader, speed, protocol?

There have been several different bootloaders in the history of Arduino, and the source code for the current “canonical” loaders is included in the Arduino software distribution.  The bootloader is a little piece of code that allows you to program the flash memory of the Arduino’s atmega328p via serial or USB instead of using an ICSP programmer.  These bootloaders implement a subset of the STK500 8bit protocol (not to be confused with STK500v2) which is documented at www.atmel.com/atmel/acrobat/doc2525.pdf

Arduino MEGA (1280 and 2560) use yet another bootloader, one that uses the stk500v2 protocol instead.

The source code for the bootloader used by the diecimila, duemilanove, and a few other clones  is in …\arduino-1.0\hardware\arduino\bootloaders\atmega. Many clones use this, or a variant hacked by Lady Ada (Limor Fried).

The UNO and other later Arduino variants use a much smaller bootloader called Optiboot (more room for your code!). A little secret is that you can actually burn this bootloader into your older arduinos (at least at atmega168 and greater) and then just refer to the board as an UNO.

Adafruit Forum user westfw (one of /the?) author of  optiboot points out:

Optiboot also supports the mega8. However, you can only call a board an Uno if it at has a m328 cpu in it. For m8 and m168s with optiboot, you’ll need to make a new entry in boards.txt that copies the Uno bootloader parameters, but has the correct “build.mcu” specification (and fuses, if you want to program the bootloader using the IDE.)

The code for this is in …\arduino-1.0\hardware\arduino\bootloaders\optiboot. If you need to change the processor or baud rate, the settings are in the Makefile. This version is very stripped down, and doesn’t support, for example, writing to EEPROM. I’m choosing to use this as my initial target. Most of the code will still work on the older bootloader, but may require a slightly different command set.

The latest and greatest optiboot can be found at it’s Google code site: http://code.google.com/p/optiboot/

Which is also the preferred place for bug reports and to check for newer versions (atmega1284 is now supported!)

Because of varying clock rates, and different bootloader code, the various boards use different baud rates to talk to the IDE. This information is found in the …\arduino-1.0\hardware\arduino\boards.txt file. The UNO programs at 115200 baud, the Duemilanove (with ATmega328p) programs at 57600 baud. The Diecemila or Duemilanove with ATmega168 programs at 19200 baud.

Looking at the actual protocol

After the Arduino IDE compiles everything down to a intel hex file for downloading to the target Arduino, it uses the avrdude command to program the Arduino. The upload protocol is also specified in the boards.txt file and is called arduino, which is a slight variant of avrdude’s stk500 protocol. Most of the commands are from the stk500 module, except the signature reading is slightly different. For now, I’m adapting the avrdude code directly for the Arduino. This requires some minor porting (eliminating fprintfs, removing some of the indirection that links it to the avrdude programmer framework). I may simplify some of this code later as I’m a little nervous about running out of room.

As I mentioned in my last post, I downloaded a trial version of AGG Software’s Advanced Serial Port Monitor, and recorded the conversation between avrdude (controlled by the Arduino IDE) and the UNO target board. I stayed up late last night annotating the conversation:

DTR and RTS are both toggled from High to low several times

Avrdude then sends the GET_SYNCH command, thows away whatever comes back and sends it again a couple of times
Avrdude/Arduino IDE:#30#20 STK_GET_SYNCH, Sync_CRC_EOP
Target/Arduino UNO:  #14#10 STK_INSYNC, STK_OK
Avrdude/Arduino IDE: #30#20 STK_GET_SYNCH, Sync_CRC_EOP
Target/Arduino UNO:  #14#10 STK_INSYNC, STK_OK
Avrdude/Arduino IDE: #30#20 STK_GET_SYNCH, Sync_CRC_EOP
Target/Arduino UNO: #14#10 STK_INSYNC, STK_OK

Get the version number of the bootloader (in this case it’s 4.4) we could use this to branch to different variants of protocol.
Avrdude/Arduino IDE: #41#81#20 STK_GET_PARAMETER, STK_SW_MAJOR, SYNC,CRC_EOP
Target/Arduino UNO: #14#04#10 STK_INSYNC, 0x04, STK_OK
Avrdude/Arduino IDE: #41#82#20 STK_GET_PARAMETER, STK_SW_MINOR, SYNC_CRC_EOP
Target/Arduino UNO: #14#04#10 STK_INSYNC, 0x04, STK_OK

The next two commands are consumed but ignored (probably used by a real programmer to retrieve device specific stuff.)
Avrdude/Arduino IDE: #42#86#00#00#01#01#01#01#03#FF#FF#FF#FF#00#80#04#00#00#00#80#00#20(This is a STK_SET_DEVICE Command that is consumed but ignored by the bootloader)
Target/Arduino UNO: #14#10 STK_INSYNC, STK_OK
Avrdude/Arduino IDE: #45#05#04#D7#C2#00#20 STK_SET_DEVICE_EXT (also ignored)
Target/Arduino UNO: #14#10 STK_INSYNC, STK_OK

Enter Programming mode.
Avrdude/Arduino IDE: #50#20 STK_ENTER_PROGMODE, SYNC_CRC_EOP
Target/Arduino UNO: #14#10 STK_INSYNC, STK_OK
Avrdude/Arduino IDE: #75#20 STK_READ_SIGN, SYNC_CRC_EOP (read device signature)
Target/Arduino UNO: #14#1E#95#0F#10 STK_INSYNC, (three byte signature), STK_OK

The next four commands are consumed but ignored. I won’t bother to reproduce them in my code.
Avrdude/Arduino IDE: #56#A0#03#FC#00#20 STK_UNIVERSAL,0xA0,0x03,0xFC,0x00 SYNC_CRC_EOP (This is a pass through command that is supposed to be used to perform arbitrary native SPI commands. In this case, and the next 3, they are Read EEPROM byte commands They are consumed but ignored by the bootloader)
Target/Arduino UNO: #14#00#10 STK_INSYNC, (last byte written by the Universal command, STK_OK
Avrdude/Arduino IDE: #56#A0#03#FD#00#20 STK_UNIVERSAL,0xA0,0x03,0xFD,0x00,SYNC_CRC_EOP (Ignored by the bootloader)
Target/Arduino UNO: #14#00#10 STK_INSYNC, (last byte written by the Universal command, STK_OK
Avrdude/Arduino IDE: #56#A0#03#FE#00#20 STK_UNIVERSAL, 0xA0,0x03,0xFE,0x00,SYNC_CRC_EOP (Ignored by the bootloader)
Target/Arduino UNO: #14#00#10 STK_INSYNC, (last byte written by the Universal command, STK_OK
Avrdude/Arduino IDE: #56#A0#03#FF#00#20 STK_UNIVERSAL, 0xA0,0x03,0xFF,0x00,SYNC_CRC_EOP (Ignored by the bootloader)
Target/Arduino UNO: #14#00#10 STK_INSYNC, (last byte written by the Universal command, STK_OK

Here’s where we actually get started. This specifies the address in Flash where the follwoing PROGRAM_PAGE data goes.
Avrdude/Arduino IDE: #55#00#00#20 STK_LOAD_ADDRESS, 0x0000, SYNC_CRC_EOP
Target/Arduino UNO: #14#10 STK_INSYNC, STK_OK
And then the actual data. Note that the data is in the same order as the bytes in the Intel Hex file
Avrdude/Arduino IDE:
#64#00#80#46#0C#94#61#00#0C#94#7E#00#0C#94#7E#00#0C#94#7E#00#0C
#94#7E#00#0C#94#7E#00#0C
#94#7E#00#0C#94#7E#00#0C#94#7E#00#0C#94
#7E#00#0C#94#7E#00#0C#94#7E#00#0C#94#7E#00#0C#94#7E#00#0C#94#7E
#00#0C#94#7E#00#0C#94#9A#00#0C#94#7E#00#0C#94#7E#00#0C#94#7E#00
#0C#94#7E#00#0C#94#7E#00#0C#94#7E#00#0C#94#7E#00#0C#94#7E#00#0C
#94#7E#00#00#00#00#00#24#00#27#00#2A#00#00#00#00#00#25#00#28#00#2B
#00#00#00#00#00#20
STK_PROGRAM_PAGE, 0x0080 (page size), ‘F'(flash memory), data bytes…,SYNC_CRC_EOP
Target/Arduino UNO: #14#10 STK_INSYNC, STK_OK

And then we repeat – set address, program page, etc.
Avrdude/Arduino IDE: #55#40#00#20 STK_LOAD_ADDRESS, 0x0040, SYNC_CRC_EOP
Target/Arduino UNO: #14#10 STK_INSYNC, STK_OK
A
vrdude/Arduino IDE: STK_PROGRAM_PAGE, 0x0080 (page size), ‘F'(flash memory), data bytes….,SYNC_CRC_EOP
Target/Arduino UNO: #14#10 STK_INSYNC, STK_OK
.
.
.
Then it reads several pages (probably to verify what it wrote)

Avrdude/Arduino IDE: #55#00#00#20 STK_LOAD_ADDRESS, 0x0000,SYNC_CRC_EOP
Target/Arduino UNO: #14#10 STK_INSYNC, STK_OK 

Avrdude/Arduino IDE: #74#00#80#46#20 STK_READ_PAGE,0x0080 bytes, ‘F’ for flash, SYNC_CRC_EOP
 Target/Arduino UNO #14 STK_INSYNC
Target/Arduino UNO #14#10 STK_INSYNC, STK_OK
#0C#94#61#00#0C#94#7E#00#0C#94#7E#00#0C#94#7E#00#0C#94#7E#00#0C#94#7E
#00#0C#94#7E#00#0C#94#7E#00#0C#94#7E#00#0C#94#7E#00#0C#94#7E#00#0C#94
#7E#00#0C#94#7E#00#0C#94#7E#00#0C#94#7E#00#0C#94#7E#00#0C#94#9A#00#0C
#94#7E#00#0C#94#7E#00#0C#94#7E#00#0C#94#7E#00#0C#94#7E#00#0C#94#7E#00
#0C#94#7E#00#0C#94#7E#00#0C#94#7E#00#00#00#00#00#24#00#27#00#2A#00#00
#00#00#00#25#00#28#00#2B#00#00#00#00#00 

#10 STK_OK

repeat several times at different addresses

.
.

And then leaves programming mode
Avrdude/Arduino IDE: #51#20 STK_LEAVE_PROGMODE, SYNC_CRC_EOP
Target/Arduino UNO #14#10 STK_INSYNC, STK_OK

Then we’re done! Avrdude then toggles DTR/RTS to reset

 

 

Detour: From Auto-programmer to Serial Boot drive

When I originally posted about the Auto-programmer I was pleased to see several people on my Google+ stream and in the Adafruit forums were interested. Justin Shaw of Wyolum labs was interested in the idea of reading the program off the SD card, but instead of programming a microcontroller chip directly, program another Arduino compatible (specifically one of his gorgeous clocks!)

He’s already made an Arduino compatible SD card reader board he calls I2SD (it speaks I2C) that also speaks TTL serial, so it would be perfect. I’m putting the Auto-programmer on hold to make …. drum roll please…. The Boot Drive for Arduino!

I promised a blow by blow, and I’ve been working on this for a couple of sessions. I’ve read through all the docs (8 bit stk500 protocol, optiboot source code, AVRDUDE source.) and It looks fairly straight forward. Essentially the “programming arduino” stands in for the IDE.

The optiboot source code is pretty cleanly documented (used in most newer arduinos, like the UNO). It’s pretty tiny and does only the bare minimum to get the job done. Since it’s fairly stateless (not completely, as there are timeouts that cause you to jump to the user program), I needed to get an idea of the actual sequence.

I downloaded a trial version of AGG Software’s Advanced Serial Port Monitor which lets you “listen in” on the conversation between a computer (i.e. the Arduino IDE) and a device (the Arduino.) I collected sample program downloads for the UNO and for the Duemilanove (they have different bootloaders). There were no surprises, but it was nice to confirm the sequence. If people are interested, I could post about this later. Drop me a line on my Google+ stream.

Here’s how I have it wired (using regular Arduinos until I can get my hands on an I2SD).  Note I haven’t set up the Adafruit MicroSD breakout board yet.


I’ve got pins 2 and 3 configured as software serial on the “Master” Arduino hooked in a null modem configuration with pins 0 and 1 of the “Target” Arduino. I chose to do this, so I can send debugging info down the USB serial channel. I’m doing this at 115200, because that’s what the UNO bootloader operates at. I also hooked a digital pin from the Master to the Reset of the Target. If I read the code correctly, you have a very short period of time to start sending STK500 commands before the bootloader times out and jumps to user code after RESET. The Arduino IDE asserts reset by toggling the RTS line (well, actually a software call on the USB-serial driver). The RTS output of the FTDI chip (or equivalent on the UNO) is tied to RESET.

Now comes the frustrating part, I haven’t been able to get them to talk. I get bytes back but they aren’t what I expect, and I’m not sure where they are coming from if I’m not properly entering the bootloader.

I also tried setting up dummy programs, the Target sending “Hello” in a loop, and the “Master just trying to receive it and print it out. That doesn’t work either.

I’ll keep you posted. I’m also going to try talking to a TTL serial Arduino clone (one of the WIBLOCKS Pico boards).

 

Arduino Auto-programmer part 1

I thought I’d try something new with this project. Write about it as I go along, revealing all the mistakes and false starts, etc. and not wait for it to be finished. Heck, it might never be finished!

This project was inspired by the various arduino-ISP shield tutorials out there.  Evilmadscientist.com has an excellent shield, and Adafruit has a do-it-yourself tutorial. These generally make the arduino into an STK500 compatible USB programmer, and you need a computer to burn the chip. I thought, why not make a shield that had a micro-sd card on it and push a button, and bang! chip programmed!

Not many people probably need this kind of production, but I thought I could learn a few things.

Now Adafruit has another cool project based on another project called Optiloader, where you can embed a program in the Arduino program and burn standalone, but the program has to fit on the Arduino along with the programming code.

Here’s my basic plan of attack:

  1. Decide what I want the project to do. Here I brainstorm a bunch of features and put it into a google doc. I then prioritize what I want for the first iteration.
    Here’s basically what I came up with:
  2. Project Overview:
    Create an Arduino Shield for standalone programming of atmega chips from files stored on a micro-sd card. First iteration will handle one program on the card (selection of files would require UI)
    Functions:
    • Program chip from files on SD card
    • Read chip to files on SD card
    • Maintain ArduinoISP functionality?
    • Log ArduinoISP session to card?
    • replay ArduinoISP session from card?UI
      • Read(read from chip to SD card) button
        • Green Light indicator
      • Write (program chip from SD card)
        • Red LED indicator during/flashing green at finish
      • Error indicated via flashing red
      • If USB is connected, information printed via serial
  3. Order any parts I need. In this case, I bought a micro-SD breakout board from Adafruit. This has a voltage shifter chip to protect the cards (which use 3.3 V from the 5 V Arduino signals. I already had a zif socket.
  4. Breadboard the project. As you can see above I did the minimum. For the “shield version” I’ll probably also add some buttons and indicator LED’s
    Here’s the wiring to the atmega/ziff socket (from the adafruit tutorial):

    1. Pin 1 to digital 10 – Blue
    2. Pin 7 to 5V – Red
    3. Pin 8 to Ground – Black
    4. Pin 9 to digital 9 – Gray
    5. Pin 17 to digital 11 – Brown
    6. Pin 18 to digital 12 – Orange
    7. Pin 19 to digital 13 – Yellow
    8. Pin 20 to +5V – Red
    9. Pin 22 to Ground – Black
      SD Breakout Wiring:
    10. GND to Ground
    11. 5V to 5V
    12. CLK to Arduino Pin 13
    13. DO to Arduino Pin 12
    14. DI to Arduino Pin 11
    15. and CS to pin 8 (important as this has to be different than the line used to select the 328!)
  5. Test the individual parts to make sure they don’t interfere with each other. I loaded the Arduino ISP code, and programmed an atmega328, and I loaded the SD library and read some files off the card. You’ll also need to change the code line in the SD example code to use the different chipSelect line.  I learned/realized a couple of things:
    1. I should probably include a crystal/oscillator so that you can burn fuses that require an external oscillator (like the Arduino itself)
    2. One of the SPI lines is tied directly to the SD card activity light. This means that that light will flicker when the chip is being programmed.

This is as far as I’ve gotten so far. Next:

  1. Write the code to read Intel Hex files from the card
  2. Define and write code for a file for fuses
  3. Adapt Optiloader code to write data read from the card
  4. Implement user interface