How to update Arduino software externally?

Scenario:
A device with an embedded Arduino is shipped with working software. The device contains a SD socket. The SD socket is normally used to log data.

Let us say that a sketch update needs to be loaded onto the Arduino. In this case, the pre-compiled sketch would be placed onto the SD card and read by the Arduino. How would this be possible? This needs to be as simple as possible for a consumer audience. (no FTDI cables…)

I’m imagining this software would need to live in flash memory and know enough to read the SD card data and update the Arduino code.

My main question is how to upload a new image from a storage device without using the IDE and a FTDI cable?

Any suggestions?

Surely someone has been down this road before?

You want the arduino that is executing a program to stop what it is doing, and install a new program, and then run that program?

Good luck.

You might be able to have another Arduino read the SD card... and emulate the serial connection that the Arduino board normally uses to program the chip.

But... this would be a hell of an effort.. and if you're asking these questions I'm not sure you would be able to pull it off alone. (I'm not even sure it's possible :P)

Personally, I would rather bring out the TX,RX,GROUND and RESET pins... that way you just plug an Arduino board into it.. or a USB-to-Serial converter (such as the FTDI board you don't want to use, lol) and update it that way.

Let me clarify. I would like the arduino to check upon booting up to see if a new program is available (from SD), and if so load it. If not, execute the currently loaded program. If there are other options, I’m open to them.

Basically, how can one easily update the Arduino software after it’s installed in consumer devices? Assuming there is some storage device such as an SD card available.

Imagine having 500 devices in use by consumers. Now you have a software update. How can the consumer easily apply the update?

Imagine having 500 devices in use by consumers. Now you have a software update. How can the consumer easily apply the update?

You can what thousands of manufacturers do.... plug it into the computer? Lol, you can get many firmware updates for DVD players.. TV's and such.. from the internet now.

Regardless of how you look at it, I don't think the extra work would be worth loading a sketch from an SD card. Why not just bring out a USB-to-Serial connection? Here's a fairly cheap and small chip.. it's already on a proto-board: http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&item=380179064995&ssPageName=STRK:MEWNX:IT

No matter what.. you need something other than the SD-card and the Arduino... whether it be another Arduino, maybe another micro-controller.. most likely the FTDI idea.. but you can't just upload a sketch from an SD card.

Like I was saying... read the data from the SD card.. then emulate the Arduinos programming sequence (I have no idea how to do this.. but you have to set the baudrate and such to the Arduino bootloaders speed, 115200?I'm probably wrong.. but speed must be correct) Then when it's in the bootloader mode.. have the Arduino send the information, just as if it were a computer uploading a sketch over the Serial connection.

I did look into this some time ago and basically found that it would be extremely difficult to do. I was thinking of coding an arduino from an arduino so slightly more complex.

You would need the sketch loaded onto the SD card as 'machine code' so that it can just be 'sent' to the arduino rather than needing processing which your computer normally does.

Mowcius

well, in principle it's not that hard is it? It's a combination of a modified boot-loader and code to read the flash card.

It would seem like it would have a serious risk of bricking the device though, if the process went wrong or got interrupted.

Thanks for the input - I believe the most direct route is to incorporate a USB-to-Serial converter into the device. The consumer can connect a usb cable directly the a computer and upload new firmware.

Next question: Do I need to use AVRDude to transfer the hex file to the Arduino? Is there a more simple approach which could be integrated into an update application?

Do I need to use AVRDude to transfer the hex file to the Arduino? Is there a more simple approach which could be integrated into an update application?

Actually, you'll only be able to use the Arduino IDE from what I'm aware of with the USB-to-Serial converter. The bootloader is what makes the Arduino.. the Arduino, for the most part! (Actually it's these awesome forums, but we're talking about in terms of hardware!:D) To use AVRDude, you'll need a programmer such as the USBTinyISP, uh.. I'm not familiar with alot of them, too lazy to look.. but an AVR-ISP. (Generally run about $20 - $50, much more if you want an uber-badass model)

You could just give them a .PDE from the Arduino environment, have them plug in the USB, and select the port, upload.. and that's it for the firmware update.

EDIT: I believe there's a way to upload a .hex with the Arduino IDE, but I don't have experience with that.. someone else will have to answer. I believe when the sketch is compiled before it's uploaded to the board, the IDE is actually turning it into a .HEX.

Actually, you’ll only be able to use the Arduino IDE from what I’m aware of with the USB-to-Serial converter

Not actually factual. The Arduino IDE passes control to AVRDUDE to perform the actual upload via serial link to the bootloader code. The only trick the IDE does before passing control to AVRDUDE is to activate the automatic reset function via the serial DTR control. Without the auto-reset function, one has to press the reset on the board at the correct time for AVRDUDE to operate. However it’s been stated that the next version of the Arduino IDE will use a newer version of AVRDUDE that will utilize the auto-reset directly.

One can also uitilize AVRDUDE directly in command line mode and upload code to the AVR mega chip with Arduino bootloader installed. And of course one can use AVRDUDE directly with several different hardware programmers to upload code (HEX files) via the ISP pins rather then through a serial link to bootloader code.

Lots of ways to skin the cat. :wink:

Lefty

Ah, my apologies! I always considered AVRDUDE a complete separate program..process.. everything.. lol I've only used it a few times to upload some test bootloaders. (And to upload without a bootloader all together:D)

Learn something new everyday! Well from a "production" standpoint, I think the usb-to-serial converter is the way to go. Especially if you can solder the small chips.. you can get them even cheaper than the link I listed. (Actually, this chip is used in alot of the USB-to-TTL boards you see on eBay)

Well for the OP's hypothetical situation where you wish to give the customer an easy way to update firmware of a Arduino based consumer product, you run into the requirement that the customer's computer needs to have the FTDI USB serial driver installed before any new firmware file could be installed. Then the updating software on the PC has to know what comm port number was assigned to the FTDI device. This is bound to be a support hassle if it's not a product aimed at technical people.

A USB memory stick used for updating firmware to a Arduino based consumer product is a neat idea, but not very practacal in that it would add a lot of size and costs to the product, as a lot of extra components would be required, even if it can be done, which I'm not 100% convinced. I just don't think a single Arduino supported AVR processor has the horse power to pull it all off.

Lefty

I just don't think a single Arduino supported AVR processor has the horse power to pull it all off.

Maybe you could use one of these neat little ARM processors that you can now buy with USB and eveything :) They can be over $100 though...

Mowcius

Once i had a project , a gps looger on for a sd card, where i managed to update the software with a binary file written to the sacard. its a kind of bootloader which reads the card and write the binary file into the flash. it was for the mega8 and because of the limited space the software can handle only a simplified fat12 system where the uploadfile has to be the first file on the card with a fixed length. all was programmed in bascom and inline assembler but for devices like atmega368 it its probably easy to adapt to arduino.
but making it reliable its time consuming process !
regards

Code Snippet:
'*****************************************************************
’ start der assembler bios funktionen
’ in der nrww section des flash
'*****************************************************************
$boot = $e00 ’ Boot Size = 512 Words
’ entrypoint at $1c00, leave 1Kb for bootloader

$asm
_nrww:

’ Mega8 Fuse Bit Settings
’ 1(unprogrammed) , ponyprog x=checked=programmed=0
’ (x) Boostsz1 1K Bootsize
’ ( ) Boostsz0 0C00-0FFF
’ (x) Boostrst reset start at 0C00

’ (x) Cksel3 Cksel 0…3 = 0100 = 8MHz
’ ( ) Cksel2
’ (x) Cksel1
’ (x) Cksel0

rjmp _skip_vectors

jmp $0002 ’ Interrupt Vector Table
jmp $0004 ’
jmp $0006 ’
jmp $0008 ’
jmp $000A ’
jmp $000C ’
jmp $000E ’
jmp $0010 ’
jmp $0012 ’
jmp $0004 ’

_skip_vectors:
cli ’ clear interrupts

ldi r16,&h00 ’ disable flashwrite
sts {d_flash},r16

Ldi r16,&h04 ’ initialize Stackpointer to 045F
!Out sph,r16
Ldi r16,&h5f
!Out spl,r16

ldi r16,170 ’ oscillator calibration byte
!out Osccal,r16
’ 0=input
ldi r16,&B00101100 ’ portb = 2,3,5 = output
!out ddrb,r16

ldi r16,&B00011100 ’ portd 2,3,4 = output
!out ddrd,r16

ldi r16,103 ’ baud rate register set to 4800 at 8MHz
!out ubrr,r16

ldi r16,&h18 ’ uart ucsrb TX+RX enable
!out ucsrb,r16

rcall _pr_crlf ’ print cr lf
_chk_f0:

sbi portb,0 ’ set taster pullup
sbi portb,2 ’ set card ss

sbi Spcr,spe ’ enable spi
sbi Spcr,mstr ’ spi Master

sbi Spcr,spr1 ’ Clock rate fck/4 = 125KHz
cbi Spcr,spr0

rcall _spi_init ’ init card
clr r17 ’ jump on read error <> 0
cpse r18,r17
rjmp _chk_f_error1
nop

ldi r16,&h00 ’ disable flashwrite
sts {d_flash},r16

_chk_f1: ’ this section is done 2 times
’ 1.read 7k of mmc, calculate crc and compare
’ to crc in 2 last bytes of last block, when
’ ok perform section 2. and write 7K to flash

ldi r18,00 ’ get l_bladr Hi byte (only 12 bit)
ldi r17,01 ’ from eeprom P_lsn_ee
rcall _ee_read
andi r16,&B00001111 ’ use only first first 4096 blocks
mov r14,r16 ’ store to r14
rcall _pr_hex

ldi r18,00 ’ get l_bladr lo byte (only 12 bit)
ldi r17,00
rcall _ee_read
mov r13,r16 ’ store to r13
rcall _pr_hex
rcall _pr_crlf
clr r16
sts &h01f2,r16 ’ clear l_bladr hi 16 bit
sts &h01f3,r16

clr r16
sts &h1fd,r16 ’ clear variable crc
sts &h1fe,r16

ldi r16,14 ’ read 14 blocks ( 7K in mmc)
mov r12,r16 ’ r12 counter

clr zl ’ clear page adress for bootloader
clr zh

_chk_f2: ’ loop over 14 blockreads
sts &h01f0,r13 ’ get l_bladr (only 16 bit)
sts &h01f1,r14

push zl
push zh

lds r10,&h1fd ’ push crc
lds r11,&h1fe
ldi r17,C_read_block
sts {cmd},r17
rcall _spi_readblock
clr r17 ’ jump on read error <> 0
cpse r18,r17
rjmp _chk_f_error1
sts &h1fd,r10 ’ pop crc
sts &h1fe,r11
rcall _crc16blbu

pop zh
pop zl
rcall _boot_loader ’ write block to flash in 2. pass

ldi r16,1 ’ l_bladr=l_bladr+1
add r13,r16
clr r16
adc r14,r16

dec r12 ’ end loop 14x
brne _chk_f2

lds r16,{d_flash} ’ 2. pass done ?
cpi r16,&h55 ’ then
brne _chk_f2a ’ exit
rjmp _chk_f_out

’ now read block #16
_chk_f2a:
lds r10,&h1fd ’ push crc
lds r11,&h1fe
ldi r16,1 ’ l_bladr=l_bladr+1
add r13,r16
clr r16
adc r14,r16
sts &h01f0,r13 ’ put l_bladr (only 16 bit)
sts &h01f1,r14
ldi r17,C_read_block
sts {cmd},r17
rcall _spi_readblock
clr r17 ’ jump on read error
cpse r18,r17
rjmp _chk_f_error1
sts &h1fd,r10 ’ pop crc
sts &h1fe,r11

’ rcall _pr_h_dump

lds r16,&h1fe ’ print calculated crc from
rcall _pr_hex ’ file
lds r16,&h1fd
rcall _pr_hex
rcall _pr_crlf

lds r16,&h3ff ’ print crc in last block
rcall _pr_hex
lds r16,&h3fe
rcall _pr_hex
rcall _pr_crlf

lds r16,&h3fe ’ compare crc of 7K flash with
lds r17,&h1fd ’ crc signature in last bytes of file
cp r16,r16 ’ in block #16
brne _chk_f_out
lds r16,&h3ff
lds r17,&h1fe
cp r16,r17
brne _chk_f_out ’ if crc fails out
’ crc test ok > ready to burn flash
_chk_f_ok1:
ldi r20,50 ’ load value 50 for diddle led when crc ok
ldi r16,&B00001000 ’ led on
!out portd,r16
_chk_f_ok2:

in r16,portd ’ diddle leds loop as ok message
ldi r17,&B00001100
eor r16,r17
!out portd,r16
clr xh
clr xl
rcall _waitmicro

sbis pinb,0 ’ keypressed
rjmp _chk_f3 ’ yes, continue writeflash

dec r20
brne _chk_f_ok2

rjmp _chk_f_out

_chk_f3:
lds r16,{d_flash} ’
cpi r16,&h55
brne _chk_f4
clr r16 ’ disable flashwrite and do block readloop
sts {d_flash},r16
rjmp _chk_f5

_chk_f4: ’ write 55 signature to enable lpm
ldi r16,&h55 ’ in flashwrite and do block readloop
sts {d_flash},r16 ’ again for 2. pass
rjmp _chk_f1

_chk_f5:

_chk_fore:
rjmp _chk_fore

_chk_f_error1:

ldi r16,&h45 ’ E = Error
rcall _pr_cout
mov r16,r18 ’ print Errorc

Nice, is there a writeup of that somewhere, it could really help the arduino community (and me!) ;)

Mowcius

Then the updating software on the PC has to know what comm port number was assigned to the FTDI device

Wouldn't you be able to write a simple program in C++ to choose the correct com port, and upload. (after installing the drivers) Basically just an "update" software.

The way I see it, people are more likely to have a computer than a USB drive, and I think alot could depend on how often you need to update. If I had to update alot... a flash drive would be easier. (or SD card, something mobile) But if it it's only once every few months or something.. I think plugging it into a computer would be fine. (And save some money on hardware and time on extra software setup.)

Of course, you could implement both.. flash drive and the computer. Adds another complication to software though. :P

And agreed! I've got a few atmega8's and an SD card I'd be willing to test with, the datalogging isn't as important as the updating of sketches. :D

rbrockman, let's step back up to the 30,000 ft level, as they say.

A device with an embedded Arduino is shipped with working software.

When it is time to upgrade software, would you be willing to ship a replacement device, pre-programmed with the new software, in exchange for the original, returned to you? You seemed willing to ship an SD card with pre-loaded software in your original scenario.

Since you could reprogram the devices you received back, and ship them to other customers, the cost to you would be a set of "in transit" devices, some of which you might not get back. Compare that risk to the expense of buying SD cards, none of which you expect to get back.

This seems to be the easiest, most foolproof, and least troublesome for the customer, but I suppose it depends on the size and cost of the "device," and whether it is embedded in something else or stand-alone.

Just trying to brainstorm for you...

Great input - I appreciate the responses.

As a last resort, one could replace hardware to update firmware; but this isn't very scalable. However given the limitations I'm understanding, this could be the only solution.

With my product, the SD adapter and card are part of the product already because it also does data logging. I was hoping to leverage this hardware to additionally do firmware updates which would be made available as an internet download to be saved onto the SD card.

Keep the suggestions coming though, as I'm enjoying the learning.

There is now a perfect solution at http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1260909294/0#0.

Thanks to bhagman there.