Skip to content

4. Embedded Programming

This week i took a look at the ATtiny85 microcontroller by first inspecting its datasheet and then programming and simulating it via Wokwi. I then once again teamed up with Anna, Kerstin and Lars, the other students from HRW FabLab, to compare its toolchains and development workflows to the ones for different microcontrollers. You can find our group work page right here

ATtiny85

Atmel’s tiny85 is an 8-bit microcontroller based on the RISC (Reduced Instrucion Set Computing) architecture, designed to be used in embedded systems. It is most commonly used for sensor data acquisition, motor control and audio processing. The ATtiny85 shares its layout and size with the tiny25 and tiny45 microcontrollers but is the largest of the three in terms of programmable memory, EEPROM and SRAM.

There are “V” variants of these controllers that can safely operate at as low as 1.8V instead of 2.7V but in turn have a lower maximum clockspeed, 10MHz instead of 20MHz. These variants are useful for projects that are powered by regular AA or AAA batteries but will not be as performant.

All of them feature 6 programmable Input/Output pins, 4 of which support analog to digital conversion.

These infos barely scratch the surface of the 230 page datasheet from which i took them. You can download it at the bottom of this page. In there you will find documentation of the inner workings of the controllers, their technical drawings and code examples in Assembly and C.

Programming the ATtiny85 works either directly via Assembly or in any integrated development envirnment that supports C or Python. After installing a few necessary libraries and drivers, which you can read more about on our group page, you can even program it in the Arduino IDE.

Simulating the ATtiny85 in Wokwi

Part of this week’s assignment revolves around the simulation of code for interaction and communication with our microcontroller of choice so i headed over to WOKWI. At first i was kind of confused because i did not see the ATtiny85 anywhere but later found out that it was listed in the “Start from Scratch” section of the Arduino page.

  • your browser should show something like This

  • on the left you will find the code that drives your circuit and on the right the whole thing will be simulated

  • click on the blue plus icon to see all the components you can add to the circuit

  • to start off simple i added an LED, a resistor and a push button

  • click on the component in the simulation window to see the settings bar where you can change its values or orientation

  • also check out the ? icon next to the component or in the settings bar to see Wokwi’s documentation page for that part

  • one thing i found strange was that Wokwi assumes that your cicuit is powered correctly by default because there seem to be no powersupplies or batteries in the parts list

  • this is all fine while we stay in the simulation(definitely not a Matrix reference) but as soon as we try to build the real thing there are going to be some problems with that

  • out of this exact reason i included a resistor in order to not blow up the LED

  • Digikey provides a really helpful Resistor Calculator if you are unsure what kind of resistor you should use

  • let’s assume that the ATtiny85 is powered with 5V

  • we are using a red LED so we can expect a forward voltage (amount of voltage needed to get current to flow across a diode) of 2V

  • the recommended forward current is usually listed in the LED’s datasheet but for now 10mA should be a good starting point

  • this gives us a value of 300Ω for our resistor

  • Digikey actually suggests using a resisor with anywhere between 2 and 10 times that resistance to avoid excessive temperatures, so 600Ω it is

  • Wokwi’s ATtiny85 Reference has a list of all the controller’s pins and their functions

  • with that i was able to build my fist little circuit

  • you may have noticed that there is a 10kΩ resistor connecting the button to VCC a.k.a positive voltage

  • this is a so called pull-up resistor, meaning it tells the button’s I/O pin that when the button is not pressed it shall be considered as a logical 1 instead of “floating” and possibly causing unpredicted behavior due to electrical noise

  • here is a great article that helped me understand the situation

  • the following code lets me toggle the LED on or off when pressing the button

#define BTN PB4
#define LED PB5

void setup() {
  // put your setup code here, to run once:
  pinMode(BTN, INPUT);
  pinMode(LED, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (!digitalRead(BTN)) {
    digitalWrite(LED, !digitalRead(LED));
    delay(500);
  }
}
  • first i defined easier to remember variable names for the I/O pins

  • as the comments in the code suggest, the setup part is used for global settings such as defining that the I/O pins PB4 and PB5 (here BTN and LED) shall be used as an input and an output pin respectively

  • the loop part should be pretty self explanatory, all the code written inside it will be repeated indefinitely

  • digitalRead(BTN) returns the button’s current state

  • since it is always considered as a logical 1 due to the pull-ip resisor when not pressed i had to negate the expression by adding ! in front of it

  • digitalWrite(LED, !digitalRead(LED)) essentially flips the LED pin’s state when called

  • delay(500) pauses the program for half a second after it has been called to prevent any weirdness happening when pressing the button for too long

  • just for fun i got rid of the button and rewrote the code to get the classic blinking LED example

#define LED PB4

void setup() {
  // put your setup code here, to run once:
  pinMode(LED, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(LED, HIGH);
  delay(1000);
  digitalWrite(LED, LOW);
  delay(1000);
}
  • next let’s try setting up serial communication, this can be useful for debugging

  • i added another LED and a potentiometer to my circuit

  • the ATtiny85 does not have hardware support for serial communication but according to this Wokwi Docs page we can use the SoftwareSerial library to emulate it

  • following what was written in the docs i headed into the diagram.json file in the top left corner and add the following lines to the connections section:

  [ "tiny:PB0", "$serialMonitor:TX", "" ],
  [ "tiny:PB1", "$serialMonitor:RX", "" ],
  • to enable the serial monitor i then added the following code to the end:

"serialMonitor": { "display": "terminal", "newline": "lf", "convertEol": false }

  • my diagram.json file now looks like This
{
  "version": 1,
  "author": "asdasd",
  "editor": "wokwi",
  "parts": [
    { "type": "wokwi-attiny85", "id": "tiny", "top": -10.8, "left": -196, "attrs": {} },
    {
      "type": "wokwi-resistor",
      "id": "r1",
      "top": -72,
      "left": -173.35,
      "rotate": 90,
      "attrs": { "value": "600" }
    },
    {
      "type": "wokwi-resistor",
      "id": "r2",
      "top": -72,
      "left": -202.15,
      "rotate": 90,
      "attrs": { "value": "600" }
    },
    {
      "type": "wokwi-led",
      "id": "led1",
      "top": -157.2,
      "left": -197.8,
      "attrs": { "color": "red" }
    },
    {
      "type": "wokwi-led",
      "id": "led2",
      "top": -157.2,
      "left": -169,
      "attrs": { "color": "green" }
    },
    { "type": "wokwi-potentiometer", "id": "pot1", "top": -126.1, "left": -317, "attrs": {} }
  ],
  "connections": [
    [ "tiny:PB0", "$serialMonitor:TX", "", [] ],
    [ "tiny:PB1", "$serialMonitor:RX", "", [] ],
    [ "r2:1", "led1:A", "red", [ "h0" ] ],
    [ "r1:1", "led2:A", "red", [ "h0" ] ],
    [ "led2:C", "tiny:GND", "black", [ "v9.6", "h29.2", "v134.4", "h-37.2" ] ],
    [ "led1:C", "led2:C", "black", [ "v9.6", "h0.4" ] ],
    [ "tiny:VCC", "pot1:VCC", "red", [ "v-8.4", "h-76.8" ] ],
    [ "pot1:GND", "tiny:GND", "black", [ "v86.4", "h124.8" ] ],
    [ "r1:2", "tiny:PB4", "red", [ "h38.4", "v94.8", "h-67.2" ] ],
    [ "tiny:PB0", "tiny:PB1", "magenta", [ "h-1.2", "v-8.4", "h-9.6" ] ],
    [ "tiny:PB5", "r2:2", "red", [ "v28.8", "h76.8", "v-76.8", "h-57.6" ] ],
    [ "tiny:PB3", "pot1:SIG", "gold", [ "v19.2", "h-29.2" ] ]
  ],
  "serialMonitor": { "display": "always", "newline": "lf", "convertEol": false },
  "dependencies": {}
}
  • after that i went back into the sketch.ino file where i changed the code to
#include <SoftwareSerial.h>
SoftwareSerial Serial(PB0, PB1);

#define GREEN PB4
#define RED PB5
#define POT PB3

void setup() {
  Serial.begin(9600);
  pinMode(RED, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(POT, INPUT);
}

void loop() {
  Serial.print("POT:");
  Serial.println(analogRead(POT));

if(analogRead(POT)<=512){
  Serial.print("Delay:");
  Serial.println((1024-analogRead(POT))/2);
  digitalWrite(GREEN, LOW);
  digitalWrite(RED, HIGH);
  delay((1024-analogRead(POT))/2);
  digitalWrite(RED, LOW);
  delay((1024-analogRead(POT))/2);
}
else{
  Serial.print("Delay:");
  Serial.println(analogRead(POT)/2);
  digitalWrite(RED, LOW);
  digitalWrite(GREEN, HIGH);
  delay(analogRead(POT)/2);
  digitalWrite(GREEN, LOW);
  delay(analogRead(POT)/2);
}
}
  • first i had to include the SoftwareSerial library and set up the corresponding pins (PB0 and PB1)

  • then i defined new names for the LED and potentiometer pins

  • in the setup section i started the serial communication with a baudrate of 9600 which is hard coded in the simulator and configured the other I/O pins

  • the loop section looks kind of messy but i can explain…

  • Serial.print and Serial.println are used to display text and values in the serial monitor

  • digitalWrite as usual is used to turn the LEDs on or off

  • analogRead returns the current value of the potentiometer

  • as stated in the datasheet, the ATtiny85 features 10-bit analog to digital converters for its pins so the potentiometer’s range goes from 0 to 1023

  • the if logic checks to which side the potentiometer is turned and lets the corresponding LED blink with a delay depending on the analog value

  • the further the potentiometer is turned towards the middle, the faster the LED flashes until the center is reached and it completely switches to the other LED

Downloads

ATtiny85_Datasheet.pdf