Embedded Programming

The assigment page
The goal of this week was to program the Hello echo board.

Download the code

Microcontroller datasheet.

I've read Attiny44 summary documentation (26 pages).
So it's a "High Performance, Low Power AVR® 8-Bit Microcontroller". The pinout layout is very useful as the Pins Descriptions part:



I'd like to understand the Register Summary part, because I think it will be my futures problems' causes.
I have to admit that all those technicals infos, in english, are hard to understand for me who don't have scientific background. I think I have to come back to this doc for times to times, when my electronics knowledges will increase.

Flashing the board.
Assuming that you're board is brand-new, you can check is there's a communication between the microcontroller and your computer.
Take your FabISP, and plug your 6 pin cable into the 6 pin header. Plug the other side to your board.
Watch out that FabISP's pins connect to the correct one on the board:



The result once connected:



Now open your terminal and enter this command:
avrdude -c usbtiny -p t44

If the result is:
avrdude: AVR device initialized and ready to accept instructions

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

avrdude: Device signature = 0x1e9207 (probably t44)

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

avrdude done. Thank you.


Good for you! Your board can't wait to be flash!

If you're not using an attiny44 like me, don't forget to change it in the command. For exemple for an attiny84:
avrdude -c usbtiny -p t84

Arduino
Download Arduino IDE.

Once Arduino IDE is open, go to File -> Preferences.

Put this URL in the Additional Boards Manager URLs box:
https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json

Now Tools -> Board -> Board Manager. A windows appears, type attiny in the search bar, install the package by David A. Mellis.

You have to configure Arduino with the correct settings. So in Tools:



Board in this menu you select board's familly. Here it's Attiny24/44/84, there's also an Attiny25/45/85 familly.
Processor choose the one on your board. Here, Attiny44.
Clock choose "External 20 MHz" in order to have the best clock accuracy.
Port don't touch it now.
Programmer choose the one you're using, I'm using the USBFabISP. But you can use an Arduino Uno for exemple.

Now you're ready to flash your board. In Tools, click on Burn Bootload.
If it's good, "Done burning bootloader" appears.

First code upload.
Create a new sketch, File -> New.

Copy-paste this code:

int led_pin = 7; //7 is the pin number on the microcontroller who connects to LED.

// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin led_pin as an output.
pinMode(led_pin, OUTPUT);
}

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

To check Attiny's pins:



Hello-Echo LED is connected to PA6, so to 7th pin.

To upload your code, click on the Upload button (➡).
The LED will be blinking each second !

My codes
The first code I made turn the board into a SOS device, it's based on the Blink exemple. The LED spells S, O, S, in morse. Here's the code:

/*
* SOS morse
*
*
*/

int led_pin = 7; // Define LED pin
int Sshort = 500; // S blinking time
int Olong = 1000; // O S blinking time

void setup() {

pinMode(led_pin,OUTPUT); // Define LED pin as an output

}

void loop() {

S(); // Call the S loop
delay(1500); // Wait 1500 ms
O(); // Call the 0 loop
delay(1500);
S();
delay(1500);

}

void S(){ // Define a S loop

digitalWrite(led_pin,HIGH);
delay(Sshort);
digitalWrite(led_pin,LOW);
delay(Sshort);
digitalWrite(led_pin,HIGH);
delay(Sshort);
digitalWrite(led_pin,LOW);
delay(Sshort);
digitalWrite(led_pin,HIGH);
delay(Sshort);
digitalWrite(led_pin,LOW);
delay(Sshort);
}

void O(){ // Define a O loop

digitalWrite(led_pin,HIGH);
delay(Olong);
digitalWrite(led_pin,LOW);
delay(Olong);
digitalWrite(led_pin,HIGH);
delay(Olong);
digitalWrite(led_pin,LOW);
delay(Olong);
digitalWrite(led_pin,HIGH);
delay(Olong);
digitalWrite(led_pin,LOW);
delay(Olong);

}

I upgrated it, now to launch the SOS code, you have to press the button for 2 seconds. There's also a free mode in order to code your own morse code.
And if you press the button for 4 seconds, it launch an "HELLO WORLD" code!
It's base on this code: https://programmingelectronics.com/make-one-button-functionality-two-arduino/.

/*Using a Single Button, create mutliple options based on how long the button is pressed.
So the board is turned into a morse-code device with three options: a free mode, an SOS displayer mode and an Hello World diplayer mode.

2018 Xavier Klein WTFPL
Based on this code:
Created DEC 2014 by Scuba Steve
Modified JAN 2015 by Michael James
Both members of https://programmingelectronics.com

*/
/////////Declare and Initialize Variables////////////////////////////
//We need to track how long the momentary pushbutton is held in order to execute different comman
ds //This value will be recorded in seconds
float pressLength_milliSeconds = 0;
int Short = 500;
int Long = 1000;
// Define the *minimum* length of time, in milli-seconds, that the button must be pressed for a p
articular option to occur int optionOne_milliSeconds = 100;

int optionTwo_milliSeconds = 2000;

int optionThree_milliSeconds = 4000;

//The Pin your button is attached to

int buttonPin = 3;

//Pin your LEDs are attached to

int led_pin = 7;

void setup(){

// Initialize the pushbutton pin as an input pullup

// Keep in mind, when pin 2 has ground voltage applied, we know the button is being pressed

pinMode(buttonPin, INPUT_PULLUP);

//set the LEDs pins as outputs

pinMode(led_pin, OUTPUT);

//Start serial communication - for debugging purposes only

//Serial.begin(9600);

} // close setup

void loop() {

//Record *roughly* the tenths of seconds the button in being held down

while (digitalRead(buttonPin) == LOW ){

delay(100); //if you want more resolution, lower this number

pressLength_milliSeconds = pressLength_milliSeconds + 100;

}

//Different if-else conditions are triggered based on the length of the button press

//Start with the longest time option first

//Option 2 - Execute the third option if the button is held for 3 seconds, it's spelling Hello
World in morse. if (pressLength_milliSeconds >= optionThree_milliSeconds){

H();
E();
L();
L();
O();
Space();
W();
O();
R();
L();
D();

}

//Option 1 - Execute the first option, it's free mode for morse coding.

else if(pressLength_milliSeconds >= optionTwo_milliSeconds){

S();
O();
S();

}

else if(pressLength_milliSeconds >= optionOne_milliSeconds){

digitalWrite(led_pin,HIGH);

delay(100);

digitalWrite(led_pin,LOW);

}//close if options

//every time through the loop, we need to reset the pressLength_Seconds counter

pressLength_milliSeconds = 0;

}
//////Functions for Short and Long

void ShortBlink(){
digitalWrite(led_pin,HIGH);
delay(Short);
digitalWrite(led_pin,LOW);
delay(Short);
}

void LongBlink(){
digitalWrite(led_pin,HIGH);
delay(Long);
digitalWrite(led_pin,LOW);
delay(Long);
}

////Functions for letters
void H(){
ShortBlink();
ShortBlink();
ShortBlink();
ShortBlink();
delay(1500);
}

void E(){
ShortBlink();
delay(1500);
}

void L(){
ShortBlink();
LongBlink();
ShortBlink();
ShortBlink();
delay(1500);
}

void Space(){
delay(3000);
}

void W(){
ShortBlink();
LongBlink();
LongBlink();
delay(1500);
}

void R(){
ShortBlink();
LongBlink();
ShortBlink();
delay(1500);
}

void D(){
LongBlink();
ShortBlink();
ShortBlink();
delay(1500);
}

void S(){
ShortBlink();
ShortBlink();
ShortBlink();
delay(1500);
}

void O(){
LongBlink();
LongBlink();
LongBlink();
delay(1500);
}

Here the result!


Try to code in C.
For this one, I followed David instructions on his website.
So I went on this website and followed the tutorial.
I modified the blink code in order to work with my attiny44:

//
// A simple program for the ATtiny44 that blinks an LED.
//
// electronut.in
//

#include
#include

#define F_CPU 8000000

int main (void)
{
// set PA6 to be output - connect your LED to pin 7
DDRA = (1 << PA6);

// loop
while (1) {

// set PB1 high
PORTA = (1 << PA6);

_delay_ms(200);

// set PB1 low
PORTA &= ~(1 << PA6);

_delay_ms(200);
}

return 1;
}

And I edited the Makefile for an Attiny44. It didn't work so I changed the Fuses line using this fuses calculator. It work !:

avr-gcc -Wall -Os -DF_CPU=8000000 -mmcu=attiny44 -c main.c -o main.o
avr-gcc -Wall -Os -DF_CPU=8000000 -mmcu=attiny44 -o main.elf main.o
rm -f main.hex
avr-objcopy -j .text -j .data -O ihex main.elf main.hex
avr-size --format=avr --mcu=attiny44 main.elf
AVR Memory Usage
----------------
Device: attiny44

Program: 102 bytes (2.5% Full)
(.text + .data + .bootloader)

Data: 0 bytes (0.0% Full)
(.data + .bss + .noinit)


avrdude -c usbtiny -p attiny44 -U flash:w:main.hex:i

avrdude: AVR device initialized and ready to accept instructions

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

avrdude: Device signature = 0x1e9207 (probably t44)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "main.hex"
avrdude: writing flash (102 bytes):

Writing | ################################################## | 100% 0.21s

avrdude: 102 bytes of flash written
avrdude: verifying flash memory against main.hex:
avrdude: load data flash data from input file main.hex:
avrdude: input file main.hex contains 102 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.26s

avrdude: verifying ...
avrdude: 102 bytes of flash verified

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

avrdude done. Thank you.

avrdude -c usbtiny -p attiny44 -U lfuse:w:0x6A:m -U hfuse:w:0xDF:m -U efuse:w:0x
FF:m
avrdude: AVR device initialized and ready to accept instructions

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

avrdude: Device signature = 0x1e9207 (probably t44)
avrdude: reading input file "0x6A"
avrdude: writing lfuse (1 bytes):

Writing | ################################################## | 100% 0.01s

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

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

avrdude: verifying ...
avrdude: 1 bytes of lfuse verified
avrdude: reading input file "0xDF"
avrdude: writing hfuse (1 bytes):

Writing | ################################################## | 100% 0.00s

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

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

avrdude: verifying ...
avrdude: 1 bytes of hfuse verified
avrdude: reading input file "0xFF"
avrdude: writing efuse (1 bytes):

Writing | ################################################## | 100% 0.00s

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

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

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

avrdude: safemode: Fuses OK (E:FF, H:DF, L:6A)

avrdude done. Thank you.


But nothing is blinking in the board... So I change few things in the C code and try to flash it again and...

avrdude -c usbtiny -p attiny44 -U flash:w:main.hex:i

avrdude: initialization failed, rc=-1
Double check connections and try again, or use -F to override
this check.

Ok so the computer doesn't seem to see the board anymore. I try to burn the bootloader in Arduino, nothing.
Perhaps it was a bit #YOLO to change the fuse, I don't really know...
It's only my second Hello Board. Call me the Board Destoyer.

Problems:
I break my first board, the FTDI pins, I had to remake it.