ATtiny 1-series with Arduino support

Creating a break-out board for the ATtiny1616 where sketches can be uploaded from Arduino with the Arduino UNO or a modified AVR JTAG ICE

Similar projects worth following
The ATMEL ATtiny’s have been my favorite microcontroller for basic projects. I have been using these to control LED’s in earrings, OLED displays and APA102 (Dotstar) LED’s in wearables. The ATtiny84a comes in a 3 X 3mm footprint, has an internal oscillator and only requires an external capacitor to get it going, and all for less than $1.
Obviously, it does not match the specifications of the ATMEGA328P used in the Arduino UNO, and I do hit limitations all the time. Not enough flash memory is probably the biggest issue, but using peripherals, like SPI, I2C and UART, is very limited as well and I had an issue with running servo’s and APA102 LED’s simultaneously since it only has 2 timers (and 1 is only 8 bits).
This project will follow the development of an Arduino compatible break-out board of the ATtiny1616 (and most likely the ATtiny3217 in the future).

ATMEL was acquired by Microchip Technology in 2016 and last year they came out with a new microcontroller family sharing their technology, the tinyAVR and megaAVR. Out of this new offering the ATtiny1616 draw my attention. Looks like it has all the benefits from the ATtiny84a, same foot print, same power specifications, and some great additional features as well as you can see in the table below:

MCU name:




Operating Voltage:

1.8 - 5.5V

1.8 - 5.5V

1.8 - 5.5V

Digital I/O pins




PWM Digital




Analog Inputs




Analog Outputs




Flash Memory

8 KB

32 KB

16 KB









Clock Speed


20 MHz

20 MHz


3x3 body

4x4 body

3x3 body


1x8b, 1x16b

2x8b, 1x16b

1x12b, 3x16b

Digital Communication Peripherals




Able to run this from the 20 MHz internal oscillator, twice as much flash and four times more SRAM (compared to the ATtiny84) and support of most common peripherals excites me! There are just some minor problems. There is no Arduino support (yet) and there is no DIP version to plug into a breadboard.

This project will document the development of the Arduino Core for the tinyAVR 1-series and a breakout board for the ATtiny1616. Throughout different logs different challenges will be explained and resolved.

A regular Arduino UNO can be used to program the ATtiny1616:

ATtiny1616 Break-out Board.pdf

Schematic for the ATtiny1616 break-out Board

Adobe Portable Document Format - 21.73 kB - 06/02/2019 at 18:33


  • 1 × ATTINY1616-MNR 8-bit microcontroller, 16KB flash, 2KB SRAM, 20MHz
  • 1 × 100nF Capacitor 0603
  • 1 × 4.7K Ohm Resistor 085

  • Use the AVR-GCC tool chain libraries with Sleep example, using low power

    Sander van de Bor06/16/2019 at 05:59 0 comments

    In the first log the structure of the Arduino was explained, together with the required components like the Device Family Pack (DFP) and the AVR-GCC compiler. We have been using the DFP in the last examples by using the macros defined in the IO files for each microcontroller to set registers. While most macros are very well described and could be used for almost everything there is an even more convenient solution for some peripherals; the AVR-GCC tool chain libraries!

    In the first log was explained how certain commands in Arduino, like delay, are just functions called from the Arduino core (a collection of libraries). While the Arduino core has the major functions for the most used controls to pins and communication peripherals it just cannot do them all.

    In the previous log for example the Real Time Counter (RTC) was used by setting registers since the RTC has not been developed for the Arduino core. At the end of that log I also mentioned that the CPU is still running while it is doing nothing. We have to put the CPU in sleep mode if we want to conserve energy. Like the RTC, sleep is not part of the Arduino core, so we must write to the registers ourselves.

    Page#96 of the ATtiny1616 manual describes the different sleep modes:

    11.3.1 Initialization describes the steps to setup the sleep mode. First we need an interrupt to get out of sleep mode which we already had set with the RTC of the previous log (ISR(RTC_CNT_vect)). Next, we must select the sleep mode (will get back to that later) and enable sleep mode with the enable bit. Enabling the sleep mode will not put the CPU to sleep, it just enabled sleep mode so that is can put the device to sleep when needed.


    After setting these bits in the register we must to send an instruction to put the MCU to sleep. While setting up the sleep mode and enabling is probably done only once and for that reason can be done in the setup, putting the CPU to sleep must be done after each time it wakes up, and in this example we can just add it to the main loop. Writing an instruction is new in this series of logs, but can be done as follows:

    __asm__ __volatile__ ( "sleep" "\n\t" :: ); 

    The code should be update as follows:

    void setup() {      
        pinMode(LED_BUILTIN, OUTPUT);   
    void loop()
        // time too sleep!     
        __asm__ __volatile__ ( "sleep" "\n\t" :: );

    While this works great, there is actually a cleaner method available within the AVR-GCC compiler libraries. We can find these libraries in the following location:


    There is a file called sleep.h which we will use on the sketch. On the top of the sketch add a line:

    #include <avr/sleep.h>

    #include <avr/sleep.h> 

    Now we can use the functions within this library instead of writing directly to the registers and creating instructions. The new code will look as follows:

    #include <avr/sleep.h>
    void RTC_init(int RTCdelay)
      RTC.CLKSEL = RTC_CLKSEL_INT32K_gc;    // 32.768kHz Internal Crystal Oscillator (INT32K) 
      while (RTC.STATUS > 0);               // Wait for all register to be synchronized
      RTC.PER = RTCdelay;                   // Set period for delay
      RTC.INTCTRL |= RTC_OVF_bm;            // Enable overflow Interrupt which will trigger ISR
      RTC.CTRLA = RTC_PRESCALER_DIV32_gc    // 32768 / 32 = 1024 (sec) ~ 1 ms
      | RTC_RTCEN_bm                        // Enable: enabled 
      | RTC_RUNSTDBY_bm;                    // Run In Standby: enabled 
      RTC.INTFLAGS = RTC_OVF_bm;            // Clear flag by writing '1'
    Read more »

  • Timers, use the RTC to blink LED

    Sander van de Bor06/15/2019 at 04:16 0 comments

    In our world we use clocks to keep track of time and in the micro-controller world we use timers to count the clock. Clocks used in microcontrollers do not keep track of time!

    Timers on the micro-controller can be confusing and could be hard to understand but are so important for the microcontroller to operate. For example, when we like to flash a single LED every 500 millisecond, then we must keep track of time somehow. Almost every micro-controller out there has at least one or two timers, the ATtiny84a had 2, the ATtiny1616 has 4. But a timer will not count (the method to keep track of time) by itself. It needs an input, a source from something that pulses, called a clock. The most common clock is an oscillator and some microcontrollers have some build in. Most of the older controllers uses external oscillators for a better accuracy, for example the Arduino UNO has two:

    Fortunately, the ATtiny has internal oscillators that are sufficient for most project. The internal oscillator for the Attiny84a used to be calibrated for 8MHz, this new ATtiny1616 uses a 16/20 MHz low-power RC oscillator.

    These clocks are used as an input to the timers and currently configured as follows (taken from the Atmel Start application):  

    On the left you see the different oscillators, where the 3 options in the middle (20MHz, 16MHz and 32KHz) are internal and the other two external. In the middle are the sources, where the clock can be manipulated before getting used. For example, the Main Clock can be divided by 2 which will result in a 10MHz source for peripherals on the right (and the CPU will run only at half the speed). Running the CPU at a slower speed can help to reduce the power consumption.

    Under components you see the actual timers used by the micro-controller, and if you are paying attention you might notice that there are 5 timers listed, not 4 I mentioned above. It gets even more complicated! According to the ATtiny1616 spec sheet there are 4 timers: Timer/Counter Type A (TCA0), Timer/Counter Type B (TCB0 and TCB1), and the fourth Timer/Counter Type D (TCD0). TCD0 is actually listed under sources, probably because it is always active while the other components could be turned off (and they do not appear on the picture above).

    The WDT is the Watch Dog Timer. Yes, it is a timer, but cannot be used to execute some code on the ATtiny1616. The WDT can only be used to reset the microcontroller when it gets stuck in some code (an infinite loop).

    RTC is the real time counter. It is not a timer, it is a time counter. To be honest that confuses the heck out of me as well. The RTC is actually a great counter which you will appreciate for your low power consumption projects. On the older ATtiny’s the WDT could be used to wake-up the micro-controller, but that is not longer an option on the ATtiny1616; it is done with the RTC.

    You can see above that almost all the timers use the 20MHz oscillator. The 20MHz is accurate (±2%), but will use some power to run it. The RTC and WDT are using the 32.768 kHz (note it can be written as 32Khz as well which is 32khz*1024), which is slow and not so accurate (±10% when not calibrated), but the power consumption is very low! It is also a timer which is probably not going to be used by anything else on the Arduino, so it will be available without any interference with other existing code.

    In this example I am going to demonstrate how to use RTC to blink an LED, the “hello world” of the Arduino. I will introduce some new instructions which can be used.

    We probably all know how to make an LED blink in Arduino, there is even an example in the IDE called blink:

    void setup() {
      pinMode(LED_BUILTIN, OUTPUT);
    void loop() {
    Read more »

  • New method for writting registers on the 0- and 1-series

    Sander van de Bor06/08/2019 at 05:21 0 comments

    Arduino uses a lot of functions and macros to make it easier for an end-user, with some minor programming and no micro-controller experience, to develop a sketch. Without using these functions, but still using macros, a program for the ATMEGA328P will look like this:

    int main(void) {
      DDRB |= (1 << 2);
      while (1) {
        PORTB |= (1 << 2);
        PORTB &= ~(1 << 2);
      return 0;

    DDRB and PORTB are both macros and are referring to a register on the ATMEGA328P.

    This example above sets PB2 as an output and toggles it on and off. Read by someone experienced in C or C++, but with no experience with the AVR, this code will probably not make any sense. What is DDRB, and why do we write a value to PORTB?

    DDRB and PORTB are macro’s and converted by the preprocessor to a register address. DDRB is address 0x04 and PORTB is 0x05. See page#100 of the datasheet for more information:

    But why use macro names that are so hard to understand. Often I hear that a good written code does not need any comments since the variables should be clear to understand.

    Here comes the beauty of these new 0- and 1-series micro-controllers where almost every register and every variable going into those registers has a label or name that makes more sense. You can find all of these labels in the C:\Users\username\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino5\avr\include\avr folder and just compare IOM4809.IO (229KB for ATMEGA4809) vs iom328p.h (20KB for ATMEGA328P). Here is a simple example of the same code above for the ATtiny1616:

    int main(void)
      PORTB.DIRSET= PIN2_bm;
      While (1) {
          PORTB.OUTSET = PIN2_bm;
          PORTB.OUTCLR = PIN2_bm;    

    It is a little bit easier to read. DIRSET set the direction of PIN2 of PORTB followed by setting and clearing the output with OUTSET and OUTCLR using PIN#2 bitmask.  

    See this blog for some more information:  

    Everything we do on the micro-controller is done by setting bits in registers. As you can see above you can shift bits in and out or use macros. Macros are not slowing down your code or increasing your compiled code, because the values for the macros replaced in your code by the preprocessor before it will be compiled. These macros are getting very helpful when you work with the registers for peripherals.

    The addresses of registers for peripherals can be found in the datasheet for the ATtiny1616 on page#44 (

    You will see the base address in the first column and a description in the second. This is just a base address, a lot more registers for these peripherals after this base address could be reserved to store data, for example PORTMUX has a base of 0x0200. Going to page#138 shows the registers following this PORTMUX baseline of 0x0200 and the needed offset. For example, CTRLB has an offset of 0x01, so it has the address of 0x0200 + 0x01 = 0x0201.

    In this register you can set the alternative pin locations for SPI0 and USART0. Just shifting in a bit to turn on the first bit will activate USART0 on the alternative pin. Instead if using bit shifts, there are actually macros created for each possible combination, which will result in the following code:

    PORTMUX.CTRLB|= PORTMUX_USART0_DEFAULT_gc; // does this -> (0x0200 + 0x01 |= (0x00<<0) 

    I recommend looking at the log of Simon’s project  since it has some other great examples of how to use the macros on this new 0- and 1-series AVR’s as well:

    Read more »

  • PORTMUX on the 0- and 1- series explained

    Sander van de Bor06/08/2019 at 03:34 1 comment

    Grocery shopping was easy where I grew up. The store was small, and the options limited. Need milk, you grab a carton, tea did not have thousands of different flavors and beer was just a Pilsener. Today is different and you can spend hours in the store since there are too many options, just like the peripherals on these new micro-controllers.

    The ATMEGA328P used in the Arduino UNO is pretty good controller and suit most of my projects. It has some nice peripherals to other devices as you can see in the picture below:

    You can create an SPI connection with pins PB2 to PB5 (SS, MOSI, MISO and SCK). Have a “serial” (UART) connection with PD0 (RXD) and PD1 (TXD) and create a wire connection with PC4 (SDA) and PC5 (SCL). All the analog inputs are on PC0 (ADCx) up to PC5, but there is also a conflict since PC4 and PC5 were used for wire already. So, when you use wire, you basically only have ADC0 up ADC3 left for analog inputs since the others (ADC4 and ADC5) are used.

    The more advanced 32 bits micro-controllers like the SAMD21G18A, used on the Arduino M0, has even more peripherals per pin. A pin could have up to 8 different peripherals and a conflict between pins is more common. Fortunately, unlike the ATMEGA328P, you can move certain peripherals around between certain pins when pins are used for something else. For example, with the issue above where we want to use all the analog input pins, there will be an option on more advanced micro-controllers to move the SDA and SCL pins to a different pins of even a PORT. This is all described in the PORT Function Multiplexing table and called PORTMUX. The ATMEGA4809 supports PORTMUX and so does the ATtiny1616. I will skip the more advanced micro-controllers and go straight to the ATtiny1616 since that has the easiest PORTMUX table I have worked with so far.

    The PORTMUX table can be found on page#16 (chapter 5) of the ATtiny1616 datasheet:

    For our ATtiny1616 break-out board we want at least all the 3 serial communication options (USART, SPI and TWI) and as many PWM (TCA) and analog input pins (ADC). The ATtiny1616 even supports 1 analog output (DAC)! The PORTMUX table mentioned above is added to the pins_arduino.h variant file for reference as wel (see:

    You will notice that the columns USART0, SPI0, TWI0, TCA0, TCBn and CCL have the same description on multiple pins. For example, MOSI is shown behind PA1 and PC1. That does not mean the ATtiny1616 support two individual SPI peripherals, you must pick one of the two. You might also notice that one is in typewriter font which means that it is the alternative pin location for that peripheral.

    Based on this table I was able to update the ASCII board lay-out from my previous log:

                      VDD   1|*    |20  GND
     (nSS)  (AIN4) PA4  0~  2|     |19  16~ PA3 (AIN3)(EXTCLK)
            (AIN5) PA5  1~  3|     |18  15  PA2 (AIN2)(MISO)
     (DAC)  (AIN6) PA6  2   4|     |17  14  PA1 (AIN1)(MOSI)
            (AIN7) PA7  3   5|     |16      PA0 (nRESET/UPDI)
            (AIN8) PB5  4   6|     |15  13  PC3
            (AIN9) PB4  5   7|     |14  12  PC2 
     (RXD) (TOSC1) PB3  6   8|     |13  11  PC1
     (TXD) (TOSC2) PB2  7~  9|     |12  10  PC0
     (SDA) (AIN10) PB1  8~ 10|_____|11   9~ PB0 (AIN11)(SCL)

    For now I just picked all the standard locations, but I might move the SPI pins to PC0 to PC3 or use the ADC1 in the future since those pin in PORTC are available and not really used for something else besides regular I/O. Using alternative pin locations requires register changes which I will describe in another log. The following changes are made to the pins_arduino.h with the following settings for all Serial communication:

    #define SPI_MUX              (PORTMUX_SPI0_DEFAULT_gc)
    #define PIN_SPI_MISO    (15)
    Read more »

  • Adding a custom board to Arduino, setting up I/O

    Sander van de Bor06/06/2019 at 00:32 3 comments

    Most of us start off with the Arduino UNO, but after a while you might try out more advanced boards, or boards from other suppliers, and you must add these board to the board manager. You might end up like me with an endless long list of boards. Adafruit boards, ESP32 and ESP8266, ATtinyCore etc.

    I will not go into details how these are created, but when you are interested in the process and want to learn more, there is a good description in the wiki section of the Arduino Github page:

    I have done multiple custom boards before. Added the Micronucleus bootloader to SpenceKonde ATTinyCore; created custom M0+ board and my latest was a custom board with an ATSAME54N20A based on the Metro M4 from Adafruit. So adding a custom variant to MegaAvr should be a piece of cake, at least that was what I thought.

    Each board in the board manager has a variant file where mainly all Arduino related naming is linked to a pin, timer, output etc. by mainly using macros. At least, it used to be like that. The MegaAvr variant file still contains a lot of macro’s, but some information is actually stored in the flash memory if the micro-controller. Something new to get used to. The files in the variants folder are named different as well and do contain some additional information. All this information is spread over the following file which you can find in the variants folder for the Arduino Uno WiFi Rev2 and Arduino Nano Every:

    • pins_arduino.h
    • timers.h
    • variant.c

    To be flat out honest with everybody, I don’t know where the timers.h is used for (something with time tracking, but isn’t that the Real Time Counter (RTC)?), and the variant.c is currently going over my head and need some more time to understand, so for today I will only focus on pin_arduino.h

    When you write to a pin number in Arduino, you are actually setting a bit in a so called PORT. Each PORT is a register, and the length of that register is determined by the type of micro-controller you are using. For example the Arduino UNO is 8 bits, so each PORT controls 8 I/O pins. Since the ATMEGA328P, the micro-controller used on the Arduino UNO, has 23 I/O pins it needs at least 3 registers to control all of these. PORTB controlling 8 I/O pins, PORTC 7, and PORTD 8. You are probably wondering what happened to PORTA. I do not know, but I am sure Atmel at that time had a good reason to start at PORTB, probably because it is sharing the same architecture with other (larger) controllers where PORTA was required for additional I/O pins. While most 32 bits micro-controller have more I/O pins, they require less PORTS since each port can control 32 I/O pins. For example the ATSAMD21G18A, used on the M0, has 38 I/O pins, but only 2 PORTS.

    So each PORT is identified by an alphabetic letter and each pin with a number, starting at 0, which will result in pin identifications like PB5, PORTB pin number 5 (keep in mind this is the sixth pin). This concept is important to understand when we start working with the pin_arduino.h file.

    We will use the pin_arduino.h located in the C:\Users\username\AppData\Local\Arduino15\packages\arduino\hardware\megaavr\1.8.1\variants

    The code start as follows:

    #ifndef Pins_Arduino_h
    #define Pins_Arduino_h
    #include <avr/pgmspace.h>
    #include "timers.h"
    #define NUM_DIGITAL_PINS            22 // (14 on digital headers + 8 on analog headers)
    #define NUM_ANALOG_INPUTS           14
    #define NUM_RESERVED_PINS           6  // (TOSC1/2, VREF, RESET, DEBUG USART Rx/Tx)
    #define NUM_INTERNALLY_USED_PINS    10 // (2 x Chip select + 2 x UART + 4 x IO + LED_BUILTIN + 1 unused pin)
    #define NUM_I2C_PINS                2  // (SDA / SCL)
    #define NUM_SPI_PINS                3  // (MISO / MOSI / SCK)
    #define ANALOG_INPUT_OFFSET...
    Read more »

  • Preparing Arduino IDE to write sketches for the ATtiny 0- and 1-series

    Sander van de Bor06/04/2019 at 01:36 1 comment

    Arduino is a great tool for makers and hobbyists to develop code for tons of different micro-controllers. For the user the code always looks very similar and most code can be compiled for different devices. But in order to make this all happen a lot is happening behind the scenes of Arduino, and a lot of different parties are involved.

    Different “translations” are done from the sketch in Arduino to the actual machine code which will be uploaded to the micro-controller. The language the micro-controller is speaking differs for each controller and must be provided by the manufacturer. In this case the ATtiny 0- and 1-series are provided by Microchip and Microchip provides the language in a so-called Device Family Pack (DFP).

    When you compile a sketch in Arduino with verbose output turned on (in settings) you will get the location of the compiler and the DFP in the Arduino IDE output window. For example, when you compile a sketch for the Arduino UNO you might see lines like:


    When you browse to that folder it will show all the different devices that are similar to the micro-controller used on the Arduino UNO (ATMEGA328P), with a complete list shown in the folder device-specs. The files in the device-specs folder are loaded, specific for the micro-controller, to tell the compiler where to find libraries for this device.  

    Some might notice that the ATtiny1616 is part of the list. Adding the ATtiny 0- and 1-series DFP to Arduino was requested a couple of months ago and they were so kind to make it standard in the latest releases. But just updating the DFP with new packages will not always do the trick. Sometimes new functions are added, and these must be understood by the translator, in this case the compiler.

    Arduino is using avr-gcc compiler for the 8-bit microcontrollers. Version 5.4.0 was sufficient for micro-controllers like the ATMEGA328P and the ATtiny series like the ATtiny85 and ATtiny84a. Unfortunately, this compiler version had issues with the new DFP for the 0- and 1-series and a newer compiler version is required (and available).

    While the DFP is provided by the manufacturer of the chip, the actual Arduino Core is developed by the Arduino team. It is a collection of libraries which are used to translate the language spoken in Arduino to commands or write to registers described in the DFP. For example, we are all familiar with the delay function. On the Arduino UNO the following function is used (all in the background, so you probably did not even know you were calling out functions):

    void delay(unsigned long ms)
        uint32_t start = micros();
        while (ms > 0) {
            while ( ms > 0 && (micros() - start) >= 1000) {
                start += 1000;

    Unfortunately, this will not work for the new ATtiny 0- and 1-series, a new core is required.

    Luckily enough the Arduino team did come out with a new core and compiler when they released the Arduino UNO WIFI REV2. This new device is using the ATMEGA4809, part of the megaAVR 0-Series, and in the same family as the ATtiny 0- and 1-series. You can see the changes by adding the board from the board manager and just compile an empty sketch with the Arduino Uno WiFi Rev2 board selected. You will notice that the avr-gcc version 7.3.0 is used. The Arduino core is different too, for example the function for delay is now as follows:

    void delay(unsigned long ms)
        uint32_t start_time = micros(), delay_time = 1000*ms;
        /* Calculate future time to return */
        uint32_t return_time = start_time + delay_time;
        /* If return time overflows */
        if(return_time < delay_time){
            /* Wait until micros overflows */
            while(micros() > return_time);
        /* Wait until return time */
        while(micros() < return_time);

    With the Arduino core, compiler and DFP in place it should be pretty straight forward to make a variant...

    Read more »

  • DIP version of ATtiny1616

    Sander van de Bor06/02/2019 at 18:30 0 comments

    SMD components are getting more popular. They are easy to assemble in production and they get small, very small! Unfortunately with the rise of SMD the through hole version, the Dual In-line Package (DIP), is no longer available for newer micro-controllers and break-out boards are needed to use these on the breadboard.

    The ATtiny1616 is available in two packages, the 20-Pin SOIC and the 20-Pin VQFN. For the 20-Pin SOIC there are some break-out boards widely available, for example:

    While the SOIC works great, it is relatively large. Instead, the VQFN version is only 3x3MM and allows some additional features which can be added to a custom break-out board for the ATtiny1616.

    Since this micro-controller has a build in 20MHz oscillator and will run between 1.8V to 5.5V, there is no need for almost any additional components. A bypass capacitor is recommended between GND and VCC for the microelectronic and a 4.7K Ohm resistor from the programmer to the UPDI pin. The actual pin out position will match the SOIC and see here the results:

    Schematic is available in the files section of this project.

    Next step is preparing the Arduino IDE to compile sketches.

  • Uploading sketches to the ATtiny1616

    Sander van de Bor06/02/2019 at 04:35 0 comments

      The ATtiny micron-controllers are very popular in the makers community. Only a single capacitor is recommended to stabilize the incoming power and different power sources between 1.8V to 5.5V can be used. The 8MHz internal oscillator will work for most projects and at a cost of about $1 for the DIP version it can be integrated into a project for a fraction of a full blown Arduino UNO.

      In order to program micro-controllers programmers are used and offered by the manufactures from these chips. The cost of these programmers start around $50 and can go up to a couple hundreds of dollars. While these programmers are great, and excellent for debugging as well, it is a cost that most makers are not willing to spend. Fortunately the Arduino platform offered a solution where the Arduino UNO can be programmed with a sketch to operate as an SPI programmer.  Using the MOSI, MISO, SCK and reset lines allowed uploading sketches through the Arduino UNO to the ATtiny-AVR.

      The new ATtiny1616 is a little bit different, and the SPI programmer for the ATtiny-AVR will no longer work. These so called tinyAVR® 1-Series, and similar to the tinyAVR® 0-Series and the megaAVR® 0-series, are using the UPDI 1-wire interface. This new protocol sound very promising since it only requires 1 pin to communicate instead of the 4 pins for SPI and fortunately an Arduino is already there!

      El Tangas created a great solution (which can be used on the Arduino UNO) to turn most common Arduino devices into UPDI programmers. The code can be found on Github;

      While a like using the Arduino UNO (I have done all my ATtiny84a projects with the UNO) it is often bulky and requires a lot of wires. An alternative solution is upgrading a AVR JTAG ICE clone with new firmware per following instructions:

      The 10 pin ribbon cable is great, because you can press 1.02 diameter pogo pins into the end.

      It is very similar to the SEGGER pin needle adapters used for programming, but only at a fraction of the cost. While El Tangas shows connecting pin#2 to GND pin#4 for VCC and #6 for UPDI, I decided to use pin #10 for ground instead for the following reasons:

      1. The DIP break out board for the ATtiny1616 must fit on the bread board, and the VCC and GND need 4 pins spacing between each other, which I get by having VCC on pin #4 and GND on pin #10
      2. Having the 3 pins separated by an empty pin generates a key so that connecting it to the board will only fit one way (originally the 3 pins were next to each other, so VCC and GND could easily be swapped.

      Here is a picture of how this is applied to the board:

      With the pogo pins it is even possible to connect when header pins are applied:

      Next will be the design of the break-out board.

View all 8 project logs

Enjoy this project?



Alan Green wrote 06/05/2019 at 06:02 point

I've been using the 3217 extensively for the last few months, so much so that I gave Blue Board #01 the appropriate 24-pin VQFN footprint. I have also been using the 1616, 416 and 404. In my case, I've been using an Atmel ICE (left over from a previous project). I'm also planning to get hold of the $15 MPLAB Snap programmer.

With regards to the reset pin: the factory default configuration allows the reset pin to be used for programming without any further configuration.

Like Simon, I'm very much looking forward to hearing how you got the Arduino bootloader and environment going!

  Are you sure? yes | no

Sander van de Bor wrote 06/06/2019 at 03:16 point

I was actually looking at the MPLAB PICkit 4 because creating the Arduino core without some proper debugging tools is very challenging, but fortunately I have Serial working now and I am able to get some feedback. I was not aware of the MPLAB Snap programmer, that sound like an even better deal!

  Are you sure? yes | no

Simon Merrett wrote 06/03/2019 at 13:30 point

This is great! I'm not as skilled as you on getting the core running for the ATtiny 0 and 1 series, so I'll be paying close attention. Let me know if I can contribute in any way. You can see what I've been playing with at #ATtiny 0 Series programming on the cheap  

  Are you sure? yes | no

Sander van de Bor wrote 06/03/2019 at 14:22 point

Looks like the core is going to be pretty easy since most of the work is done for the Arduino Uno Wifi v2 and the new Arduino Nano Every. I like your ATtiny 0 series. There is not a lot of documentation out there yet, so any bit of information others can share is nice. Looks like you use the Nano as UPDI programmer? Did you have to disable the reset pin in order for it to work? You might have mentioned it in one of the logs, but haven't read it all yet.

  Are you sure? yes | no

Simon Merrett wrote 06/03/2019 at 16:22 point

I do use the Nano as the UPDI programmer. I don't recall having to change anything from the default jtag2updi repository regarding reset pin. One thing I tried a couple of times but gave up on was editing the baud rates to get jtag2updi running on a 3.3V pro mini. I thought that would be a useful  thing to program low voltage systems but they're not something I've needed yet, so haven't persevered with that hardware configuration. 

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates