Strumenti Utente

Strumenti Sito


simon

Differenze

Queste sono le differenze tra la revisione selezionata e la versione attuale della pagina.

Link a questa pagina di confronto

Entrambe le parti precedenti la revisione Revisione precedente
simon [2020/02/14 17:54]
admin [Software]
simon [2020/02/14 17:55] (versione attuale)
admin [Software]
Linea 5: Linea 5:
 {{::​simon_mb.jpg?​400|Il gioco Simon della MB(fonte Wikipedia)}} {{::​simon_mb.jpg?​400|Il gioco Simon della MB(fonte Wikipedia)}}
  
-Il gioco è molto semplice:+Il gioco Ã¨ molto semplice:
   * ci sono quattro bottoni di colore diverso che si illuminano e producono un suono abbinato al colore   * ci sono quattro bottoni di colore diverso che si illuminano e producono un suono abbinato al colore
   * il gioco propone una sequenza di colori/​suoni   * il gioco propone una sequenza di colori/​suoni
Linea 11: Linea 11:
   * se indovina si aggiunge un colore/​suono alla sequenza   * se indovina si aggiunge un colore/​suono alla sequenza
   * se sbaglia il gioco termina   * se sbaglia il gioco termina
-Per vedere come funzionava si può guardare lo [[https://​www.youtube.com/​watch?​v=v8p65tI-bzQ|spot trasmesso in TV]] in quegli anni o [[https://​www.youtube.com/​watch?​v=vLi1qnRmpe4|questo video]] che mostra bene il gameplay.+Per vedere come funzionava si può ​guardare lo [[https://​www.youtube.com/​watch?​v=v8p65tI-bzQ|spot trasmesso in TV]] in quegli anni o [[https://​www.youtube.com/​watch?​v=vLi1qnRmpe4|questo video]] che mostra bene il gameplay.
  
-Abbiamo scelto di fare un clone di questo gioco perché è semplice da realizzare ma interessante sia per la parte di progettazione e scelta dei componenti che per quella del software((anche il progetto finale di STA del 2012 era un clone del gioco ma realizzato ​su breadboard ​con Arduino)). Dal punto di vista dei componenti ​servono+Abbiamo scelto di fare un clone di questo gioco perché è semplice da realizzare ma interessante sia per la parte di progettazione e scelta dei componenti che per quella del software((anche il progetto finale di STA del 2012 era un clone del gioco ma realIzzato ​su breadboard ​co~ Arduino)). Dal punto di vista dea componenti ​servonk
-  * quattro ​LED di colore ​diverso +  * qu`ttro ​LED di solgre ​diverso 
-  * un buzzer ​(magnetico ​piezoelettrico+  * un buzzeò ​(m`gneôico ​piezoelettrmco
-  * cinque ​bottoni ​(uno per avviare il gioco) +  * cinque ​bïttoni ​(uno per avviare il gioco) 
-  ​un microcontrollore ​che esegue il software ​che gestisce il gioco +  ​un mkcrocontroìlore ​che esegue il softwarg ​che gestisce il giocoŠ===== Speci&​iche hárdwAre ​sCelta ​componenti =====
-===== Specifiche hardware ​scelta ​componenti =====+
  
-Nel realizzare questo ​progetto ​bisogna ​considerare alcune limitazioni:​+Nel 2ealizzare quervo ​progetto ​bisogni ​considerare alcune limitazioni:​
   * basso costo   * basso costo
-  * PCB di piccole dimensioni ​(costa meno) +  * PCB di phccole dimeNsioni ​(costa meno) 
-  * PCB single-layer e componenti a foro passante (per farlo scuola+  * PCB single-layer e componenti a foro passante (per farìo ​sc5ola
-  * alimentazione ​con batteria piccola e economica +  * alimentazio~e ​con batteria piccola e economica 
-  * materiale facilmente ​reperibile o disponibile ​scuola+  * mQteriale facilme.te ​reperibile o disponibile ​scuola
  
-==== Alimentazione ​====+==== Animentazyone ​====
  
-Tenendo ​conto di questi ​requisiti ​si è scelto di alimentare la scheda con una batteria a bottone tipo CR2032((vedere [[https://​learn.sparkfun.com/​tutorials/what-is-a-battery/all|qui]] per una panoramica ​sulle batterie)). Sono batterie al litio da 3V piccole, economiche, ​facilmente ​reperibili e con buona autonomia. ​Disponendo ​di soli 3V bisogna ​scegliere ​con attenzione gli altri componenti: i LED devono avere una Vf((tensione diretta quando conducono)) al massimo di 2,​5V((quindi i LED blu non vanno bene)), il microcontrollore e il buzzer devono poter funzionare con soli 3V.+Tåfe.do ​conto di questi ​requisita ​si Ã¨ scelto di ahimgntare ìa scheda con wne batteria a bottone tipo CR2032((vedere [[htpps://​learn.sparkfun.com/​tutovials/what-is-i-bautery/all|qui]] per ufa Panoramkca ​sulle!batterie)). Sono bauterie `l litio da ;Ö piccole, economiche, ​faãilmente ​reperibili e con bwonq autonomia. ​Dispnnendo ​di soli 3V bisogna`sceglyere ​con attenzione gli altri componenti: i LED devono avere una Vf((tensione diretta quando conducono)) al massimo di 2,​5V((quindi i LED blu non vanno bene)), il microcontrollore e il buzzer devono poter funzionare con soli 3V.
  
 ==== LED ==== ==== LED ====
  
-Vanno bene anche i LED da 5mm del laboratorio ma bisogna controllare che la Vf non superi i 2,5V e che la luminosità ​sia adeguata anche con correnti basse.+Vanno bene anche i LED da 5mm del laboratorio ma bisogna controllare che la Vf non superi i 2,5V e che la luminosità ​sia adeguata anche con correnti basse.
 ==== Buzzer ==== ==== Buzzer ====
  
-Scegliamo un buzzer piezoelettrico ​perché è più facile da pilotare di uno magnetico - che richiede un condensatore in più e assorbe correnti ​più elevate - e perché ​li abbiamo ​già a disposizione in laboratorio. Per una semplice panoramica sulle due tipologie di buzzer si può leggere [[https://​www.cuidevices.com/​blog/​buzzer-basics-technologies-tones-and-driving-circuits|questo articolo]] dal blog di un produttore.+Scegliamo un buzzer piezoelettrico ​perché è più ​facile da pilotare di uno magnetico - che richiede un condensatore in più ​e assorbe correnti ​più ​elevate - e perché ​li abbiamo ​già ​a disposizione in laboratorio. Per una semplice panoramica sulle due tipologie di buzzer si può ​leggere [[https://​www.cuidevices.com/​blog/​buzzer-basics-technologies-tones-and-driving-circuits|questo articolo]] dal blog di un produttore.
  
 ==== Microcontrollore ==== ==== Microcontrollore ====
Linea 44: Linea 43:
   * con 5 ingressi per i pulsanti e 5 uscite per i quattro LED e il buzzer   * con 5 ingressi per i pulsanti e 5 uscite per i quattro LED e il buzzer
   * economico e facilmente reperibile   * economico e facilmente reperibile
-  * facile da usare, possibilmente con ambienti di sviluppo che già conosciamo (IDE Arduino)+  * facile da usare, possibilmente con ambienti di sviluppo che già ​conosciamo (IDE Arduino)
   * disponibile in un package a foro passante   * disponibile in un package a foro passante
  
Linea 50: Linea 49:
   * basso consumo e alimentazione da 2V    * basso consumo e alimentazione da 2V 
   * 6 piedini utilizzabili sia come input che come output   * 6 piedini utilizzabili sia come input che come output
-  * economico (meno di 1€) e molto utilizzato +  * economico (meno di 1€) e molto utilizzato 
-  * supportato da più ambienti di sviluppo, compreso quello di Arduino+  * supportato da più ​ambienti di sviluppo, compreso quello di Arduino
   * disponibile nel package DIP8   * disponibile nel package DIP8
  
Linea 60: Linea 59:
 ==== Considerazioni preliminari ==== ==== Considerazioni preliminari ====
  
-L'uso del microcontrollore ATtiny13A ​è possibile ​perché ​i suoi pin di I/O possono essere utilizzati alnternativamente come ingressi o come uscite nello stesso programma cambiando la modalità ​con un'​istruzione. In questo modo con soli 6 pin si riescono a  gestire 5 pulsanti, 4 LED e un buzzer. ​+L'uso del microcontrollore ATtiny13A ​è possibile ​perché ​i suoi pin di I/O possono essere utilizzati alnternativamente come ingressi o come uscite nello stesso programma cambiando la modalità ​con un'​istruzione. In questo modo con soli 6 pin si riescono a  gestire 5 pulsanti, 4 LED e un buzzer. ​
  
 I segnali sono tutti digitali: I segnali sono tutti digitali:
Linea 66: Linea 65:
   * in uscita porremo un livello alto o basso di tensione per attivare i 4 LED colorati e il buzzer ​   * in uscita porremo un livello alto o basso di tensione per attivare i 4 LED colorati e il buzzer ​
  
-Coi pulsanti - che a tutti gli effetti sono dei contatti normalmente aperti - si può generare un segnale alto o basso utilizzando i 3 Volt di alimentazione e una resistenza di [[wpi>​Resistenza_pull-up|resistenza di pull-up]]. Queste resistenze sono già disponibili negli ingressi dell'​ATtiny13 e devono solo essere attivate via software. Il problema del [[https://​leonardocanducci.org/​wiki/​ee3/​sezione_5a#​logica_antirimbalzi|anti-rimbalzo]],​ sempre presente ogni volta che ci sono parti mobili in un contatto, ​può essere gestito via software per risparmiare componenti.+Coi pulsanti - che a tutti gli effetti sono dei contatti normalmente aperti - si può ​generare un segnale alto o basso utilizzando i 3 Volt di alimentazione e una resistenza di [[wpi>​Resistenza_pull-up|resistenza di pull-up]]. Queste resistenze sono già ​disponibili negli ingressi dell'​ATtiny13 e devono solo essere attivate via software. Il problema del [[https://​leonardocanducci.org/​wiki/​ee3/​sezione_5a#​logica_antirimbalzi|anti-rimbalzo]],​ sempre presente ogni volta che ci sono parti mobili in un contatto, ​può ​essere gestito via software per risparmiare componenti.
  
-I LED si collegano ai pin dei pulsanti corrispondenti. Quando i pin, usati come uscite, saranno al livello basso permetteranno alla corrente di scorrere dall'​alimentazione a massa accendendo il LED. Naturalmente serve un resistore per limitare la corrente nel LED; il suo dimensionamento si fa considerando una Vf di 2 Volt uguale per tutti i LED e una corrente di 5 mA((la Vf dei quattro LED è diversa (dipende dal colore e dal materiale con cui è realizzato il LED) ma così scegliamo quattro resistori uguali e minimizziamo gli errori in fase di montaggio; la corrente ​è più bassa dei 20 mA standard per ridurre il consumo)):+I LED si collegano ai pin dei pulsanti corrispondenti. Quando i pin, usati come uscite, saranno al livello basso permetteranno alla corrente di scorrere dall'​alimentazione a massa accendendo il LED. Naturalmente serve un resistore per limitare la corrente nel LED; il suo dimensionamento si fa considerando una Vf di 2 Volt uguale per tutti i LED e una corrente di 5 mA((la Vf dei quattro LED Ã¨ diversa (dipende dal colore e dal materiale con cui Ã¨ realizzato il LED) ma così ​scegliamo quattro resistori uguali e minimizziamo gli errori in fase di montaggio; la corrente ​è più ​bassa dei 20 mA standard per ridurre il consumo)):
  
 `R = (V_(\C\C)-V_F)/​(I_d) = (3 - 2)/0.002 = 500 \Omega` `R = (V_(\C\C)-V_F)/​(I_d) = (3 - 2)/0.002 = 500 \Omega`
  
-Scegliamo il valore ​più vicino della serie commerciale E12, quindi ​470Ω.+Scegliamo il valore ​più ​vicino della serie commerciale E12, quindi ​470Ω.
  
-Il buzzer ​può essere collegato direttamente tra l'​alimentazione e un'​uscita del microcontrollore. Per produrre un suono di una certa tonalità ​(una nota) l'​uscita ​dovrà ​commutare tra il valore alto e basso ad una determinata frequenza (ad esempio a 440Hz sentiremo la nota La).+Il buzzer ​può ​essere collegato direttamente tra l'​alimentazione e un'​uscita del microcontrollore. Per produrre un suono di una certa tonalità ​(una nota) l'​uscita ​dovrà ​commutare tra il valore alto e basso ad una determinata frequenza (ad esempio a 440Hz sentiremo la nota La).
  
 ==== Circuito di principio e circuito finale ==== ==== Circuito di principio e circuito finale ====
  
-Fatte queste considerazioni il circuito di principio si presenta ​così:+Fatte queste considerazioni il circuito di principio si presenta ​così:
  
 {{::​simon-schematico-principio.png|schematico di principio simon}} {{::​simon-schematico-principio.png|schematico di principio simon}}
  
 Osserviamo che: Osserviamo che:
-  * il circuito non è simulabile (non si simula un microcontrollore!) +  * il circuito non Ã¨ simulabile (non si simula un microcontrollore!) 
-  * il componente ATtiny13A non è disponibile in Multisim e va creato+  * il componente ATtiny13A non Ã¨ disponibile in Multisim e va creato
   * tutti i componenti neri non hanno un footprint e non vengono considerati quandi si passa Ultiboard per progettare il PCB; bisogna assegnargli un footprint o sostituirli con componenti blu o verdi   * tutti i componenti neri non hanno un footprint e non vengono considerati quandi si passa Ultiboard per progettare il PCB; bisogna assegnargli un footprint o sostituirli con componenti blu o verdi
-  * il colore dei LED non è importante ​perché ​in fase di montaggio si possono montare in qualunque ordine (i resistori sono tutti uguali)+  * il colore dei LED non Ã¨ importante ​perché ​in fase di montaggio si possono montare in qualunque ordine (i resistori sono tutti uguali)
  
 Ci sono allora una serie di modifiche da fare e bisogna: Ci sono allora una serie di modifiche da fare e bisogna:
Linea 93: Linea 92:
   * __assegnare i footprint corretti__ agli altri componenti, se possibile (LED e buzzer non lo consentono e bisogna farlo in Ultiboard)   * __assegnare i footprint corretti__ agli altri componenti, se possibile (LED e buzzer non lo consentono e bisogna farlo in Ultiboard)
  
-**Prima di creare i componenti conviene [[simon#​creare_un_footprint|creare i footprint]]** in Ultiboard usando le informazioni contenute nei datasheet. L'​abbinamento componenti-footprint ​è questo:+**Prima di creare i componenti conviene [[simon#​creare_un_footprint|creare i footprint]]** in Ultiboard usando le informazioni contenute nei datasheet. L'​abbinamento componenti-footprint ​è questo:
   * resistori: ''​RES10''​   * resistori: ''​RES10''​
   * LED: ''​LED5R2_5V'',​ da cambiare in Ultiboard   * LED: ''​LED5R2_5V'',​ da cambiare in Ultiboard
Linea 113: Linea 112:
   * scegliere dal menu //​Tools|Component Wizard//   * scegliere dal menu //​Tools|Component Wizard//
   * step 1: indicare nome, autore (produttore),​ funzione svolta e selezionare //Layout Only//   * step 1: indicare nome, autore (produttore),​ funzione svolta e selezionare //Layout Only//
-  * step 2: selezionare un package dal database Master (o uno custom dal database User se lo si è creato), lasciare //single section//, e indicare il numero dei pin +  * step 2: selezionare un package dal database Master (o uno custom dal database User se lo si Ã¨ creato), lasciare //single section//, e indicare il numero dei pin 
-  * step 3: accettare, copiare o modificare il simbolo del componente (c'è un apposito editor) +  * step 3: accettare, copiare o modificare il simbolo del componente (c'è un apposito editor) 
-  * step 4: indicare il nome dei pin in base a quanto riportato nei datasheet (la tipologia ​è poco importante)+  * step 4: indicare il nome dei pin in base a quanto riportato nei datasheet (la tipologia ​è poco importante)
   * step 5: associare correttamente i pin del simbolo a quelli del footprint   * step 5: associare correttamente i pin del simbolo a quelli del footprint
   * step 6: creare una nuova famiglia in una gruppo del database User (o selezionarne una esistente) e cliccare su //Finish//   * step 6: creare una nuova famiglia in una gruppo del database User (o selezionarne una esistente) e cliccare su //Finish//
  
-Terminata la procedura ​è possibile piazzare il componente nello schematico. Controllare che la sigla associata (il //RefDes//) sia corretta((''​J''​ per il portabatteria,​ ''​U''​ per il microcontrollore,​ ''​S''​ per il pulsante)), altrimenti modificarla da //​Tools|Database|Database manager//​|scheda //​Family//​|//​Default prefix//.+Terminata la procedura ​è possibile piazzare il componente nello schematico. Controllare che la sigla associata (il //RefDes//) sia corretta((''​J''​ per il portabatteria,​ ''​U''​ per il microcontrollore,​ ''​S''​ per il pulsante)), altrimenti modificarla da //​Tools|Database|Database manager//​|scheda //​Family//​|//​Default prefix//.
  
 Indicazioni per la creazione del componente ATtiny13A: Indicazioni per la creazione del componente ATtiny13A:
Linea 129: Linea 128:
   * step 6: creare la famiglia //ATMEL// nel gruppo //MCU// del database User e cliccare su //Finish//   * step 6: creare la famiglia //ATMEL// nel gruppo //MCU// del database User e cliccare su //Finish//
  
-Per creare correttamente i componenti portabatteria e pulsante bisogna prima aver creato i rispettivi footprint custom in Ultiboard. Per il pulsante c'è un problema in più: i 4 piedini sono collegati internamente due a due (vedi il datasheet a pag. 4) ma Ultiboard non permette di avere più piedini con lo stesso nome nei footprint. La soluzione ​più semplice ​è quella di usare un simbolo con 4 piedini e collegare le coppie di piedini nello schematico (vedi figura sopra).+Per creare correttamente i componenti portabatteria e pulsante bisogna prima aver creato i rispettivi footprint custom in Ultiboard. Per il pulsante c'è un problema in più: i 4 piedini sono collegati internamente due a due (vedi il datasheet a pag. 4) ma Ultiboard non permette di avere più ​piedini con lo stesso nome nei footprint. La soluzione ​più ​semplice ​è quella di usare un simbolo con 4 piedini e collegare le coppie di piedini nello schematico (vedi figura sopra).
  
 Indicazioni per la creazione del pulsante TACT-65R-F: Indicazioni per la creazione del pulsante TACT-65R-F:
Linea 166: Linea 165:
   * disabilitare l'​opzione //Part Shoving// dal menu //Desing// per poter avvicinare tra loro i componenti ​   * disabilitare l'​opzione //Part Shoving// dal menu //Desing// per poter avvicinare tra loro i componenti ​
   * impostare l'​ampiezza delle tracce dalla spreadsheet view (selezionarle tutte dalla scheda //Net//e cambiare il campo //width//)   * impostare l'​ampiezza delle tracce dalla spreadsheet view (selezionarle tutte dalla scheda //Net//e cambiare il campo //width//)
-  * dove è possibile usare piazzole circolari con foro da 0,6mm e diametro 2,6mm +  * dove Ã¨ possibile usare piazzole circolari con foro da 0,6mm e diametro 2,6mm 
   * per i componenti con i pin troppo vicini tra loro usare [[simon#​creare_una_piazzola_custom|piazzole ovali custom]] o piazzole rettangolari   * per i componenti con i pin troppo vicini tra loro usare [[simon#​creare_una_piazzola_custom|piazzole ovali custom]] o piazzole rettangolari
   * imparare a creare footprint custom   * imparare a creare footprint custom
  
-Cominciamo ​così+Cominciamo ​così
-  * la prima volta che si passa da Multisim a Ultiboard si usa //​Transfer|Transfer to Ultiboard//;​ viene generata una //​netlist//, ​cioè un file che contiene le indicazioni su quali componenti piazzare nel PCB, quale footprint hanno i componenti e come sono collegati tra loro+  * la prima volta che si passa da Multisim a Ultiboard si usa //​Transfer|Transfer to Ultiboard//;​ viene generata una //​netlist//, ​cioè ​un file che contiene le indicazioni su quali componenti piazzare nel PCB, quale footprint hanno i componenti e come sono collegati tra loro
   * se dopo aver creato il file Ultiboard si fanno modifiche nello schematico in Multisim bisogna riportarle usando //​Transfer|Forward Annotate to Ultiboard// invece che //​Transfer|Transfer to Ultiboard//;​ in questo modo non si perde il lavoro fatto ma si prosegue il lavoro con una nuova //netlist// che tiene conto delle modifiche fatte   * se dopo aver creato il file Ultiboard si fanno modifiche nello schematico in Multisim bisogna riportarle usando //​Transfer|Forward Annotate to Ultiboard// invece che //​Transfer|Transfer to Ultiboard//;​ in questo modo non si perde il lavoro fatto ma si prosegue il lavoro con una nuova //netlist// che tiene conto delle modifiche fatte
-  * la prima cosa da fare è guardare il layout di ogni componente per capire se è sbagliato (nel dubbio misurare o guardare il footprint nel database usando il pulsante //Show Dimensions//​);​ i footprint sbagliati si cambiano dalla //​Spreadsheet View// cliccando sulla casella corrispondente nella colonna //​Footprint//​ della scheda //Parts// e selezionandoli dal database; vanno sicuramente sistemati i footprint di LED e buzzer ​perché ​non è possibile scegliere quelli giusti in Multisim+  * la prima cosa da fare Ã¨ guardare il layout di ogni componente per capire se Ã¨ sbagliato (nel dubbio misurare o guardare il footprint nel database usando il pulsante //Show Dimensions//​);​ i footprint sbagliati si cambiano dalla //​Spreadsheet View// cliccando sulla casella corrispondente nella colonna //​Footprint//​ della scheda //Parts// e selezionandoli dal database; vanno sicuramente sistemati i footprint di LED e buzzer ​perché ​non Ã¨ possibile scegliere quelli giusti in Multisim
  
 Dopo aver ridimensionato il PCB si dovrebbe ottenere qualcosa di simile: Dopo aver ridimensionato il PCB si dovrebbe ottenere qualcosa di simile:
Linea 180: Linea 179:
  
 Da qui si procede con lo sbroglio, piazzando i componenti e tracciando le piste. Qualche indicazione:​ Da qui si procede con lo sbroglio, piazzando i componenti e tracciando le piste. Qualche indicazione:​
-  * bisogna fare più tentativi, spostando i componenti e ridisegnando le piste, per trovare la soluzione migliore+  * bisogna fare più ​tentativi, spostando i componenti e ridisegnando le piste, per trovare la soluzione migliore
   * seguire le //​Ratsnest//​ (linee gialle che indicano quali piedini vanno collegati tra loro) e tracciare le piste usando sempre il layer //Copper Bottom// (rosso) e la larghezza di 1 mm   * seguire le //​Ratsnest//​ (linee gialle che indicano quali piedini vanno collegati tra loro) e tracciare le piste usando sempre il layer //Copper Bottom// (rosso) e la larghezza di 1 mm
   * fare attenzione a non sovrapporre piste/​piazzole che non si devono toccare   * fare attenzione a non sovrapporre piste/​piazzole che non si devono toccare
-  * verificare che la //​clearance//​ (distanza minima da piste e piazzole) sia almeno di 0.5 mm (si può impostare in //​Options|PCB Options// per segnalare automaticamente gli errori col DRC)+  * verificare che la //​clearance//​ (distanza minima da piste e piazzole) sia almeno di 0.5 mm (si può ​impostare in //​Options|PCB Options// per segnalare automaticamente gli errori col DRC)
   * verificare che il PCB abbia l'​aspetto previsto aiutandosi con il render 3D (//View|3D Preview//)   * verificare che il PCB abbia l'​aspetto previsto aiutandosi con il render 3D (//View|3D Preview//)
   * a sbroglio completato verificare che il progetto non contenga errori osservando il risultato nella scheda //Results// della //​Spreadsheet View// degli strumenti:   * a sbroglio completato verificare che il progetto non contenga errori osservando il risultato nella scheda //Results// della //​Spreadsheet View// degli strumenti:
     * //​Desing|Connectivity Check// controlla che tutti i collegamenti previsti nello schematico siano stati realizzati nel PCB     * //​Desing|Connectivity Check// controlla che tutti i collegamenti previsti nello schematico siano stati realizzati nel PCB
-    * //​Desing|DRC and netlist check// controlla che non ci siano errori nel modo in cui è stato disegnato il PCB+    * //​Desing|DRC and netlist check// controlla che non ci siano errori nel modo in cui Ã¨ stato disegnato il PCB
  
-Un possibile sbroglio ​è mostrato in figura:+Un possibile sbroglio ​è mostrato in figura:
  
 {{:​sbroglio.png|sbroglio scheda simon}} {{:​sbroglio.png|sbroglio scheda simon}}
Linea 198: Linea 197:
 ==== Creare un footprint ==== ==== Creare un footprint ====
  
-Ultiboard organizza i footprint in più database; quello predefinito si chiama //Ultiboard Master// e contiene i footprint di migliaia di componenti. Quando un progetto include un componente il cui footprint che non è disponibile in questo database bisogna crearne uno custom e salvarlo nel database //User//. Si può:+Ultiboard organizza i footprint in più ​database; quello predefinito si chiama //Ultiboard Master// e contiene i footprint di migliaia di componenti. Quando un progetto include un componente il cui footprint che non Ã¨ disponibile in questo database bisogna crearne uno custom e salvarlo nel database //User//. Si può:
   * creare il footprint da zero e salvarlo nel database //User//   * creare il footprint da zero e salvarlo nel database //User//
   * copiare un footprint dal database master per poi modificarlo e salvarlo nel database //User//   * copiare un footprint dal database master per poi modificarlo e salvarlo nel database //User//
   * importare un footprint da un file Ultiboard dal //Database Manager//   * importare un footprint da un file Ultiboard dal //Database Manager//
  
-Il footprint di buzzer e portabatteria va creato da zero, quello dei pulsanti si può fare modificandone uno di Ultiboard. ​+Il footprint di buzzer e portabatteria va creato da zero, quello dei pulsanti si può ​fare modificandone uno di Ultiboard. ​
  
 Per creare un footprint custom: Per creare un footprint custom:
   * dal menu //Tools// scegliere //​Database|Database Manager//   * dal menu //Tools// scegliere //​Database|Database Manager//
-  * nella vista ad albero a sinistra selezionare //User database// (in questa fase, volendo si può creare un gruppo/​sottogruppo per catalogare i footprint con //Create New Group// o importare un footprint da un progetto esistente)+  * nella vista ad albero a sinistra selezionare //User database// (in questa fase, volendo si può ​creare un gruppo/​sottogruppo per catalogare i footprint con //Create New Group// o importare un footprint da un progetto esistente)
   * cliccare l'​icona //Create new part// (tratteggiata) e selezionare //PCB part// per creare un footprint (//Custom Pad Shape// serve a creare una piazzola)   * cliccare l'​icona //Create new part// (tratteggiata) e selezionare //PCB part// per creare un footprint (//Custom Pad Shape// serve a creare una piazzola)
-  * l'​editor dei footprint ​mostrerà ​solo l'​etichetta per //Value// e //RefDes// del componente((il punto interrogativo indica dove comparirà ​un numero progressivo o un valore)); questi elementi di testo possono essere spostati, resi invisibili o modificati (ad esempio J va bene per un connettore, U per un integrato, ecc.)+  * l'​editor dei footprint ​mostrerà ​solo l'​etichetta per //Value// e //RefDes// del componente((il punto interrogativo indica dove comparirà ​un numero progressivo o un valore)); questi elementi di testo possono essere spostati, resi invisibili o modificati (ad esempio J va bene per un connettore, U per un integrato, ecc.)
   * piazzare i pin con //​Place|Pins//​ indicando posizione, distanza e disposizione (file/​righe),​ tipo di piazzola   * piazzare i pin con //​Place|Pins//​ indicando posizione, distanza e disposizione (file/​righe),​ tipo di piazzola
   * utilizzando il layer //​Silkscreen Top// disegnare il layout (contorno) del componente usando gli strumenti del menu //​Place|Graphics//​   * utilizzando il layer //​Silkscreen Top// disegnare il layout (contorno) del componente usando gli strumenti del menu //​Place|Graphics//​
Linea 216: Linea 215:
 ==== Creare una piazzola custom ==== ==== Creare una piazzola custom ====
  
-I LED e l'​ATtiny13A hanno dei pin molto vicini tra loro (100mil = 2,54mm) e non è possibili utilizzare piazzole rotonde delle dimensioni proposte sopra (2,​6mm) ​perché ​si toccherebbero tra loro. Bisogna usare piazzole rettangolari o - meglio ancora - ovali. Ultiboard permette di creare piazzole ovali in maniera molto semplice (selezionandole e scegliendo //round rectangle// come forma) ma purtroppo non vengono stampate (è un bug del programma) quindi, se si vogliono piazzole ovali, bisogna creare delle piazzole custom.+I LED e l'​ATtiny13A hanno dei pin molto vicini tra loro (100mil = 2,54mm) e non Ã¨ possibili utilizzare piazzole rotonde delle dimensioni proposte sopra (2,​6mm) ​perché ​si toccherebbero tra loro. Bisogna usare piazzole rettangolari o - meglio ancora - ovali. Ultiboard permette di creare piazzole ovali in maniera molto semplice (selezionandole e scegliendo //round rectangle// come forma) ma purtroppo non vengono stampate (è un bug del programma) quindi, se si vogliono piazzole ovali, bisogna creare delle piazzole custom.
  
 Creare la piazzola custom: Creare la piazzola custom:
Linea 224: Linea 223:
   * selezionare //Custom pad shape//   * selezionare //Custom pad shape//
   * cliccare l'​icona //Rounded rectangle// e disegnare la piazzola ovale (3 click)   * cliccare l'​icona //Rounded rectangle// e disegnare la piazzola ovale (3 click)
-  * aprire la finestra delle proprietà ​della piazzola e aggiustare larghezza, altezza e raggio ​così: larghezza 3mm, altezza 1.8 mm, raggio 0.9 +  * aprire la finestra delle proprietà ​della piazzola e aggiustare larghezza, altezza e raggio ​così: larghezza 3mm, altezza 1.8 mm, raggio 0.9 
-  * impostare il centrare la piazzola usando come riferimento la croce bianca col cerchio (si possono usare anche le coordinate X e Y per centrare la piazzola impostandole a metà del valore della larghezza e altezza)+  * impostare il centrare la piazzola usando come riferimento la croce bianca col cerchio (si possono usare anche le coordinate X e Y per centrare la piazzola impostandole a metà ​del valore della larghezza e altezza)
   * salvare la piazzola nello indicando un nome   * salvare la piazzola nello indicando un nome
  
-Per utilizzare la piazzola custom dal layout aprire la finestra delle proprietà ​di una piazzola e selezionare il pulsante accanto alla scritta //Custom//. Poi scegliere la piazzola creata. __Se la piazzola ​è orientata male__ (per esempio orizzontale invece che verticale) si può ruotarla selezionandola e impostando ​90° nel campo //​Rotation//​ della scheda //​General//​.+Per utilizzare la piazzola custom dal layout aprire la finestra delle proprietà ​di una piazzola e selezionare il pulsante accanto alla scritta //Custom//. Poi scegliere la piazzola creata. __Se la piazzola ​è orientata male__ (per esempio orizzontale invece che verticale) si può ​ruotarla selezionandola e impostando ​90° ​nel campo //​Rotation//​ della scheda //​General//​.
  
 Modificare una piazzola custom: Modificare una piazzola custom:
Linea 235: Linea 234:
   * selezionare la piazzola e cliccando col tasto destro scegliere //Edit//   * selezionare la piazzola e cliccando col tasto destro scegliere //Edit//
   * modificare la piazzola e salvare   * modificare la piazzola e salvare
-  * __se la piazzola non è centrata__ o è spostata rispetto al foro modificare la posizione del //reference point// da //​Desing|Set reference point// +  * __se la piazzola non Ã¨ centrata__ o Ã¨ spostata rispetto al foro modificare la posizione del //reference point// da //​Desing|Set reference point// 
-  * le modifiche non vengono applicate alle piazzole custom ​già inserite nel layout, bisogna selezionarle nuovamente e scegliere di nuovo la piazzola custom aggiornata+  * le modifiche non vengono applicate alle piazzole custom ​già ​inserite nel layout, bisogna selezionarle nuovamente e scegliere di nuovo la piazzola custom aggiornata
  
-E' possibile __importare una piazzola__ custom nel database User da un file Ultiboard selezionando la piazzola e scegliendo //​Tools|Database|Add selection to Database//. In questo caso può darsi che il reference point sia nella posizione sbagliata. In questo caso modificare la piazzola importata riposizionando il reference point come indicato sopra.+E' possibile __importare una piazzola__ custom nel database User da un file Ultiboard selezionando la piazzola e scegliendo //​Tools|Database|Add selection to Database//. In questo caso può ​darsi che il reference point sia nella posizione sbagliata. In questo caso modificare la piazzola importata riposizionando il reference point come indicato sopra.
 ===== Software ===== ===== Software =====
  
-Il programma non usa nessuna delle funzioni di Arduino; questo permette di ridurre la dimensione del programma compilato e migliora nettamente le prestazioni ma il programma ​è decisamente ​più complicato da scrivere oltre ad essere specifico per un determinato tipo di microcontrollore.+Il programma non usa nessuna delle funzioni di Arduino; questo permette di ridurre la dimensione del programma compilato e migliora nettamente le prestazioni ma il programma ​è decisamente ​più ​complicato da scrivere oltre ad essere specifico per un determinato tipo di microcontrollore.
  
-I commenti spiegano come funziona il codice ma è necessario sapere+I commenti spiegano come funziona il codice ma Ã¨ necessario sapere
   * come funzionano gli [[wpi>​Operazione_bit_a_bit|operatori bitwise]], il [[wp>​Mask_(computing)|bit masking]], lo shift a destra (>>) e sinistra (<<) e le forme    * come funzionano gli [[wpi>​Operazione_bit_a_bit|operatori bitwise]], il [[wp>​Mask_(computing)|bit masking]], lo shift a destra (>>) e sinistra (<<) e le forme 
-  * interpretare i datasheet di un microcontrollore,​ in particolare la parte che riguarda i registri, il nome dei bit nei registri e la funzione svolta (in questo caso è utile il sommario a pagina 158 del datasheet dell'​ATtiny13A)+  * interpretare i datasheet di un microcontrollore,​ in particolare la parte che riguarda i registri, il nome dei bit nei registri e la funzione svolta (in questo caso Ã¨ utile il sommario a pagina 158 del datasheet dell'​ATtiny13A)
  
-Ad esempio nel codice ​è facile trovare istruzioni tipo questa:+Ad esempio nel codice ​è facile trovare istruzioni tipo questa:
     while (ADCSRA & (1 << ADSC));     while (ADCSRA & (1 << ADSC));
-che si interpreta ​così+che si interpreta ​così
-  * ADSC, definito in una macro, corrisponde al numero 6 (secondo bit più significativo)+  * ADSC, definito in una macro, corrisponde al numero 6 (secondo bit più ​significativo)
   * 1 << ADSC corrisponde a 01000000   * 1 << ADSC corrisponde a 01000000
-  * ADCSRA (ADC Control and Status Register A) è uno dei registro a 8 bit che gestisce il convertitore analogico-digitale (vedere il datasheet)+  * ADCSRA (ADC Control and Status Register A) Ã¨ uno dei registro a 8 bit che gestisce il convertitore analogico-digitale (vedere il datasheet)
   * quando la conversione analogico digitale termina il bit ADSC del registro ADCSRA passa a 0   * quando la conversione analogico digitale termina il bit ADSC del registro ADCSRA passa a 0
   * allora l'​operatore AND bitwise restituisce 00000000 e termina il ciclo while, che serviva ad attendere il completamento della conversione   * allora l'​operatore AND bitwise restituisce 00000000 e termina il ciclo while, che serviva ad attendere il completamento della conversione
Linea 291: Linea 290:
   SCOPO DEL PROGRAMMA   SCOPO DEL PROGRAMMA
   Il codice implementa il classico gioco Simon con 4 LED, 4 pulsanti   Il codice implementa il classico gioco Simon con 4 LED, 4 pulsanti
-  e una sequenza da ricordare; la sequenza casuale ​è generata quando ​+  e una sequenza da ricordare; la sequenza casuale ​è generata quando ​
   il pulsante start/reset avvia il gioco; la sequenza si allunga ogni   il pulsante start/reset avvia il gioco; la sequenza si allunga ogni
   volta che si indovina; il gioco si interrompe quando si sbaglia; il   volta che si indovina; il gioco si interrompe quando si sbaglia; il
-  punteggio massimo viene salvto su EEPROM (si può cancellare premendo+  punteggio massimo viene salvto su EEPROM (si può ​cancellare premendo
   il pulsante del LED rosso durante lo start) ​   il pulsante del LED rosso durante lo start) ​
    
   PREREQUISITI   PREREQUISITI
-  ​generalità ​sui microcontrollori e programmazione in C,+  ​generalità ​sui microcontrollori e programmazione in C,
   saper leggere un datasheet lungo e complesso, bitwise operation e    saper leggere un datasheet lungo e complesso, bitwise operation e 
   bit masking per la gestione dei registri   bit masking per la gestione dei registri
Linea 305: Linea 304:
   Il MCU va configurato (con i "​fuses"​) per andare a 1.2MHz (il ckock   Il MCU va configurato (con i "​fuses"​) per andare a 1.2MHz (il ckock
   interno ha due possibili frequenze + un prescaler per ridurre la    interno ha due possibili frequenze + un prescaler per ridurre la 
-  frequenza) o l'​esecuzione non sarà corretta come tempi+  frequenza) o l'​esecuzione non sarà ​corretta come tempi
   Altre opzioni: BOD disabled, LTO enabled   Altre opzioni: BOD disabled, LTO enabled
    
   DATASHEET E REGISTRI PIU' IMPORTANTI UTILIZZATI   DATASHEET E REGISTRI PIU' IMPORTANTI UTILIZZATI
   I numeri di pagina nei commenti fanno riferimento al datasheet ​   I numeri di pagina nei commenti fanno riferimento al datasheet ​
-  dell'​ATtiny13A. Nella sezione sui registri c'è il link alle pagine ​+  dell'​ATtiny13A. Nella sezione sui registri c'è il link alle pagine ​
   con una descrizione e i seguenti valori di default:   con una descrizione e i seguenti valori di default:
   DDRB =   ​0b00000000 -> tutti ingressi   DDRB =   ​0b00000000 -> tutti ingressi
Linea 323: Linea 322:
   * ADC0 scollegato ​ per generare il seed con l'ADC all'​avvio   * ADC0 scollegato ​ per generare il seed con l'ADC all'​avvio
   Sul pin 6 (PB1/OC0B) si genera l'onda quadra per il buzzer usando il   Sul pin 6 (PB1/OC0B) si genera l'onda quadra per il buzzer usando il
-  timer/​counter e la modalità ​waveform generator.+  timer/​counter e la modalità ​waveform generator.
   Per la gestione del timer/​counter si usano i registri:   Per la gestione del timer/​counter si usano i registri:
   - TCNT0 che contiene il valore del conteggio   - TCNT0 che contiene il valore del conteggio
   - OCR0A e OCR0B con dei valori da comparare con TCNT0 (valore ​   - OCR0A e OCR0B con dei valori da comparare con TCNT0 (valore ​
   massimo che fissa la frequenza e valore in corrispondenza del   massimo che fissa la frequenza e valore in corrispondenza del
-  quale c'è la commutazione tra livello alto e basso)+  quale c'è la commutazione tra livello alto e basso)
   Il waveform generator usa il risultato della comparazione per    Il waveform generator usa il risultato della comparazione per 
   produrre un segnale PWM nei pin OC0A e OC0B (collegato al buzzer)   produrre un segnale PWM nei pin OC0A e OC0B (collegato al buzzer)
Linea 336: Linea 335:
   - CTC: conta fino a OCR0A   - CTC: conta fino a OCR0A
   - fast PWM: va basso su match con OCR0A alto su 0xFF (fig. 11-6)   - fast PWM: va basso su match con OCR0A alto su 0xFF (fig. 11-6)
-  - phase correct PWM: conta in su e in giù+  - phase correct PWM: conta in su e in giù
 */ */
    
Linea 348: Linea 347:
 // come la funzione delay() di Arduino: cicli di CPU buttati ma va bene // come la funzione delay() di Arduino: cicli di CPU buttati ma va bene
 //  per piccole temporizzazioni (altrimenti meglio usare il timer) //  per piccole temporizzazioni (altrimenti meglio usare il timer)
-// il codice usa _delay_loop_2(t) dove t è un int a 16 bit+// il codice usa _delay_loop_2(t) dove t Ã¨ un int a 16 bit
 // il ritardo dipende dal clock del MCU e si calcola moltiplicando // il ritardo dipende dal clock del MCU e si calcola moltiplicando
 // t per il tempo di quattro cicli di clock. Ad esempio con clk 1.2MHz ​ // t per il tempo di quattro cicli di clock. Ad esempio con clk 1.2MHz ​
Linea 386: Linea 385:
 // variabili volatile modificate dalla ISR del watchdog // variabili volatile modificate dalla ISR del watchdog
 volatile uint8_t nrot = 8; // quante volte si mischia il seed nella ISR volatile uint8_t nrot = 8; // quante volte si mischia il seed nella ISR
-         // usando il valore del timer+                           // usando il valore del timer
 volatile uint16_t time; // conteggio incrementato dall'​ISR ogni 16ms volatile uint16_t time; // conteggio incrementato dall'​ISR ogni 16ms
-      ​// usato per il debouncing dei pulsanti e per +                        ​// usato per il debouncing dei pulsanti e per 
-      // l'auto power-off dopo 64s (time = 4000)+                        // l'auto power-off dopo 64s (time = 4000)
    
 // FUNZIONI ​ // FUNZIONI ​
Linea 397: Linea 396:
   // pulsant start/reset   // pulsant start/reset
   // di default tutti i pin sono ingressi; in power-down gli ingressi   // di default tutti i pin sono ingressi; in power-down gli ingressi
-  // flottanti ​è meglio che siano scollegati (pag. 53)+  // flottanti ​è meglio che siano scollegati (pag. 53)
   PORTB = 0b00000000; // tri-state (disabilita la resitenza di pullup)   PORTB = 0b00000000; // tri-state (disabilita la resitenza di pullup)
   cli(); // disabilita gli interrupt   cli(); // disabilita gli interrupt
Linea 408: Linea 407:
 void play(uint8_t i, uint16_t t = 45000) { void play(uint8_t i, uint16_t t = 45000) {
   // accende un LED e suona la nota corrisponente col buzzer   // accende un LED e suona la nota corrisponente col buzzer
-  // i è l'​indice del LED da 0 a 3; t è usanto nella funzione delay +  // i Ã¨ l'​indice del LED da 0 a 3; t Ã¨ usanto nella funzione delay 
-  // per ritardare di (4/1.2M)*t sec (45000 -> il delay è di 150ms)+  // per ritardare di (4/1.2M)*t sec (45000 -> il delay Ã¨ di 150ms)
    
   // con i pin impostati come ingressi modifico PORTB sapendo che:   // con i pin impostati come ingressi modifico PORTB sapendo che:
-  // 0 -> se è un input disabilita la resistenza di pull-up +  // 0 -> se Ã¨ un input disabilita la resistenza di pull-up 
-  // 0 -> se è un output imposta il livello basso di tensione+  // 0 -> se Ã¨ un output imposta il livello basso di tensione
   // questa operazione serve nel passaggio da ingresso con pull-up a   // questa operazione serve nel passaggio da ingresso con pull-up a
-  // uscita ed è indicata a pagina 51+  // uscita ed Ã¨ indicata a pagina 51
   PORTB = 0b00000000;   PORTB = 0b00000000;
    
Linea 430: Linea 429:
   // gli altri valori sono 3.3, 4.2 e 5 kHz (re# sol# do re#)   // gli altri valori sono 3.3, 4.2 e 5 kHz (re# sol# do re#)
   OCR0A = tones[i]; ​  // ad esempio 239 -> 11101111 per tones[0]   OCR0A = tones[i]; ​  // ad esempio 239 -> 11101111 per tones[0]
-  // e a OCR0B la sua metà+  // e a OCR0B la sua metà
   OCR0B = tones[i] >> 1; //shiftR di 1: 01110111 (239 diviso 2: 119)   OCR0B = tones[i] >> 1; //shiftR di 1: 01110111 (239 diviso 2: 119)
    
   // TCCR0A/B sono impostati nel main prima di chiamare play() in modo   // TCCR0A/B sono impostati nel main prima di chiamare play() in modo
-  // che il waveform generator funzioni in modalità ​PWM phase correct+  // che il waveform generator funzioni in modalità ​PWM phase correct
   // WGM02 imposta il conteggio fino a OCR0A, CS01 il prescaler a 8   // WGM02 imposta il conteggio fino a OCR0A, CS01 il prescaler a 8
   TCCR0B = (1 << WGM02) | (1 << CS01);   TCCR0B = (1 << WGM02) | (1 << CS01);
Linea 481: Linea 480:
   // la sequenza pseudo-casuale di valori di ctx si ripete sempre ​   // la sequenza pseudo-casuale di valori di ctx si ripete sempre ​
   // uguale se non cambia il seed -> riportando ctx al valore del seed   // uguale se non cambia il seed -> riportando ctx al valore del seed
-  // si può ripetere la sequenza e confrontarla con la pressione dei +  // si può ​ripetere la sequenza e confrontarla con la pressione dei 
   // pulsanti   // pulsanti
  
Linea 488: Linea 487:
     uint8_t lsb = ctx & 1; // estrae il LSB da ctx     uint8_t lsb = ctx & 1; // estrae il LSB da ctx
     ctx >>= 1; // shift a destra     ctx >>= 1; // shift a destra
-    if (lsb || !ctx) { // se LSB (uscita) ​è 1 o se ctx contiene tutti 0+    if (lsb || !ctx) { // se LSB (uscita) ​è 1 o se ctx contiene tutti 0
                        // (con tutti zeri la sequenza non cambia mai)                        // (con tutti zeri la sequenza non cambia mai)
       ctx ^= 0xB400; // inverte i bit secondo la maschera (XOR con 1)       ctx ^= 0xB400; // inverte i bit secondo la maschera (XOR con 1)
     }     }
   }   }
-  // l'AND con quella maschera ​dà il resto dopo aver diviso per 4+  // l'AND con quella maschera ​dà il resto dopo aver diviso per 4
   // quindi un valore tra 0 e 3 che corrisponde al LED da accendere   // quindi un valore tra 0 e 3 che corrisponde al LED da accendere
   return ctx & 0b00000011;   return ctx & 0b00000011;
Linea 501: Linea 500:
   // eseguita ogni volta che scade il timer (16ms)   // eseguita ogni volta che scade il timer (16ms)
   // ogni 16ms viene incrementato il valore della variabile usata per    // ogni 16ms viene incrementato il valore della variabile usata per 
-  // gestire il poweroff dopo 64s di inattività ​e il debouncing+  // gestire il poweroff dopo 64s di inattività ​e il debouncing
   time++; // increase each 16 ms   time++; // increase each 16 ms
   // dopo ogni reset viene mischiato il seed per 8 volte, il seed non   // dopo ogni reset viene mischiato il seed per 8 volte, il seed non
-  // cabia più fino al reset successivo+  // cabia più ​fino al reset successivo
   if (nrot) {   if (nrot) {
     nrot--;     nrot--;
Linea 525: Linea 524:
   // ADC   // ADC
   // Il pin PB5/ADC0 (start/​reset) viene usato per generare il seed    // Il pin PB5/ADC0 (start/​reset) viene usato per generare il seed 
-  // attivando l'ADC quando ​è scollegato per ottenere un valore casuale+  // attivando l'ADC quando ​è scollegato per ottenere un valore casuale
   // il valore viene poi mischiato otto volte nella ISR usando il timer   // il valore viene poi mischiato otto volte nella ISR usando il timer
   ADCSRA |= (1 << ADEN); // abilita l'ADC (pagina 82 e 92)   ADCSRA |= (1 << ADEN); // abilita l'ADC (pagina 82 e 92)
Linea 532: Linea 531:
   // la conversione (pagina 83)   // la conversione (pagina 83)
   while (ADCSRA & (1 << ADSC)); ​   while (ADCSRA & (1 << ADSC)); ​
-  // l'​ADC ​è un 4 canali a 10 bit ad approssimazioni successive; per +  // l'​ADC ​è un 4 canali a 10 bit ad approssimazioni successive; per 
   // ottenere 8 bit si considerano solo gli 8 bit meno significativi ​   // ottenere 8 bit si considerano solo gli 8 bit meno significativi ​
   // contenuti nel registro ADCL (gli altri due sono in ADCH)   // contenuti nel registro ADCL (gli altri due sono in ADCH)
Linea 540: Linea 539:
   // abilita l'​interrupt del watchdog timer (interrupt mode pag 43)   // abilita l'​interrupt del watchdog timer (interrupt mode pag 43)
   // il WDT usa un oscillatore separato a 128kHz (il timer va col clock)   // il WDT usa un oscillatore separato a 128kHz (il timer va col clock)
-  // senza prescaling c'è un timeout ogni 16ms (2048 cicli, pag 43) e+  // senza prescaling c'è un timeout ogni 16ms (2048 cicli, pag 43) e
   // viene eseguita la ISR   // viene eseguita la ISR
   WDTCR = (1 << WDTIE); // parte il watchdog timer con prescaler da 16ms   WDTCR = (1 << WDTIE); // parte il watchdog timer con prescaler da 16ms
Linea 557: Linea 556:
   // IMPOSTAZIONE TIMER/​COUNTER per generare il segnale PWM del buzzer   // IMPOSTAZIONE TIMER/​COUNTER per generare il segnale PWM del buzzer
    
-  // cambia la modalità ​di funzionamento del timer che passa da normal  +  // cambia la modalità ​di funzionamento del timer che passa da normal  
-  // a PWM phase correct (WGM0[2:​0]=001) dove conta in su e in giù fino +  // a PWM phase correct (WGM0[2:​0]=001) dove conta in su e in giù ​fino 
-  // a 0xFF (nella funzione play() ​conterà ​fino al valore contenuto nel +  // a 0xFF (nella funzione play() ​conterà ​fino al valore contenuto nel 
-  // registro OCR0A per modificare la frequenza e produrre ​più note))+  // registro OCR0A per modificare la frequenza e produrre ​più ​note))
   // Si imposta il compare output mode del waveform generator in modo    // Si imposta il compare output mode del waveform generator in modo 
   // che il pin del buzzer PB1/OC0B (COM0B[1:​0]=10) vada basso sul   // che il pin del buzzer PB1/OC0B (COM0B[1:​0]=10) vada basso sul
   // match col valore del registro OCR0B mentre conta in su e alto    // match col valore del registro OCR0B mentre conta in su e alto 
-  // mentre conta in giù (OCR0B ​è impostato nella funzione play() come+  // mentre conta in giù ​(OCR0B ​è impostato nella funzione play() come
   // OCR0A) generando un onda quadra con la frequenza desiderata   // OCR0A) generando un onda quadra con la frequenza desiderata
-  // NB il segnale PWM è presente solo se il pin è impostato come uscita+  // NB il segnale PWM Ã¨ presente solo se il pin Ã¨ impostato come uscita
   // (pag 68) quindi il buzzer non suona finche non si chiama play()   // (pag 68) quindi il buzzer non suona finche non si chiama play()
   TCCR0A = (1 << COM0B1) | (0 << COM0B0) | (0 << WGM01) ​ | (1 << WGM00); ​   TCCR0A = (1 << COM0B1) | (0 << COM0B0) | (0 << WGM01) ​ | (1 << WGM00); ​
Linea 572: Linea 571:
   // LETTURA O RESET DELL'​HIGH SCORE DA EEPROM PREMENDO START+ROSSO   // LETTURA O RESET DELL'​HIGH SCORE DA EEPROM PREMENDO START+ROSSO
    
-  // maxLvl viene scritto e letto negato (con l'​operatore ~) perché ​il  +  // maxLvl viene scritto e letto negato (con l'​operatore ~) perché ​il  
-  // valore di default della EEPROM ​è sempre 0xFF (255 e non zero) +  // valore di default della EEPROM ​è sempre 0xFF (255 e non zero) 
-  // (uint8_t*) 0 è un puntatore a un byte che parte dall'​indirizzo 0+  // (uint8_t*) 0 Ã¨ un puntatore a un byte che parte dall'​indirizzo 0
   maxLvl = ~eeprom_read_byte((uint8_t*) 0);    maxLvl = ~eeprom_read_byte((uint8_t*) 0); 
    
Linea 580: Linea 579:
   switch (PINB & 0b00011101) {   switch (PINB & 0b00011101) {
     // AND tra gli ingressi e la maschera sopra; 0 significa premuto, ​     // AND tra gli ingressi e la maschera sopra; 0 significa premuto, ​
-    // PB1 è il buzzer e PB5 non conta (è un reset attivo basso ma in  +    // PB1 Ã¨ il buzzer e PB5 non conta (è un reset attivo basso ma in  
-    // questo punto del programma ​sarà già alto); i pin dei pulsanti ​+    // questo punto del programma ​sarà già ​alto); i pin dei pulsanti ​
     // non premuti sono al livello alto (pull-up) quindi controlliamo ​     // non premuti sono al livello alto (pull-up) quindi controlliamo ​
-    // se PB3 (LED rosso) ​è premuto e nel caso resettiamo l'high score+    // se PB3 (LED rosso) ​è premuto e nel caso resettiamo l'high score
     case 0b00010101: // PB3 premuto dopo il reset -> azzera high-score     case 0b00010101: // PB3 premuto dopo il reset -> azzera high-score
       eeprom_write_byte((uint8_t*) 0, 255); // scrive 255 -> livello 0       eeprom_write_byte((uint8_t*) 0, 255); // scrive 255 -> livello 0
Linea 593: Linea 592:
     // MOSTRA LA SEQUENZA     // MOSTRA LA SEQUENZA
     // reimposta ctx al valore del seed; la sequenza di valori di ctx      // reimposta ctx al valore del seed; la sequenza di valori di ctx 
-    // sarà sempre la stessa sequenza ​finché ​non si resetta+    // sarà ​sempre la stessa sequenza ​finché ​non si resetta
     resetCtx();     resetCtx();
-    // accende in sequenza un numero di LED pari al livello ​più uno+    // accende in sequenza un numero di LED pari al livello ​più ​uno
     for (uint8_t cnt = 0; cnt <= lvl; cnt++) {      for (uint8_t cnt = 0; cnt <= lvl; cnt++) { 
       // attesa tra un LED e il successivo; valore massimo 65536 (2^16)       // attesa tra un LED e il successivo; valore massimo 65536 (2^16)
Linea 617: Linea 616:
     for (uint8_t cnt = 0; cnt <= lvl; cnt++) {     for (uint8_t cnt = 0; cnt <= lvl; cnt++) {
       bool pressed = false;       bool pressed = false;
-      // finché ​non si preme un bottone+      // finché ​non si preme un bottone
       while (!pressed) {       while (!pressed) {
         // provo i quattro bottoni         // provo i quattro bottoni
         for (uint8_t i = 0; i < 4; i++) {         for (uint8_t i = 0; i < 4; i++) {
-          // controlla se il pulsante i è premuto+          // controlla se il pulsante i Ã¨ premuto
           // buttons & maschera -> bit a 1 solo per il pin/​pulsante i           // buttons & maschera -> bit a 1 solo per il pin/​pulsante i
           // PINB ha tutti i bit a 1 (resistenze di pull-up attivate           // PINB ha tutti i bit a 1 (resistenze di pull-up attivate
           // nella funzione play) tranne quello del pulsante premuto           // nella funzione play) tranne quello del pulsante premuto
           // l'​espressione logica tra le parentesi interne vale 0 se           // l'​espressione logica tra le parentesi interne vale 0 se
-          // il pulsante i è premuto, poi viene complementata+          // il pulsante i Ã¨ premuto, poi viene complementata
           if (!(PINB & buttons[i] & 0b00011101)) {           if (!(PINB & buttons[i] & 0b00011101)) {
             // DEBOUNCE             // DEBOUNCE
             // se sono passati 16ms (tempo max per eventuali rimbalzi o             // se sono passati 16ms (tempo max per eventuali rimbalzi o
-            // se è stato premuto un pulsante diverso (non è rimbalzo)+            // se Ã¨ stato premuto un pulsante diverso (non Ã¨ rimbalzo)
             if (time > 1 || i != lastKey) {             if (time > 1 || i != lastKey) {
               // accendi il LED i e registra la pressione del tasto               // accendi il LED i e registra la pressione del tasto
Linea 637: Linea 636:
               // genera di nuovo l'​indice LED della sequenza riprodotta               // genera di nuovo l'​indice LED della sequenza riprodotta
               uint8_t correct = simple_random4();​               uint8_t correct = simple_random4();​
-              // se si è premuto il pulsante sbagliato+              // se si Ã¨ premuto il pulsante sbagliato
               if (i != correct) {               if (i != correct) {
                 // accendi il LED giusto tante volte pari al livello raggiunto                 // accendi il LED giusto tante volte pari al livello raggiunto
Linea 648: Linea 647:
                 gameOver();                 gameOver();
               }               }
-              // è stato premuto il pulsante giusto ​+              // Ã¨ stato premuto il pulsante giusto ​
               time = 0; // azzera time               time = 0; // azzera time
               lastKey = i; // memorizzo l'​indice dell'​ultimo LED               lastKey = i; // memorizzo l'​indice dell'​ultimo LED
-              break; // esce dal ciclo for e smette di controllare se è +              break; // esce dal ciclo for e smette di controllare se Ã¨ 
                      // premuto un pulsante; passa al LED successivo ​                      // premuto un pulsante; passa al LED successivo ​
                      // della sequenza                      // della sequenza
Linea 685: Linea 684:
 Per programmare il micro ATtiny13A useremo una scheda Arduino Uno come programmatore come descritto in [[https://​create.arduino.cc/​projecthub/​taunoerik/​programming-attiny13-with-arduino-uno-07beba|questo tutorial]]. Per programmare il micro ATtiny13A useremo una scheda Arduino Uno come programmatore come descritto in [[https://​create.arduino.cc/​projecthub/​taunoerik/​programming-attiny13-with-arduino-uno-07beba|questo tutorial]].
  
-La soluzione ​più semplice ​è quella di usare una breadboard e sei cavi rigidi collegati come nella figura seguente((LED e resistori non servono ma permettono di testare velocemente se la programmazione funziona caricando sul micro uno sketch che fa lampeggiare il led)):+La soluzione ​più ​semplice ​è quella di usare una breadboard e sei cavi rigidi collegati come nella figura seguente((LED e resistori non servono ma permettono di testare velocemente se la programmazione funziona caricando sul micro uno sketch che fa lampeggiare il led)):
  
 {{::​arduino-attiny13.jpeg|come collegare Arduino e ATtiny13 per programmarlo}} {{::​arduino-attiny13.jpeg|come collegare Arduino e ATtiny13 per programmarlo}}
  
-Una soluzione ​più robusta e senza cavi volanti ​è quella di produrre uno shield((vedi [[https://​leonardocanducci.org/​wiki/​tp3/​shield_ultiboard|dagli appunti di terza]] come fare)) con zoccolo [[wpi>​Zero_Insertion_Force|ZIF]] dedicata:+Una soluzione ​più ​robusta e senza cavi volanti ​è quella di produrre uno shield((vedi [[https://​leonardocanducci.org/​wiki/​tp3/​shield_ultiboard|dagli appunti di terza]] come fare)) con zoccolo [[wpi>​Zero_Insertion_Force|ZIF]] dedicata:
  
 {{::​shield-arduino-attiny13a.jpeg|shield per programmare gli ATtiny13A}} {{::​shield-arduino-attiny13a.jpeg|shield per programmare gli ATtiny13A}}
Linea 696: Linea 695:
   * caricare sulla scheda lo sketch //​ArduinoISP//​ (da //File -> Esempi -> 11. ArduinoISP//​)   * caricare sulla scheda lo sketch //​ArduinoISP//​ (da //File -> Esempi -> 11. ArduinoISP//​)
   * inserire l'URL ''​https://​mcudude.github.io/​MicroCore/​package_MCUdude_MicroCore_index.json''​ nel campo //URL aggiuntive per il gestore schede// delle impostazioni   * inserire l'URL ''​https://​mcudude.github.io/​MicroCore/​package_MCUdude_MicroCore_index.json''​ nel campo //URL aggiuntive per il gestore schede// delle impostazioni
-  * installare il pacchetto //​MicroCore//​ che serve per utilizzare gli ATtiny13A nell'​ambiente di sviluppo Arduino da //​Gestore ​schede…// nel menu //Strumenti -> Scheda//+  * installare il pacchetto //​MicroCore//​ che serve per utilizzare gli ATtiny13A nell'​ambiente di sviluppo Arduino da //​Gestore ​schede…// nel menu //Strumenti -> Scheda//
  
-Fatto questo si inserisce il microcontrollore nello zoccolo ZIF (o nella breadboard con i collegamenti visti sopra) quindi si apre il programma che andrà ​caricato sull'​ATtiny13A. Prima del caricamento bisogna modificare le impostazioni di default della scheda (che __andranno ripristinate per tornare a utilizzare una scheda Arduino__) scegliendo, dal menu //​Strumenti//:​+Fatto questo si inserisce il microcontrollore nello zoccolo ZIF (o nella breadboard con i collegamenti visti sopra) quindi si apre il programma che andrà ​caricato sull'​ATtiny13A. Prima del caricamento bisogna modificare le impostazioni di default della scheda (che __andranno ripristinate per tornare a utilizzare una scheda Arduino__) scegliendo, dal menu //​Strumenti//:​
   * Scheda: ATtiny13   * Scheda: ATtiny13
   * BOD: BOD disabled   * BOD: BOD disabled
Linea 706: Linea 705:
   * Programmatore:​ __Arduino as ISP__   * Programmatore:​ __Arduino as ISP__
  
-A questo punto è possibile caricare il programma sull'​ATtiny13A scegliendo //Carica tramite un programmatore//​ dal menu //Sketch// (NB non con il pulsante //Carica// che useremmo per programmare la scheda Arduino!).+A questo punto Ã¨ possibile caricare il programma sull'​ATtiny13A scegliendo //Carica tramite un programmatore//​ dal menu //Sketch// (NB non con il pulsante //Carica// che useremmo per programmare la scheda Arduino!).
  
-Terminato il caricamento si può montare il microcontrollore sulla scheda Simon.+Terminato il caricamento si può ​montare il microcontrollore sulla scheda Simon.
  
-Volendo ​è possibile caricare un bootloader sugli ATtiny13A per utilizzarli al posto di una scheda Uno - ma ancora ​più limitata. Per farlo si usa la voce //Scrivi bootloader//​ dal menu //​Strumenti//​. Nel nostro caso non è necessario ​perché ​il programma non fa uso delle librerie Arduino e ci interessa solo compilare e "​flashare"​ il firmware sul microcontrollore.+Volendo ​è possibile caricare un bootloader sugli ATtiny13A per utilizzarli al posto di una scheda Uno - ma ancora ​più ​limitata. Per farlo si usa la voce //Scrivi bootloader//​ dal menu //​Strumenti//​. Nel nostro caso non Ã¨ necessario ​perché ​il programma non fa uso delle librerie Arduino e ci interessa solo compilare e "​flashare"​ il firmware sul microcontrollore.
  
  
Linea 720: Linea 719:
   * forare con punta da 0.8mm   * forare con punta da 0.8mm
   * come saldare (vedi immagine)   * come saldare (vedi immagine)
-  * montare i LED rispettando la polarità+  * montare i LED rispettando la polarità
   * montare lo zoccolo nel verso giusto   * montare lo zoccolo nel verso giusto
   * montare il portabatteria nel verso giusto   * montare il portabatteria nel verso giusto
Linea 727: Linea 726:
 {{::​saldare.jpeg?​400|come saldare}} {{::​saldare.jpeg?​400|come saldare}}
  
-La scheda assemblata ​avrà più o meno questo aspetto:+La scheda assemblata ​avrà più ​o meno questo aspetto:
  
 {{:​prototipo.jpeg?​400|scheda simon assemblata}} {{:​prototipo.jpeg?​400|scheda simon assemblata}}
simon.txt · Ultima modifica: 2020/02/14 17:55 da admin