Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

19
voti

Arduino: non il solito approccio.

Indice

Introduzione

Ho scritto questo articolo pensando a chi come me, dopo aver comprato una scheda hardware Arduino, si affaccia al mondo dei microcontrollori.

Non sono mai stato un amante degli IDE, perchè penso che nella maggior parte delle volte, per chi comincia a programmare possono essere controproducenti riguardo alcuni dettagli, come per esempio la correzione automatica degli errori di sintassi, che non abitua il programmatore ad imparare dalle proprie correzioni (cosa che non avviene tramite un normale editore di testo).

Nell'ambiente di sviluppo di Arduino però, il caso è differente. Se diamo una occhiata al codice dei numerosi esempi inclusi nel software (ed altrettanto disponibili in rete a questo indirizzo), e sapendo che l'hardware Arduino incorpora un microcontrollore della famiglia AVR, si nota che i programmi nascondono all'utente "il dietro le quinte" della programmazione del software con le avr-libc.

Per fare un esempio pratico, nel programma Blink, la chiamata alla funzione

pinMode(13,OUTPUT);

non ci insegna veramente a configurare un pin come output. Se dovessimo programmare un ATMEGA su un circuito che non è la scheda hardware Arduino, come faremmo senza la funzione pinMode?

Nel mio caso quindi, accendere un LED con la funzione digitalWrite non è soddisfacente. Ho bisogno di sapere di più, ovvero, quale codice si nasconde dietro ad una funzione di questo tipo? Questa curiosità è ciò che mi ha spinto a cominciare in una maniera differente e successivamente a scrivere questo articolo. Voglio precisare che non vuole essere l'ennesimo tutorial, ma bensì mostrare una alternativa altrettanto interessante per cominciare a programmare Arduino, con lo scopo di invogliare l'utente ad acquisire esperienza con la programmazione di un microcontrollore della famiglia AVR.

Blink2

Come esempio pratico ho scritto una versione alternativa di Blink (ovvero il programma che ci permette di fare lampeggiare un LED collegato al pin nº 13 della scheda hardware) chiamata Blink2, che pur essendo un programma veramente piccolo e semplice riesce a evidenziare qualche concetto di base.

Il primo requisito è ovviamente avere lo schema della scheda hardware (nel mio caso una Arduino Duemilanove con schema completo reperibile a questo indirizzo). Successivamente è bene procurarsi il datasheet del microcontrollore che ci si accinge a programmare (nel mio caso un ATMEGA328P con datasheet reperibile a questo indirizzo). In caso di disporre un hardware differente, si tratta solamente di seguire gli stessi passi per l'hardware acquistato.

Per motivi di spazio e formattazione, mi limito a rappresentare la porzione di circuito che rappresenta la connessione dei pin del microcontrollore con quelli a cui vengono collegati i componenti esterni.

Arduino_uC.gif

Arduino_uC.gif

Un occhio attento nota subito che il pin 13 a cui si collega il LED non è collegato al pin 13 del microcontrollore, ma bensì al nº 19, ovvero il PORTB:5 (PB5) o bit nº 5 del PORTB.

I pin dei microcontrollori a loro volta formano quelle che si chiamano "porte di I/O". Un microcontrollore può avere una, due, tre o più porte a seconda delle sue caratteristiche hardware. Normalmente vengono chiamate PORTA, PORTB, PORTC, etc. Ogni porta prima di essere usata deve essere configurata attraverso un apposito registro interno.

Nel caso dei microcontrollori AVR, il registro è chiamato Data Direction Register, come si può leggere a pagina 94 del datasheet (link sopra). Nel nostro caso il Data Direction Register associato al PORTB è il DDRB.

Il programma del LED lampeggiante quindi si basa solamente sul fatto di cambiare lo stato di un singolo pin (o chiamiamolo bit) in maniera intermittente. A tale scopo quindi useremo una funzione di temporizzazione chiamata _delay_ms (appartente alle librerie C AVR, ovvero le avr-libc).

Il codice C di Blink2 è il seguente

/* 
  Blink2.c
  Arduino LED blinking on board pin nº 13
  Author: Gohan
*/

/* Set XTAL frequency */
#define F_CPU 16000000UL 

/* I/O & delay headers */
#include <avr/io.h>
#include <util/delay.h>

int main (void)
{
    /* set PORTB as output    */
    DDRB = 0xff;

    /* Infinite loop */
    while(1)
    {
        /* turn on LED */
        PORTB |= _BV(PB5);
 
        /* 1s delay */
        _delay_ms(1000);

        /* turn off LED */
        PORTB &= ~_BV(PB5);

        /* 1s delay */
        _delay_ms(1000);            
    }    

    return 1;
}
/* end of LED program */


La costante F_CPU definisce la frequenza di clock alla quale lavorerà la CPU del microcontrollore grazie all' oscillatore esterno, ed è obbligatorio dichiarla al principio del codice in caso di utilizzare la funzione _delay_ms o qualsiasi altra funzione dichiarata in utils/delay.h. Se il valore della costante F_CPU non coincidesse con la frequenza di clock i ritardi sarebbero di tempi sbagliati. F_CPU è quindi il valore di riferimento di frequenza per le funzioni dichiarate nell'header appena citato. L'Arduino Duemilanove monta un quarzo a 16MHz, con cui si spiega il valore attribuito alla riga #7. Affinchè l'I/O funzioni, bisogna successivamente includere l'header file <avr/io.h>. La funzione _delay_ms invece è dichiarata nell'header file <util/delay.h>. Come si può vedere il programma è molto semplice e intuitivo, però confrontandolo con Blink

/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.
 
  This example code is in the public domain.
 */

void setup(){                
  // initialize the digital pin as an output.
  // Pin 13 has an LED connected on most Arduino boards:
  pinMode(13, OUTPUT);     
}

void loop() {
  digitalWrite(13, HIGH);   // set the LED on
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);    // set the LED off
  delay(1000);              // wait for a second
}

è evidente che quest'ultimo non mette in evidenza quello che sarebbe bene imparare fin da subito.

Caricamento del programma

Caricare il software funzionante nel microcontrollore vuol dire prima compilare il programma e successivamente generare il file .hex, che contiene la informazione che il microcontrollore può interpretare. Nel mio caso, che lavoro con Linux, ho usato lo stesso Arduino IDE per caricare il programma, semplicemente aprendo il codice in C e caricandolo come qualsiasi altro. Ricordarsi che i programmi fatti da sè e creati all'infuori dell' Arduino IDE possono solo essere aperti se salvati nella cartella di sketchbook, cartella in cui vengono salvati anche quando vengono scritti con tale ambiente di sviluppo.

Una alternativa "fai da te" consiste nel compilare il programma con avr-gcc, generare il file .hex con avr-objcopy ed infine caricare il file con avr-dude attraverso un opportuno makefile. Tale lavoro può però portare a delle complicazioni che potrebbero richiedere abbastanza tempo per essere risolte, in quanto è opportuno conoscere anche gli argomenti a riga di comando da passare al programma. Questo va oltre lo scopo di questo articolo, quindi il mio primo consiglio senza complicarsi la vita, è caricare il programma grazie all'IDE, che in questo caso è di grande aiuto.

Putroppo non uso Windows, quindi non avendo esperienza con questo OS mi limito a segnalare questo tutorial.

Scusate ma sono sempre stato un amante di Linux.

Conclusioni

Questo è stato il mio approccio personale per cominciare con Arduino. Considero che tale scheda può essere quindi uno strumento per familiarizzare con gli AVR. Per chi non avesse ancora comprato Arduino, il PIERIN AT90 di TardoFreak (reperibile al suo blog) rappresenta una ottima alternativa a mio parere.

Comprai Arduino poco più di un'anno fà, ricordo ancora il mio primo post sul forum nel quale chiesi informazioni su libri a riguardo. Dopo un anno di lezioni ed esami, finalmente ho avuto il tempo di metterci mano in questo modo. Spero quindi che quest'articolo venga preso in considerazione allo scopo per cui è stato scritto, e che possa essere uno stimolo di partenza per altre persone.

Per ultimo, non vuole assolutamente essere una critica alla metodologia applicata dallo staff creatore di Arduino secondo gli esempi.


Links Utili

AVR LibC Home Page, dove si può scaricare l'ultima versione del manuale delle avr-libc.

AvrFreaks Application Notes

Introduction to Microcontrollers

AVR Assembler User Guide

11

Commenti e note

Inserisci un commento

di ,

Questo natale la mia famiglia m'ha regalato un arduino starter kit, anche se io avrei voluto un'oscilloscopio! Vabé, apparte il buon viso a cattivo gioco, appena ho iniziato a leggere un po di docs su arduino ho pensato: "ma che cagata è questa!?!?!" allora mi son subito messo all'opera per programmare direttamente ATMEGA328 montato sul mio arduino uno rev.3... se avessi visto st'articolo all'ora sarebbe stato per me oro colato!

Rispondi

di ,

il suo principale limite di arduino è il suo principale successo :-) si compra la scheda arduino, si vuole andare oltre il suo wiring e le sue facilities; nessun problema: si può caricare on-board file hex compilati in assembly, gcc, basic l'unica limitazione è il programmatore: avrdude, l'unico che riconosce il protocollo di arduino (stk500v1) ma chi se ne importa :-) tanto si fa tutto dalla riga di comando ;-)

Rispondi

di ,

Mi sono accorto dopo che l'argomento è stato approfondito nell'articolo successivo "Assembly : The Codefather" (anche se il titolo non lega apparentemente con questo).

Rispondi

di ,

Grazie xyz per il suggerimento. Al momento di scrivere l'articolo mi sarebbe piaciuto poter sviluppare il programma con le mie mani ma non è stato possibile, diciamo per questioni di tempo. Nell'articolo successivo infatti mi sono aiutato con avr-gcc per generare il codice asm. Ti ringrazio ancora, sei stato molto gentile.

Rispondi

di ,

Se volete vedere assembler per AVR generato dal sorgente in C basta usare l'opzione "-S" del compilatore GCC. Ad esempio per un target mcpu ATmega328 con ottimizzazione in velocità "-O2": $> avr-gcc -mmcu=atmega328 -S -O2 source.c il file generato source.s contiene il codice assembler prima di essere passato all'assemblatore. Se volete vere la versione ottimizzata per spazio basta sostituire l'opzione "-O2" con "-Os" o con nessuna ottimizzazione con "-O0" (alcune funzioni come "_delay_ms" funzionano solo se le ottimizzazioni sono abilitate).

Rispondi

di ,

Sono appunto interessato a scrivere un articoletto proprio sul linguaggio Assembly. Ci sto pensando sopra per come strutturarlo in modo che esca qualcosa di interessante. Ciao crestus!

Rispondi

di ,

Bravo! :) Per la versione assembly potrebbe anche essere interessante soltanto un confronto Codice C-Arduino C-Avr Asm...delle stesse istruzioni...:) (cosa che ho intenzione di fare nei miei articoli sui PIC... :) )

Rispondi

di ,

Proporre il programma in Assembly è un dettaglio a cui avevo pensato, non lo nego. Tuttavia non ho ancora acquisito tale esperienza per l'Assembly AVR, diversamente con i PICs. Ammetto che avevo pensato a scrivere un articolo sulla programmazione in Assembly, linguaggio spesso considerato obsoleto e dimenticato. Grazie per la marcia in più! ;)

Rispondi

di ,

Concordo con TardoFreak, bell'iniziativa! Credo sarebbe pure interessante analizzare il programma scritto in assembly, così da scavare più a fondo e rendere tutto ancora più trasparente! ;)

Rispondi

di ,

Grazie mille TardoFreak! Al dire la verità mi sarebbe piaciuto fare qualcosa di leggermente più complesso che l'esempio del LED. Però avrei avuto bisogno di più tempo per praticare, temevo sarebbe andato troppo oltre ed in più volevo inaugurare il blog. Sono fresco fresco con gli AVR, spero che il tempo mi permetta di approfondire a dovere.

Rispondi

di ,

Fa paicere vedere qualcuno che vuole andare oltre le librerie pronte all' uso per capirne di più sui microcontrollori. Questo approccio è ottimo, aiuta veramente ad imparare ad usare la macchina e, quando la macchina non avrà più segreti, sarà bello semplificarsi la vita ed usare le soluzioni pronte. Ottimo articolo! :)

Rispondi

Inserisci un commento

Per inserire commenti è necessario iscriversi ad ElectroYou. Se sei già iscritto, effettua il login.