ATtiny85 - Blink (76 bytes)

Zápisník experimentátora

Hierarchy: ATtiny85

A few years ago I wrote an article ATtiny85 - Blink. At that time I wrote a few examples and the smallest of the programs was 468 bytes long after compilation. Now we will show a program that behaves the same and has only 76 bytes. Let's make this blink using the ATtiny85 microcontroller.

The Blink program is the most basic program for the Arduino, where you will learn the basics of controlling the output pins of the microcontroller. An LED with a resistor is connected to the pin and this LED flashes at regular intervals.

Typical blink

For Arduino (and all the different clones), this program appears on thousands of pages in a virtually unchanged form, which is shown in the following example. For ATtiny85, you only need to make a change in the source code and set the output pin from number 13 to one of the pins that this miniature microcontroller contains. This is usually pin 0. A typical code is used in the program to control the output pin. The selected pin is set as the output and then the pin is constantly switched to HIGH or LOW and the function delay is used to wait a few milliseconds for the flashing to be visible. The source code, when compiled with IDE 1.8.12 and the ATTinyCore 1.1.5 core, is 880 bytes in size.

const int led = 0;
const int sleep = 1000;

// the setup routine runs once when you press reset:
void setup() {
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);

// the loop routine runs over and over again forever
void loop() {
  digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
  delay(sleep);            // wait for a second
  digitalWrite(led, LOW);  // turn the LED off by making the voltage LOW
  delay(sleep);            // wait for a second

Optimized blink

If we rewrite this code according to the following example, the program size will be 76 bytes after compilation. How did I achieve this? If you study the source code, you will see that it hardly resembles the original source code at all. The setup and loop functions have completely disappeared and been replaced by a single main function. But this seemingly small change has big consequences. By removing all ATTinyCore core functions from the source code, the compiler automatically reduced the size of the resulting code. The _delay_ms function is used, which is programmed as several instructions in the assembler. It is more economical than the commonly used delay function. It is only accurate up to 262 ms, then it automatically switches to a less accurate variant. This is sufficient for the purposes of our program.

The last important change is in the use of the main function. Our function replaces another function and completely disables the initial system registry initializations that are usually performed when Arduino starts. The result is code savings, but no register is set up, so be careful if you want to use some other functions that depend on the registry settings. An example of the original main function can be found in the following chapter.

#include <util/delay.h>

const int led = 0;
const int sleep = 1000;

int main() {
  // initialize the digital pin as an output.
  bitSet(DDRB, led);
  for (;;) {
    bitSet(PINB, led);

ATTinyCore function main

This is what the original main function in the ATTinyCore core looks like. Calls the init function, which performs many different registry settings. The tax for this, however, is an increase in the size of the resulting program after compilation.

#include <WProgram.h>

int main(void)

    for (;;)
    return 0;

Source code

The source code is located on the GitHub server.