Week 08: Embedded programming

Overview

For this assignment I will use a board that I call MidTiny, it is an ATtiny board with all of its pins exposed and it also has an integrated button and LED.

The ATtiny1614 is a microcontroller featuring the 8-bit AVR® processor with hardware multiplier, running at up to 20 MHz and with 16 KB Flash, 2 KB SRAM and 128B of EEPROM in a 14-pin package.

Because the ATtiny1614 has an AVR processor it can be programmed using the standard AVR tools, but it is also possible to program it as if it were an Arduino, thanks to Spence Konde and the "megaTinyCore" library which is an Arduino Core for the tinyAVR 0-series and 1-series chips.

The megaTinyCore library relates the pins of the microcontroller with a pin number just like an Arduino, as this facilitates the programming process and frees the programmer from thinking if the pin corresponds to the PORTA or PORTB etc.

The following image illustrates the ATtiny1614 microcontroller, the pins of the microcontroller, its equivalent in Arduino and the functionalities or actions associated with each pin.

The datasheet of the ATtiny1614 microcontroller can be found at this link

From the datasheet an important image to program the pins of the microcontroller is the following one showing the pins to be programmed.

A very useful link is this which contains information on how to program AVR architecture microcontrollers in C.

Blink - Arduino Code

The following Arduino program blinks the LED that is connected to the PA5 pin of the microcontroller, that pin corresponds to pin 1 in the megaTinyCore library.

                        
                           /*
                           * Blink program
                           * An arduino program that blink the led 
                           * connected to pin 1/PA5 of the MidTiny board (ATtiny1614).
                           * 
                           * Author: Harley Lara
                           * Create: 03 May 2021
                           * License: (CC BY-SA 4.0) Attribution-ShareAlike 4.0 International
                           * 
                           * This work may be reproduced, modified, distributed,
                           * performed, and displayed for any purpose, but must
                           * acknowledge this project. Copyright is retained and
                           * must be preserved. The work is provided as is; no
                           * warranty is provided, and users accept all liability.
                           * 
                           */
                           
                           #define LED 1 // Define LED pin
                           #define DELAY 500 // Define waiting time
                           
                           void setup() {
                               pinMode(LED, OUTPUT); // Define the led port as output.
                           }
                           
                           void loop() {
                               digitalWrite(LED, HIGH); // LED ON
                               delay(DELAY); // Wait half a second
                               digitalWrite(LED, LOW); //LED OFF
                               delay(DELAY); // Wait half a second
                           }                       
                        
                     

The code is quite simple, it starts by defining LED 1 which corresponds to the pin to which the pcb LED is connected, it also defines DELAY 500, which corresponds to 500ms of blinking.

In the setup() section we define with pinMode() the LED port as output.

The loop() section is the function that is repeated indefinitely and contains the code that turns the LED on and off. To turn on the LED the pin must be high, that is achieved with the digitalWrite() function, that function is given as argument the pin we want to write and the value we want to write.

The following instruction simply waits 500ms and then passes to the next one.

Blink - C code 01

It is also possible to program the ATtiny microcontrollers using C, in this section I made the same program above with its C equivalent.

                        
                           #define F_CPU 3333333 
                           #include <avr/io.h>
                           #include <util/delay.h>
                           
                           #define LED PIN5_bm // Define LED pin
                           #define DELAY 500 // Define waiting time
                           
                           int main(){
                           
                               PORTA.DIR |= LED; // Define the led port as output
                           
                               while(true){
                                   PORTA.OUT |= LED; // LED ON
                                   _delay_ms(DELAY); // Wait half a second
                           
                                   PORTA.OUT &= ~LED; //LED OFF
                                   _delay_ms(DELAY); // Wait half a second
                               }
                           
                               return 0;
                           }
                        
                     

To use C functions to program the board it is necessary to include the avr/io.h library that contains all the definitions to work with I/O in AVR processors. The next library that needs to be added is util/delay.h which allows to use delay functions, but for the delay time to be interpreted correctly it is necessary to define the clock speed, this is achieved with #define F_CU 3333333 this number represents the clock speed divided by 6.

As in the arduino code the pin to which the LED is connected is defined with the difference that in the code pin 1 is used but this time it is necessary to use the microcontroller pin, which corresponds to PIN 5 of the PORTA.

In C there is a main function called main() which is the entry point of the program.

The next instruction defines the LED pin as the output.

For the program to continue indefinitely and not terminate after executing all the instructions it is necessary to add the while(true) function that keeps the loop executing.

To activate the LED it is necessary to define the output port to which the pin to be activated corresponds.

The delay function simply waits 500ms.

The next instruction that makes use of "&= ~" turn off the LED.

Blink - C code 02

The above C code works very well but it can be a bit more efficient if you use an assignment that reverses the state of the LED, this works like a state toggle. Using that we can reduce the task of blinking the LED to just 2 lines of code.

                     
                        /*
                        * Blink program
                        * An C program that blink the led 
                        * connected to PA5 of the MidTiny board (ATtiny1614).
                        * 
                        * Author: Harley Lara
                        * Create: 03 May 2021
                        * License: (CC BY-SA 4.0) Attribution-ShareAlike 4.0 International
                        * 
                        * This work may be reproduced, modified, distributed,
                        * performed, and displayed for any purpose, but must
                        * acknowledge this project. Copyright is retained and
                        * must be preserved. The work is provided as is; no
                        * warranty is provided, and users accept all liability.
                        * 
                        */
                        
                        #define F_CPU 3333333 
                        #include <avr/io.h>
                        #include <util/delay.h>
                        
                        #define LED PIN5_bm // Define LED pin
                        #define DELAY 500 // Define waiting time
                        
                        int main(){
                        
                            PORTA.DIR |= LED; // Define the led port as output
                        
                            while(true){
                            PORTA.OUT ^= LED; // LED toggle ON/OFF
                            _delay_ms(DELAY); // Wait half a second
                            }
                        
                            return 0;
                        }
                     
                    
Button - C code

The following C program activates the LED when the button connected to pin PA4 (equivalent to pin 0 in arduino) is pressed.

                     
                        /*
                        * Button pressed LED ON
                        * A C program that activates the LED connected 
                        * to the PA5 pin when pressing the button 
                        * connected to the PA4 pin of the MidTiny board (Base ATtiny1614).
                        *
                        * Author: Harley Lara
                        * Create: 03 May 2021
                        * License: (CC BY-SA 4.0) Attribution-ShareAlike 4.0 International
                        *
                        * This work may be reproduced, modified, distributed,
                        * performed, and displayed for any purpose, but must
                        * acknowledge this project. Copyright is retained and
                        * must be preserved. The work is provided as is; no
                        * warranty is provided, and users accept all liability.
                        */
                        
                        #define F_CPU 3333333
                        #include <avr/io.h>
                        #include <util/delay.h>
                        
                        #define LED PIN5_bm // Define LED pin
                        #define BUTTON PIN4_bm // Define BUTTON pin
                        
                        int main() {
                        
                            PORTA.DIR |= LED; // Define the LED port as output
                            PORTA.OUT &= ~LED; // Set the initial state of the LED OFF
                        
                            PORTA.DIR &= ~BUTTON; // Define the button port as input
                            PORTA.PIN4CTRL = 0; // Don't use the internal pullup resistor
                        
                            while (true) {
                            _delay_ms(10); // Wait
                            if (PORTA.IN & BUTTON) // If the button is pressed
                            {
                                PORTA.OUT ^= LED; // LED toggle ON/OFF
                            } else {
                                PORTA.OUT &= ~LED; // If the button is not pressed set LED OFF
                            }
                            }
                        
                            return 0;
                        }
                        
                    
Latch and Debounce

The following code implements debounce to avoid rapid state changes and Latching to maintain the previous state.

                     
                        /*
                     Blink program
                     Latch and Debounce for the MidTiny board (ATtiny1614).

                     Author: Harley Lara
                     Create: 03 May 2021
                     License: (CC BY-SA 4.0) Attribution-ShareAlike 4.0 International

                     This work may be reproduced, modified, distributed,
                     performed, and displayed for any purpose, but must
                     acknowledge this project. Copyright is retained and
                     must be preserved. The work is provided as is; no
                     warranty is provided, and users accept all liability.

                     */

                     #define F_CPU 3333333
                     #include <avr/io.h>
                     #include <util/delay.h>

                     #define LED PIN5_bm // Define LED pin
                     #define BUTTON PIN4_bm // Define BUTTON pin

                     // saves the latest status
                     //    false: released
                     //    true: pressed
                     bool last = false;

                     int push_level = 0;
                     int release_level = 0;
                     int threshold = 50;

                     int main() {

                     PORTA.DIR |= LED; // Define the LED port as output
                     PORTA.OUT &= ~LED; // Set the initial state of the LED OFF

                     PORTA.DIR &= ~BUTTON; // Define the button port as input
                     PORTA.PIN4CTRL = 0; // Don't use the internal pullup resistor

                     while (true) {
                        if (PORTA.IN & BUTTON) {
                           push_level ++;
                           release_level = 0;
                           if (push_level > threshold ){
                           if (last == false){
                              PORTA.OUT ^= LED; // LED toggle ON/OFF
                              last = true;
                           }
                           push_level = 0;
                           }
                        } 
                        else {
                           release_level ++;
                           push_level = 0;
                           if (release_level > threshold){
                           last = false;
                           release_level = 0;
                           }
                        }

                        _delay_ms(10);
                     }

                     return 0;
                     }
                     
                  
Group Assignment

For this section I will compare the performance of 3 boards corresponding to the ATtiny1614, Arduino UNO (ATMEGA328P), Arduino DUE (AT91SAM3X8E).

The code used is the same for all tests.

                        
                           /*
                           * pi.ino
                           * Neil Gershenfeld 12/20/20
                           * pi calculation benchmark
                           * pi = 3.14159265358979323846
                           */
                           
                           #define NPTS 100000
                           
                           float a,b,c,pi,dt,mflops;
                           unsigned long i,tstart,tend;
                           
                           void setup() {
                              Serial.begin(115200);
                              }
                           
                           void loop() {
                              tstart = millis();
                              a = 0.5;
                              b = 0.75;
                              c = 0.25;
                              pi = 0;
                              for (i = 1; i <= NPTS; ++i)
                                 pi += a/((i-b)*(i-c));
                              tend = millis();
                              dt = (tend-tstart)/1000.0;
                              mflops = NPTS*5.0/(dt*1e6);
                              Serial.print("NPTS = ");
                              Serial.print(NPTS);
                              Serial.print(" pi = ");
                              Serial.println(pi);
                              Serial.print("time = ");
                              Serial.print(dt);
                              Serial.print(" estimated MFlops = ");
                              Serial.println(mflops);
                           }
                        
                     

For the ATtiny1614 board the performance is as follows:

If we compare it with the previous generation (ATMEGA328P) we can see that the ATtiny1614 has an improvement in performance.

For the last test I used an Arduino DUE (AT91SAM3X8E) with a 32-bit ARM architecture. By default the library to program this board is not included in the Arduino IDE but it can be added very easily.

In the Arduino IDE go to the Tools -> Board: ... -> Boards Manager ... option.

Then in the search bar type "Arduino DUE" and the following result will appear, just click on install and that's it.

The result for the Arduino DUE board is as follows.

Indeed, it has better performance than the previous boards.

Link to the Group Assignment page

Softwares
Files
Blink Arduino
Blink C 01
Blink C 02
Button C
Latch and Debounce