Juan García-Maestro Gil-Casares

FABLAB MADRID CEU


8. Embedded Programming


Procedure:
0. Assignment
1. Understanding Attiny 44 - Data Sheet
2. My Board
3. Functions used: programming with arduino
4. My Final Program: Concept
5. My Final Program: Code
6. Example 1: Blinking Leds + modification
7. Example 2: Blinking Leds Using Millis()
8. Example 3 and 4: Using Button
9. Example 5: Communicating with Serial Monitor
10. Example 6: Pushing Button Several Times To Do Something
11. Download Files

0. Assignment



Read a Microcontroller Data Sheet


Program your board to do something, with as many different programming languages and programming environments as possible.


LEARNING OUTCOMES



Identify relevant information in a microcontroller data sheet.

Implement programming protocols.

HAVE YOU...



...documented what you learned from reading a microcontroller datasheet.

...what questions do you have? What would you like to learn more about?

...programmed your board

...described the programming process/es you used

...included your code

1. Understanding Attiny 44 - Data Sheet

Other Week Assignment where I mention Data Sheets:







Taking a look to Attiny 44 Data Sheet, a made a summary with the most important parts:

CPU Core - Architectural Overview

Your browser does not support this image

Pin Configurations

Your browser does not support this image Your browser does not support this image

VCC: Supply Voltage

GND: Ground

Port B (PB3: PB0): It is a 4-bit bi-directional I/O Port with internal PULL-UP resistor. As well, port B pins are tri-stated when RESET condition becomes activated.

Reset: reset input. A low level on this pin for nolonger than the minimum pulse length will generate a reset, even if the clock is not running and provided the reset pin has not been disabled.

Port A (PA7:PA0): Port A is a 8-bit bi-directional I/O portwith internet PULL-UP resistors. As well, Port A pins are tri-stated when a reset condition becomes activated.

ALTERNATE PORT FUNCTIONS



Your browser does not support this image

Each port can have an alternate functions, showed on the next table for Port A:

Your browser does not support this image

Following this table on the data sheet, we can find the description of each bit of the port, and its main functions:

Your browser does not support this image

Each port can have an alternate functions, showed on the next table for Port B:

Your browser does not support this image

Following this table on the data sheet, we can find the description of each bit of the port, and its main functions:

Your browser does not support this image

Memories



The AVR architecture has two main memories spaces, the Data Memory and the Program Memory space. Plus, the ATtiny 44 has an EEPROM Memory for Data storage.

For the 'Register Description' (Port A, Port B), each Port has:

-'Data Register' (PORTA/ PORTB)
- Data Direction Register (DDRA/DDRB)
-Input Pins (PINA, PINB).

Your browser does not support this image

Your browser does not support this image

Each register has its own bit coordinate storage, where you can read or write and the initial value that has when running it.

There different types of registers:

-SRAM (Static Random Access Memory) :


The lower data memory locations address both the Register File (located the first 32 locations), the I/O memory (located the next 64 locations) and the internal data SRAM (located the 256 next ones).
Program's Data - Every time the board is disconnected, all data is erased.

Your browser does not support this image

Your browser does not support this image

-EEPROM (Electrically Erasable Programmable Read Only Memory):



-The ATtiny 44A contains 256 bytes of data EEPROM.
-It is accessible in the I/O space.
Slower, but the data is stored

- Flash - program's storage

- Fuses - mcu's storage configuration



Clock System



Next diagram represents the principal clock system in the AVR. The clocks not being used at certain times can be halted by using different sleeping modes:

Your browser does not support this image

There different clock subsystems:

-CPU Clock: it is related with the operation of the AVR Core.
-I/O Clock: It is used by the majority of the I/O modules (Time/Counter, External Interrupt module and other ones).
-Flash Clock: controls the clock of the flash interface.
-ADC Clock: it has a clock domain allowing the CPU and I/O clocks to halt to reduce noise.

External Clock



In order to have an external clock, this must be connected to CLKI as shown on the diagram below:

Your browser does not support this image

External Interrupts

Your browser does not support this image

External interrupts are triggered by the INT0 pin or any PCINT pins. If pins are enabled, the interrupt will trigger even if the INT0 or PCINT pins are configured as outputs.

This feature provides a way of generating a software interrupt.

I/O Ports:



Your browser does not support this image

ATtiny 44A has AVR poprts that have true Read-Modifiy- Write functionality when used as digital I/O ports.

Configuring the Pin

Your browser does not support this image

Each port consists of three register bits:

• DDxn:

-the DDxn bit in the DDRx Register selects the direction of this pin. If DDxn is written logic 1, Pxn is configured as an output pin.
-If DDxn is written logic 0, Pxn is configured as an input pin.

• PORTxn:

-If Portxn is written logic 1 when the pin is configured as an input pin, the pull-up resistor is activated.
-To switch the pull-up resistor off, Portxn has to be written logic 0 or the pin has to be configured as an output pin.
-The port pins are tri-stated when reset condition becomes active, even if no clocks are running.
-If Portxn is written logic 1 when the pin is configured as an output pin, the port pin is driven high (1).
-If Portxn is written logic 0 when the pin is configured as an output pint, the port pin is driven low (0).

Toggling the Pin



Your browser does not support this image

Writing a logic one to PINxn toggles the value of PORTxn, independent on the value of DDRxn.

Alternate Functions of Port A



Your browser does not support this image



-ADC0: Analog to Digital Converter
-AREF: External Analog Reference for ADC (Analog Digital Converter).
-PCINTx: Pin Change Interrupt Source x.
-ADC: Analog to Digital Converter
-AIN: Analog Comparator Positive Input.
-T0: Timer/Counter0 counter source.
-USCK: Three wire mode Universal Serial Interface Clock.
-SCL: Two-wire mode Serial Clock for USI Two-wire mode.
-DO: Data Output in USI Three-wire mode.
-MISO: Master Data Input, Slave Data output pin for SPI channel.
-OC1B: Output Compare Match output.
-SDA: Two-wire mode Serial Interface Data.
-DI: Data Input in USI Three-wire mode.
-MOSI: MAster Data output, Salve Data input for SPI channel.
-ICPx: Input Capture Pin.

Alternate Funcionts Port B



Your browser does not support this image

XTAL: Chip Clock Oscillator pin.
PCINTx: Pin Change Interrupt Source x.
CLKI: Clock Input from an external clock source.
OC0A: Output Compare Match output.
CKOUT: System Clock Output.

8-Bit Timer/Counter with PWN (Pulse-Width Modulation)



The general purpose of the 8-bit Timer/Counter module allow an accurate program execution timing and wave generation.

Here is a simplified block diagram of the 8-bit Timer/Counter:

Your browser does not support this image

Electrical Characteristics



Your browser does not support this image

Table - Decimal - Binary - Octal - Hex - ASCII

Your browser does not support this image

What questions do you have? What would you like to learn more about?



It is my first time diving myself in a data sheet. It is a challenge for me to understand everything, but after reading and re-reading, creating the board and having our instructor to help us understanding how everything works, it becomes easier.

I want to improve my comprehension in this topic, but it will take a lot of time as now I am not used to think as a programmer. I need first practice, patience and continue working.

I would like to understand better how the memory works. I can tell there are different types of memory that register everything in different ways, but a deeper comprehension is needed. Why some of them are volatile against other ones that are not? How data gets stored when no electrical impulses are taking place? How my computer (PC) really works?

I continually use my computer to make my architectural designs: how a program can work using vectors and represent them the way they do it?

It is a matter of time and emailing my instructor to have a better knowledge of what really is happening inside.

2. My Board





3. Functions used: programming with arduino



Fucntions used:


-setup()
-void loop()
-millis()
-if()...else()
-switch (case,break,default)
-including SofwaterSerial library
-println()
-pinMode()
-variables (int,const int, unsigned long, byte, long,

Vocabulary - C Language



millis(): returns the number of milliseconds since the program started running. NOTE: this number will go back to zero after 50 days aprox. -constants won't change -Debounce: Thanks to debounce, the noise that is generated while the button is pressed is avoided, and no unpredictable results occur during the new connection. This sketch uses the millis() function to work, to keep track of the time.

SOFTWARE SERIAL LIBRARY: -SoftwareSerial()-->SoftwareSerial.begin()


-available():get the number of bytes available for reading from a software serial port. This data has already arrived and stored in the serial receive buffer.

syntax: mySerial.available()


-begin(): sets the spped (baud rate) for the serial communication.
syntax: serial.begin(9600); -isListening(): tests to see if the requested seria port is actively listening.

syntax: mySerial-isListening()


-overflow():tests to see if a software serial buffer overflow has occured.

syntax: mySerial.overflow()


-peek(): returns a character that was received on the RXpin of the software serial port.
-read(): returns a character that was received on the RXpin of the software serial port.
-print(): prints data to the sthe transmit pin of the software serial port.
syntax: serial.print(value), serial.print(value, format). Te lo puede decir en varios formatos.
-prinln(): prints data to the serial port as human-readable ASCII text followed by a carriage return character (ASCII13 or '\r') and a new line character (ASCII 10, or '\n').
syntax: serial.prinln(value); serial.println(value,format).
-listen(): enables the selected software serial port to listen. Only one serial port can listen at a time. syntax: serial.listen()
write()

-SoftwareSerial.begin() is needed to enable communication.


rxPin: receives data
txPin: transmits data
inverse_logic:inverts.

Communication with the compute limitations:


-only one port can recieve data at a time
-not all pin support change interrumpts in Mega and Mega 2560.
-On arduino or GEnuino 101, max rx speed is 57600bps.


4. My Final Program: Concept



As in my board design I have 3 different leds, I wanted to experiment how time can affect different ways of reading different rhythms. My goal is to have 3 different light rhythms depending on which numbers the user has introduced to the computer's interface. Once a rhythm is activated, the board answers back with a message showing the time of each led.

These are the rhythms I wanted to do:

CONCEPT



I enter a number on the computer's serial monitor and the board activates one rhythm or another.

Rhythms:



Default Rhythm (how much time passes in milliseconds when led turns on and off): an epileptic light rhythm is intended:

-Red Led: 70
-Blue Led 1: 180
-Blue Led 2: 600

If you introduce number 1 to the computer's interface: playing around sensation is intended.

-Red Led: 250
-Blue Led 1: 500
-Blue Led 2: 250

If you enter number 2 to the computer's interface: a police visualization pursuit is intended.

-Red Led: 600
-Blue Led 1: 250
-Blue Led 2: 50

Videos



Here is a video having the default rhythm first, then entering number 1 with its related rhythm and later on number 2. Then it is repeated again.



A second video with a general view with the computer interface and attiny's reaction.




5. My Final Program: Code



Through the whole code, my comments are written for a better comprehension.

#include <SoftwareSerial.h>

SoftwareSerial mySerial(0, 1); 

// declaring leds
const int ledPinRed =  7;

const int ledPinBlue1 = 3; 
const int ledPinBlue2 = 2;

//declaring the different states
int ledState1 = LOW;   
int ledState2 = LOW;
int ledState3 = LOW;

//declaring each independent initial count        
unsigned long previousMillis1 = 0;   
unsigned long previousMillis2 = 0;
unsigned long previousMillis3 = 0;

// declaring each independent interval at which led blink (milliseconds)     
long interval1 = 600;           
long interval2 = 250;
long interval3 = 50;

//setup - activation ledpins as outputs
void setup() {
    mySerial.begin(115200);
   pinMode(ledPinRed, OUTPUT);
   pinMode(ledPinBlue1, OUTPUT);
   pinMode(ledPinBlue2, OUTPUT);
}

//loops - using millis() function
//I need three independent counts for each rhythm.
void loop() {
   unsigned long currentMillis1 = millis(); 
   unsigned long currentMillis2 = millis();
   unsigned long currentMillis3 = millis();

//using if function to create different light rhytms

//default rhythm
  if (currentMillis1 - previousMillis1 >= interval1) {
      previousMillis1 = currentMillis1;
      if (ledState1 == LOW) {
      ledState1 = HIGH;
    } else {
      ledState1 = LOW;
    }
     digitalWrite(ledPinRed, ledState1);
    

     
  } 
  
  //rhythm (1)
  if (currentMillis2 - previousMillis2 >= interval2) {
      previousMillis2 = currentMillis2;
      if (ledState2 == LOW) {
      ledState2 = HIGH;
    } else {
      ledState2 = LOW;
    }
      
     digitalWrite(ledPinBlue2, ledState2);
  }

//rhythm (2)
  if (currentMillis3 - previousMillis3 >= interval3) {
      previousMillis3 = currentMillis3;
      if (ledState3 == LOW) {
      ledState3 = HIGH;
    } else {
      ledState3 = LOW;
    }
      
     digitalWrite(ledPinBlue1, ledState3);
  }

  //creating new variable byte as 'encendido', 'turned on' in english.
  //if there is serial connection between computer and mcu, use switch
   byte encendido;
  if (mySerial.available()) {
    // read the most recent byte (which will be from 0 to 255):
    encendido = mySerial.read();

    //case 1:  number 1; case 2: number 2; default: rest of numbers
    //each time you enter a number, on the screen appears the rhythm of each led
     switch (encendido) {
      case '1':
         interval1 = 70;
         interval2 = 180;
         interval3 = 600;
    mySerial.println("r70,b180,b600");
        break;
      case '2':
        interval1 = 250;
        interval2 = 500;
        interval3 = 250;
    mySerial.println("r250,b500,b250");
        break;
      
      default:
        // turn all the LEDs off:
         interval1 = 600;
         interval2 = 250;
         interval3 = 50;
    mySerial.println("default r");
        
    }
 
 
  }
}



6. Example 1: Blinking Leds + modification



This is my first ever program to understand and modify. It showed me how to blink a led by using 'digitalWrite(led, HIGH), to activate it.

To turn the led on and off, I just used the 'delay()' function to stop the program the seconds I wanted.



To play a little bit more, I modified the program to used all three leds.

Code Of The Modified Program

			/*Blink
  
  Original Purpose:
  Turns on an LED on for one second, then off for one second, repeatedly.

  Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO 
  it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to
  the correct LED pin independent of which board is used.
  If you want to know what pin the on-board LED is connected to on your Arduino model, check
  the Technical Specs of your board  at https://www.arduino.cc/en/Main/Products
  
  This example code is in the public domain.

  modified 8 May 2014
  by Scott Fitzgerald
  
  modified 2 Sep 2016
  by Arturo Guadalupi
  
  modified 8 Sep 2016
  by Colby Newman

  modified 17 march 2017
  by Juan García-Maestro Gil-Casares
*/


// the setup function runs once when you press reset or power the board
void setup() {

  pinMode(7, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(2, OUTPUT);
}

void loop() {

  digitalWrite(7, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(50);                       // wait for a 10th of a second
  digitalWrite(7, LOW);    // turn the LED off by making the voltage LOW
  delay(50);                       // wait for a 10th of a second
  
  digitalWrite(3, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(50);                       // wait for a second
  digitalWrite(3, LOW);    // turn the LED off by making the voltage LOW
  delay(50);
  
  digitalWrite(2, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(50);                       // wait for a second
  digitalWrite(2, LOW);    // turn the LED off by making the voltage LOW
  delay(50);
}




7. Example 2: Blinking Leds Using Millis()



This programs has showed me how to control the 'millis()' function, to avoid using the 'delay()' function. It is more complex, but once understood, you can modify and apply this function to other areas where a timing count is needed.

There is no video as the result is the same as the one in Example 1.

			/* Blink without Delay

 Turns on and off a light emitting diode (LED) connected to a digital
 pin, without using the delay() function.  This means that other code
 can run at the same time without being interrupted by the LED code.

 The circuit:
 * Use the onboard LED.
 * Note: Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO 
  it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to
  the correct LED pin independent of which board is used.
  If you want to know what pin the on-board LED is connected to on your Arduino model, check
  the Technical Specs of your board  at https://www.arduino.cc/en/Main/Products

 created 2005
 by David A. Mellis
 modified 8 Feb 2010
 by Paul Stoffregen
 modified 11 Nov 2013
 by Scott Fitzgerald
 modified 9 Jan 2017
 by Arturo Guadalupi
 modified 18 Mar 2017
 by Juan Garcia-Maestro Gil-Casares


 This example code is in the public domain.
*/


const int ledPin =  7;

int ledState = LOW;            

unsigned long previousMillis = 0;      
const long interval = 500;      
void setup() {

  pinMode(ledPin, OUTPUT);
}
void loop() {
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
  
    previousMillis = currentMillis;

    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

   
    digitalWrite(ledPin, ledState);
  }
}



8. Example 3 and 4: Using Button



This program has showed me how to use a button on a board by using the 'input_pullup' pinMode. The idea is that when the button is pressed, the leds turn on.


The Code just below shows the modified program I have used to have active all leds. When pressing the button, turning them off.



/*
  Button

  Original Purpose:
 Turns on and off a light emitting diode(LED) connected to digital
 pin 13, when pressing a pushbutton attached to pin 2.


 The circuit:
 * LED attached from pin 13 to ground
 * pushbutton attached to pin 2 from +5V
 * 10K resistor attached to pin 2 from ground

 * Note: on most Arduinos there is already an LED on the board
 attached to pin 13.


 created 2005
 by DojoDave 
 modified 30 Aug 2011
 by Tom Igoe
 modified 18 March 2017
 by Juan García-Maestro Gil-Casares

 This example code is in the public domain.


const int buttonPin = 8;     
const int ledPin1 =  7;     
const int ledPin2 = 3;
const int ledPin3 = 2;

int buttonState = 0;      

void setup() {
  
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  
  pinMode(buttonPin, INPUT_PULLUP);
 
}

void loop() {
   buttonState = digitalRead(buttonPin);

   if (buttonState == LOW) {
   
    digitalWrite(ledPin1, HIGH);
    digitalWrite(ledPin2, HIGH);
    digitalWrite(ledPin3, HIGH);
  } else {
    // turn LED off:
    digitalWrite(ledPin1, LOW);
    digitalWrite(ledPin2, LOW);
    digitalWrite(ledPin3, LOW);
  }
}








9. Example 5: Communicating with Serial Monitor



This example has showed me to communicate with my board using serial communication. If I enter a 5 on the serial monitor, the led turns on and it print 'Led active, press 8 to turn it off'.

If I enter the number 8, then the led turn off and it shows another message 'Led turned off, press 5 to turn it on'.

If I enter a number that is not a 5 or an 8, then it shows another message: 'press 5 to turn the led on, press 8 to turn the led off'.








#include <SoftwareSerial.h>

SoftwareSerial mySerial(0, 1); 
const int ledPin = 7;    

void setup() {  
  mySerial.begin(115200);
  // initialize the ledPin as an output:
  pinMode(ledPin, OUTPUT);
  
}

void loop() {
  byte encendido;

  if (mySerial.available()) {   
    encendido = mySerial.read();
    if (encendido == '5') {   
    digitalWrite(ledPin, HIGH);
     mySerial.println("encendido,8 para apagar.");
  } 
  else if (encendido == '8'){
   
    digitalWrite(ledPin, LOW);
    mySerial.println("apagado, 5 para encender.");
  }
  else{
    mySerial.println("5 encender y 8 apagar.");
  }
  }
}




10. Example 6: Pushing Button Several Times To Do Something



This example has showed me that you can accumulate the number of times the button has been pressed. If this button is pressed four times, the led or either turns on or it turns off.





#include <SoftwareSerial.h>

SoftwareSerial mySerial(0, 1); 

const int  buttonPin = 8;   
const int ledPin = 7;      

int buttonPushCounter = 0;   
int buttonState = 0;         
int lastButtonState = 0;     

void setup() {
 
  pinMode(buttonPin, INPUT_PULLUP);
  
  pinMode(ledPin, OUTPUT);
  
  mySerial.begin(115200);
}


void loop() {
  
  buttonState = digitalRead(buttonPin);

  
  if (buttonState != lastButtonState) {
    
    if (buttonState == LOW) {
      buttonPushCounter++;
     
      mySerial.print("number of button pushes:  ");
      mySerial.println(buttonPushCounter);
      mySerial.println(" ");
    } 
    
    delay(50);
  }
  
  lastButtonState = buttonState;

  if (buttonPushCounter % 4 == 0) {
     digitalWrite(ledPin, HIGH);
  } else {
     digitalWrite(ledPin, LOW);
  }

}



11. Download Files



All original arduino files contain comments.