Wednesday, December 9, 2015

Fixing Pin P5 or 6 on Digispark Clones

The digispark ATTINY85 is a handy microcontroller for simple projects. The genuine version, available here: http://digistump.com/products/1 comes with the micronucleus bootloader installed and 6 GPIO pins enabled.

There are Chinese clones available on ebay for about $1.50 that are pin for pin compatible and come with the micronucleus bootloader installed. The catch is that pin P5 (the last one, physically counted as number 6, ADC0) may be configured as a reset pin. If you only need 5 pins, or want a reset pin that's great, you can stop reading. If you need 6 pins, read on.

The ATTINY85 comes from the factory set up for ISP (in system programming), for this to work it needs a reset pin. The micronucleus bootloader allows the user to program the ATTINY85 with a USB connection. This is well documented on the digistump site.

After the bootloader is added, we no longer need that reset pin, and on the genuine boards they go ahead for us and set the "fuse" on the ATTINY85 to disable the reset pin, allowing it to be used as a GPIO pin. On the clones they may not.

To test if your clone can use pin 5, there are some simple methods. One would be to upload a sketch that blinks an led on pin 5, if it works that's great! You don't need to change anything. If it doesn't work pin 5 will not work for GPIO.

Another simple test would be to pull pin 5 to ground through a small resistor (~220 ohms) while a program is running. If the program resets (the micronucleus bootloader waits 5 seconds and then the program runs) you cannot use pin 5 for GPIO.

(If pin 5 is working for GPIO and you want change it to a reset pin, it is possible. You need a high voltage programmer, which is fairly simple to build and use, but it beyond the scope of this post. Look here to get started: http://www.rickety.us/2010/03/arduino-avr-high-voltage-serial-programmer/)

Ok, so now you know that your pin 5 is configured as a reset pin and you want it for GPIO.

First and foremost be sure the micronucleus bootloader is installed on your ATTINY85 and working properly.

After we change the configuration fuse, you will not be able to load micronucleus without a high voltage programmer! Be sure the bootloader is present and working first. If you can upload programs to your ATTINY85USB via the USB connection from the Arduino IDE the bootloader is present and working.

You will still be able to upload programs via the USB connection as you normally do after changing the configuration fuse.


The next thing you will need is another Arduino, I used a Duemilanove, but you can also use an Uno. Using the Arduino IDE (I used v1.6.6), go to file > examples > ArduinoISP and upload this sketch to your Duemilanove (or Uno). If you have been playing around with your digispark, be sure the bootloader and board in the Arduino IDE are set correctly to the board you are now programming.

After uploading, go to tools > port and note the port where your Arduino is connected. For me it was  '/dev/ttyUSB0'. We will need this later.

If you are using a Duemilanove, add a 120 ohm resistor from RESET to 5v on the Duemilanove board. Do not use a resistor smaller than 110 ohms or larger than 124 ohms. Please do not skip this step. Read the comments for more information.

On an Uno, do not add the resistor but instead add a 10uF capacitor from RESET to GROUND on the Uno board. Please do not skip this step. Read the comments for more information.

Connect as shown:

Duemilanove -- > Digispark ATTINY85USB Clone

GND --> GND
5v --> 5v
10 --> P5
11 --> P0
12 --> P1
13 --> P2

These are the connections for Duemilanove and ATTINY85, for other boards be sure to determine the proper pins, you want SS, MOSI, MISO, and SCK on the other Arduino connecting to RESET (P5), MOSI (P0), MISO (P1), and SCK (P2) on the digispark ATTINY85USB clone. Note these are not the pins on the ATTINY chip itself, but the IO pins on the digispark clone.

It should look something like this...




Next go to a terminal and enter (replace '/dev/ttyUSB0' with the port your Arduino connects to that you noted earlier): 

avrdude -P /dev/ttyUSB0 -b 19200 -c avrisp -p attiny85 -n


It should output something like this...

avrdude: please define PAGEL and BS2 signals in the configuration file for part ATtiny85
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x1e930b

avrdude: safemode: Fuses OK

avrdude done.  Thank you.


I am using linux, if you use windows I would assume this works the same in command prompt, if you enter (replace '/dev/ttyUSB0' with the port your Arduino connects to that you noted earlier):

avrdude.exe -P /dev/ttyUSB0 -b 19200 -c avrisp -p attiny85 -n


If all goes well, the next command to enter is (replace '/dev/ttyUSB0' with the port your Arduino connects to that you noted earlier):

avrdude -P /dev/ttyUSB0 -b 19200 -p attiny85 -c avrisp  -U hfuse:w:0x5F:m 


The response should be:

avrdude: please define PAGEL and BS2 signals in the configuration file for part ATtiny85
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x1e930b
avrdude: reading input file "0x5F"
avrdude: writing hfuse (1 bytes):

Writing | ################################################## | 100% 0.02s

avrdude: 1 bytes of hfuse written
avrdude: verifying hfuse memory against 0x5F:
avrdude: load data hfuse data from input file 0x5F:
avrdude: input file 0x5F contains 1 bytes
avrdude: reading on-chip hfuse data:

Reading | ################################################## | 100% 0.01s

avrdude: verifying ...
avrdude: 1 bytes of hfuse verified

avrdude: safemode: Fuses OK

avrdude done.  Thank you.



That's all, your digispark clone should now allow you to use P5 as a GPIO pin, and be programmable via the USB connection. If you want to go back to having a reset pin, or program with ICSP, you need a high voltage programmer. See the link above.

15 comments:

  1. Anonymous22/2/16 14:45

    Thank you so much!

    I spend the last weekend with a digispark, trying to get adc0 working without success. I want to use it as a adc over i2c.

    Now it works as expected.

    Thank you, thank you, thank you!

    ReplyDelete
  2. Thanks man ! :D I was not familiar with fuses

    ReplyDelete
  3. Anonymous20/4/16 04:20

    Thank you Toivonen.
    I tried this on two $1.4 Chinese Digispark clones, 1st one was bricked :( (avrdude completed successfully but when plugging the Digispark I got unrecognized device). But 2nd one worked. The only difference between the 1st and 2nd runs was that for the first I didn't connect a 150ohm resistor across reset and 5V on my Uno (actually a CH340G Uno clone).
    Can you explain the reason for the this reset pullup?

    By the way, I unbricked the first clone by resetting the RSTDISBL fuse and burning Micronucleos v2.3 .
    I only used 1 resistor and a 12V source for HVSP by following this guide:
    http://www.instructables.com/id/How-to-unlock-Digispark-ATtiny85-and-convert-it-to/?ALLSTEPS
    (see Step 7: Transistors? We don't need no stinking transistors!)

    Cheers.

    ReplyDelete
    Replies
    1. Hi, thanks for the comment. This brings up a few great points.

      The resistor is required to prevent the Arduino that we are using as a programmer (Uno*, Duemilanove, etc) from resetting whenever a serial connection is established.

      For convenience, the Arduino boards come configured so that whenever a serial connection is first established, the atmega is reset. This is nice because the atmega then runs its bootloader, allowing us the option of uploading a program via usb. If there is no program to upload, the atmega goes on to run whatever program is loaded. This is typically the preferred behavior. Otherwise, you would need to manually press the reset button at the correct time when uploading a sketch. It is doable, but inconvenient.

      The circuit used to accomplish the auto reset is an RC circuit connected to the FTDI DTR pin. When the DTR pin goes low on serial connect, the arduino reset is pulsed low for about 1 ms. The resistor in this circuit is a 10k.

      In our case, we don't want the atmega to reset when it starts a serial connection. Once avrdude establishes a connection, it needs to be able to send data to the atmega, which passes it on to the attiny. If we didn't disable auto reset the atmega wouldn't be ready in time.

      By adding our 150 ohm resistor in parallel with the 10k, we change the pulse duration to something like a few microseconds, which the atmega ignores.

      I have tried it without the resistor, or with a slightly larger resistor (220 ohm) and it did not work. The "official" documentation calls for a 110 ohm to 124 ohm resistor, but I have found the 150 ohm to work just fine. I haven't bricked an attiny yet, but it's good to know that it can happen and I am glad you were able to fix it.

      *As a final note, the Uno uses different wiring for the auto reset, and the recommended way to prevent it is actually a 10uF capacitor from reset to GROUND rather than the resistor.

      I am making a few updates to the post based on your comment, thanks again.

      Delete
    2. Anonymous21/4/16 00:14

      Many thanks for the thorough explanation Toivonen!

      Delete
  4. Anonymous6/11/16 05:26

    That worked! Thanks!

    A while back I built this
    http://www.instructables.com/id/ATtiny-Programming-Shield-for-Arduino-1/

    To follow your procedure, I added jump wires from the attiny85 socket to the Digispark pins. Double checked everything before applying power to the Arduino.

    From the command prompt I used this:
    cd "C:\Program Files (x86)\Arduino\hardware\tools\avr\bin"
    avrdude -P com5 -b 19200 -c avrisp -p attiny85 -C ..\etc\avrdude.conf -n

    Then, to burn the fuse, I used this:
    avrdude -P com5 -b 19200 -c avrisp -p attiny85 -C ..\etc\avrdude.conf -U hfuse:w:0x5F:m

    (substitute your COM port as required. My Arduino showed up as COM5 from device manager)

    ReplyDelete
  5. Problem here:
    response I get after the command (I replace the port with 'com3', the one found by Arduino) is as follows:

    "avrdude: stk500_getsync<>: not in sync: resp=0x00

    avrdude done. Thank you."

    What should I do?

    ReplyDelete
  6. ...solved: I forgot to upload the sketch first, duh..

    ReplyDelete
  7. Anonymous20/3/17 17:50

    This is fantastic. I've been beating my head against a wall for hours about why my clone digispark was resetting when I started trying to use P5. I successfully set the fuse using your procedure from an Arduino Uno.

    I didn't have a 10uF capacitor handy, but a 22uF worked just fine for the reset pin.

    Thanks again!

    ReplyDelete
  8. This comment has been removed by the author.

    ReplyDelete
  9. Hi.

    Work fine with my Arduino nano clone (like a programmer) and Digispark clone. Only wires are needed! I test it with classic blink sketch (P5) is blinking after FUSE was changed. Windows 7 os.

    ************************
    C:\Users\"USER"\Documents\arduino-1.8.2\hardware\tools\avr\bin>avrdude -P com6
    -b 19200 -c avrisp -p attiny85 -C ..\etc\avrdude.conf -n

    avrdude: AVR device initialized and ready to accept instructions

    Reading | ################################################## | 100% 0.09s

    avrdude: Device signature = 0x1e930b (probably t85)

    avrdude: safemode: Fuses OK (E:FE, H:DF, L:F1)

    avrdude done. Thank you.

    ******************************

    C:\Users\"USER"\Documents\arduino-1.8.2\hardware\tools\avr\bin>avrdude -P com6
    -b 19200 -c avrisp -p attiny85 -C ..\etc\avrdude.conf -U hfuse:w:0x5F:m

    avrdude: AVR device initialized and ready to accept instructions

    Reading | ################################################## | 100% 0.07s

    avrdude: Device signature = 0x1e930b (probably t85)
    avrdude: reading input file "0x5F"
    avrdude: writing hfuse (1 bytes):

    Writing | ################################################## | 100% 0.05s

    avrdude: 1 bytes of hfuse written
    avrdude: verifying hfuse memory against 0x5F:
    avrdude: load data hfuse data from input file 0x5F:
    avrdude: input file 0x5F contains 1 bytes
    avrdude: reading on-chip hfuse data:

    Reading | ################################################## | 100% -0.00s

    avrdude: verifying ...
    avrdude: 1 bytes of hfuse verified

    avrdude: safemode: Fuses OK (E:FE, H:5F, L:F1)

    avrdude done. Thank you.

    ReplyDelete
  10. Fantastic, thanks! This saved my build. I had everything soldered up when I realised that PIN 5 was not working.

    ReplyDelete
  11. Thanks a lot. This also works with a leonardo clone.
    However, some changes are necessary.

    a) In the arduinoISP sketch, locate

    #define RESET SS

    and replace with

    #define RESET 2

    Upload sketch.

    Connect ATTiny85:

    P5 --> D2
    P0 --> MOSI (ISP Header)
    P1 --> MISO (ISP Header)
    P2 --> SCLK (ISP Header)

    No resistor or capacitor needed.

    ReplyDelete
  12. For a Windows PC, this is a bit easier:

    1. Copy avrdude.conf file from

    C:\Program Files (x86)\Arduino\hardware\tools\avr\etc

    to

    c:\users\username


    Run the two commands with -C %USERPROFILE%\avrdude.conf on the end...

    avrdude -P COM5 -b 19200 -c avrisp -p attiny85 -n -C %USERPROFILE%\avrdude.conf


    avrdude -P COM5 -b 19200 -p attiny85 -c avrisp -U hfuse:w:0x5F:m -C %USERPROFILE%\avrdude.conf

    ReplyDelete