20

I'm following this tutorial, programming the ATtiny85 with an Arduino, using it to play some tones (through a piezo speaker). I'm struggling with getting the tones at the right pitch (I'm creating the wave forms manually, as the tone() function is unsupported on the ATtiny85).

I believe the problem may be down to differing clock speeds on the Arduino and ATtiny. I understand the clock speed can be altered on the ATtiny, how do I accomplish this using the arduino environment?

JRobert
  • 3,162
  • 13
  • 27
fearoffours
  • 548
  • 2
  • 7
  • 13
  • by the way this is really cool, thanks for sharing! – vicatcu Dec 14 '10 at 17:38
  • Hats off! I've never managed to program my attiny85 this way.. I always have "programmer out of sync" errors when avrdude attempts to write the flash. Swapping the arduino with a bus pirate works though... – JonathanD Dec 14 '10 at 20:27
  • @Jon: I'm not sure of the root cause behind "programmer out of sync", but with AVR Studio you can adjust the programming frequency. There may be a similar option in avrdude, might be worth a look if you ever give it a whirl again – Nick T Dec 16 '10 at 02:19

7 Answers7

4

I'm using Arduino UNO + ArduinoISP successfully.

Add -U flags to your avrdude command to set any or all of the three ATtiny fuses.

avrdude -p attiny85 -P com8 -c stk500v1 -b 19200 -U lfuse:w:0x6f:m -U flash:w:main.hex

The clock selection is done in bits[3:0] on the third fuse ('Fuse Low Byte'). Set them as follows to make use of an external crystal (of 8MHz or faster):

-U lfuse:w:0x6f:m

Its definition (I infer) must be something like: [Fuse Low Byte]:[write]:[hex value]:[set manually]

The default value for the four high bits of this byte are 0110, so leave the 6 in 0x6f as it is, and only change the second digit, the f (its default value is 2).

NB: If your processes take longer or shorter than you expect, check your clock prescaler and your definition of F_ CPU.

JellicleCat
  • 649
  • 1
  • 8
  • 18
  • I wanted to caution that I just bricked my AtTiny85 by using the above `-U lfuse:w:0x6f:m` avrdude option. I'll need to reset it using a high-voltage setup. So a word of caution to folks (like myself) who are trying to reset fuses without knowing what they are doing. – M-V Jan 11 '13 at 04:02
  • @M-V Did you really brick it or simply did not use the external XO when trying to reset the fuse? – damd Jan 29 '14 at 15:08
  • Had no external clock to use. What does bricking mean in a stricter sense? – JellicleCat Jan 29 '14 at 15:18
  • @JellicleCat, If you set the fuse to use an external XO, you'll need to use an external XO attached to the mcu from then on to program/set/reset fuses. Not doing so, will give you the impression the mcu is bricked (~ not working anymore) because it needs the ext. XO to function, even for programming it through ISP. – damd Jan 30 '14 at 09:51
  • Alright. If I understand the matter, I set the fuses to expect an XO, and then to restore the chip, I used an Arduino to supply a standing wave, which served for an XO. – JellicleCat Jan 30 '14 at 18:31
  • Self inflicted, but I also followed the fuses here without realising exactly what it meant. Required a second chip to act like a clock just to allow reprogramming again. – David K Mar 01 '16 at 19:44
3

Try using the related tutorial by the same group (MIT's High-Low Tech) entitled Programming an ATtiny w/ Arduino 1.0.

A quick summary: From the Tools-> Board menu in the Arduino IDE, select the ATtiny85 and the frequency you wish to run at (1 or 8 Mhz internal clock, or 20Mhz external crystal) and then use the Tools -> Burn Bootloader". I believe selecting the desired speed board modifies the way the delay() and other time-related Arduino functions work in order to sync up with the clock speed.

I have had success with this approach myself using some ATtiny84 chips. The simple blink program is fixed, as well as more sensitive timing required for manually controlling pulses sent to a servo using delayMicroseconds().

Tom B
  • 31
  • 1
2

I believe the Arduino software (libraries and all) assumes you are operating at 16MHz. If you apply that assumption to the clock you are actually running at... things should work out. Assuming you are running the Tiny85 on it's internal oscillator I think it runs at 1MHz, so just multiply all your delay statements (and other notions of time) by 16.

If you need better accuracy than the internal oscillator provides you should think about using an external crystal or a resonator, but you will need to change the fuse settings of the AVR for that to work, and I think you will need a programmer like the AVRISP mkII to do that with AVR Studio (my recommendation).

I don't know much about the ArduinoISP sketch but to me it looks like it bit bangs the ISP protocol to upload a program to the target chip (not the on board Mega328), not sure it is equipped to manipulate fuses. ArduinoISP is documented here http://arduino.cc/en/Tutorial/ArduinoISP, fwiw. Note that you can't use a UNO currently to run the ArduinoISP sketch. It doesn't look to me like you can use the sketch to make the Arduino a viable interface for using the AVR Studio GUI tools.

EDIT: It looks like stuff has caught up and an UNO is viable for ArduinoISP now - thanks for the comments all

vicatcu
  • 22,499
  • 13
  • 79
  • 155
  • Thanks for the heads up about the UNO, I'm actually using a Duemilanove with the 168 chip swapped for a 328, and can get the normal ATtiny sketches to upload properly via ArduinoISP. I'll be trying your /16 tip! – fearoffours Dec 15 '10 at 09:02
  • @fearoffours You know another thing you could try is writing a sketch based on ArduinoISP that sets the fuses to a certain value. If ArduinoISP can write the Flash, there's no reason I can think of that you couldn't bit-bang the ISP protocol described in the AVR datasheets to set the Fuses. – vicatcu Dec 16 '10 at 00:42
  • 1
    @fearoffours, also I just realized (and update post) to say multiply by 16 instead of divide by 16 (your running a slower clock it will take more ticks to get the same duration) – vicatcu Dec 16 '10 at 00:45
  • I know it's over a year later, but I successfully use and UNO as AVR programmer. (However, I did alter the ArduinoISP sketch to `delay(20)` insted of `delay(40)` in its definition of `void heartbeat()`.) – JellicleCat May 30 '12 at 19:26
  • I know it's even later but I successfully used my Uno as a AVR programmer without changing anything in the sketch. – ingh.am Feb 09 '14 at 21:53
1

Default fuse settings for the ATtiny85 are: lfuse 0x62, hfuse 0xdf, efuse 0xff. This uses the internal RC (8 MHz) oscillator with "divide by 8" so clock is 1 MHz.

See http://www.engbedded.com/fusecalc for more fuse settings.

You can still use avrdude directly to change fuse settings of your ATtiny85 even when using an ArduinoISP as the programmer.

If you do end up manually changing fuse to alter the clock, be sure to edit the attiny85.build.f_cpu line of your [arduino_folder]\hardware\attiny45_85\boards.txt file.

Craig
  • 1,596
  • 2
  • 16
  • 21
1

It appears you are using ArduinoISP, try using AVR Studio or the command line options for avrdude. Depending on how the ArduinoISP was written, it may function just like an Atmel AVRISP mkII or similar.

Nick T
  • 12,360
  • 2
  • 44
  • 71
  • I didn't think the Arduino was itself an ISP programmer - I thought it has an ISP header on it so that you can burn a new bootloader onto a fresh ATMega328 in circuit... – vicatcu Dec 14 '10 at 17:33
  • reading the article more closely, it does seem like you can use the ArduinoISP sketch to do this - you learn something new every day! :) – vicatcu Dec 14 '10 at 17:42
  • AVR studio is OK if you are on Windows. Know that there is an AVR plugin for Eclipse (this is distinct from the Arduino plugin known as Sloeber). There is a nifty fuse dialogue available under Properties --> AVR. But yeah the OP just wants to use the "core" frequencies and "Burn Bootloader". – mckenzm Nov 15 '17 at 21:53
0

I think you can set the fuses with the ArduinoISP, but not with the Arduino IDE but with avrdude, check this link. Never tested it myself.

The tutorial explicitly says you can use the Arduino UNO and I have tested it and worked, so I can confirm that, so the ArduinoISP page is outdated and the UNO warning should be ignored. If your UNO was one from the first batch you probably have a faulty bootloader, you will need to reflash the bootloader. Check this page for more information (ignore the serial numbers, all my UNOs were not from that series and had problems).

The ported core libraries you downloaded from the tutorial are written to use the 1MHz internal oscillator (confirmed from boards.txt file), so maybe the timming problem might be in the ported core libraries or in your code.

Kind regards

Havok
  • 485
  • 4
  • 9
0
  1. Choose an ATTiny board from "boards manager" that includes the ATTiny85. This is in the "Tools" Menu. I think this includes "16MHz internal PLL" now. (You can install one from http://drazzy.com/package_drazzy.com_index.json)

  2. Select ATTiny85 explicitly if required.

  3. Choose a clock. Until you know more, choose an internal clock.

  4. Click "Burn Bootloader" as a Menu Item.

Caution, you may no longer be able to program the MCU if you choose very low values. If this is your intent, do this last unless you have spares or an High Voltage Programmer to reset the fuses.

mckenzm
  • 175
  • 5