Go Down

Topic: Arduino-izing the AVR Butterfly (Read 13530 times) previous topic - next topic


Dec 05, 2008, 02:54 am Last Edit: Dec 05, 2008, 04:41 am by DaveK Reason: 1
I went ahead and loaded Nick's Butterfly additions and got it working with no trouble at all. A simple LED blink sample works just fine (blinking the speaker).

Initially the clock was running at the default 1MHz setting which I presume is where the bootloader leaves it. Resetting it to 8Mhz leaves the delay function off by a factor of 2, but it works.

The ASCIITable example works too, although at half the specified baud rate.

[edit]Ok, I went and found the F_CPU setting and put it up to 8MHz to match my clock, then found that I was getting twice the baud rate. I cleared the U2X bit in UCSRA and now it's behaving as I expect. I also see that delay(1) doesn't delay for the expected time, but delayMicroseconds(1000) and delay(4) does, so that was just simple user error.[/edit]

Pretty neat.

Code: [Select]

int value = 0;                            // variable to keep the actual value
int ledPin = 13;                           // light connected to digital pin 9

void setup()
 // Reset clock prescale, no scaling for 8MHz
 CLKPR  = (1 << CLKPCE);
 CLKPR  = 0x00;

 pinMode(ledPin, OUTPUT);  

void loop()
 digitalWrite(ledPin, HIGH);   // sets the LED on
 delay(1);                           // waits 2mS
 digitalWrite(ledPin, LOW);    // sets the LED off
 delay(1);                           // waits 2mS

Mark Bramwell

I have been following this thread. I have some butterflys ordered but they are not here yet.

As I quickly read through the 169 specs, it seems to have a 168 compatibility mode.

Can I suggest something...  How about taking a bootloader meant for something like a lilypad (which I think is 8mhz without a xtal) and slightly change the fuse bits to put the butterfly into compatibility mode.  

I would think we could use arduino software as-is if we select lilypad from the board menu and the timings would be perfect.

I have already started making a library with nice to have functions to support the peripherals.


I think I'd just as soon have settings for the butterfly, as Nick has it set up. The butterfly bootloader seems to work just fine, and it should be simple enough to update init() in wiring.c with the clock prescale settings (easy to set them up to work with multiple settings of F_CPU even) and U2X.

Nick Lott

Dec 05, 2008, 07:48 am Last Edit: Dec 05, 2008, 07:55 am by Brokentoaster Reason: 1
Hi guys, I have the CPU speed in the file boards.txt set to 4MHZ which is why we get a factor of 2 error in the speeds

Change the section in boards .txt to the following and that should be fixed.


I will update my files asap.

Is it possible to put the clock setup in somewhere so the user doesn't need to do this in the sketch. (EDIT: right ok in init() in wiring.c then jsut read the prev post properly. :) )

Writing a bootloader that will work with arduino is pretty straightforward but I would rather use the standard bootloader if possible although the button pressing thing is really annoying.

The ability to work with a std butterfly in my mind is far more useful as this avoids the need for programming hardware.

[EDIT: Just updated my files at http://www.brokentoaster.com/arduino012_butterfly.zip ]


Is it possible to focus on 1mhz?  One of the charms of the butterfly is low power consumption, as it runs on a button cell.  The CPU will draw about 4 times as much power at 4mhz than at 1mhz.


FYI, I just looked at the butterfly datasheet, it states that the standard discharge current for the battery is .2ma, and should not exceed .3 for continuous use.  

The battery is a cr2450, 3v, 550mah @ .2 ma, you have to be careful about leaving internal pullup resistors on and such.  


I agree that keeping this working with the stock bootloader is desirable for people who are working without an ISP programmer. I also agree that the button pushing thing is very annoying, I've been having trouble getting good uploads (about 2/3rds of my attempts fail) and it's hard to tell if it's related to the button pushing or not.

So, I wonder if we could do both? Would it be too confusing to have configurations for both a stock butterfly and for a butterfly with a new bootloader?

Regarding clock speed, it is very nice to be able to adjust the butterfly's clock and I'd like to be able to keep that option as well.

I got rid of the button cell as soon as I could, but the ability to run on the low power is desirable. I'm not sure it should be the default as it appears that much of the code assumes 16 or 8MHz (delayMicroseconds would need to be updated).

Since the butterfly almost always runs on the internal 8MHz clock we could read F_CPU not as telling us what the crystal frequency is, but rather what the target clock should be with the assumption of the 8Mhz internal clock. Init() can call OSCCAL_Calibrate which can handle setting the clock prescaler and calibrating the OSCCAL bits.

I use Dean's version of OSCCAL_Calibrate(). from his ButtLoad project. It's fast, and allows for calibrating the clock to interesting speeds, like the 7372800Hz for 115200 baud serial comm, as discussed in the AVR Freaks thread. It looks like it shouldn't be too much work to update it to check F_CPU to set up CLKPR as necessary for the specified value of F_CPU.

Nick Lott

Dec 05, 2008, 05:34 pm Last Edit: Dec 05, 2008, 05:36 pm by Brokentoaster Reason: 1
I agree. Whereever there is reference to F_CPU in the libraries we can insert code to check the CLKPR and return the actual CPU value.

I use the same trick in my data logger project as dean does to get faster baudrates via the retuned clock. It is worth its wait in gold. The only fun will be making all the libraries handle an unexpected clock rate.

I think it should also be documented somewhere that programming the butterfly from the button cell is not recommended and can brick the bootloader on the butterfly. It is recommended that for programming the butterfly an external 3-4.5 V is connected.

I think with respect to the clock problem that as part of the butterfly library/core files we need clock manipulation library that will allow the programmer to change the clock divider, retune the clock to the crystal and make these changes known to any dependant functions.

on a side note I have noticed a reset  when you hit up or center on the joystick. probably the pin-change interrupt is not set up correctly.

DaveK: what is your error message for you 2/3 failing attempts?


Unfortunately, I am unable to load anything on the Butterfly. I followed all the directions in Nick's zip file, set the preferences, set the board and the serial port in the Tools menu but everytime I try to upload something I get either:

Found programmer: Id = "AVRBOOT"; type = S
   Software Version = 0.2; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.

Programmer supports the following devices:
   Device code: 0x75

avrdude: Expected signature for ATMEGA169 is 1E 94 05
        Double check chip, or use -F to override this check.

or the programmer is not found:

Found programmer: Id = ""; type = ?
   Software Version = =.; No Hardware Version given.
avrdude: error: buffered memory access not supported. Maybe it isn't
a butterfly/AVR109 but a AVR910 device?

Any ideas what may be wrong? I am sure I am missing something but I don't know what.


Nick Lott

Dec 05, 2008, 10:02 pm Last Edit: Dec 05, 2008, 10:03 pm by Brokentoaster Reason: 1
hmmm how old is your butterfly?
i get this when I program.

Connecting to programmer: ..
Found programmer: Id = "AVRBOOT"; type = S
   Software Version = 1.4; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.

Programmer supports the following devices:
   Device code: 0x75

can you program through the command line

Code: [Select]
avrdude -c butterfly -p m169 -P /dev/cu.usbserial -U flash:w:BlinkWithoutDelay.hex

where /dev/cu.usbserial is your serial port
and BlinkWithoutDelay.hex is your project hex file (in the applet folder of your sketch after verifying)

I find tapping the button a few times after selecting upload rather than holding it down to be a good technique.

hope this helps.


I'm not sure how old it is, a couple of years. The thing is I was never able to program my butterfly using avrdude, I have no idea why. I always used AVRProg from AVRStudio and this works fine every time, I just tested it again.

It would be awesome if I could use avrdude.

Nick Lott

Dec 05, 2008, 10:43 pm Last Edit: Dec 05, 2008, 10:44 pm by Brokentoaster Reason: 1
I think you have quite an old version of the bootloader code. I think some of the original batch reported themselves as atmeger16 or something strange.

You could try avrdude using avr910 or avr109 as an option other than butterfly in the command line.

I don't supose you have a JTAG or ISP programmer handy to update the bootloader :P

Might be worth a search over on avrfreaks to see if anyone else has had this issue.

Sadly if you can't program the butterfly with avrdude then there is nothing that the ardunio IDE can do to help as it simply calls avrdude to do the actual programing. :(

[edit]You can of course still use the IDE and libraries.. you will just have to program using avrporg/avrstudio[/edit]


Dec 05, 2008, 11:55 pm Last Edit: Dec 06, 2008, 12:18 am by merlin13 Reason: 1
I assume this is the case, I'll try to find the avrfreaks post describing how to make an ISP cable and update the bootloader.

There was a very similar issue on avrfreaks a while back (http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=144097) but even by updating to the latest avrdude it still didn't work.

I'll see what I can find/build/do this weekend. Thanks a lot for patience and help.

I forgot to mention: the idea of using AVRProg is awesome, it works great! Thank you!


When mine works I get

Code: [Select]
Connecting to programmer: ..
Found programmer: Id = "AVRBOOT"; type = S
   Software Version = 1.4; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.

Programmer supports the following devices:
   Device code: 0x75

When it fails I get:

Code: [Select]
Connecting to programmer: .
Found programmer: Id = ""; type = ?
   Software Version = ?.?; No Hardware Version given.
avrdude: error: buffered memory access not supported. Maybe it isn't
a butterfly/AVR109 but a AVR910 device?

I'm not sure where my bootloader is from, it's one I picked up from a link in the AVR Freaks thread about the fuse bits preventing serial programming.

I've also found that slowly clicking the button a few times seems to work better.

It would be nice if the Arduino IDE would redirect the AVRDude output to itself and either simply display it or parse it and display a progress bar.


I've made a few changes to Nick's files.

I've added osccal.c/h which are used by wiring.c. This is the OSCCAL_Calibrate() function I mentioned earlier. I've modified it by removing the CLKPR reset that it used.

In wiring.c I've added CLKPR_Calibrate() which checks F_CPU then sets CLKPR to the scaling that gets it the closest, based on the 8MHz RC oscillator.

In wiring.c Init() I call CLKPR_Calibrate() to set the clock prescaler, then OSCCAL_Calibrate() to try to use the 32kHz crystal to try to get the clock within a few percent of the target rate.

I tested on my Butterfly at 1,000,000, 4,000,000, 7,372,800, and 8,000,000. I tried at 500,000 too, but that didn't work. Everything else worked well enough that serial comm works. At 1mhz I was using 9600, and at 7.3mhz 115200 worked.

The delays that delayMicroseconds() produces are wrong when running with F_CPU < 8MHz, but delay() usually comes in pretty close. For very slow clocks I think the timer0 configuration for millis is going to have to be changed.

In wiring.c Init() I updated the setting of the A2D prescale in ADCSRA. I try to find the first prescale value under 200kHz and use that.

In wiring_serial.c I updated beginSerial() to set U2X when F_CPU is <= 1MHz, and to use the appropriate calculation for UBRR.

I think that's it. The result is that you can set your clock frequency in boards.txt (1,2,4 and 8Mhz should all work, as well as fairly wide deviations from those), and serial communication should behave like it is supposed to, and the calibration routine should get the clock within 2 or 3% of the requested frequency. The calibration routine does take just a little longer to start up, but it's under a second.

It could probably be better, but at least it seems to be working here.

You can download the files I changed.

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131