<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="it">
	<id>https://www.raspibo.org/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Oloturia</id>
	<title>raspibo - Contributi utente [it]</title>
	<link rel="self" type="application/atom+xml" href="https://www.raspibo.org/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Oloturia"/>
	<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php/Speciale:Contributi/Oloturia"/>
	<updated>2026-05-23T21:06:11Z</updated>
	<subtitle>Contributi utente</subtitle>
	<generator>MediaWiki 1.35.5</generator>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=OV7670&amp;diff=7549</id>
		<title>OV7670</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=OV7670&amp;diff=7549"/>
		<updated>2025-02-08T10:11:21Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* Come funziona OV7670 e come non aver paura di YCbCr */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Diversi anni fa comprai questa OV7670 con l'illusione che sarebbe stato divertente farla funzionare con un Arduino. Il mio obiettivo era una cosa molto semplice, come un sensore che scatta foto quando triggerato e che salvasse l'immagine su una SD. Purtroppo non si è rivelato possibile per diverse limitazioni delle schede Arduino più economiche: una scheda come l'Uno non ha abbastanza RAM per memorizzare un'immagine intera alle risoluzioni più alte, ma anche la più dotata Due ha bisogno di una gabola per riuscire ad avere i colori.&lt;br /&gt;
&lt;br /&gt;
[[File:OV7670.JPG]]&lt;br /&gt;
&lt;br /&gt;
Per ovviare a questo occorre una memoria FIFO, normalmente integrata nella scheda assieme a OV7670, ma la mia non l'aveva e acquistarla a parte ha solo comportato avere due problemi (come far funzionare la cam E come far funzionare la FIFO) al posto di uno.&lt;br /&gt;
&lt;br /&gt;
Fra tutte le schede ho scelto l'Arduino Due perché ha abbastanza memoria per tenere un'intera immagine in QVGA (320x240) in bianco e nero e perché ha livelli logici a 3,3V, il che permette di collegarlo a OV7670 senza bisogno di un partitore di tensione.&lt;br /&gt;
&lt;br /&gt;
= Le Guide =&lt;br /&gt;
&lt;br /&gt;
== Instructables ==&lt;br /&gt;
&lt;br /&gt;
Il primo passo per far funzionare una qualsiasi cosa è cercare guide e datasheet. La prima guida in cui ci si imbatte è questa:&lt;br /&gt;
https://www.instructables.com/How-to-Connect-OV7670-to-Arduino-Due/&lt;br /&gt;
&lt;br /&gt;
Questo Instructable è stato il mio punto di partenza. Inizia con un semplice schema per il wiring:&lt;br /&gt;
&lt;br /&gt;
 DUE		OV7670&lt;br /&gt;
 3.3V		VDD&lt;br /&gt;
 GND		GND&lt;br /&gt;
 SCL(21)	SDIOC&lt;br /&gt;
 SDA(20)	SDIOD&lt;br /&gt;
 52		VSYNC&lt;br /&gt;
 32		PCLK&lt;br /&gt;
 7		XCLK&lt;br /&gt;
 44		D7&lt;br /&gt;
 45		D6&lt;br /&gt;
 46		D5&lt;br /&gt;
 47		D4&lt;br /&gt;
 48		D3&lt;br /&gt;
 49		D2&lt;br /&gt;
 50		D1&lt;br /&gt;
 51		D0&lt;br /&gt;
 33		RESET&lt;br /&gt;
 GND		PWDN&lt;br /&gt;
&lt;br /&gt;
A questo schema -senza nessun commento- manca il collegamento di HREF. Non verrà utilizzato e non è necessario collegarlo, ma nella guida non è specificato.&lt;br /&gt;
Nel resto della guida si spiega come il Due debba generare un clock e come scrivere nei registri di OV7670 tramite I²C. Viene fornito anche uno sketch che sembrerebbe funzionare e che in teoria leggerebbe l'immagine in bianco e nero per poi mandare l'output su seriale. Putroppo i programmi per decodificare questo segnale sono su un sito irraggiungibile. Ero quindi a un punto morto.&lt;br /&gt;
&lt;br /&gt;
Ok ok non del tutto, nei commenti (ahimè l'ho scoperto quando ormai avevo già riscritto parte del codice) c'è una soluzione fatta in Processing che funziona bene:&lt;br /&gt;
https://pastebin.com/weAEcrQG&lt;br /&gt;
&lt;br /&gt;
== Come funziona OV7670 e come non aver paura di YCbCr ==&lt;br /&gt;
&lt;br /&gt;
http://embeddedprogrammer.blogspot.com/2012/07/hacking-ov7670-camera-module-sccb-cheat.html&lt;br /&gt;
&lt;br /&gt;
Trovandomi un po' spiazzato, ho pensato che forse avrei dovuto approfittarne per riscrivere da capo tutto quanto, così da far funzionare finalmente la cam e allo stesso tempo imparare qualcosa di nuovo. Lo sketch dell'instructable precedente era per me un po' ostico da leggere, con molti riferimenti a me sconosciuti ai registri interni dell'Arduino Due e della cam. Punto di partenza è stato questo sito che spiega diverse cose sul funzionamento di OV7670.&lt;br /&gt;
&lt;br /&gt;
Qui scopriamo che:&lt;br /&gt;
 VSYNC è il segnale di sincronia verticale (HREF quello orizzontale, ma non lo useremo)&lt;br /&gt;
 PCLK è il clock del pixel (in realtà -mezzo- pixel)&lt;br /&gt;
 XCLK è il clock esterno, OV7670 ha bisogno di un clock esterno per funzionare: se volete scansionare gli indirizzi I²C per scoprire quello della cam, dovrete prima collegare un clock a XCLK&lt;br /&gt;
&lt;br /&gt;
Un pixel su un monitor è composto da due informazioni: la posizione e il colore. La posizione è espressa in coordinate X e Y mentre il colore dalla luminosità dei colori primari R=Red/Rosso, G=Green/Verde e B=Blue/Blu. Normalmente ogni colore è espresso con 8 bit, da cui il nome RGB888. Purtroppo OV7670 invece comunica i pixel sequenzialmente a partire da 0,0 a 320,240 riga per riga e come formati di colore ha RGB565, RGB555 e RGB444 oppure YCbCr422. Il primo semplicemente manda 5 bit di R, 6 di G e 5 di B oppure rispettivamente 5 e 4 per ogni colore. L'ultimo formato invece è completamente diverso e necessita di un approfondimento.&lt;br /&gt;
&lt;br /&gt;
Nel format YCbCr l'immagine è separata in tre canali: la luma (Y) ossia la luminosità (se prendessimo solo Y come valore per RGB allora vedremmo l'immagine in bianco e nero) e la croma, ovvero i livelli di differenza da Y dal blu (Cb) e dal rosso (Cr). Ognuno di questi occupa un byte di informazione.&lt;br /&gt;
&lt;br /&gt;
Ogni falling del PCLK la cam invia un byte di informazione in modo parallelo sui pin da D0 a D7. Come fa quindi a comunicare un pixel ogni colpo PCLK? Semplice: non lo fa. Manda i valori alternati in questo modo:&lt;br /&gt;
Cb0,Y0,Cr0,Y1,Cb2,Y2,Cr2,Y3...&lt;br /&gt;
La definizione di &amp;quot;Pixel Clock&amp;quot; è infatti fuorviante. Sarebbe &amp;quot;Half Pixel Clock&amp;quot; semmai.&lt;br /&gt;
&lt;br /&gt;
Se bastasse l'immagine in bianco e nero allora basterà memorizzare un PCLK no e uno sì e avremo la luma. Questo è quello che faceva in teoria lo sketch del primo instructable. Ovviamente a me non bastava (a parte il fatto che comunque non funzionava), volevo anche i colori. Cb e Cr sono comuni per due pixel alla volta. Sempre secondo il link alla guida sopra: &lt;br /&gt;
 pixel 0 = Y0 Cb0 Cr0&lt;br /&gt;
 pixel 1 = Y1 Cb0 Cr0&lt;br /&gt;
 pixel 2 = Y2 Cb2 Cr2&lt;br /&gt;
 pixel 3 = Y3 Cb2 Cr2&lt;br /&gt;
&lt;br /&gt;
Questo semplificava molto le cose. Invece di mandare la luma via seriale e scartare la croma, avrei mandato alternativamente prima la luma del frame e successivamente la croma. Avrebbe causato degli strani effetti nelle immagini in movimento ma sarebbe stato meglio di prima.&lt;br /&gt;
Perché non mandare contemporaneamente l'informazione? L'Arduino Due ha solo 96KB di SRAM, la luma o le crome da sole sono 320*240*1 byte = 76.8KB l'una. Mandare i dati via seriale alla fine della riga poteva essere una soluzione ma causava numerosi glitch sull'immagine risultante.&lt;br /&gt;
&lt;br /&gt;
La guida è chiara, ma purtroppo manca uno sketch per il Due e relativo programma per processare l'immagine da seriale.&lt;br /&gt;
&lt;br /&gt;
== Il datasheet ==&lt;br /&gt;
&lt;br /&gt;
http://web.mit.edu/6.111/www/f2015/tools/OV7670app.pdf&lt;br /&gt;
&lt;br /&gt;
In questo datasheet sono elencati i registri interni di OV7670. Nello sketch dell'Instructable sono impostati nella maggior parte dei casi senza spiegare cosa servono. Gli stessi valori li ho trovati anche in quest'altra guida: http://embeddedprogrammer.blogspot.com/2012/07/hacking-ov7670-camera-module-sccb-cheat.html e dal relativo codice su github: https://github.com/indrekluuk/LiveOV7670 per il collegamento della cam a un display. &lt;br /&gt;
Da quel che mi è parso di capire, sono i valori che il driver di Linux mette di default e usa per le varie impostazioni della cam (ad es. per passare da QVGA ad altri formati come il QCIF). Molto interessante ma a questo punto la mia missione era già diventata qualcos'altro, ovvero fare in modo che questi registri potessero essere modificati in modo interattivo.&lt;br /&gt;
&lt;br /&gt;
= La soluzione =&lt;br /&gt;
&lt;br /&gt;
L'obiettivo è quindi creare un programma che leggesse la seriale e restituisse l'immagine e allo stesso tempo fare in modo che si potessero leggere e scrivere i registri della cam.&lt;br /&gt;
&lt;br /&gt;
== Lato Arduino Due ==&lt;br /&gt;
&lt;br /&gt;
Lo sketch dell'Instructable fa le seguenti cose:&lt;br /&gt;
* Imposta i registri di OV7670 in modo che sia QVGA in formato YCbCr422&lt;br /&gt;
* Manda un segnale &amp;quot;*RDY*&amp;quot; e memorizza su una matrice un byte no e uno sì dei pin D0-D7&lt;br /&gt;
* Quando l'immagine è completa, manda via seriale ogni singolo byte della matrice&lt;br /&gt;
&lt;br /&gt;
La modifica più importante è stata quella di mandare alternati il valore di Y e quello di CbCr. Nel frattempo avrebbe anche aspettato dallo script lato computer un segnale per dare il via alla lettura oppure un comando per leggere o scrivere su uno dei registri. Successivamente ho anche eliminato tutte le configurazioni che non cambiavano significativamente l'immagine e che probabilmente hanno a che fare con cose come il bilanciamento del bianco.&lt;br /&gt;
&lt;br /&gt;
Vediamo alcuni dettagli dello sketch.&lt;br /&gt;
&lt;br /&gt;
=== Generare un segnale di clock con Arduino ===&lt;br /&gt;
&lt;br /&gt;
Arduino Due ha un generatore di PWM con i quali è possibile creare un segnale di clock di almeno 8MHz sufficienti per il XCLK di OV7670.&lt;br /&gt;
&lt;br /&gt;
  int32_t PWM_pin = digitalPinToBitMask(XCLK);&lt;br /&gt;
  REG_PMC_PCER1 = 1 &amp;lt;&amp;lt; 4;     // Enable peripheral ID 36 (PWM) in the peripheral clock enable register - see 28.15.23&lt;br /&gt;
  REG_PIOC_PDR |= PWM_pin;    // Allow peripheral control for PWM_pin&lt;br /&gt;
  REG_PIOC_ABSR |= PWM_pin;   // Select peripheral B&lt;br /&gt;
  REG_PWM_CPRD6 = 8;          // Period: 84 MHz / 8 = 10.5 MHz - see 38.6.2.2 of datasheet&lt;br /&gt;
  REG_PWM_CDTY6 = 4;          // Duty Cycle: 8 / 4  = 0.5&lt;br /&gt;
  REG_PWM_ENA = 1 &amp;lt;&amp;lt; 6;       // Enable PWML6 (pin 7) - see 38.5.1 and 38.7.5 of datasheet for more info&lt;br /&gt;
&lt;br /&gt;
Gran parte delle informazioni su come funziona questo codice è spiegato su questa guida:&lt;br /&gt;
https://nhoffmanresearch.com/index.php/12-arduino-trap-control&lt;br /&gt;
e relativo datasheet del SAM3X9E:&lt;br /&gt;
http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-11057-32-bit-Cortex-M3-Microcontroller-SAM3X-SAM3A_Datasheet.pdf&lt;br /&gt;
&lt;br /&gt;
=== I registri ===&lt;br /&gt;
&lt;br /&gt;
Tramite I²C è possibile leggere lo stato di un registro o scrivere un nuovo valore. La lista dei registri è elencata sul datasheet, tuttavia alcuni, descritti come &amp;quot;Reserved&amp;quot;, non sono documentati. La prima cosa quando si accende la cam è settare i registri in modo che trasmetta le informazioni nel formato QVGA e YCbCr, inoltre sono abilitate alcune funzioni come l'autobilanciamento del bianco. Una volta impostate queste cose, si può cominciare a catturare le immagini.&lt;br /&gt;
&lt;br /&gt;
=== Loop ===&lt;br /&gt;
&lt;br /&gt;
Una delle cose che non riuscivo a far funzionare era centrare l'immagine. Essendo scollegato HREF il punto di inizio era arbitrario, e questo comportava che l'immagine fosse fuori quadro. Ho cambiato un po' questa filosofia e ho fatto in modo che l'Arduino Due aspettasse un segnale sulla seriale prima di iniziare a trasmettere. Il segnale è composto da due byte, se sono entrambi 0xD0 allora invia una nuova immagine, se invece il primo è un altro valore, viene inviato il registro corrispondente a quel valore, se sono entrambi diversi il registro corrispondente al primo valore viene aggiornato con il secondo valore. Non esiste un registro 0xD0, quindi possiamo usare tale byte per segnalare quando siamo pronti a ricevere una nuova immagine.&lt;br /&gt;
&lt;br /&gt;
In questo modo è possibile alterare in diretta l'immagine, cambiare luminosità, formato e anche scoprire a cosa servono i registri &amp;quot;Reserved&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Cattura dell'immagine ===&lt;br /&gt;
&lt;br /&gt;
La cattura è fatta in due passate per questioni di spazio sulla RAM. Per prima cosa leggiamo Y e poi CbCr. Se non siamo interessati al colore, possiamo commentare la seconda chiamata alla funzione captureImg a cui ho aggiunto un terzo parametro, il bool chroma, per specificare se salvare i bit pari o quelli dispari.&lt;br /&gt;
Ogni PCLK basso viene aggiunto un valore (Y oppure CbCr) alla matrice che rappresenta le righe e le colonne. Durante la lettura il tempo è critico, per cui occorrono alcuni accorgimenti per sveltire le operazioni.&lt;br /&gt;
&lt;br /&gt;
 noInterrupts();&lt;br /&gt;
&lt;br /&gt;
Questo comando disabilita gli interrupt. Non mi sembra che abbia nessun effetto benefico, ma male non fa.&lt;br /&gt;
&lt;br /&gt;
 REG_PIOB_PDSR &amp;amp; (1 &amp;lt;&amp;lt; 21)&lt;br /&gt;
 REG_PIOD_PDSR &amp;amp; (1 &amp;lt;&amp;lt; 10)&lt;br /&gt;
&lt;br /&gt;
Purtroppo le tanto comode funzioni digitalRead() di Arduino sono troppo lente per l'output di OV7670. Leggere direttamente il Pin Data Status Register (PDSR) di SAM3X9E è molto più veloce. Il bit 21 del PortB corrisponde al pin 52, che è quello dove abbiamo attaccato VSYNC, il bit 10 del PortD è il pin 32, dove abbiamo attaccato PCLK. Non è immediato convertire il pin in registro, ma ci sono moltissimi schemi con il pinout del Due, con descritto per ogni pin il Port e il bit.&lt;br /&gt;
&lt;br /&gt;
 (REG_PIOC_PDSR &amp;amp; 0xFF000) &amp;gt;&amp;gt; 12&lt;br /&gt;
&lt;br /&gt;
Invece il PortC sono tutti i pin dov0 abbiamo collegato da D0 a D7. Memorizzando lo stato del Port e applicando un filtro in modo che restituisca solo i valori che ci interessano (PortC dalla 12 alla 19), non dobbiamo subire la costrizione di leggere lo stato di un pin alla volta.&lt;br /&gt;
&lt;br /&gt;
Allo stesso tempo non è possibile usare la seriale di programmazione per trasmettere la matrice, occorre usare la porta nativa (Native) e invece di Serial, la funzione SerialUSB.write. Non c'è bisogno di inizializzarla con un baud rate perché andrà sempre alla velocità massima possibile. Questo dualismo mi ha permesso anche di fare alcune cose interessanti, come usare la porta nativa per la comunicazione con il programma che elabora le immagini e la porta di programmazione per mandare dei messaggi di debug.&lt;br /&gt;
&lt;br /&gt;
== Lato Python ==&lt;br /&gt;
&lt;br /&gt;
Sul computer ho scritto un piccolo script che pettinasse l'output dell'Arduino.&lt;br /&gt;
&lt;br /&gt;
Per prima cosa manda un segnale di due byte. Se il segnale è 0xD0 0xD0 allora si mette in attesa di larghezza*altezza byte. Una volta ricevuti e messi in ordine (ricordate, un dato di croma vale per due pixel, mentre la luma c'è per ognuno) occorre usare alcune formule per trasformare i dati in RGB. Ho usato questa formula, che si può trovare nelle guide già citate sopra:&lt;br /&gt;
 R = int(max(0, min(255,Y + 1.40200 * (Cr - 0x80))))&lt;br /&gt;
 G = int(max(0, min(255,Y - 0.34414 * (Cb - 0x80) - 0.71414 * (Cr - 0x80))))&lt;br /&gt;
 B = int(max(0, min(255,Y + 1.77200 * (Cb - 0x80))))&lt;br /&gt;
&lt;br /&gt;
Lo script readYUV422.py restituisce quindi una bitmap. Gli altri script saveYUV422.py e showYUV422.py rispettivamente salvano l'immagine con PIL oppure la mostrano con pygame. L'altro script, tkinterface.py, invece è un'interfaccia fatta con tkinter con cui possiamo interagire direttamente con i registri di OV7670. Per risolvere il problema delle azioni concorrenti, ho usato un thread che facesse il refresh dell'immagine. La porta usata è /dev/ttyACM0, ma è possibile cambiarla aggiungendo un argomento quando si lancia lo script.&lt;br /&gt;
&lt;br /&gt;
[[File:OVCAM.JPG]]&lt;br /&gt;
&lt;br /&gt;
= I risultati =&lt;br /&gt;
&lt;br /&gt;
Non è andato sempre tutto bene al primo colpo. Soprattutto all'inizio, quando non avevo ancora capito come leggere l'output, la cam ha dato degli output interessanti. Eccone alcuni.&lt;br /&gt;
[[File:Glitches.jpg]]&lt;br /&gt;
&lt;br /&gt;
= Il repo =&lt;br /&gt;
&lt;br /&gt;
Tutta la roba, con tutte le istruzioni e quant'altro, lo trovate nel repository su:&lt;br /&gt;
https://github.com/oloturia/ovcam&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=OV7670&amp;diff=7548</id>
		<title>OV7670</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=OV7670&amp;diff=7548"/>
		<updated>2025-02-08T10:10:48Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* Come funziona OV7670 e come non aver paura di YCbCr */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Diversi anni fa comprai questa OV7670 con l'illusione che sarebbe stato divertente farla funzionare con un Arduino. Il mio obiettivo era una cosa molto semplice, come un sensore che scatta foto quando triggerato e che salvasse l'immagine su una SD. Purtroppo non si è rivelato possibile per diverse limitazioni delle schede Arduino più economiche: una scheda come l'Uno non ha abbastanza RAM per memorizzare un'immagine intera alle risoluzioni più alte, ma anche la più dotata Due ha bisogno di una gabola per riuscire ad avere i colori.&lt;br /&gt;
&lt;br /&gt;
[[File:OV7670.JPG]]&lt;br /&gt;
&lt;br /&gt;
Per ovviare a questo occorre una memoria FIFO, normalmente integrata nella scheda assieme a OV7670, ma la mia non l'aveva e acquistarla a parte ha solo comportato avere due problemi (come far funzionare la cam E come far funzionare la FIFO) al posto di uno.&lt;br /&gt;
&lt;br /&gt;
Fra tutte le schede ho scelto l'Arduino Due perché ha abbastanza memoria per tenere un'intera immagine in QVGA (320x240) in bianco e nero e perché ha livelli logici a 3,3V, il che permette di collegarlo a OV7670 senza bisogno di un partitore di tensione.&lt;br /&gt;
&lt;br /&gt;
= Le Guide =&lt;br /&gt;
&lt;br /&gt;
== Instructables ==&lt;br /&gt;
&lt;br /&gt;
Il primo passo per far funzionare una qualsiasi cosa è cercare guide e datasheet. La prima guida in cui ci si imbatte è questa:&lt;br /&gt;
https://www.instructables.com/How-to-Connect-OV7670-to-Arduino-Due/&lt;br /&gt;
&lt;br /&gt;
Questo Instructable è stato il mio punto di partenza. Inizia con un semplice schema per il wiring:&lt;br /&gt;
&lt;br /&gt;
 DUE		OV7670&lt;br /&gt;
 3.3V		VDD&lt;br /&gt;
 GND		GND&lt;br /&gt;
 SCL(21)	SDIOC&lt;br /&gt;
 SDA(20)	SDIOD&lt;br /&gt;
 52		VSYNC&lt;br /&gt;
 32		PCLK&lt;br /&gt;
 7		XCLK&lt;br /&gt;
 44		D7&lt;br /&gt;
 45		D6&lt;br /&gt;
 46		D5&lt;br /&gt;
 47		D4&lt;br /&gt;
 48		D3&lt;br /&gt;
 49		D2&lt;br /&gt;
 50		D1&lt;br /&gt;
 51		D0&lt;br /&gt;
 33		RESET&lt;br /&gt;
 GND		PWDN&lt;br /&gt;
&lt;br /&gt;
A questo schema -senza nessun commento- manca il collegamento di HREF. Non verrà utilizzato e non è necessario collegarlo, ma nella guida non è specificato.&lt;br /&gt;
Nel resto della guida si spiega come il Due debba generare un clock e come scrivere nei registri di OV7670 tramite I²C. Viene fornito anche uno sketch che sembrerebbe funzionare e che in teoria leggerebbe l'immagine in bianco e nero per poi mandare l'output su seriale. Putroppo i programmi per decodificare questo segnale sono su un sito irraggiungibile. Ero quindi a un punto morto.&lt;br /&gt;
&lt;br /&gt;
Ok ok non del tutto, nei commenti (ahimè l'ho scoperto quando ormai avevo già riscritto parte del codice) c'è una soluzione fatta in Processing che funziona bene:&lt;br /&gt;
https://pastebin.com/weAEcrQG&lt;br /&gt;
&lt;br /&gt;
== Come funziona OV7670 e come non aver paura di YCbCr ==&lt;br /&gt;
&lt;br /&gt;
http://embeddedprogrammer.blogspot.com/2012/07/hacking-ov7670-camera-module-sccb-cheat.html&lt;br /&gt;
&lt;br /&gt;
Trovandomi un po' spiazzato, ho pensato che forse avrei dovuto approfittarne per riscrivere da capo tutto quanto, così da far funzionare finalmente la cam e allo stesso tempo imparare qualcosa di nuovo. Lo sketch dell'instructable precedente era per me un po' ostico da leggere, con molti riferimenti a me sconosciuti ai registri interni dell'Arduino Due e della cam. Punto di partenza è stato questo sito che spiega diverse cose sul funzionamento di OV7670.&lt;br /&gt;
&lt;br /&gt;
Qui scopriamo che:&lt;br /&gt;
 VSYNC è il segnale di sincronia verticale (HREF quello orizzontale, ma non lo useremo)&lt;br /&gt;
 PCLK è il clock del pixel (in realtà -mezzo- pixel)&lt;br /&gt;
 XCLK è il clock esterno, OV7670 ha bisogno di un clock esterno per funzionare: se volete scansionare gli indirizzi I²C per scoprire quello della cam, dovrete prima collegare un clock a XCLK&lt;br /&gt;
&lt;br /&gt;
Un pixel su un monitor è composto da due informazioni: la posizione e il colore. La posizione è espressa in coordinate X e Y mentre il colore dalla luminosità dei colori primari R=Red/Rosso, G=Green/Verde e B=Blue/Blu. Normalmente ogni colore è espresso con 8 bit, da cui il nome RGB888. Purtroppo OV7670 invece comunica i pixel sequenzialmente a partire da 0,0 a 320,240 riga per riga e come formati di colore ha RGB565, RGB555 e RGB444 oppure YCbCr422. Il primo semplicemente manda 5 bit di R, 6 di G e 5 di B oppure rispettivamente 5 e 4 per ogni colore. L'ultimo formato invece è completamente diverso e necessita di un approfondimento.&lt;br /&gt;
&lt;br /&gt;
Nel format YCbCr l'immagine è separata in tre canali: la luma (Y) ossia la luminosità (se prendessimo solo Y come valore per RGB allora vedremmo l'immagine in bianco e nero) e la croma, ovvero i livelli di differenza da Y del blu (Cb) e del rosso (Cr). Ognuno di questi occupa un byte di informazione.&lt;br /&gt;
&lt;br /&gt;
Ogni falling del PCLK la cam invia un byte di informazione in modo parallelo sui pin da D0 a D7. Come fa quindi a comunicare un pixel ogni colpo PCLK? Semplice: non lo fa. Manda i valori alternati in questo modo:&lt;br /&gt;
Cb0,Y0,Cr0,Y1,Cb2,Y2,Cr2,Y3...&lt;br /&gt;
La definizione di &amp;quot;Pixel Clock&amp;quot; è infatti fuorviante. Sarebbe &amp;quot;Half Pixel Clock&amp;quot; semmai.&lt;br /&gt;
&lt;br /&gt;
Se bastasse l'immagine in bianco e nero allora basterà memorizzare un PCLK no e uno sì e avremo la luma. Questo è quello che faceva in teoria lo sketch del primo instructable. Ovviamente a me non bastava (a parte il fatto che comunque non funzionava), volevo anche i colori. Cb e Cr sono comuni per due pixel alla volta. Sempre secondo il link alla guida sopra: &lt;br /&gt;
 pixel 0 = Y0 Cb0 Cr0&lt;br /&gt;
 pixel 1 = Y1 Cb0 Cr0&lt;br /&gt;
 pixel 2 = Y2 Cb2 Cr2&lt;br /&gt;
 pixel 3 = Y3 Cb2 Cr2&lt;br /&gt;
&lt;br /&gt;
Questo semplificava molto le cose. Invece di mandare la luma via seriale e scartare la croma, avrei mandato alternativamente prima la luma del frame e successivamente la croma. Avrebbe causato degli strani effetti nelle immagini in movimento ma sarebbe stato meglio di prima.&lt;br /&gt;
Perché non mandare contemporaneamente l'informazione? L'Arduino Due ha solo 96KB di SRAM, la luma o le crome da sole sono 320*240*1 byte = 76.8KB l'una. Mandare i dati via seriale alla fine della riga poteva essere una soluzione ma causava numerosi glitch sull'immagine risultante.&lt;br /&gt;
&lt;br /&gt;
La guida è chiara, ma purtroppo manca uno sketch per il Due e relativo programma per processare l'immagine da seriale.&lt;br /&gt;
&lt;br /&gt;
== Il datasheet ==&lt;br /&gt;
&lt;br /&gt;
http://web.mit.edu/6.111/www/f2015/tools/OV7670app.pdf&lt;br /&gt;
&lt;br /&gt;
In questo datasheet sono elencati i registri interni di OV7670. Nello sketch dell'Instructable sono impostati nella maggior parte dei casi senza spiegare cosa servono. Gli stessi valori li ho trovati anche in quest'altra guida: http://embeddedprogrammer.blogspot.com/2012/07/hacking-ov7670-camera-module-sccb-cheat.html e dal relativo codice su github: https://github.com/indrekluuk/LiveOV7670 per il collegamento della cam a un display. &lt;br /&gt;
Da quel che mi è parso di capire, sono i valori che il driver di Linux mette di default e usa per le varie impostazioni della cam (ad es. per passare da QVGA ad altri formati come il QCIF). Molto interessante ma a questo punto la mia missione era già diventata qualcos'altro, ovvero fare in modo che questi registri potessero essere modificati in modo interattivo.&lt;br /&gt;
&lt;br /&gt;
= La soluzione =&lt;br /&gt;
&lt;br /&gt;
L'obiettivo è quindi creare un programma che leggesse la seriale e restituisse l'immagine e allo stesso tempo fare in modo che si potessero leggere e scrivere i registri della cam.&lt;br /&gt;
&lt;br /&gt;
== Lato Arduino Due ==&lt;br /&gt;
&lt;br /&gt;
Lo sketch dell'Instructable fa le seguenti cose:&lt;br /&gt;
* Imposta i registri di OV7670 in modo che sia QVGA in formato YCbCr422&lt;br /&gt;
* Manda un segnale &amp;quot;*RDY*&amp;quot; e memorizza su una matrice un byte no e uno sì dei pin D0-D7&lt;br /&gt;
* Quando l'immagine è completa, manda via seriale ogni singolo byte della matrice&lt;br /&gt;
&lt;br /&gt;
La modifica più importante è stata quella di mandare alternati il valore di Y e quello di CbCr. Nel frattempo avrebbe anche aspettato dallo script lato computer un segnale per dare il via alla lettura oppure un comando per leggere o scrivere su uno dei registri. Successivamente ho anche eliminato tutte le configurazioni che non cambiavano significativamente l'immagine e che probabilmente hanno a che fare con cose come il bilanciamento del bianco.&lt;br /&gt;
&lt;br /&gt;
Vediamo alcuni dettagli dello sketch.&lt;br /&gt;
&lt;br /&gt;
=== Generare un segnale di clock con Arduino ===&lt;br /&gt;
&lt;br /&gt;
Arduino Due ha un generatore di PWM con i quali è possibile creare un segnale di clock di almeno 8MHz sufficienti per il XCLK di OV7670.&lt;br /&gt;
&lt;br /&gt;
  int32_t PWM_pin = digitalPinToBitMask(XCLK);&lt;br /&gt;
  REG_PMC_PCER1 = 1 &amp;lt;&amp;lt; 4;     // Enable peripheral ID 36 (PWM) in the peripheral clock enable register - see 28.15.23&lt;br /&gt;
  REG_PIOC_PDR |= PWM_pin;    // Allow peripheral control for PWM_pin&lt;br /&gt;
  REG_PIOC_ABSR |= PWM_pin;   // Select peripheral B&lt;br /&gt;
  REG_PWM_CPRD6 = 8;          // Period: 84 MHz / 8 = 10.5 MHz - see 38.6.2.2 of datasheet&lt;br /&gt;
  REG_PWM_CDTY6 = 4;          // Duty Cycle: 8 / 4  = 0.5&lt;br /&gt;
  REG_PWM_ENA = 1 &amp;lt;&amp;lt; 6;       // Enable PWML6 (pin 7) - see 38.5.1 and 38.7.5 of datasheet for more info&lt;br /&gt;
&lt;br /&gt;
Gran parte delle informazioni su come funziona questo codice è spiegato su questa guida:&lt;br /&gt;
https://nhoffmanresearch.com/index.php/12-arduino-trap-control&lt;br /&gt;
e relativo datasheet del SAM3X9E:&lt;br /&gt;
http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-11057-32-bit-Cortex-M3-Microcontroller-SAM3X-SAM3A_Datasheet.pdf&lt;br /&gt;
&lt;br /&gt;
=== I registri ===&lt;br /&gt;
&lt;br /&gt;
Tramite I²C è possibile leggere lo stato di un registro o scrivere un nuovo valore. La lista dei registri è elencata sul datasheet, tuttavia alcuni, descritti come &amp;quot;Reserved&amp;quot;, non sono documentati. La prima cosa quando si accende la cam è settare i registri in modo che trasmetta le informazioni nel formato QVGA e YCbCr, inoltre sono abilitate alcune funzioni come l'autobilanciamento del bianco. Una volta impostate queste cose, si può cominciare a catturare le immagini.&lt;br /&gt;
&lt;br /&gt;
=== Loop ===&lt;br /&gt;
&lt;br /&gt;
Una delle cose che non riuscivo a far funzionare era centrare l'immagine. Essendo scollegato HREF il punto di inizio era arbitrario, e questo comportava che l'immagine fosse fuori quadro. Ho cambiato un po' questa filosofia e ho fatto in modo che l'Arduino Due aspettasse un segnale sulla seriale prima di iniziare a trasmettere. Il segnale è composto da due byte, se sono entrambi 0xD0 allora invia una nuova immagine, se invece il primo è un altro valore, viene inviato il registro corrispondente a quel valore, se sono entrambi diversi il registro corrispondente al primo valore viene aggiornato con il secondo valore. Non esiste un registro 0xD0, quindi possiamo usare tale byte per segnalare quando siamo pronti a ricevere una nuova immagine.&lt;br /&gt;
&lt;br /&gt;
In questo modo è possibile alterare in diretta l'immagine, cambiare luminosità, formato e anche scoprire a cosa servono i registri &amp;quot;Reserved&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Cattura dell'immagine ===&lt;br /&gt;
&lt;br /&gt;
La cattura è fatta in due passate per questioni di spazio sulla RAM. Per prima cosa leggiamo Y e poi CbCr. Se non siamo interessati al colore, possiamo commentare la seconda chiamata alla funzione captureImg a cui ho aggiunto un terzo parametro, il bool chroma, per specificare se salvare i bit pari o quelli dispari.&lt;br /&gt;
Ogni PCLK basso viene aggiunto un valore (Y oppure CbCr) alla matrice che rappresenta le righe e le colonne. Durante la lettura il tempo è critico, per cui occorrono alcuni accorgimenti per sveltire le operazioni.&lt;br /&gt;
&lt;br /&gt;
 noInterrupts();&lt;br /&gt;
&lt;br /&gt;
Questo comando disabilita gli interrupt. Non mi sembra che abbia nessun effetto benefico, ma male non fa.&lt;br /&gt;
&lt;br /&gt;
 REG_PIOB_PDSR &amp;amp; (1 &amp;lt;&amp;lt; 21)&lt;br /&gt;
 REG_PIOD_PDSR &amp;amp; (1 &amp;lt;&amp;lt; 10)&lt;br /&gt;
&lt;br /&gt;
Purtroppo le tanto comode funzioni digitalRead() di Arduino sono troppo lente per l'output di OV7670. Leggere direttamente il Pin Data Status Register (PDSR) di SAM3X9E è molto più veloce. Il bit 21 del PortB corrisponde al pin 52, che è quello dove abbiamo attaccato VSYNC, il bit 10 del PortD è il pin 32, dove abbiamo attaccato PCLK. Non è immediato convertire il pin in registro, ma ci sono moltissimi schemi con il pinout del Due, con descritto per ogni pin il Port e il bit.&lt;br /&gt;
&lt;br /&gt;
 (REG_PIOC_PDSR &amp;amp; 0xFF000) &amp;gt;&amp;gt; 12&lt;br /&gt;
&lt;br /&gt;
Invece il PortC sono tutti i pin dov0 abbiamo collegato da D0 a D7. Memorizzando lo stato del Port e applicando un filtro in modo che restituisca solo i valori che ci interessano (PortC dalla 12 alla 19), non dobbiamo subire la costrizione di leggere lo stato di un pin alla volta.&lt;br /&gt;
&lt;br /&gt;
Allo stesso tempo non è possibile usare la seriale di programmazione per trasmettere la matrice, occorre usare la porta nativa (Native) e invece di Serial, la funzione SerialUSB.write. Non c'è bisogno di inizializzarla con un baud rate perché andrà sempre alla velocità massima possibile. Questo dualismo mi ha permesso anche di fare alcune cose interessanti, come usare la porta nativa per la comunicazione con il programma che elabora le immagini e la porta di programmazione per mandare dei messaggi di debug.&lt;br /&gt;
&lt;br /&gt;
== Lato Python ==&lt;br /&gt;
&lt;br /&gt;
Sul computer ho scritto un piccolo script che pettinasse l'output dell'Arduino.&lt;br /&gt;
&lt;br /&gt;
Per prima cosa manda un segnale di due byte. Se il segnale è 0xD0 0xD0 allora si mette in attesa di larghezza*altezza byte. Una volta ricevuti e messi in ordine (ricordate, un dato di croma vale per due pixel, mentre la luma c'è per ognuno) occorre usare alcune formule per trasformare i dati in RGB. Ho usato questa formula, che si può trovare nelle guide già citate sopra:&lt;br /&gt;
 R = int(max(0, min(255,Y + 1.40200 * (Cr - 0x80))))&lt;br /&gt;
 G = int(max(0, min(255,Y - 0.34414 * (Cb - 0x80) - 0.71414 * (Cr - 0x80))))&lt;br /&gt;
 B = int(max(0, min(255,Y + 1.77200 * (Cb - 0x80))))&lt;br /&gt;
&lt;br /&gt;
Lo script readYUV422.py restituisce quindi una bitmap. Gli altri script saveYUV422.py e showYUV422.py rispettivamente salvano l'immagine con PIL oppure la mostrano con pygame. L'altro script, tkinterface.py, invece è un'interfaccia fatta con tkinter con cui possiamo interagire direttamente con i registri di OV7670. Per risolvere il problema delle azioni concorrenti, ho usato un thread che facesse il refresh dell'immagine. La porta usata è /dev/ttyACM0, ma è possibile cambiarla aggiungendo un argomento quando si lancia lo script.&lt;br /&gt;
&lt;br /&gt;
[[File:OVCAM.JPG]]&lt;br /&gt;
&lt;br /&gt;
= I risultati =&lt;br /&gt;
&lt;br /&gt;
Non è andato sempre tutto bene al primo colpo. Soprattutto all'inizio, quando non avevo ancora capito come leggere l'output, la cam ha dato degli output interessanti. Eccone alcuni.&lt;br /&gt;
[[File:Glitches.jpg]]&lt;br /&gt;
&lt;br /&gt;
= Il repo =&lt;br /&gt;
&lt;br /&gt;
Tutta la roba, con tutte le istruzioni e quant'altro, lo trovate nel repository su:&lt;br /&gt;
https://github.com/oloturia/ovcam&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Pagina_principale&amp;diff=7342</id>
		<title>Pagina principale</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Pagina_principale&amp;diff=7342"/>
		<updated>2021-07-16T15:59:49Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* Makerspace */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
{| id=&amp;quot;table-top-top&amp;quot; style=&amp;quot;margin-top:2px; background:none;align:center;width:100%;border:1px solid red;-moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius:10px;&amp;quot;&lt;br /&gt;
| style=&amp;quot;background:white; width:75%; vertical-align:top; color:#000; padding: 5px 10px 10px 8px; &amp;quot; |&lt;br /&gt;
[[File:Emblem-important-2.png|left|48px|link=Prossimi appuntamenti]]&lt;br /&gt;
&lt;br /&gt;
=[[Prossimi appuntamenti|Prossimi appuntamenti]]=&lt;br /&gt;
&lt;br /&gt;
{{:Prossimi appuntamenti}}&lt;br /&gt;
&lt;br /&gt;
-----------&lt;br /&gt;
'' Iscriviti alle nostre [http://liste.raspibo.org/wws/ mailing list]! ''&lt;br /&gt;
 &lt;br /&gt;
-----------&lt;br /&gt;
&lt;br /&gt;
Gli appuntamenti fissi si tengono ogni '''secondo e quarto marted&amp;amp;igrave; del mese''' dalle ore 20.30 in avanti. La sala resta a disposizione anche i restanti marted&amp;amp;igrave; e tutti i gioved&amp;amp;igrave;: se volete usare i nostri spazi per i vostri incontri e progetti, scrivetelo sulla lista pubblica [http://liste.raspibo.org/wws/info/agora agora] e segnalate la vostra presenza sul nostro [http://lela.ismito.it:3000 sistema di prenotazioni].&lt;br /&gt;
&lt;br /&gt;
[[Eventi passati]]&lt;br /&gt;
&lt;br /&gt;
| style=&amp;quot;background:white; width:75%; vertical-align:top; color:#000; padding: 5px 10px 10px 8px; &amp;quot; |&lt;br /&gt;
[[File:Go-home-9.png|right|48px|link=makerspace]]&lt;br /&gt;
&lt;br /&gt;
= [[makerspace|Makerspace]] =&lt;br /&gt;
[http://centrocroce.blogspot.it/ Presso il centro sociale CROCE]&lt;br /&gt;
[[makerspace|Via Canonica 18 a Casalecchio di Reno]].&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Cookie =&lt;br /&gt;
Questo sito usa solamente Cookie Tecnici. &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Cookie Tecnici|maggiori informazioni]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- =====================  INIZIO TABELLA CENTRALE  ==================== --&amp;gt;&lt;br /&gt;
{| id=&amp;quot;table-central&amp;quot; style=&amp;quot;margin-top:10px; background:none;&amp;quot;&lt;br /&gt;
| style=&amp;quot;background:white; width:35%; border:1px solid #a7d7f9; vertical-align:top; color:#000; padding: 5px 10px 10px 8px; -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius:10px;&amp;quot; |&lt;br /&gt;
&amp;lt;!-- =====================  TABELLA CENTRALE - COLONNA DI SINISTRA  ==================== --&amp;gt;&lt;br /&gt;
{| id=&amp;quot;table-central-left&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;5&amp;quot; style=&amp;quot;width:100%; vertical-align:top; background:transparent;&amp;quot;&lt;br /&gt;
[[File:PCB-icon.png|right|48px]]&lt;br /&gt;
&lt;br /&gt;
= [[gruppi|Gruppi]] e [[:Categoria:Progetti|Progetti]] =&lt;br /&gt;
&lt;br /&gt;
{{:Gruppi}}&lt;br /&gt;
&lt;br /&gt;
[[File:Maker-faire.png|right|128px|link=Maker_Faire_2014]]&lt;br /&gt;
[[File:Maker_of_merit.jpg|right|128px|link=FotoMakerFaireRome2014]]&lt;br /&gt;
&lt;br /&gt;
'''Dettagli sui [[I_gruppi_di_lavoro_del_non-corso|gruppi di lavoro]].'''&lt;br /&gt;
&lt;br /&gt;
'''Vetrina dei [[:Categoria:Progetti|progetti in corso]].'''&lt;br /&gt;
&lt;br /&gt;
'''Leggi la [[Documentazione|documentazione prodotta]].'''&lt;br /&gt;
&lt;br /&gt;
'''Iscrivetevi alle [http://liste.raspibo.org mailing list].'''&lt;br /&gt;
&lt;br /&gt;
'''[[ wireless_comunity_network |NINUX Bologna - Wireless community network]].'''&lt;br /&gt;
&lt;br /&gt;
'''[[ link_e_idee |Link&amp;amp;Idee]].'''&lt;br /&gt;
&lt;br /&gt;
'''[[ Renzo's Bliki ]].'''&lt;br /&gt;
&lt;br /&gt;
'''[[ Laboratory of Making ]].'''&lt;br /&gt;
&lt;br /&gt;
Abbiamo raccolto alcuni progetti di autoproduzione riguardanti il '''[[ Covid19 ]].'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Applications-science.png|right|48px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Serate aperte a tutti ==&lt;br /&gt;
&lt;br /&gt;
''Gli incontri presso il [[makerspace]] sono ad accesso libero e gratuito, vedi anche le [[RIVOLUZIONE ALL'INCONTRO DEL 7 MARZO|note su come di solito procediamo]]''&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se pensate di partecipare, segnalate la vostra presenza sul sistema [https://ibt2.ismito.it/ RaspiBO makerspace booking], basta il vostro nickname. Per favore ricordate di aggiornarlo.&lt;br /&gt;
&lt;br /&gt;
== Gite, fiere ed eventi ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maker, segnalate [[Gite|qui ]] tutti gli eventi che ritenete interessanti!&lt;br /&gt;
&lt;br /&gt;
= Acquisti ossessivo-compulsivi =&lt;br /&gt;
&lt;br /&gt;
Ogni tanto ci vengono voglie strane; per amortizzare le spese di spedizione, cerchiamo di [[Elenco degli acquisti|aggregare gli ordini]].&lt;br /&gt;
&lt;br /&gt;
= Convenzioni acquisti =&lt;br /&gt;
La ditta Homotix e la ditta Katodo praticano, agli utenti RaspiBo, uno sconto. Per usufruirne segui le '''[[convenzioni acquisti | istruzioni]]'''.&lt;br /&gt;
&lt;br /&gt;
= Il non-staff ed i contatti =&lt;br /&gt;
&lt;br /&gt;
Non desideriamo strutturare troppo la '''non-associazione''', ma un gruppetto si sta prendendo in carico di seguirne la gestione; [[Non-staff|scoprite chi sono]] e soprattutto come potete aiutarli, dato che c'è [[Aiuto:Indice|bisogno del contributo]] di tutti!&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- =====================  TABELLA CENTRALE - FINE COLONNA SINISTRA  ==================== --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;!-- DIVISORE COLONNE --&amp;gt; style=&amp;quot;border:3px solid transparent;&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- =====================  TABELLA CENTRALE - COLONNA DI DESTRA  ==================== --&amp;gt;&lt;br /&gt;
| style=&amp;quot;width:65%; border:1px solid #a7d7f9; background:#f5faff; vertical-align:top; padding: 5px 10px 10px 8px; -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius:10px;&amp;quot; |&lt;br /&gt;
{| id=&amp;quot;table-central-right&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;5&amp;quot; style=&amp;quot;width:100%; vertical-align:top; background:#f5faff; background:transparent;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:RASPIBOfinale.png|left|130px|link=http://www.raspibo.org]]&lt;br /&gt;
[[File:Help-3.png|right|48px]]&lt;br /&gt;
= Chi siamo =&lt;br /&gt;
&lt;br /&gt;
'''''RaspiBO''''' è un gruppo informale di appassionati di elettronica ed informatica libera della zona di '''Bologna''' (ma non solo).&lt;br /&gt;
&lt;br /&gt;
Nato ad inizio 2013 per iniziativa del professor [http://www.cs.unibo.it/~renzo/ Renzo Davoli], [http://www.raccattaraee.net/ RaccattaRAEE], [http://erlug.linux.it/ ERLUG] e [http://www.bfsf.it/ BFSF], il gruppo si muove ora autonomamente, incontrandosi con frequenza almeno bimensile per serate dedicate allo sviluppo ed alla presentazione di nuove idee.&amp;lt;br /&amp;gt;&lt;br /&gt;
Chiamiamo questi incontri '''''il non-corso''''', perché non vogliono essere delle semplici lezioni frontali, ma un momento di scambio di opinioni ed esperienze.&lt;br /&gt;
&lt;br /&gt;
Le nostre competenze sono molto varie; '''informatica''', '''elettronica''', '''meccanica''', '''arti''' e mestieri vari: qualcuno è un esperto nel proprio campo, alcuni sono alle prime armi, ma tutti hanno tanta voglia di mettere a disposizione la propria esperienza.&amp;lt;br /&amp;gt;&lt;br /&gt;
Potete definirci '''makers'''; quello che più conta per noi resta comunque '''l'imparare''' sempre qualcosa di nuovo ed il '''far circolare la conoscenza''' coinvolgendo quante più persone possibile.&lt;br /&gt;
&lt;br /&gt;
Se preferisci abbiamo raccolto qualche informazione [http://www.raspibo.org/wiki/index.php/Chi_siamo in questa pagina].&lt;br /&gt;
&lt;br /&gt;
[[File:Audio-card-3.png|right|48px]]&lt;br /&gt;
&lt;br /&gt;
= Gli incontri del non-corso ed i gruppi di lavoro =&lt;br /&gt;
&lt;br /&gt;
'''Gratuiti e aperti a tutti''', chiunque voglia passare a trovarci anche solo per fare due chiacchiere su elettronica, informatica e meccanica (tutto rigorosamente in ''salsa libera'') è il benvenuto!&lt;br /&gt;
&lt;br /&gt;
Lo spirito dei nostri incontri è espresso nelle nostre [[Linee guida per gli incontri|linee guida]].&amp;lt;br /&amp;gt;&lt;br /&gt;
Oltre a tanta improvvisazione, di norma alcuni di noi si organizzano in '''tavoli''' per proseguire su specifici progetti; appena possibile, il [[I gruppi di lavoro del non-corso|lavoro svolto dai singoli gruppi]] viene presentato e documentato a beneficio di tutti.&lt;br /&gt;
&lt;br /&gt;
[[File:Apps-system-users-icon.png|right|48px]]&lt;br /&gt;
&lt;br /&gt;
= Serate a tema =&lt;br /&gt;
&lt;br /&gt;
Occasionalmente RaspiBO organizza serate per sviluppare un tema specifico, generalmente invitiamo uno o più ospiti per introdurre temi di interesse comune e condividere esperienze. [http://www.raspibo.org/wiki/index.php?title=Categoria:Serate_a_tema Serate a tema]&lt;br /&gt;
&lt;br /&gt;
[[File:Books-1-icon.png|right|48px]]&lt;br /&gt;
&lt;br /&gt;
= Dalla teoria alla pratica = &lt;br /&gt;
&lt;br /&gt;
Se vuoi puoi iniziare con l'[[1-_Elettronica_di_Base|elettronica]] oppure scoprire come configurare [[Raspberry Pi]] per iniziare i primi test.&lt;br /&gt;
&lt;br /&gt;
Se sei già pratico o se vuoi capire come utilizzare Raspberry Pi puoi visualizzare un elenco di [[6- Applicazioni di Raspberry PI|applicazioni]] che abbiamo già testato e documentato. &lt;br /&gt;
&lt;br /&gt;
Tutte queste informazioni le trovi nella sezione [[Documentazione|Documentazione]] .&lt;br /&gt;
&lt;br /&gt;
Sono inoltre disponibili [[Archivio dei Lucidi|lucidi e registrazioni]] di alcune lezioni frontali.&lt;br /&gt;
&lt;br /&gt;
[[File:User-group-new-2.png|link=http://social.raspibo.org|right|48px]]&lt;br /&gt;
&lt;br /&gt;
Con calma stiamo anche raccogliendo [[SanboxManuali|qui]] link a documentazione, pinout e tutto quanto serve avere sottomano quando si sperimenta.&lt;br /&gt;
&lt;br /&gt;
= la mailing list =&lt;br /&gt;
&lt;br /&gt;
Il nostro principale strumento di comunicazione è la '''[http://liste.raspibo.org/wws/subscribe/agora mailing list agora]''', i cui archivi sono [http://liste.raspibo.org/wws/arc/agora consultabili da qui].&lt;br /&gt;
&lt;br /&gt;
Se invece preferite ricevere periodicamente nostre notizie via mail, potete [http://liste.raspibo.org/wws/subscribe/newsletter iscrivervi alla newsletter].&lt;br /&gt;
&lt;br /&gt;
[[File:Strumenti.png|link=http://social.raspibo.org|right|48px]]&lt;br /&gt;
&lt;br /&gt;
= Strumenti per la collaborazione =&lt;br /&gt;
&lt;br /&gt;
Se vi piace chattare o volete una info al volo vi suggeriamo di utilizzare il canale #raspibo sul server freenode.net anche in [https://webchat.freenode.net/?channels=raspibo&amp;amp;uio=d4 webchat].&lt;br /&gt;
&lt;br /&gt;
Alcuni software sviluppati per i nostri progetti li appoggiamo sul nostro [https://github.com/raspibo/ archivio github].&lt;br /&gt;
&lt;br /&gt;
= Un pochino di storia =&lt;br /&gt;
[http://www.raspibo.org/wiki/index.php/Chi_siamo Un piccolo riassunto]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- =====================  TABELLA CENTRALE - FINE COLONNA DI DESTRA  ==================== --&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- =====================  FINE TABELLA CENTRALE  ==================== --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- =====================  INIZIO TABELLA FOOTER  ==================== --&amp;gt;&lt;br /&gt;
{| id=&amp;quot;table-footer&amp;quot; style=&amp;quot;margin-top:10px; background:none;&amp;quot;&lt;br /&gt;
| style=&amp;quot;width:35%; border:1px solid #a7d7f9; background:#f5faff; vertical-align:top; padding: 5px 10px 10px 8px; -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius:10px;&amp;quot; |&lt;br /&gt;
&amp;lt;!-- =====================  TABELLA FOOTER - COLONNA SINISTRA  ==================== --&amp;gt;&lt;br /&gt;
{| id=&amp;quot;table-footer-left&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;5&amp;quot; style=&amp;quot;width:100%; vertical-align:top; background:#f5faff; background:transparent;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[File:Emblem-what.png|right|48px]]&lt;br /&gt;
&lt;br /&gt;
= Help! =&lt;br /&gt;
&lt;br /&gt;
Vuoi modificare una pagina di questo wiki ma non ci riesci? Assicurati di aver letto le [[Qui|istruzioni]] per sconfiggere il nostro potente sistema anti-bot. :-)&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- =====================  TABELLA FOOTER - FINE COLONNA SINISTRA  ==================== --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;!-- DIVISORE COLONNE --&amp;gt; style=&amp;quot;border:5px solid transparent;&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- =====================  TABELLA FOOTER - COLONNA DI DESTRA  ==================== --&amp;gt;&lt;br /&gt;
| style=&amp;quot;background:white; width:65%; border:1px solid #a7d7f9; vertical-align:top; color:#000; padding: 5px 10px 10px 8px; -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius:10px;&amp;quot; |&lt;br /&gt;
{| id=&amp;quot;table-footer-right&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;5&amp;quot; style=&amp;quot;width:100%; vertical-align:top; background:transparent;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
= Ringraziamenti =&lt;br /&gt;
&lt;br /&gt;
[[File:Stemma Comune Casalecchio.png|70px|right]]&lt;br /&gt;
&lt;br /&gt;
Si ringrazia il Centro Sociale Croce ed il [http://www.comune.casalecchio.bo.it Comune di Casalecchio di Reno] .&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- =====================  TABELLA FOOTER - FINE COLONNA SINISTRA  ==================== --&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- =====================  FINE TABELLA FOOTER  ==================== --&amp;gt;&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=ESProbottino&amp;diff=7341</id>
		<title>ESProbottino</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=ESProbottino&amp;diff=7341"/>
		<updated>2021-06-20T16:25:43Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;ESProbottino è l'evoluzione di [[Ardubottino]]. L'idea è quella di sfruttare le capacità wi-fi dell'[https://www.espressif.com/en/products/socs/esp32 ESP32] per fare un piccolo server per il controllo remoto di un piccolo rover. L'ESP32 usato in questo caso è l'[https://docs.ai-thinker.com/en/esp32-cam Ai-Thinker ESP32-CAM] che ha a bordo una cam per lo streaming. La cam purtroppo impegna gran parte dei pin disponibili, per cui è stato necessario usare un altro integrato, in questo caso un ATmega8, per la gestione dei motori, dei sensori e degli encoder.[[File:ESP32BOTTINO.JPG]]&lt;br /&gt;
&lt;br /&gt;
= Componenti =&lt;br /&gt;
&lt;br /&gt;
La maggior parte dei componenti è la stessa dell'Ardubottino:&lt;br /&gt;
* Ai-Thinker ESP32-CAM [https://docs.ai-thinker.com/en/esp32-cam]&lt;br /&gt;
* AVR ATmega8 [https://www.microchip.com/wwwproducts/en/ATmega8]&lt;br /&gt;
* Board per ponte H L298&lt;br /&gt;
* Kit Tamiya per robotica, con chassis e motori&lt;br /&gt;
* Sensore a ultrasuoni SRF05&lt;br /&gt;
* Sensore di vicinanza IR&lt;br /&gt;
* RobotShop coppia di Encoder [https://www.robotshop.com/en/encoder-pair-tamiya-twin-motor-gearbox.html]&lt;br /&gt;
* Batterie e powerbank&lt;br /&gt;
&lt;br /&gt;
= ESP32-CAM =&lt;br /&gt;
&lt;br /&gt;
Per aggiungere le schede ESP32 alle board programmabili dalla IDE di Arduino occorre inserire questo indirizzo fra le Preferences, alla voce Additional Boards Manager URLs. Se avete già delle voci, separatele con una virgola.&lt;br /&gt;
https://dl.espressif.com/dl/package_esp32_index.json&lt;br /&gt;
&lt;br /&gt;
Questo aggiungerà le board ESP32 al vostro menu Tools/Board e aggiungerà uno sketch di esempio.&lt;br /&gt;
&lt;br /&gt;
L'ESP32-CAM, con il programma di esempio, fa tre cose:&lt;br /&gt;
* Si collega o crea una wi-fi&lt;br /&gt;
* Tira su un piccolo server web con una pagina con alcuni controlli per la cam&lt;br /&gt;
* Scrive sulla porta seriale dei messaggi di debug (l'indirizzo IP)&lt;br /&gt;
&lt;br /&gt;
Per piegare ESP32-CAM alle nostre esigenze, occorrerà fare delle piccole modifiche.&lt;br /&gt;
&lt;br /&gt;
== CameraWebServer - Sketch principale ==&lt;br /&gt;
&lt;br /&gt;
Per prima cosa modifichiamo lo sketch principale. Negli esempi della board si trova con il nome di CameraWebServer.&lt;br /&gt;
&lt;br /&gt;
Per prima cosa occorre selezionare la nostra board scegliendo la define giusta. Nel nostro caso occorre decommentare la riga:&lt;br /&gt;
 #define CAMERA_MODEL_AI_THINKER&lt;br /&gt;
e commentare le altre.&lt;br /&gt;
&lt;br /&gt;
Nelle due righe successive&lt;br /&gt;
 const char* ssid = &amp;quot;nostra_rete&amp;quot;;&lt;br /&gt;
 const char* password = &amp;quot;password_rete&amp;quot;;&lt;br /&gt;
bisogna specificare una rete alla quale il nostro ESP32 dovrà collegarsi.&lt;br /&gt;
&lt;br /&gt;
Non occorre fare altro, ma già che c'ero ho cambiato alcune cose per migliorare alcuni aspetti.&lt;br /&gt;
* Tolto tutte le comunicazioni seriali non necessarie perché avrebbero potuto interferire con l'ATmega8&lt;br /&gt;
* Abbassato il baud da 115200 a 9600, mi sembra che i motori facessero un po' di disturbo sulla seriale e mi è sembrato che abbassare il rate risolvesse gli errori&lt;br /&gt;
* Prima dell'assegnamento dell'indirizzo IP ho messo come comando una richiesta al sensore a ultrasuoni (manda un 0 sulla seriale), in modo che lampeggi durante l'attesa&lt;br /&gt;
&lt;br /&gt;
Per i test avevo aggiunto anche la stampa sulla porta seriale del MAC address e dell'indirizzo IP. Nella versione finale è disabilitata perché interferiva con i comandi di movimento del robot e inoltre, essendo la seriale attaccata all'ATmega8, non era comunque possibili leggere tali messaggi. Le funzioni da chiamare sono:&lt;br /&gt;
&lt;br /&gt;
 WiFi.macAddress()&lt;br /&gt;
&lt;br /&gt;
e&lt;br /&gt;
&lt;br /&gt;
 WiFi.localIP()&lt;br /&gt;
&lt;br /&gt;
Riguardo il setup della camera non occorre modificare niente. Dal codice si può notare come gran parte dei pin sia occupato dalla CAM. È possibile (credo) anche modificare i parametri di default, tuttavia funzionano perfettamente out-of-the-box.&lt;br /&gt;
&lt;br /&gt;
== app_httpd.cpp - Server web ==&lt;br /&gt;
&lt;br /&gt;
Questa parte del codice lancia un server web con l'interfaccia per cambiare i parametri della CAM e lanciare o arrestare lo streaming, nonché gestire la parte di riconoscimento facciale. Di particolare interesse sono le variabili &amp;quot;variable&amp;quot; e &amp;quot;value&amp;quot; che contengono il nome di una variabile e del suo valore passato tramite GET. I controlli della CAM mandano una richiesta GET che chiama una funzione che ha come parametro il valore. Ad es.&lt;br /&gt;
 s-&amp;gt;set_wb_mode(s,val)&lt;br /&gt;
altera il bilanciamento del bianco del valore &amp;quot;val&amp;quot; (&amp;quot;val&amp;quot; è &amp;quot;value&amp;quot; tradotta in integer).&lt;br /&gt;
&lt;br /&gt;
Per aggiungere i controlli del robot avrei dovuto quindi creare dei bottoni che inviassero alla Seriale il valore val. Il tutto è stato abbastanza semplice, è bastato aggiungere queste due righe:&lt;br /&gt;
 else if(!strcmp(variable, &amp;quot;controls&amp;quot;)){&lt;br /&gt;
 	Serial.print(value); }&lt;br /&gt;
alla lista dei vari altri controlli. Se GET legge la variabile &amp;quot;controls&amp;quot;, il suo valore &amp;quot;value&amp;quot; viene mandato dalla seriale all'ATmega8.&lt;br /&gt;
&lt;br /&gt;
== camera_index.h - La pagina web ==&lt;br /&gt;
&lt;br /&gt;
Alla pagina web occorre aggiungere i pulsanti per il controllo del nostro rover. Ogni pulsante chiamerà una funzione che passerà tramite GET la variabile &amp;quot;controls&amp;quot; e un carattere che corrisponde all'azione da fare.&lt;br /&gt;
&lt;br /&gt;
Ora però c'è un problema: la pagina è in html ma 1) in esadecimale e 2) compressa in gz. Qui c'è stato bisogno di un aiuto da CyberChef!&lt;br /&gt;
&lt;br /&gt;
https://gchq.github.io/CyberChef/&lt;br /&gt;
&lt;br /&gt;
Questo software traduce da e in esadecimale, g/un/zippa e fa anche moltissime altre cose. Per ora però limitiamoci a chiedergli queste tre cose:&lt;br /&gt;
&lt;br /&gt;
* Remove whitespace (toglie gli spazi fra le cifre hex, nonché gli a capo)&lt;br /&gt;
* From Hex, 0x with comma (traduce da hex a dec)&lt;br /&gt;
* Gunzip&lt;br /&gt;
&lt;br /&gt;
Ora incolliamo nella finestra input tutto l'array &amp;quot;const uint8_t index_ov2640_html_gz[]&amp;quot;. Come per magia comparirà la pagina html! Modifichiamola aggiungendo i comandi per il robot.&lt;br /&gt;
Aggiungo un nuovo &amp;lt;div&amp;gt; con i bottoni sotto il layer dove dovrebbe comparire lo streaming. Già che c'ero ho aggiunto uno stile al css.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;controls&amp;gt;&lt;br /&gt;
  &amp;lt;\div class=&amp;quot;grid-container&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;\div class=&amp;quot;item1&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/\div&amp;gt;&lt;br /&gt;
  &amp;lt;\div class=&amp;quot;item2&amp;quot;&amp;gt;&amp;lt;button id=&amp;quot;Forward&amp;quot;&amp;gt;↑&amp;lt;/button&amp;gt;&amp;lt;/\div&amp;gt;&lt;br /&gt;
  &amp;lt;\div class=&amp;quot;item3&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/\div&amp;gt;&lt;br /&gt;
  &amp;lt;\div class=&amp;quot;item4&amp;quot;&amp;gt;&amp;lt;button id=&amp;quot;Left&amp;quot;&amp;gt;←&amp;lt;/button&amp;gt;&amp;lt;/\div&amp;gt;&lt;br /&gt;
  &amp;lt;\div class=&amp;quot;item5&amp;quot;&amp;gt;&amp;lt;button id=&amp;quot;NoMov&amp;quot;&amp;gt;O&amp;lt;/button&amp;gt;&amp;lt;/\div&amp;gt;&lt;br /&gt;
  &amp;lt;\div class=&amp;quot;item6&amp;quot;&amp;gt;&amp;lt;button id=&amp;quot;Right&amp;quot;&amp;gt;→&amp;lt;/button&amp;gt;&amp;lt;/\div&amp;gt;&lt;br /&gt;
  &amp;lt;\div class=&amp;quot;item7&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/\div&amp;gt;&lt;br /&gt;
  &amp;lt;\div class=&amp;quot;item8&amp;quot;&amp;gt;&amp;lt;button id=&amp;quot;Back&amp;quot;&amp;gt;↓&amp;lt;/button&amp;gt;&amp;lt;/\div&amp;gt;&lt;br /&gt;
  ... (eccetera)&lt;br /&gt;
  &amp;lt;/\div&amp;gt;&lt;br /&gt;
 &amp;lt;/controls&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ora bisogna associare a ogni tasto una chiamata GET. Per far questo mi appoggio allo script che già viene usato per i controlli della CAM. Andiamo quindi a modificare la funzione document.addEventListener&lt;br /&gt;
&lt;br /&gt;
Per prima cosa si prendono i vari elementi e si mettono nelle costanti:&lt;br /&gt;
&lt;br /&gt;
  const forward = document.getElementById('Forward')&lt;br /&gt;
  const left = document.getElementById('Left')&lt;br /&gt;
  const right = document.getElementById('Right')&lt;br /&gt;
  const back = document.getElementById('Back')&lt;br /&gt;
  const nomov = document.getElementById('NoMov')&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
Poi si associano i listener:&lt;br /&gt;
&lt;br /&gt;
  forward.onclick = () =&amp;gt; { fetch(`${baseHost}/control?var=controls&amp;amp;val=F`) }&lt;br /&gt;
  left.onclick = () =&amp;gt; { fetch(`${baseHost}/control?var=controls&amp;amp;val=L`) }&lt;br /&gt;
  right.onclick = () =&amp;gt; { fetch(`${baseHost}/control?var=controls&amp;amp;val=R`) }&lt;br /&gt;
  back.onclick = () =&amp;gt; { fetch(`${baseHost}/control?var=controls&amp;amp;val=B`) }&lt;br /&gt;
  nomov.onclick = () =&amp;gt; { fetch(`${baseHost}/control?var=controls&amp;amp;val=N`) }&lt;br /&gt;
&lt;br /&gt;
Al click la pagina control viene richiamata la pagina control che prende una variabile &amp;quot;controls&amp;quot; di valore &amp;quot;val&amp;quot;. Questo valore viene letto dal server che lo manda via seriale all'ATmega8.&lt;br /&gt;
&lt;br /&gt;
Una volta fatto questo occorre ri-usare CyberChef e fare l'esatto opposto per codificare la pagina com'era in origine, ovvero:&lt;br /&gt;
&lt;br /&gt;
* gzip&lt;br /&gt;
* To Hex, 0x with comma&lt;br /&gt;
&lt;br /&gt;
Per quanto riguarda gli a capo e gli spazi, possiamo ignorarlo perché possiamo scrivere tranquillamente tutto su una sola linea.&lt;br /&gt;
&lt;br /&gt;
Invece è importante cambiare la lunghezza dell'array. Nel mio caso sono passato da 4926 a:&lt;br /&gt;
&lt;br /&gt;
 #define index_ov2640_html_gz_len 5022&lt;br /&gt;
&lt;br /&gt;
Se non mettiamo la lunghezza giusta la pagina verrà troncata. CyberChef conta i caratteri dell'output in automatico, ovviamente compresso. Ri-traducete la vostra pagina come all'inizio però disabilitando il gunzip e dovrebbe dirvi quanti byte è lunga.&lt;br /&gt;
&lt;br /&gt;
Lato ESP32-CAM abbiamo finito. Occorre adesso flashare.&lt;br /&gt;
&lt;br /&gt;
== Flashare l'ESP32-CAM ==&lt;br /&gt;
&lt;br /&gt;
Per flashare l'ESP32-CAM occorre un adattatore USB a TTL. Collegare il filo rosso a +5v, il nero a un GND, bianco a TX e verde a RX.&lt;br /&gt;
&lt;br /&gt;
Per mettere l'ESP32-CAM in modalità programmazione occorre collegare il pin 0 a GND e resettare. Occorre farlo subito dopo aver lanciato l'uploading quando compare il messaggio &amp;quot;Connecting ......______......&amp;quot;, se fallisce (e se state usando la IDE di Arduino) conviene copiare il comando che lancia esptool e abbassare il baud rate.&lt;br /&gt;
&lt;br /&gt;
= ATmega8 =&lt;br /&gt;
&lt;br /&gt;
All'ATmega8 è lasciata tutta la parte di controllo dei pin. Il suo lavoro è molto semplice: legge un comando in entrata sulla seriale ed esegue una delle operazioni. Oltre a questo, controlla anche lo stato dei sensori e degli encoder. L'ATmega8 è molto ridotto e molto economico ma è sufficiente per quel che dobbiamo fare.&lt;br /&gt;
&lt;br /&gt;
== Seriale ==&lt;br /&gt;
&lt;br /&gt;
ESP32-CAM e ATmega8 sono collegati tramite la porta seriale. La funzione Serial.available() è &amp;gt;0 quando ci sono dei caratteri in attesa di essere letti. Serial.read() li legge. Il carattere lo si mette solitamente in una variabile char.&lt;br /&gt;
&lt;br /&gt;
  if (Serial.available() &amp;gt; 0) {&lt;br /&gt;
    command = Serial.read(); }&lt;br /&gt;
&lt;br /&gt;
Una volta ricevuto il comando, verrà chiamata una funzione. &lt;br /&gt;
&lt;br /&gt;
 switch(command) {&lt;br /&gt;
   case 'F':&lt;br /&gt;
     forward(4);&lt;br /&gt;
   case 'R':&lt;br /&gt;
     right(4);&lt;br /&gt;
   (etc.)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Le funzioni forward(), backward(), right() e left() (rispettivamente comandi 'F', 'B', 'R' e 'L') prendono come parametro un intero. Quel parametro sarà la distanza da coprire in passi dell'encoder. Alcuni comandi non vengono eseguiti ad es. se il sensore di caduta segnala che c'è rischio di caduta. Le funzioni accendono i pin collegati al ponte ad H in modo che i motori girino nella direzione desiderata e li tengono accesi fino a che non è finita l'esecuzione della funzione steps, che calcola i passi.&lt;br /&gt;
&lt;br /&gt;
Il comando 'M' abiliterà l'automazione del movimento. Esprobottino andrà in giro da solo evitando gli ostacoli (per quanto possibile) facendo affidamento sul sensore di distanza.&lt;br /&gt;
&lt;br /&gt;
Ci sono anche quattro comandi ('1','2','3' e '4') per calibrare i due motori e uno per scrivere ('W') la calibrazione nella EEPROM. Questi comandi variano il duty cycle del PWM collegato agli Enable dei motori.&lt;br /&gt;
&lt;br /&gt;
Altri comandi che possono essere interpretati: 'D' abilita il debug via seriale, '0' interroga i sensori e 'C' dovrebbe far partire la calibrazione in automatico (ma è ancora da rivedere).&lt;br /&gt;
&lt;br /&gt;
== Encoder ==&lt;br /&gt;
&lt;br /&gt;
A differenza di quanto pensavo per la prima versione dell'Ardubottino, gli encoder non sono digitali ma analogici. Per questo avevo delle letture non precise. Il problema di questo tipo di sensore è che non potendo usare l'interrupt, occorre fare delle letture continue, il polling, durante la marcia. Questo però comporta che durante il movimento il nostro integrato deve rimanere in ascolto e non può fare nient'altro.&lt;br /&gt;
&lt;br /&gt;
La funzione steps conta quanti passi sono stati fatti.&lt;br /&gt;
&lt;br /&gt;
== Sensori di distanza ==&lt;br /&gt;
&lt;br /&gt;
Ci sono due sensori di distanza sull'ESProbottino.&lt;br /&gt;
&lt;br /&gt;
=== Sensore a ultrasuoni ===&lt;br /&gt;
&lt;br /&gt;
Il sensore a ultrasuoni ci restituisce la distanza in cm dall'ostacolo più vicino. Funziona come un sonar: lanciando un ultrasuono e ascoltandone l'eco possiamo capire quanto sia distante l'oggetto che sta davanti al sensore. &lt;br /&gt;
Qui c'è un link sul suo funzionamento, con anche un programma di esempio: &lt;br /&gt;
https://create.arduino.cc/projecthub/abdularbi17/ultrasonic-sensor-hc-sr04-with-arduino-tutorial-327ff6&lt;br /&gt;
&lt;br /&gt;
=== Sensore IR ===&lt;br /&gt;
&lt;br /&gt;
Il sensore IR è molto più semplice. Tramite una vite si regola quale dev'essere la soglia oltre il quale si accende. Uso questo sensore per capire se davanti a ESProbottino c'è un vuoto. Semplicemente se il pin è acceso, allora c'è un vuoto, altrimenti non c'è rischio di caduta. Se c'è un vuoto, la variabile falling diventa vera e impedisce ad es. di eseguire la funzione forward()&lt;br /&gt;
&lt;br /&gt;
== Ponte ad H ==&lt;br /&gt;
&lt;br /&gt;
Il ponte ad H permette di manovrare i due motori.&lt;br /&gt;
Per ogni motore ci sono tre pin: uno è un Enable, ovvero accende il motore quando riceve +5v, gli altri due determinano il verso in cui girerà.&lt;br /&gt;
&lt;br /&gt;
EN P1 P2 &lt;br /&gt;
+  -  -  Motore fermo&lt;br /&gt;
+  +  -  Motore gira in senso orario&lt;br /&gt;
+  -  +  Motore gira in senso antiorario&lt;br /&gt;
-  ?  ?  Motore fermo&lt;br /&gt;
&lt;br /&gt;
Un PWM al pin Enable permette di controllare la velocità del motore.&lt;br /&gt;
&lt;br /&gt;
La board del ponte H dovrebbe essere in grado anche di alimentare a 5v la board ESP32 e l'ATmega8, ma dopo diversi tentativi ho preferito separare le alimentazioni. Spesso la partenza dei motori richiedeva troppa corrente che riavviava o creava rumore nell'ESP32.&lt;br /&gt;
&lt;br /&gt;
== Movimento automatico ==&lt;br /&gt;
&lt;br /&gt;
Il movimento automatico non è molto elaborato per ora. Va avanti, se incontra un ostacolo guarda prima a destra, poi a sinistra e infine decide di prendere la strada dove ha sentito più spazio. Se si accende il sensore di caduta allora fa retromarcia e poi fa circa 180° prima di ripartire.&lt;br /&gt;
&lt;br /&gt;
== Flash ==&lt;br /&gt;
&lt;br /&gt;
Per flashare l'ATmega8 occorre un Arduino che abbia il firmware &amp;quot;Arduino as ISP&amp;quot;. Nell'ultima versione della IDE, nel Boards Manager c'è la possibilità di aggiungere le board ATmega8. Nelle Preferences, in &amp;quot;Additional Boards Manager URLs&amp;quot; occorre inserire:&lt;br /&gt;
https://mcudude.github.io/MiniCore/package_MCUdude_MiniCore_index.json&lt;br /&gt;
(se avete già degli indirizzi, separateli con una virgola)&lt;br /&gt;
dovrebbe comparire fra le board un nuovo menu chiamato &amp;quot;MiniCore&amp;quot;, fra cui c'è anche l'ATmega8.&lt;br /&gt;
&lt;br /&gt;
Per tutti i problemi relativi al flash dell'ATmega8 vi rimando all'[[OttoBot]], che è basato sullo stesso integrato.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Il codice =&lt;br /&gt;
&lt;br /&gt;
TBD&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=ESProbottino&amp;diff=7340</id>
		<title>ESProbottino</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=ESProbottino&amp;diff=7340"/>
		<updated>2021-05-20T15:11:29Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: Creata pagina con 'Coming soon...  File:ESP32BOTTINO.JPG'&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Coming soon...&lt;br /&gt;
&lt;br /&gt;
[[File:ESP32BOTTINO.JPG]]&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=File:ESP32BOTTINO.JPG&amp;diff=7339</id>
		<title>File:ESP32BOTTINO.JPG</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=File:ESP32BOTTINO.JPG&amp;diff=7339"/>
		<updated>2021-05-20T15:10:24Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: ESP32bottino&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;ESP32bottino&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Gruppo_Robottini&amp;diff=7338</id>
		<title>Gruppo Robottini</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Gruppo_Robottini&amp;diff=7338"/>
		<updated>2021-05-17T17:43:45Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* Progetti completati */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Gruppo&lt;br /&gt;
|nome=Robottini&lt;br /&gt;
|descrizione=l'umanità non ha speranza!&lt;br /&gt;
|social=http://raspibo.ofpcina.net/groups/profile/2815/robottini-terrestri&lt;br /&gt;
|mailinglist=http://liste.raspibo.org/wws/subscribe/robot.terrestri Vuoi partecipare o solamente essere informato? Iscriviti alla mailing list&lt;br /&gt;
|iscritti=Daniele [http://raspibo.ofpcina.net/profile/dancast78 dancast78], Savino [http://raspibo.ofpcina.net/profile/thegamer thegamer], Carmelo [http://raspibo.ofpcina.net/profile/tarmelop tarmelop], Gianni, Peppe, Marco, Luigi, Antonio, [http://raspibo.ofpcina.net/profile/oloturia1979 Oloturia], Elia [http://raspibo.ofpcina.net/profile/DasNetz DasNetz], &lt;br /&gt;
Lupo [http://raspibo.ofpcina.net/profile/Desmolupo Desmolupo],Walter [http://raspibo.ofpcina.net/profile/wave wave]}}&lt;br /&gt;
&lt;br /&gt;
= Progetti in corso =&lt;br /&gt;
&lt;br /&gt;
* [[RaspiRuga]]: un piccolo robot mosso da due motori passo-passo.&lt;br /&gt;
* [[OttoBot]]: il tentativo di fare un robottino con il cheap(!) ATmega8&lt;br /&gt;
* [[MultiFollower]]: Robot didattico che segue percorsi di tipo diverso.&lt;br /&gt;
* [[:Categoria:Ruschino]]: Interfaccia WiFi, si pilota da una pagina web con smartphone e tablet, hardware di recupero, esperimenti in corso!&lt;br /&gt;
* [[Pinza robotica]]: Dopo Ruschino proviamo a riciclare un altro tipo di motori del distributore automatico&lt;br /&gt;
&lt;br /&gt;
= Progetti completati =&lt;br /&gt;
&lt;br /&gt;
* [[Ardubottino]]: un robottino che evita gli ostacoli.&lt;br /&gt;
* [[ESProbottino]]: Ardubottino ha avuto un upgrade.&lt;br /&gt;
* [[Milkbot]]: un automa parzialmente scremato.&lt;br /&gt;
* [[RaspiTank]]: l'evoluzione della RaspiCar basata su un vecchio giocattolo; caratteristiche: servi comandati da Raspberry Pi, braccio meccanico.&lt;br /&gt;
* [[RaspiCar]]: automobilina radiocomandata basata su Raspberry Pi; caratteristiche: motori comandati da relè, relè azionati da transistor, comandare due pin contemporaneamente creando dei thread in Python.&lt;br /&gt;
* [[WindCar]]: (quasi) come sopra, ma con Arietta G25 al posto di Raspberry Pi&lt;br /&gt;
* Il [[braccio robot]] di Simone.&lt;br /&gt;
* [[Camera di sorveglianza]]: una semplicissima camera montata su un pan-tilt che fa lo streaming di cosa succede a casa vostra&lt;br /&gt;
* [[BlueCar]]: un'altra macchinina comandata da un RPi via Wi-Fi o Bluetooth&lt;br /&gt;
* [[Contalike]]: un aggeggino che vi permette di vedere quando perdete o guadagnate un like da un noto social network&lt;br /&gt;
* [[Cesarino]]: un robot assemblato in fretta e furia per testare quanto siano cool le fotoresistenze&lt;br /&gt;
* [[Roomba_scheduler]]: se avete un robot spazzino e volete schedularne l'avvio&lt;br /&gt;
&lt;br /&gt;
= Varie =&lt;br /&gt;
&lt;br /&gt;
* [[Display LCD Hitachi HD44780]] come usarlo, per esempio per avere un feedback sullo status del nostro robot.&lt;br /&gt;
* [[Display LCD SPI a colori]] e tutti i numerosi grattacapi per farlo funzionare.&lt;br /&gt;
* [[HC-05 e HC-06]] i moduli per trasmettere la seriale tramite il Bluetooth.&lt;br /&gt;
* [[Presepe]] un presepe con lucette comandate dal Raspberry Pi.&lt;br /&gt;
* [[OV7670]] come collegare una OV7670 ad Arduino Due.&lt;br /&gt;
&lt;br /&gt;
= Informazioni utili =&lt;br /&gt;
&lt;br /&gt;
* [http://www.servocity.com/index.html Servocity] store di materiale per la robotica particolarmente orientato ai motori e ai servo.&lt;br /&gt;
* [https://www.youtube.com/watch?v=9BQQLgB_mZQ Stepper Motor Pressed Gear Removal] Procedura di rimozione della corona sui motori passo passo. La procedura e' corretta ma occorre procedere delicatamente per non danneggiare i componenti.&lt;br /&gt;
* [http://www.raspibo.org/wiki/index.php?title=AxR75Project001 AxR75Project001] Interfacciamento motore lego, con SN75441ONE e con Raspberry Pi&lt;br /&gt;
* [http://shallowsky.com/blog/hardware/motors-with-arduino.html Interfacciamento motori] in particolare per Arduino, ma adattabile anche ad altri sistemi.&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=OV7670&amp;diff=7331</id>
		<title>OV7670</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=OV7670&amp;diff=7331"/>
		<updated>2021-02-20T12:50:59Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* Lato Arduino Due */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Diversi anni fa comprai questa OV7670 con l'illusione che sarebbe stato divertente farla funzionare con un Arduino. Il mio obiettivo era una cosa molto semplice, come un sensore che scatta foto quando triggerato e che salvasse l'immagine su una SD. Purtroppo non si è rivelato possibile per diverse limitazioni delle schede Arduino più economiche: una scheda come l'Uno non ha abbastanza RAM per memorizzare un'immagine intera alle risoluzioni più alte, ma anche la più dotata Due ha bisogno di una gabola per riuscire ad avere i colori.&lt;br /&gt;
&lt;br /&gt;
[[File:OV7670.JPG]]&lt;br /&gt;
&lt;br /&gt;
Per ovviare a questo occorre una memoria FIFO, normalmente integrata nella scheda assieme a OV7670, ma la mia non l'aveva e acquistarla a parte ha solo comportato avere due problemi (come far funzionare la cam E come far funzionare la FIFO) al posto di uno.&lt;br /&gt;
&lt;br /&gt;
Fra tutte le schede ho scelto l'Arduino Due perché ha abbastanza memoria per tenere un'intera immagine in QVGA (320x240) in bianco e nero e perché ha livelli logici a 3,3V, il che permette di collegarlo a OV7670 senza bisogno di un partitore di tensione.&lt;br /&gt;
&lt;br /&gt;
= Le Guide =&lt;br /&gt;
&lt;br /&gt;
== Instructables ==&lt;br /&gt;
&lt;br /&gt;
Il primo passo per far funzionare una qualsiasi cosa è cercare guide e datasheet. La prima guida in cui ci si imbatte è questa:&lt;br /&gt;
https://www.instructables.com/How-to-Connect-OV7670-to-Arduino-Due/&lt;br /&gt;
&lt;br /&gt;
Questo Instructable è stato il mio punto di partenza. Inizia con un semplice schema per il wiring:&lt;br /&gt;
&lt;br /&gt;
 DUE		OV7670&lt;br /&gt;
 3.3V		VDD&lt;br /&gt;
 GND		GND&lt;br /&gt;
 SCL(21)	SDIOC&lt;br /&gt;
 SDA(20)	SDIOD&lt;br /&gt;
 52		VSYNC&lt;br /&gt;
 32		PCLK&lt;br /&gt;
 7		XCLK&lt;br /&gt;
 44		D7&lt;br /&gt;
 45		D6&lt;br /&gt;
 46		D5&lt;br /&gt;
 47		D4&lt;br /&gt;
 48		D3&lt;br /&gt;
 49		D2&lt;br /&gt;
 50		D1&lt;br /&gt;
 51		D0&lt;br /&gt;
 33		RESET&lt;br /&gt;
 GND		PWDN&lt;br /&gt;
&lt;br /&gt;
A questo schema -senza nessun commento- manca il collegamento di HREF. Non verrà utilizzato e non è necessario collegarlo, ma nella guida non è specificato.&lt;br /&gt;
Nel resto della guida si spiega come il Due debba generare un clock e come scrivere nei registri di OV7670 tramite I²C. Viene fornito anche uno sketch che sembrerebbe funzionare e che in teoria leggerebbe l'immagine in bianco e nero per poi mandare l'output su seriale. Putroppo i programmi per decodificare questo segnale sono su un sito irraggiungibile. Ero quindi a un punto morto.&lt;br /&gt;
&lt;br /&gt;
Ok ok non del tutto, nei commenti (ahimè l'ho scoperto quando ormai avevo già riscritto parte del codice) c'è una soluzione fatta in Processing che funziona bene:&lt;br /&gt;
https://pastebin.com/weAEcrQG&lt;br /&gt;
&lt;br /&gt;
== Come funziona OV7670 e come non aver paura di YCbCr ==&lt;br /&gt;
&lt;br /&gt;
http://embeddedprogrammer.blogspot.com/2012/07/hacking-ov7670-camera-module-sccb-cheat.html&lt;br /&gt;
&lt;br /&gt;
Trovandomi un po' spiazzato, ho pensato che forse avrei dovuto approfittarne per riscrivere da capo tutto quanto, così da far funzionare finalmente la cam e allo stesso tempo imparare qualcosa di nuovo. Lo sketch dell'instructable precedente era per me un po' ostico da leggere, con molti riferimenti a me sconosciuti ai registri interni dell'Arduino Due e della cam. Punto di partenza è stato questo sito che spiega diverse cose sul funzionamento di OV7670.&lt;br /&gt;
&lt;br /&gt;
Qui scopriamo che:&lt;br /&gt;
 VSYNC è il segnale di sincronia verticale (HREF quello orizzontale, ma non lo useremo)&lt;br /&gt;
 PCLK è il clock del pixel (in realtà -mezzo- pixel)&lt;br /&gt;
 XCLK è il clock esterno, OV7670 ha bisogno di un clock esterno per funzionare: se volete scansionare gli indirizzi I²C per scoprire quello della cam, dovrete prima collegare un clock a XCLK&lt;br /&gt;
&lt;br /&gt;
Un pixel su un monitor è composto da due informazioni: la posizione e il colore. La posizione è espressa in coordinate X e Y mentre il colore dalla luminosità dei colori primari R=Red/Rosso, G=Green/Verde e B=Blue/Blu. Normalmente ogni colore è espresso con 8 bit, da cui il nome RGB888. Purtroppo OV7670 invece comunica i pixel sequenzialmente a partire da 0,0 a 320,240 riga per riga e come formati di colore ha RGB565, RGB555 e RGB444 oppure YCbCr422. I primi tre semplicemente mandavano 5 bit di R, 6 di G e 5 di B oppure rispettivamente 5 oppure 4 per ogni colore. L'ultimo formato invece era completamente diverso e necessita di un approfondimento.&lt;br /&gt;
&lt;br /&gt;
Nel format YCbCr l'immagine è separata in tre canali: la luma (Y) ossia la luminosità (se prendessimo solo Y come valore per RGB allora vedremmo l'immagine in bianco e nero) e la croma, ovvero i livelli di differenza da Y del blu (Cb) e del rosso (Cr). Ognuno di questi occupa un byte di informazione.&lt;br /&gt;
&lt;br /&gt;
Ogni falling del PCLK la cam invia un byte di informazione in modo parallelo sui pin da D0 a D7. Come fa quindi a comunicare un pixel ogni colpo PCLK? Semplice: non lo fa. Manda i valori alternati in questo modo:&lt;br /&gt;
Cb0,Y0,Cr0,Y1,Cb2,Y2,Cr2,Y3...&lt;br /&gt;
La definizione di &amp;quot;Pixel Clock&amp;quot; è infatti fuorviante. Sarebbe &amp;quot;Half Pixel Clock&amp;quot; semmai.&lt;br /&gt;
&lt;br /&gt;
Se bastasse l'immagine in bianco e nero allora basterà memorizzare un PCLK no e uno sì e avremo la luma. Questo è quello che faceva in teoria lo sketch del primo instructable. Ovviamente a me non bastava (a parte il fatto che comunque non funzionava), volevo anche i colori. Cb e Cr sono comuni per due pixel alla volta. Sempre secondo il link alla guida sopra: &lt;br /&gt;
 pixel 0 = Y0 Cb0 Cr0&lt;br /&gt;
 pixel 1 = Y1 Cb0 Cr0&lt;br /&gt;
 pixel 2 = Y2 Cb2 Cr2&lt;br /&gt;
 pixel 3 = Y3 Cb2 Cr2&lt;br /&gt;
&lt;br /&gt;
Questo semplificava molto le cose. Invece di mandare la luma via seriale e scartare la croma, avrei mandato alternativamente prima la luma del frame e successivamente la croma. Avrebbe causato degli strani effetti nelle immagini in movimento ma sarebbe stato meglio di prima.&lt;br /&gt;
Perché non mandare contemporaneamente l'informazione? L'Arduino Due ha solo 96KB di SRAM, la luma o le crome da sole sono 320*240*1 byte = 76.8KB l'una. Mandare i dati via seriale alla fine della riga poteva essere una soluzione ma causava numerosi glitch sull'immagine risultante.&lt;br /&gt;
&lt;br /&gt;
La guida è chiara, ma purtroppo manca uno sketch per il Due e relativo programma per processare l'immagine da seriale.&lt;br /&gt;
&lt;br /&gt;
== Il datasheet ==&lt;br /&gt;
&lt;br /&gt;
http://web.mit.edu/6.111/www/f2015/tools/OV7670app.pdf&lt;br /&gt;
&lt;br /&gt;
In questo datasheet sono elencati i registri interni di OV7670. Nello sketch dell'Instructable sono impostati nella maggior parte dei casi senza spiegare cosa servono. Gli stessi valori li ho trovati anche in quest'altra guida: http://embeddedprogrammer.blogspot.com/2012/07/hacking-ov7670-camera-module-sccb-cheat.html e dal relativo codice su github: https://github.com/indrekluuk/LiveOV7670 per il collegamento della cam a un display. &lt;br /&gt;
Da quel che mi è parso di capire, sono i valori che il driver di Linux mette di default e usa per le varie impostazioni della cam (ad es. per passare da QVGA ad altri formati come il QCIF). Molto interessante ma a questo punto la mia missione era già diventata qualcos'altro, ovvero fare in modo che questi registri potessero essere modificati in modo interattivo.&lt;br /&gt;
&lt;br /&gt;
= La soluzione =&lt;br /&gt;
&lt;br /&gt;
L'obiettivo è quindi creare un programma che leggesse la seriale e restituisse l'immagine e allo stesso tempo fare in modo che si potessero leggere e scrivere i registri della cam.&lt;br /&gt;
&lt;br /&gt;
== Lato Arduino Due ==&lt;br /&gt;
&lt;br /&gt;
Lo sketch dell'Instructable fa le seguenti cose:&lt;br /&gt;
* Imposta i registri di OV7670 in modo che sia QVGA in formato YCbCr422&lt;br /&gt;
* Manda un segnale &amp;quot;*RDY*&amp;quot; e memorizza su una matrice un byte no e uno sì dei pin D0-D7&lt;br /&gt;
* Quando l'immagine è completa, manda via seriale ogni singolo byte della matrice&lt;br /&gt;
&lt;br /&gt;
La modifica più importante è stata quella di mandare alternati il valore di Y e quello di CbCr. Nel frattempo avrebbe anche aspettato dallo script lato computer un segnale per dare il via alla lettura oppure un comando per leggere o scrivere su uno dei registri. Successivamente ho anche eliminato tutte le configurazioni che non cambiavano significativamente l'immagine e che probabilmente hanno a che fare con cose come il bilanciamento del bianco.&lt;br /&gt;
&lt;br /&gt;
Vediamo alcuni dettagli dello sketch.&lt;br /&gt;
&lt;br /&gt;
=== Generare un segnale di clock con Arduino ===&lt;br /&gt;
&lt;br /&gt;
Arduino Due ha un generatore di PWM con i quali è possibile creare un segnale di clock di almeno 8MHz sufficienti per il XCLK di OV7670.&lt;br /&gt;
&lt;br /&gt;
  int32_t PWM_pin = digitalPinToBitMask(XCLK);&lt;br /&gt;
  REG_PMC_PCER1 = 1 &amp;lt;&amp;lt; 4;     // Enable peripheral ID 36 (PWM) in the peripheral clock enable register - see 28.15.23&lt;br /&gt;
  REG_PIOC_PDR |= PWM_pin;    // Allow peripheral control for PWM_pin&lt;br /&gt;
  REG_PIOC_ABSR |= PWM_pin;   // Select peripheral B&lt;br /&gt;
  REG_PWM_CPRD6 = 8;          // Period: 84 MHz / 8 = 10.5 MHz - see 38.6.2.2 of datasheet&lt;br /&gt;
  REG_PWM_CDTY6 = 4;          // Duty Cycle: 8 / 4  = 0.5&lt;br /&gt;
  REG_PWM_ENA = 1 &amp;lt;&amp;lt; 6;       // Enable PWML6 (pin 7) - see 38.5.1 and 38.7.5 of datasheet for more info&lt;br /&gt;
&lt;br /&gt;
Gran parte delle informazioni su come funziona questo codice è spiegato su questa guida:&lt;br /&gt;
https://nhoffmanresearch.com/index.php/12-arduino-trap-control&lt;br /&gt;
e relativo datasheet del SAM3X9E:&lt;br /&gt;
http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-11057-32-bit-Cortex-M3-Microcontroller-SAM3X-SAM3A_Datasheet.pdf&lt;br /&gt;
&lt;br /&gt;
=== I registri ===&lt;br /&gt;
&lt;br /&gt;
Tramite I²C è possibile leggere lo stato di un registro o scrivere un nuovo valore. La lista dei registri è elencata sul datasheet, tuttavia alcuni, descritti come &amp;quot;Reserved&amp;quot;, non sono documentati. La prima cosa quando si accende la cam è settare i registri in modo che trasmetta le informazioni nel formato QVGA e YCbCr, inoltre sono abilitate alcune funzioni come l'autobilanciamento del bianco. Una volta impostate queste cose, si può cominciare a catturare le immagini.&lt;br /&gt;
&lt;br /&gt;
=== Loop ===&lt;br /&gt;
&lt;br /&gt;
Una delle cose che non riuscivo a far funzionare era centrare l'immagine. Essendo scollegato HREF il punto di inizio era arbitrario, e questo comportava che l'immagine fosse fuori quadro. Ho cambiato un po' questa filosofia e ho fatto in modo che l'Arduino Due aspettasse un segnale sulla seriale prima di iniziare a trasmettere. Il segnale è composto da due byte, se sono entrambi 0xD0 allora invia una nuova immagine, se invece il primo è un altro valore, viene inviato il registro corrispondente a quel valore, se sono entrambi diversi il registro corrispondente al primo valore viene aggiornato con il secondo valore. Non esiste un registro 0xD0, quindi possiamo usare tale byte per segnalare quando siamo pronti a ricevere una nuova immagine.&lt;br /&gt;
&lt;br /&gt;
In questo modo è possibile alterare in diretta l'immagine, cambiare luminosità, formato e anche scoprire a cosa servono i registri &amp;quot;Reserved&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Cattura dell'immagine ===&lt;br /&gt;
&lt;br /&gt;
La cattura è fatta in due passate per questioni di spazio sulla RAM. Per prima cosa leggiamo Y e poi CbCr. Se non siamo interessati al colore, possiamo commentare la seconda chiamata alla funzione captureImg a cui ho aggiunto un terzo parametro, il bool chroma, per specificare se salvare i bit pari o quelli dispari.&lt;br /&gt;
Ogni PCLK basso viene aggiunto un valore (Y oppure CbCr) alla matrice che rappresenta le righe e le colonne. Durante la lettura il tempo è critico, per cui occorrono alcuni accorgimenti per sveltire le operazioni.&lt;br /&gt;
&lt;br /&gt;
 noInterrupts();&lt;br /&gt;
&lt;br /&gt;
Questo comando disabilita gli interrupt. Non mi sembra che abbia nessun effetto benefico, ma male non fa.&lt;br /&gt;
&lt;br /&gt;
 REG_PIOB_PDSR &amp;amp; (1 &amp;lt;&amp;lt; 21)&lt;br /&gt;
 REG_PIOD_PDSR &amp;amp; (1 &amp;lt;&amp;lt; 10)&lt;br /&gt;
&lt;br /&gt;
Purtroppo le tanto comode funzioni digitalRead() di Arduino sono troppo lente per l'output di OV7670. Leggere direttamente il Pin Data Status Register (PDSR) di SAM3X9E è molto più veloce. Il bit 21 del PortB corrisponde al pin 52, che è quello dove abbiamo attaccato VSYNC, il bit 10 del PortD è il pin 32, dove abbiamo attaccato PCLK. Non è immediato convertire il pin in registro, ma ci sono moltissimi schemi con il pinout del Due, con descritto per ogni pin il Port e il bit.&lt;br /&gt;
&lt;br /&gt;
 (REG_PIOC_PDSR &amp;amp; 0xFF000) &amp;gt;&amp;gt; 12&lt;br /&gt;
&lt;br /&gt;
Invece il PortC sono tutti i pin dov0 abbiamo collegato da D0 a D7. Memorizzando lo stato del Port e applicando un filtro in modo che restituisca solo i valori che ci interessano (PortC dalla 12 alla 19), non dobbiamo subire la costrizione di leggere lo stato di un pin alla volta.&lt;br /&gt;
&lt;br /&gt;
Allo stesso tempo non è possibile usare la seriale di programmazione per trasmettere la matrice, occorre usare la porta nativa (Native) e invece di Serial, la funzione SerialUSB.write. Non c'è bisogno di inizializzarla con un baud rate perché andrà sempre alla velocità massima possibile. Questo dualismo mi ha permesso anche di fare alcune cose interessanti, come usare la porta nativa per la comunicazione con il programma che elabora le immagini e la porta di programmazione per mandare dei messaggi di debug.&lt;br /&gt;
&lt;br /&gt;
== Lato Python ==&lt;br /&gt;
&lt;br /&gt;
Sul computer ho scritto un piccolo script che pettinasse l'output dell'Arduino.&lt;br /&gt;
&lt;br /&gt;
Per prima cosa manda un segnale di due byte. Se il segnale è 0xD0 0xD0 allora si mette in attesa di larghezza*altezza byte. Una volta ricevuti e messi in ordine (ricordate, un dato di croma vale per due pixel, mentre la luma c'è per ognuno) occorre usare alcune formule per trasformare i dati in RGB. Ho usato questa formula, che si può trovare nelle guide già citate sopra:&lt;br /&gt;
 R = int(max(0, min(255,Y + 1.40200 * (Cr - 0x80))))&lt;br /&gt;
 G = int(max(0, min(255,Y - 0.34414 * (Cb - 0x80) - 0.71414 * (Cr - 0x80))))&lt;br /&gt;
 B = int(max(0, min(255,Y + 1.77200 * (Cb - 0x80))))&lt;br /&gt;
&lt;br /&gt;
Lo script readYUV422.py restituisce quindi una bitmap. Gli altri script saveYUV422.py e showYUV422.py rispettivamente salvano l'immagine con PIL oppure la mostrano con pygame. L'altro script, tkinterface.py, invece è un'interfaccia fatta con tkinter con cui possiamo interagire direttamente con i registri di OV7670. Per risolvere il problema delle azioni concorrenti, ho usato un thread che facesse il refresh dell'immagine. La porta usata è /dev/ttyACM0, ma è possibile cambiarla aggiungendo un argomento quando si lancia lo script.&lt;br /&gt;
&lt;br /&gt;
[[File:OVCAM.JPG]]&lt;br /&gt;
&lt;br /&gt;
= I risultati =&lt;br /&gt;
&lt;br /&gt;
Non è andato sempre tutto bene al primo colpo. Soprattutto all'inizio, quando non avevo ancora capito come leggere l'output, la cam ha dato degli output interessanti. Eccone alcuni.&lt;br /&gt;
[[File:Glitches.jpg]]&lt;br /&gt;
&lt;br /&gt;
= Il repo =&lt;br /&gt;
&lt;br /&gt;
Tutta la roba, con tutte le istruzioni e quant'altro, lo trovate nel repository su:&lt;br /&gt;
https://github.com/oloturia/ovcam&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=OV7670&amp;diff=7330</id>
		<title>OV7670</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=OV7670&amp;diff=7330"/>
		<updated>2021-02-20T01:57:36Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: OV7670&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Diversi anni fa comprai questa OV7670 con l'illusione che sarebbe stato divertente farla funzionare con un Arduino. Il mio obiettivo era una cosa molto semplice, come un sensore che scatta foto quando triggerato e che salvasse l'immagine su una SD. Purtroppo non si è rivelato possibile per diverse limitazioni delle schede Arduino più economiche: una scheda come l'Uno non ha abbastanza RAM per memorizzare un'immagine intera alle risoluzioni più alte, ma anche la più dotata Due ha bisogno di una gabola per riuscire ad avere i colori.&lt;br /&gt;
&lt;br /&gt;
[[File:OV7670.JPG]]&lt;br /&gt;
&lt;br /&gt;
Per ovviare a questo occorre una memoria FIFO, normalmente integrata nella scheda assieme a OV7670, ma la mia non l'aveva e acquistarla a parte ha solo comportato avere due problemi (come far funzionare la cam E come far funzionare la FIFO) al posto di uno.&lt;br /&gt;
&lt;br /&gt;
Fra tutte le schede ho scelto l'Arduino Due perché ha abbastanza memoria per tenere un'intera immagine in QVGA (320x240) in bianco e nero e perché ha livelli logici a 3,3V, il che permette di collegarlo a OV7670 senza bisogno di un partitore di tensione.&lt;br /&gt;
&lt;br /&gt;
= Le Guide =&lt;br /&gt;
&lt;br /&gt;
== Instructables ==&lt;br /&gt;
&lt;br /&gt;
Il primo passo per far funzionare una qualsiasi cosa è cercare guide e datasheet. La prima guida in cui ci si imbatte è questa:&lt;br /&gt;
https://www.instructables.com/How-to-Connect-OV7670-to-Arduino-Due/&lt;br /&gt;
&lt;br /&gt;
Questo Instructable è stato il mio punto di partenza. Inizia con un semplice schema per il wiring:&lt;br /&gt;
&lt;br /&gt;
 DUE		OV7670&lt;br /&gt;
 3.3V		VDD&lt;br /&gt;
 GND		GND&lt;br /&gt;
 SCL(21)	SDIOC&lt;br /&gt;
 SDA(20)	SDIOD&lt;br /&gt;
 52		VSYNC&lt;br /&gt;
 32		PCLK&lt;br /&gt;
 7		XCLK&lt;br /&gt;
 44		D7&lt;br /&gt;
 45		D6&lt;br /&gt;
 46		D5&lt;br /&gt;
 47		D4&lt;br /&gt;
 48		D3&lt;br /&gt;
 49		D2&lt;br /&gt;
 50		D1&lt;br /&gt;
 51		D0&lt;br /&gt;
 33		RESET&lt;br /&gt;
 GND		PWDN&lt;br /&gt;
&lt;br /&gt;
A questo schema -senza nessun commento- manca il collegamento di HREF. Non verrà utilizzato e non è necessario collegarlo, ma nella guida non è specificato.&lt;br /&gt;
Nel resto della guida si spiega come il Due debba generare un clock e come scrivere nei registri di OV7670 tramite I²C. Viene fornito anche uno sketch che sembrerebbe funzionare e che in teoria leggerebbe l'immagine in bianco e nero per poi mandare l'output su seriale. Putroppo i programmi per decodificare questo segnale sono su un sito irraggiungibile. Ero quindi a un punto morto.&lt;br /&gt;
&lt;br /&gt;
Ok ok non del tutto, nei commenti (ahimè l'ho scoperto quando ormai avevo già riscritto parte del codice) c'è una soluzione fatta in Processing che funziona bene:&lt;br /&gt;
https://pastebin.com/weAEcrQG&lt;br /&gt;
&lt;br /&gt;
== Come funziona OV7670 e come non aver paura di YCbCr ==&lt;br /&gt;
&lt;br /&gt;
http://embeddedprogrammer.blogspot.com/2012/07/hacking-ov7670-camera-module-sccb-cheat.html&lt;br /&gt;
&lt;br /&gt;
Trovandomi un po' spiazzato, ho pensato che forse avrei dovuto approfittarne per riscrivere da capo tutto quanto, così da far funzionare finalmente la cam e allo stesso tempo imparare qualcosa di nuovo. Lo sketch dell'instructable precedente era per me un po' ostico da leggere, con molti riferimenti a me sconosciuti ai registri interni dell'Arduino Due e della cam. Punto di partenza è stato questo sito che spiega diverse cose sul funzionamento di OV7670.&lt;br /&gt;
&lt;br /&gt;
Qui scopriamo che:&lt;br /&gt;
 VSYNC è il segnale di sincronia verticale (HREF quello orizzontale, ma non lo useremo)&lt;br /&gt;
 PCLK è il clock del pixel (in realtà -mezzo- pixel)&lt;br /&gt;
 XCLK è il clock esterno, OV7670 ha bisogno di un clock esterno per funzionare: se volete scansionare gli indirizzi I²C per scoprire quello della cam, dovrete prima collegare un clock a XCLK&lt;br /&gt;
&lt;br /&gt;
Un pixel su un monitor è composto da due informazioni: la posizione e il colore. La posizione è espressa in coordinate X e Y mentre il colore dalla luminosità dei colori primari R=Red/Rosso, G=Green/Verde e B=Blue/Blu. Normalmente ogni colore è espresso con 8 bit, da cui il nome RGB888. Purtroppo OV7670 invece comunica i pixel sequenzialmente a partire da 0,0 a 320,240 riga per riga e come formati di colore ha RGB565, RGB555 e RGB444 oppure YCbCr422. I primi tre semplicemente mandavano 5 bit di R, 6 di G e 5 di B oppure rispettivamente 5 oppure 4 per ogni colore. L'ultimo formato invece era completamente diverso e necessita di un approfondimento.&lt;br /&gt;
&lt;br /&gt;
Nel format YCbCr l'immagine è separata in tre canali: la luma (Y) ossia la luminosità (se prendessimo solo Y come valore per RGB allora vedremmo l'immagine in bianco e nero) e la croma, ovvero i livelli di differenza da Y del blu (Cb) e del rosso (Cr). Ognuno di questi occupa un byte di informazione.&lt;br /&gt;
&lt;br /&gt;
Ogni falling del PCLK la cam invia un byte di informazione in modo parallelo sui pin da D0 a D7. Come fa quindi a comunicare un pixel ogni colpo PCLK? Semplice: non lo fa. Manda i valori alternati in questo modo:&lt;br /&gt;
Cb0,Y0,Cr0,Y1,Cb2,Y2,Cr2,Y3...&lt;br /&gt;
La definizione di &amp;quot;Pixel Clock&amp;quot; è infatti fuorviante. Sarebbe &amp;quot;Half Pixel Clock&amp;quot; semmai.&lt;br /&gt;
&lt;br /&gt;
Se bastasse l'immagine in bianco e nero allora basterà memorizzare un PCLK no e uno sì e avremo la luma. Questo è quello che faceva in teoria lo sketch del primo instructable. Ovviamente a me non bastava (a parte il fatto che comunque non funzionava), volevo anche i colori. Cb e Cr sono comuni per due pixel alla volta. Sempre secondo il link alla guida sopra: &lt;br /&gt;
 pixel 0 = Y0 Cb0 Cr0&lt;br /&gt;
 pixel 1 = Y1 Cb0 Cr0&lt;br /&gt;
 pixel 2 = Y2 Cb2 Cr2&lt;br /&gt;
 pixel 3 = Y3 Cb2 Cr2&lt;br /&gt;
&lt;br /&gt;
Questo semplificava molto le cose. Invece di mandare la luma via seriale e scartare la croma, avrei mandato alternativamente prima la luma del frame e successivamente la croma. Avrebbe causato degli strani effetti nelle immagini in movimento ma sarebbe stato meglio di prima.&lt;br /&gt;
Perché non mandare contemporaneamente l'informazione? L'Arduino Due ha solo 96KB di SRAM, la luma o le crome da sole sono 320*240*1 byte = 76.8KB l'una. Mandare i dati via seriale alla fine della riga poteva essere una soluzione ma causava numerosi glitch sull'immagine risultante.&lt;br /&gt;
&lt;br /&gt;
La guida è chiara, ma purtroppo manca uno sketch per il Due e relativo programma per processare l'immagine da seriale.&lt;br /&gt;
&lt;br /&gt;
== Il datasheet ==&lt;br /&gt;
&lt;br /&gt;
http://web.mit.edu/6.111/www/f2015/tools/OV7670app.pdf&lt;br /&gt;
&lt;br /&gt;
In questo datasheet sono elencati i registri interni di OV7670. Nello sketch dell'Instructable sono impostati nella maggior parte dei casi senza spiegare cosa servono. Gli stessi valori li ho trovati anche in quest'altra guida: http://embeddedprogrammer.blogspot.com/2012/07/hacking-ov7670-camera-module-sccb-cheat.html e dal relativo codice su github: https://github.com/indrekluuk/LiveOV7670 per il collegamento della cam a un display. &lt;br /&gt;
Da quel che mi è parso di capire, sono i valori che il driver di Linux mette di default e usa per le varie impostazioni della cam (ad es. per passare da QVGA ad altri formati come il QCIF). Molto interessante ma a questo punto la mia missione era già diventata qualcos'altro, ovvero fare in modo che questi registri potessero essere modificati in modo interattivo.&lt;br /&gt;
&lt;br /&gt;
= La soluzione =&lt;br /&gt;
&lt;br /&gt;
L'obiettivo è quindi creare un programma che leggesse la seriale e restituisse l'immagine e allo stesso tempo fare in modo che si potessero leggere e scrivere i registri della cam.&lt;br /&gt;
&lt;br /&gt;
== Lato Arduino Due ==&lt;br /&gt;
&lt;br /&gt;
Lo sketch dell'Instructable fondamentalmente fa le seguenti cose&lt;br /&gt;
 Imposta i registri di OV7670 in modo che sia QVGA in formato YCbCr422&lt;br /&gt;
 Manda un segnale &amp;quot;*RDY*&amp;quot; e memorizza su una matrice un byte no e uno sì dei pin D0-D7&lt;br /&gt;
 Quando l'immagine è completa, manda via seriale ogni singolo byte della matrice&lt;br /&gt;
&lt;br /&gt;
La modifica più importante è stata quella di mandare alternati il valore di Y e quello di CbCr. Nel frattempo avrebbe anche aspettato dallo script lato computer un segnale per dare il via alla lettura oppure un comando per leggere o scrivere su uno dei registri. Successivamente ho anche eliminato tutte le configurazioni che non cambiavano significativamente l'immagine e che probabilmente hanno a che fare con cose come il bilanciamento del bianco.&lt;br /&gt;
&lt;br /&gt;
Vediamo alcuni dettagli dello sketch.&lt;br /&gt;
&lt;br /&gt;
=== Generare un segnale di clock con Arduino ===&lt;br /&gt;
&lt;br /&gt;
Arduino Due ha un generatore di PWM con i quali è possibile creare un segnale di clock di almeno 8MHz sufficienti per il XCLK di OV7670.&lt;br /&gt;
&lt;br /&gt;
  int32_t PWM_pin = digitalPinToBitMask(XCLK);&lt;br /&gt;
  REG_PMC_PCER1 = 1 &amp;lt;&amp;lt; 4;     // Enable peripheral ID 36 (PWM) in the peripheral clock enable register - see 28.15.23&lt;br /&gt;
  REG_PIOC_PDR |= PWM_pin;    // Allow peripheral control for PWM_pin&lt;br /&gt;
  REG_PIOC_ABSR |= PWM_pin;   // Select peripheral B&lt;br /&gt;
  REG_PWM_CPRD6 = 8;          // Period: 84 MHz / 8 = 10.5 MHz - see 38.6.2.2 of datasheet&lt;br /&gt;
  REG_PWM_CDTY6 = 4;          // Duty Cycle: 8 / 4  = 0.5&lt;br /&gt;
  REG_PWM_ENA = 1 &amp;lt;&amp;lt; 6;       // Enable PWML6 (pin 7) - see 38.5.1 and 38.7.5 of datasheet for more info&lt;br /&gt;
&lt;br /&gt;
Gran parte delle informazioni su come funziona questo codice è spiegato su questa guida:&lt;br /&gt;
https://nhoffmanresearch.com/index.php/12-arduino-trap-control&lt;br /&gt;
e relativo datasheet del SAM3X9E:&lt;br /&gt;
http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-11057-32-bit-Cortex-M3-Microcontroller-SAM3X-SAM3A_Datasheet.pdf&lt;br /&gt;
&lt;br /&gt;
=== I registri ===&lt;br /&gt;
&lt;br /&gt;
Tramite I²C è possibile leggere lo stato di un registro o scrivere un nuovo valore. La lista dei registri è elencata sul datasheet, tuttavia alcuni, descritti come &amp;quot;Reserved&amp;quot;, non sono documentati. La prima cosa quando si accende la cam è settare i registri in modo che trasmetta le informazioni nel formato QVGA e YCbCr, inoltre sono abilitate alcune funzioni come l'autobilanciamento del bianco. Una volta impostate queste cose, si può cominciare a catturare le immagini.&lt;br /&gt;
&lt;br /&gt;
=== Loop ===&lt;br /&gt;
&lt;br /&gt;
Una delle cose che non riuscivo a far funzionare era centrare l'immagine. Essendo scollegato HREF il punto di inizio era arbitrario, e questo comportava che l'immagine fosse fuori quadro. Ho cambiato un po' questa filosofia e ho fatto in modo che l'Arduino Due aspettasse un segnale sulla seriale prima di iniziare a trasmettere. Il segnale è composto da due byte, se sono entrambi 0xD0 allora invia una nuova immagine, se invece il primo è un altro valore, viene inviato il registro corrispondente a quel valore, se sono entrambi diversi il registro corrispondente al primo valore viene aggiornato con il secondo valore. Non esiste un registro 0xD0, quindi possiamo usare tale byte per segnalare quando siamo pronti a ricevere una nuova immagine.&lt;br /&gt;
&lt;br /&gt;
In questo modo è possibile alterare in diretta l'immagine, cambiare luminosità, formato e anche scoprire a cosa servono i registri &amp;quot;Reserved&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Cattura dell'immagine ===&lt;br /&gt;
&lt;br /&gt;
La cattura è fatta in due passate per questioni di spazio sulla RAM. Per prima cosa leggiamo Y e poi CbCr. Se non siamo interessati al colore, possiamo commentare la seconda chiamata alla funzione captureImg a cui ho aggiunto un terzo parametro, il bool chroma, per specificare se salvare i bit pari o quelli dispari.&lt;br /&gt;
Ogni PCLK basso viene aggiunto un valore (Y oppure CbCr) alla matrice che rappresenta le righe e le colonne. Durante la lettura il tempo è critico, per cui occorrono alcuni accorgimenti per sveltire le operazioni.&lt;br /&gt;
&lt;br /&gt;
 noInterrupts();&lt;br /&gt;
&lt;br /&gt;
Questo comando disabilita gli interrupt. Non mi sembra che abbia nessun effetto benefico, ma male non fa.&lt;br /&gt;
&lt;br /&gt;
 REG_PIOB_PDSR &amp;amp; (1 &amp;lt;&amp;lt; 21)&lt;br /&gt;
 REG_PIOD_PDSR &amp;amp; (1 &amp;lt;&amp;lt; 10)&lt;br /&gt;
&lt;br /&gt;
Purtroppo le tanto comode funzioni digitalRead() di Arduino sono troppo lente per l'output di OV7670. Leggere direttamente il Pin Data Status Register (PDSR) di SAM3X9E è molto più veloce. Il bit 21 del PortB corrisponde al pin 52, che è quello dove abbiamo attaccato VSYNC, il bit 10 del PortD è il pin 32, dove abbiamo attaccato PCLK. Non è immediato convertire il pin in registro, ma ci sono moltissimi schemi con il pinout del Due, con descritto per ogni pin il Port e il bit.&lt;br /&gt;
&lt;br /&gt;
 (REG_PIOC_PDSR &amp;amp; 0xFF000) &amp;gt;&amp;gt; 12&lt;br /&gt;
&lt;br /&gt;
Invece il PortC sono tutti i pin dov0 abbiamo collegato da D0 a D7. Memorizzando lo stato del Port e applicando un filtro in modo che restituisca solo i valori che ci interessano (PortC dalla 12 alla 19), non dobbiamo subire la costrizione di leggere lo stato di un pin alla volta.&lt;br /&gt;
&lt;br /&gt;
Allo stesso tempo non è possibile usare la seriale di programmazione per trasmettere la matrice, occorre usare la porta nativa (Native) e invece di Serial, la funzione SerialUSB.write. Non c'è bisogno di inizializzarla con un baud rate perché andrà sempre alla velocità massima possibile. Questo dualismo mi ha permesso anche di fare alcune cose interessanti, come usare la porta nativa per la comunicazione con il programma che elabora le immagini e la porta di programmazione per mandare dei messaggi di debug.&lt;br /&gt;
&lt;br /&gt;
== Lato Python ==&lt;br /&gt;
&lt;br /&gt;
Sul computer ho scritto un piccolo script che pettinasse l'output dell'Arduino.&lt;br /&gt;
&lt;br /&gt;
Per prima cosa manda un segnale di due byte. Se il segnale è 0xD0 0xD0 allora si mette in attesa di larghezza*altezza byte. Una volta ricevuti e messi in ordine (ricordate, un dato di croma vale per due pixel, mentre la luma c'è per ognuno) occorre usare alcune formule per trasformare i dati in RGB. Ho usato questa formula, che si può trovare nelle guide già citate sopra:&lt;br /&gt;
 R = int(max(0, min(255,Y + 1.40200 * (Cr - 0x80))))&lt;br /&gt;
 G = int(max(0, min(255,Y - 0.34414 * (Cb - 0x80) - 0.71414 * (Cr - 0x80))))&lt;br /&gt;
 B = int(max(0, min(255,Y + 1.77200 * (Cb - 0x80))))&lt;br /&gt;
&lt;br /&gt;
Lo script readYUV422.py restituisce quindi una bitmap. Gli altri script saveYUV422.py e showYUV422.py rispettivamente salvano l'immagine con PIL oppure la mostrano con pygame. L'altro script, tkinterface.py, invece è un'interfaccia fatta con tkinter con cui possiamo interagire direttamente con i registri di OV7670. Per risolvere il problema delle azioni concorrenti, ho usato un thread che facesse il refresh dell'immagine. La porta usata è /dev/ttyACM0, ma è possibile cambiarla aggiungendo un argomento quando si lancia lo script.&lt;br /&gt;
&lt;br /&gt;
[[File:OVCAM.JPG]]&lt;br /&gt;
&lt;br /&gt;
= I risultati =&lt;br /&gt;
&lt;br /&gt;
Non è andato sempre tutto bene al primo colpo. Soprattutto all'inizio, quando non avevo ancora capito come leggere l'output, la cam ha dato degli output interessanti. Eccone alcuni.&lt;br /&gt;
[[File:Glitches.jpg]]&lt;br /&gt;
&lt;br /&gt;
= Il repo =&lt;br /&gt;
&lt;br /&gt;
Tutta la roba, con tutte le istruzioni e quant'altro, lo trovate nel repository su:&lt;br /&gt;
https://github.com/oloturia/ovcam&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=File:Glitches.jpg&amp;diff=7329</id>
		<title>File:Glitches.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=File:Glitches.jpg&amp;diff=7329"/>
		<updated>2021-02-20T01:33:47Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=File:OVCAM.JPG&amp;diff=7328</id>
		<title>File:OVCAM.JPG</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=File:OVCAM.JPG&amp;diff=7328"/>
		<updated>2021-02-20T01:26:48Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=File:OV7670.JPG&amp;diff=7327</id>
		<title>File:OV7670.JPG</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=File:OV7670.JPG&amp;diff=7327"/>
		<updated>2021-02-20T01:19:44Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Gruppo_Robottini&amp;diff=7326</id>
		<title>Gruppo Robottini</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Gruppo_Robottini&amp;diff=7326"/>
		<updated>2021-02-20T01:03:32Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* Varie */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Gruppo&lt;br /&gt;
|nome=Robottini&lt;br /&gt;
|descrizione=l'umanità non ha speranza!&lt;br /&gt;
|social=http://raspibo.ofpcina.net/groups/profile/2815/robottini-terrestri&lt;br /&gt;
|mailinglist=http://liste.raspibo.org/wws/subscribe/robot.terrestri Vuoi partecipare o solamente essere informato? Iscriviti alla mailing list&lt;br /&gt;
|iscritti=Daniele [http://raspibo.ofpcina.net/profile/dancast78 dancast78], Savino [http://raspibo.ofpcina.net/profile/thegamer thegamer], Carmelo [http://raspibo.ofpcina.net/profile/tarmelop tarmelop], Gianni, Peppe, Marco, Luigi, Antonio, [http://raspibo.ofpcina.net/profile/oloturia1979 Oloturia], Elia [http://raspibo.ofpcina.net/profile/DasNetz DasNetz], &lt;br /&gt;
Lupo [http://raspibo.ofpcina.net/profile/Desmolupo Desmolupo],Walter [http://raspibo.ofpcina.net/profile/wave wave]}}&lt;br /&gt;
&lt;br /&gt;
= Progetti in corso =&lt;br /&gt;
&lt;br /&gt;
* [[RaspiRuga]]: un piccolo robot mosso da due motori passo-passo.&lt;br /&gt;
* [[OttoBot]]: il tentativo di fare un robottino con il cheap(!) ATmega8&lt;br /&gt;
* [[MultiFollower]]: Robot didattico che segue percorsi di tipo diverso.&lt;br /&gt;
* [[:Categoria:Ruschino]]: Interfaccia WiFi, si pilota da una pagina web con smartphone e tablet, hardware di recupero, esperimenti in corso!&lt;br /&gt;
* [[Pinza robotica]]: Dopo Ruschino proviamo a riciclare un altro tipo di motori del distributore automatico&lt;br /&gt;
&lt;br /&gt;
= Progetti completati =&lt;br /&gt;
&lt;br /&gt;
* [[Ardubottino]]: un robottino che evita gli ostacoli.&lt;br /&gt;
* [[Milkbot]]: un automa parzialmente scremato.&lt;br /&gt;
* [[RaspiTank]]: l'evoluzione della RaspiCar basata su un vecchio giocattolo; caratteristiche: servi comandati da Raspberry Pi, braccio meccanico.&lt;br /&gt;
* [[RaspiCar]]: automobilina radiocomandata basata su Raspberry Pi; caratteristiche: motori comandati da relè, relè azionati da transistor, comandare due pin contemporaneamente creando dei thread in Python.&lt;br /&gt;
* [[WindCar]]: (quasi) come sopra, ma con Arietta G25 al posto di Raspberry Pi&lt;br /&gt;
* Il [[braccio robot]] di Simone.&lt;br /&gt;
* [[Camera di sorveglianza]]: una semplicissima camera montata su un pan-tilt che fa lo streaming di cosa succede a casa vostra&lt;br /&gt;
* [[BlueCar]]: un'altra macchinina comandata da un RPi via Wi-Fi o Bluetooth&lt;br /&gt;
* [[Contalike]]: un aggeggino che vi permette di vedere quando perdete o guadagnate un like da un noto social network&lt;br /&gt;
* [[Cesarino]]: un robot assemblato in fretta e furia per testare quanto siano cool le fotoresistenze&lt;br /&gt;
* [[Roomba_scheduler]]: se avete un robot spazzino e volete schedularne l'avvio&lt;br /&gt;
&lt;br /&gt;
= Varie =&lt;br /&gt;
&lt;br /&gt;
* [[Display LCD Hitachi HD44780]] come usarlo, per esempio per avere un feedback sullo status del nostro robot.&lt;br /&gt;
* [[Display LCD SPI a colori]] e tutti i numerosi grattacapi per farlo funzionare.&lt;br /&gt;
* [[HC-05 e HC-06]] i moduli per trasmettere la seriale tramite il Bluetooth.&lt;br /&gt;
* [[Presepe]] un presepe con lucette comandate dal Raspberry Pi.&lt;br /&gt;
* [[OV7670]] come collegare una OV7670 ad Arduino Due.&lt;br /&gt;
&lt;br /&gt;
= Informazioni utili =&lt;br /&gt;
&lt;br /&gt;
* [http://www.servocity.com/index.html Servocity] store di materiale per la robotica particolarmente orientato ai motori e ai servo.&lt;br /&gt;
* [https://www.youtube.com/watch?v=9BQQLgB_mZQ Stepper Motor Pressed Gear Removal] Procedura di rimozione della corona sui motori passo passo. La procedura e' corretta ma occorre procedere delicatamente per non danneggiare i componenti.&lt;br /&gt;
* [http://www.raspibo.org/wiki/index.php?title=AxR75Project001 AxR75Project001] Interfacciamento motore lego, con SN75441ONE e con Raspberry Pi&lt;br /&gt;
* [http://shallowsky.com/blog/hardware/motors-with-arduino.html Interfacciamento motori] in particolare per Arduino, ma adattabile anche ad altri sistemi.&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=HC-05_e_HC-06&amp;diff=7325</id>
		<title>HC-05 e HC-06</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=HC-05_e_HC-06&amp;diff=7325"/>
		<updated>2021-02-01T13:06:26Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* Bluetooth Manager */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;HC-05 e HC-06 sono due tipi di moduli Bluetooth che ci permettono di trasmettere e ricevere dati tramite l'interfaccia seriale (ma non solo). Sono molto semplici da usare e hanno molteplici utilizzi.&lt;br /&gt;
&lt;br /&gt;
[[File:Hc-05.jpg]]&lt;br /&gt;
&lt;br /&gt;
Nella foto potete vedere a sinistra il modulo senza lo zoccolo, i cui pin sono i contatti intorno, a destra la versione più comune, saldata su uno zoccolo con i pin di alimentazione e la seriale libera. Gli zoccoli hanno diverse forme e alcuni (come questo) hanno anche alcuni pin in più con funzioni diverse.&lt;br /&gt;
&lt;br /&gt;
= Pinout =&lt;br /&gt;
&lt;br /&gt;
Le board hanno il seguente pinout ([http://www.14core.com/working-with-hc05-hc06-to-configure-and-implementations/ immagine tratta da 14core.com])&lt;br /&gt;
[[File:Bluetooth-HC06-Versus-HC05-Bluetooth-Module-Comparison-001.jpg]]&lt;br /&gt;
&lt;br /&gt;
Essendo la board spesso saldata su uno zoccolo ed essendo quest'ultimo non standard, non è possibile dare un pinout preciso. I pin che troverete sempre sono:&lt;br /&gt;
&lt;br /&gt;
* '''Vcc''' e '''GND'''&lt;br /&gt;
* '''TXD''' e '''RXD''' (sono TX e RX seriali)&lt;br /&gt;
&lt;br /&gt;
Quelli opzionali:&lt;br /&gt;
&lt;br /&gt;
* '''Key''' questo pin è collegato al pin della board che deve essere collegato alla 3,3V per entrare in modalità AT, normalmente lo zoccolo ha anche un pulsante che fa la stessa cosa, in mancanza dell'uno e dell'altro dovrete fare ponte con qualcosa di conduttivo fra una sorgente a 3,3V e il pin Key sulla board&lt;br /&gt;
* '''State''' questo pin dovrebbe essere alto quando il device è connesso a qualcosa e basso quando non è collegato a niente&lt;br /&gt;
* '''EN''' dovrebbe essere l'enable, ma non è chiaro come funzioni&lt;br /&gt;
&lt;br /&gt;
Le board hanno anche il collegamento per un LED di stato. Lo zoccolo di solito ne possiede uno. Il LED ha tre stati:&lt;br /&gt;
&lt;br /&gt;
* Lampeggia velocemente: la board è accesa e non è collegata a niente&lt;br /&gt;
* Lampeggia piano (circa 1s): la board è collegata a qualcosa&lt;br /&gt;
* Lampeggia molto piano (circa 2s): la board è in modalità AT&lt;br /&gt;
&lt;br /&gt;
= Differenze HC-05 e HC-06 =&lt;br /&gt;
&lt;br /&gt;
I due device sono molto simili. Nella maggior parte dei casi potete prendere l'uno o l'altro indifferentemente. Le uniche differenze degne di nota sono:&lt;br /&gt;
&lt;br /&gt;
* L'HC-05 può essere impostato come master, mentre l''''HC-06 è solo slave'''. Questo comporta che entrambi possono ricevere connessioni ma '''solo l'HC-05 può iniziarne una'''.&lt;br /&gt;
&lt;br /&gt;
* L'HC-06 è sempre in modalità AT quando non è collegato a un altro dispositivo, mentre l'HC-05 occorre accenderlo mandando 3,3 volt allo speciale pin &amp;quot;key&amp;quot; (gli zoccoli di solito hanno un pin &amp;quot;Key&amp;quot; oppure un pulsante da premere).&lt;br /&gt;
&lt;br /&gt;
* Il pinout è diverso (ovviamente s'intende il pinout della board, non quello dello zoccolo).&lt;br /&gt;
&lt;br /&gt;
= Alimentazione =&lt;br /&gt;
I moduli vanno alimentati a 3,3V. Gli zoccoli più comuni permettono anche alimentazioni diverse tramite un regolatore di voltaggio, ma i livelli logici sono sempre a 3,3V.&lt;br /&gt;
&lt;br /&gt;
= Collegamento all'Arduino =&lt;br /&gt;
Potete collegare direttamente la seriale UART dell'Arduino al modulo HC-0X. RX (ricevitore seriale) e TX (trasmittente seriale) di Arduino (pin 0 e 1) vanno collegati rispettivamente al TX e all'RX del modulo Bluetooth (in pratica: dovete incrociarli: RX con TX e TX con RX). Se vi serve solo come ricevente, potete collegare solo il TX dell'HC-0X all'RX dell'Arduino, al contrario se vi serve solo una trasmittente collegate solo l'RX dell'HC-0X al TX dell'Arduino. RX e TX a volte sono scritti RXD e TXD. Non cambia assolutamente nulla.&lt;br /&gt;
&lt;br /&gt;
Se la seriale fisica dovesse essere occupata, è possibile averne una software su due pin diversi con la libreria [https://www.arduino.cc/en/Reference/SoftwareSerial SoftwareSerial].&lt;br /&gt;
&lt;br /&gt;
= Collegamento Bluetooth al PC =&lt;br /&gt;
&lt;br /&gt;
Sotto Linux ci sono diversi modi per attivare una comunicazione seriale fra il SO e un dispositivo che permette questo tipo di servizio. La seriale comparirà come file di device nella posizione /dev/rfcommX dove X è un numero che parte da 0. Se abbiamo una sola comunicazione seriale avremo quindi /dev/rfcomm0. A questo file ci si può collegare ad esempio con il comando screen.&lt;br /&gt;
&lt;br /&gt;
 # screen /dev/rfcommX &amp;lt;velocità baud&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Occorre essere root o dare il comando con sudo, perché l'utente normale non dovrebbe essere in grado di scrivere su rfcommX.&lt;br /&gt;
&lt;br /&gt;
== Prerequisiti ==&lt;br /&gt;
&lt;br /&gt;
L'utente deve essere nel gruppo &amp;quot;bluetooth&amp;quot;. Per aggiungersi al gruppo bisogna editare il file /etc/group e aggiungere il vostro nome al gruppo, troverete qualcosa come&lt;br /&gt;
&lt;br /&gt;
 bluetooth:x:&amp;lt;ID&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
dovete aggiungere l'utente dopo i due punti&lt;br /&gt;
&lt;br /&gt;
 bluetooth:x:&amp;lt;ID&amp;gt;:utente&lt;br /&gt;
&lt;br /&gt;
per attivare la modifica fate log out e log in&lt;br /&gt;
&lt;br /&gt;
== Bluetooth Manager ==&lt;br /&gt;
&lt;br /&gt;
Bluetooth Manager è il programma che viene aperto di default quando un adattatore Bluetooth USB è collegato al PC. Purtroppo è anche pieno di bug e abbastanza prono a crashare. Nelle ultime versioni pare che vada molto meglio. Nel caso abbiate problemi vi consiglio di chiudere il programma (dovete cliccare col tasto destro sull'icona del Bluetooth sulla barra delle applet oppure killate blueman-manager) e lanciare da un terminale blueman-manager. Vediamo passo passo come fare a creare un collegamento seriale.&lt;br /&gt;
&lt;br /&gt;
Cliccate su &amp;quot;Search&amp;quot; e cercate il dispositivo a cui dovete collegarvi. Se non l'avete rinominato, gli HC si chiameranno HC-05 o HC-06. Nel caso ce ne sia più di uno, cercate di ricordare l'indirizzo fisico, il MAC Address.&lt;br /&gt;
&lt;br /&gt;
[[File:Hc0506 1.png]]&lt;br /&gt;
&lt;br /&gt;
Cliccate col tasto destro e selezionate &amp;quot;Pair&amp;quot;. Uscirà un pop up in cui vi verrà chiesto il pin. Se non l'avete modificato normalmente è 1234.&lt;br /&gt;
&lt;br /&gt;
[[File:Hc0506 2.png]]&lt;br /&gt;
&lt;br /&gt;
Una volta avvenuto il pairing, comparirà il simbolo di una chiave vicino all'icona del vostro device Bluetooth. Cliccate di nuovo il tasto destro e selezionate Serial Port.&lt;br /&gt;
&lt;br /&gt;
[[File:Hc0506 4.png]]&lt;br /&gt;
&lt;br /&gt;
Se tutto è andato come doveva, vedrete l'indicazione di quale file di device è la vostra comunicazione seriale. Ora potete aprirlo con screen o altri programmi.&lt;br /&gt;
&lt;br /&gt;
[[File:Hc0506 5.png]]&lt;br /&gt;
&lt;br /&gt;
== bluetoothctl ==&lt;br /&gt;
&lt;br /&gt;
È possibile anche usare questo tool per riga di comando, molto utile se ad esempio siete in collegamento ssh con un Raspberry o se non amate le GUI.&lt;br /&gt;
&lt;br /&gt;
Anzitutto, consiglio di usare l'agente KeyboardOnly, altrimenti potrebbe chiedervi il pairing in un pop-up, e se siete in modalità solo testo c'è il caso che non compaia.&lt;br /&gt;
&lt;br /&gt;
 # agent off&lt;br /&gt;
&lt;br /&gt;
 # agent KeyboardOnly&lt;br /&gt;
&lt;br /&gt;
Per vedere la lista dei dispositivi bluetooth occorre usare il comando scan.&lt;br /&gt;
&lt;br /&gt;
 # scan on&lt;br /&gt;
&lt;br /&gt;
Questo mostrerà gli indirizzi MAC dei dispositivi rilevati.&lt;br /&gt;
Per fare il pairing si usa il comando pair:&lt;br /&gt;
&lt;br /&gt;
 # pair &amp;lt;indirizzo MAC&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A questo punto dovremo inserire il PIN del dispositivo. Una volta fatto questo il nostro computer e il dispositivo saranno accoppiati. Dando il comando quit si potrà uscire da bluetoothctl. A questo punto apriamo una porta seriale con rfcomm&lt;br /&gt;
&lt;br /&gt;
 $ sudo rfcomm connect /dev/rfcomm0 &amp;lt;indirizzo MAC&amp;gt; 1 &amp;amp;&lt;br /&gt;
&lt;br /&gt;
Questo creerà una porta seriale su /dev/rfcomm0 alla quale possiamo collegarci con screen, minicom o qualsiasi altro programma per la comunicazione seriale.&lt;br /&gt;
&lt;br /&gt;
= Cambiare configurazione =&lt;br /&gt;
&lt;br /&gt;
Gran parte di questo capitolo è preso da [http://www.instructables.com/id/AT-command-mode-of-HC-05-Bluetooth-module/ questa guida su Instructables].&lt;br /&gt;
Per cambiare configurazione al vostro modulo (ad es. cambiare velocità di trasmissione, nome, pin, ecc.) dovete entrare in modalità AT. L'HC-06 dovrebbe essere sempre in questa modalità, mentre l'HC-05 dev'essere acceso tenendo premuto il tasto &amp;quot;KEY&amp;quot; oppure mettendo a +3.3v il pin key sulla board. Quando è in modalità AT, l'HC-05 lampeggerà a intervalli di 2 secondi circa e potrete mandare i comandi AT alla seriale fisica sulla board. Se non avete un convertitore USB TTL, potete riciclare un Arduino per fare da ponte. Poiché l'Arduino Uno e simili (non il Mega, ad es.) ha una sola porta seriale, dovrete usare una porta seriale emulata via software. Lo sketch sarà più o meno così:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;SoftwareSerial.h&amp;gt;&lt;br /&gt;
 SoftwareSerial mySerial(10, 11); // RX, TX&lt;br /&gt;
 void setup() {&lt;br /&gt;
     Serial.begin(9600);&lt;br /&gt;
     pinMode(9,OUTPUT); digitalWrite(9,HIGH);&lt;br /&gt;
     Serial.println(&amp;quot;Enter AT commands:&amp;quot;);&lt;br /&gt;
     mySerial.begin(38400);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void loop() {&lt;br /&gt;
     if (mySerial.available()) Serial.write(mySerial.read());&lt;br /&gt;
     if (Serial.available()) mySerial.write(Serial.read());&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Notate alcune cose di questo codice: mySerial è la software seriale dove andrà collegato il vostro HC, nei pin 10 e 11 (10 è RX e 11 TX, quindi il 10 andrà collegato al TX dell'HC e l'11 al RX). '''In modalità AT il modulo HC comunica a 38400 baud'''.&lt;br /&gt;
&lt;br /&gt;
Ora aprite una seriale (va bene anche quella dell'IDE di Arduino, ricordatevi di mettere come CR e NL come fine linea) a 38400 baud e scrivete:&lt;br /&gt;
&lt;br /&gt;
 AT&lt;br /&gt;
&lt;br /&gt;
L'HC dovrebbe rispondervi&lt;br /&gt;
&lt;br /&gt;
 OK&lt;br /&gt;
&lt;br /&gt;
Se non lo fa forse avete sbagliato uno dei passi precedenti.&lt;br /&gt;
&lt;br /&gt;
I comandi più utili sono:&lt;br /&gt;
* AT+NAME=&amp;lt;nome&amp;gt; cambia nome all'ID Bluetooth&lt;br /&gt;
* AT+UART=&amp;lt;baudrate&amp;gt; cambia la velocità della trasmissione Bluetooth (la modalità AT rimane a 38400)&lt;br /&gt;
* AT+ROLE=&amp;lt;1:master 0:slave&amp;gt; permette l'HC-05 di essere master o di essere solo slave in una comunicazione&lt;br /&gt;
* AT+ORGL ripristina le configurazioni di fabbrica&lt;br /&gt;
* AT+PSWD cambia la password&lt;br /&gt;
&lt;br /&gt;
I comandi, se seguiti da ?, dovrebbero dire quale è il valore al momento memorizzato, ad esempio:&lt;br /&gt;
&lt;br /&gt;
 AT+UART?&lt;br /&gt;
&lt;br /&gt;
dovrebbe restituire&lt;br /&gt;
&lt;br /&gt;
 9600&lt;br /&gt;
&lt;br /&gt;
In [http://cdn.instructables.com/ORIG/FKY/Z0UT/HX7OYY7I/FKYZ0UTHX7OYY7I.pdf questa guida] potete trovare dettagli più approfonditi.&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Pagina_principale&amp;diff=7266</id>
		<title>Pagina principale</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Pagina_principale&amp;diff=7266"/>
		<updated>2020-03-31T10:41:19Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* Gruppi e Progetti */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
{| id=&amp;quot;table-top-top&amp;quot; style=&amp;quot;margin-top:2px; background:none;align:center;width:100%;border:1px solid red;-moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius:10px;&amp;quot;&lt;br /&gt;
| style=&amp;quot;background:white; width:75%; vertical-align:top; color:#000; padding: 5px 10px 10px 8px; &amp;quot; |&lt;br /&gt;
[[File:Emblem-important-2.png|left|48px|link=Prossimi appuntamenti]]&lt;br /&gt;
&lt;br /&gt;
=[[Prossimi appuntamenti|Prossimi appuntamenti]]=&lt;br /&gt;
&lt;br /&gt;
{{:Prossimi appuntamenti}}&lt;br /&gt;
&lt;br /&gt;
-----------&lt;br /&gt;
'' Iscriviti alle nostre [http://liste.raspibo.org/wws/ mailing list]! ''&lt;br /&gt;
 &lt;br /&gt;
-----------&lt;br /&gt;
&lt;br /&gt;
Gli appuntamenti fissi si tengono ogni '''secondo e quarto marted&amp;amp;igrave; del mese''' dalle ore 20.30 in avanti. La sala resta a disposizione anche i restanti marted&amp;amp;igrave; e tutti i gioved&amp;amp;igrave;: se volete usare i nostri spazi per i vostri incontri e progetti, scrivetelo sulla lista pubblica [http://liste.raspibo.org/wws/info/agora agora] e segnalate la vostra presenza sul nostro [http://lela.ismito.it:3000 sistema di prenotazioni].&lt;br /&gt;
&lt;br /&gt;
[[Eventi passati]]&lt;br /&gt;
&lt;br /&gt;
| style=&amp;quot;background:white; width:75%; vertical-align:top; color:#000; padding: 5px 10px 10px 8px; &amp;quot; |&lt;br /&gt;
[[File:Go-home-9.png|right|48px|link=makerspace]]&lt;br /&gt;
&lt;br /&gt;
= [[makerspace|Makerspace]] =&lt;br /&gt;
[http://centrocroce.blogspot.it/ Presso il centro sociale CROCE]&lt;br /&gt;
[[makerspace|Via Canonica 18 a Casalecchio di Reno]].&amp;lt;br/&amp;gt;&lt;br /&gt;
Una sala messa a disposizione all'interno del centro, dove ogni marted&amp;amp;igrave; e gioved&amp;amp;igrave; i gruppi e le persone che insieme collaborano ad un progetto, possono utilizzare.&lt;br /&gt;
&amp;lt;!-- '''Attenzione: siamo alla ricerca di nuovi spazi dove traslocare il nostro Makerspace''' --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Cookie =&lt;br /&gt;
Questo sito usa solamente Cookie Tecnici. &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Cookie Tecnici|maggiori informazioni]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- =====================  INIZIO TABELLA CENTRALE  ==================== --&amp;gt;&lt;br /&gt;
{| id=&amp;quot;table-central&amp;quot; style=&amp;quot;margin-top:10px; background:none;&amp;quot;&lt;br /&gt;
| style=&amp;quot;background:white; width:35%; border:1px solid #a7d7f9; vertical-align:top; color:#000; padding: 5px 10px 10px 8px; -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius:10px;&amp;quot; |&lt;br /&gt;
&amp;lt;!-- =====================  TABELLA CENTRALE - COLONNA DI SINISTRA  ==================== --&amp;gt;&lt;br /&gt;
{| id=&amp;quot;table-central-left&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;5&amp;quot; style=&amp;quot;width:100%; vertical-align:top; background:transparent;&amp;quot;&lt;br /&gt;
[[File:PCB-icon.png|right|48px]]&lt;br /&gt;
&lt;br /&gt;
= [[gruppi|Gruppi]] e [[:Categoria:Progetti|Progetti]] =&lt;br /&gt;
&lt;br /&gt;
{{:Gruppi}}&lt;br /&gt;
&lt;br /&gt;
[[File:Maker-faire.png|right|128px|link=Maker_Faire_2014]]&lt;br /&gt;
[[File:Maker_of_merit.jpg|right|128px|link=FotoMakerFaireRome2014]]&lt;br /&gt;
&lt;br /&gt;
'''Dettagli sui [[I_gruppi_di_lavoro_del_non-corso|gruppi di lavoro]].'''&lt;br /&gt;
&lt;br /&gt;
'''Vetrina dei [[:Categoria:Progetti|progetti in corso]].'''&lt;br /&gt;
&lt;br /&gt;
'''Leggi la [[Documentazione|documentazione prodotta]].'''&lt;br /&gt;
&lt;br /&gt;
'''Iscrivetevi alle [http://liste.raspibo.org mailing list].'''&lt;br /&gt;
&lt;br /&gt;
'''[[ wireless_comunity_network |NINUX Bologna - Wireless community network]].'''&lt;br /&gt;
&lt;br /&gt;
'''[[ link_e_idee |Link&amp;amp;Idee]].'''&lt;br /&gt;
&lt;br /&gt;
'''[[ Renzo's Bliki ]].'''&lt;br /&gt;
&lt;br /&gt;
'''[[ Laboratory of Making ]].'''&lt;br /&gt;
&lt;br /&gt;
Abbiamo raccolto alcuni progetti di autoproduzione riguardanti il '''[[ Covid19 ]].'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Applications-science.png|right|48px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Serate aperte a tutti ==&lt;br /&gt;
&lt;br /&gt;
''Gli incontri presso il [[makerspace]] sono ad accesso libero e gratuito, vedi anche le [[RIVOLUZIONE ALL'INCONTRO DEL 7 MARZO|note su come di solito procediamo]]''&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se pensate di partecipare, segnalate la vostra presenza sul sistema [https://ibt2.ismito.it/ RaspiBO makerspace booking], basta il vostro nickname. Per favore ricordate di aggiornarlo.&lt;br /&gt;
&lt;br /&gt;
== Gite, fiere ed eventi ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maker, segnalate [[Gite|qui ]] tutti gli eventi che ritenete interessanti!&lt;br /&gt;
&lt;br /&gt;
= Acquisti ossessivo-compulsivi =&lt;br /&gt;
&lt;br /&gt;
Ogni tanto ci vengono voglie strane; per amortizzare le spese di spedizione, cerchiamo di [[Elenco degli acquisti|aggregare gli ordini]].&lt;br /&gt;
&lt;br /&gt;
= Convenzioni acquisti =&lt;br /&gt;
La ditta Homotix e la ditta Katodo praticano, agli utenti RaspiBo, uno sconto. Per usufruirne segui le '''[[convenzioni acquisti | istruzioni]]'''.&lt;br /&gt;
&lt;br /&gt;
= Il non-staff ed i contatti =&lt;br /&gt;
&lt;br /&gt;
Non desideriamo strutturare troppo la '''non-associazione''', ma un gruppetto si sta prendendo in carico di seguirne la gestione; [[Non-staff|scoprite chi sono]] e soprattutto come potete aiutarli, dato che c'è [[Aiuto:Indice|bisogno del contributo]] di tutti!&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- =====================  TABELLA CENTRALE - FINE COLONNA SINISTRA  ==================== --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;!-- DIVISORE COLONNE --&amp;gt; style=&amp;quot;border:3px solid transparent;&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- =====================  TABELLA CENTRALE - COLONNA DI DESTRA  ==================== --&amp;gt;&lt;br /&gt;
| style=&amp;quot;width:65%; border:1px solid #a7d7f9; background:#f5faff; vertical-align:top; padding: 5px 10px 10px 8px; -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius:10px;&amp;quot; |&lt;br /&gt;
{| id=&amp;quot;table-central-right&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;5&amp;quot; style=&amp;quot;width:100%; vertical-align:top; background:#f5faff; background:transparent;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:RASPIBOfinale.png|left|130px|link=http://www.raspibo.org]]&lt;br /&gt;
[[File:Help-3.png|right|48px]]&lt;br /&gt;
= Chi siamo =&lt;br /&gt;
&lt;br /&gt;
'''''RaspiBO''''' è un gruppo informale di appassionati di elettronica ed informatica libera della zona di '''Bologna''' (ma non solo).&lt;br /&gt;
&lt;br /&gt;
Nato ad inizio 2013 per iniziativa del professor [http://www.cs.unibo.it/~renzo/ Renzo Davoli], [http://www.raccattaraee.net/ RaccattaRAEE], [http://erlug.linux.it/ ERLUG] e [http://www.bfsf.it/ BFSF], il gruppo si muove ora autonomamente, incontrandosi con frequenza almeno bimensile per serate dedicate allo sviluppo ed alla presentazione di nuove idee.&amp;lt;br /&amp;gt;&lt;br /&gt;
Chiamiamo questi incontri '''''il non-corso''''', perché non vogliono essere delle semplici lezioni frontali, ma un momento di scambio di opinioni ed esperienze.&lt;br /&gt;
&lt;br /&gt;
Le nostre competenze sono molto varie; '''informatica''', '''elettronica''', '''meccanica''', '''arti''' e mestieri vari: qualcuno è un esperto nel proprio campo, alcuni sono alle prime armi, ma tutti hanno tanta voglia di mettere a disposizione la propria esperienza.&amp;lt;br /&amp;gt;&lt;br /&gt;
Potete definirci '''makers'''; quello che più conta per noi resta comunque '''l'imparare''' sempre qualcosa di nuovo ed il '''far circolare la conoscenza''' coinvolgendo quante più persone possibile.&lt;br /&gt;
&lt;br /&gt;
Se preferisci abbiamo raccolto qualche informazione [http://www.raspibo.org/wiki/index.php/Chi_siamo in questa pagina].&lt;br /&gt;
&lt;br /&gt;
[[File:Audio-card-3.png|right|48px]]&lt;br /&gt;
&lt;br /&gt;
= Gli incontri del non-corso ed i gruppi di lavoro =&lt;br /&gt;
&lt;br /&gt;
'''Gratuiti e aperti a tutti''', chiunque voglia passare a trovarci anche solo per fare due chiacchiere su elettronica, informatica e meccanica (tutto rigorosamente in ''salsa libera'') è il benvenuto!&lt;br /&gt;
&lt;br /&gt;
Lo spirito dei nostri incontri è espresso nelle nostre [[Linee guida per gli incontri|linee guida]].&amp;lt;br /&amp;gt;&lt;br /&gt;
Oltre a tanta improvvisazione, di norma alcuni di noi si organizzano in '''tavoli''' per proseguire su specifici progetti; appena possibile, il [[I gruppi di lavoro del non-corso|lavoro svolto dai singoli gruppi]] viene presentato e documentato a beneficio di tutti.&lt;br /&gt;
&lt;br /&gt;
[[File:Apps-system-users-icon.png|right|48px]]&lt;br /&gt;
&lt;br /&gt;
= Serate a tema =&lt;br /&gt;
&lt;br /&gt;
Occasionalmente RaspiBO organizza serate per sviluppare un tema specifico, generalmente invitiamo uno o più ospiti per introdurre temi di interesse comune e condividere esperienze. [http://www.raspibo.org/wiki/index.php?title=Categoria:Serate_a_tema Serate a tema]&lt;br /&gt;
&lt;br /&gt;
[[File:Books-1-icon.png|right|48px]]&lt;br /&gt;
&lt;br /&gt;
= Dalla teoria alla pratica = &lt;br /&gt;
&lt;br /&gt;
Se vuoi puoi iniziare con l'[[1-_Elettronica_di_Base|elettronica]] oppure scoprire come configurare [[Raspberry Pi]] per iniziare i primi test.&lt;br /&gt;
&lt;br /&gt;
Se sei già pratico o se vuoi capire come utilizzare Raspberry Pi puoi visualizzare un elenco di [[6- Applicazioni di Raspberry PI|applicazioni]] che abbiamo già testato e documentato. &lt;br /&gt;
&lt;br /&gt;
Tutte queste informazioni le trovi nella sezione [[Documentazione|Documentazione]] .&lt;br /&gt;
&lt;br /&gt;
Sono inoltre disponibili [[Archivio dei Lucidi|lucidi e registrazioni]] di alcune lezioni frontali.&lt;br /&gt;
&lt;br /&gt;
[[File:User-group-new-2.png|link=http://social.raspibo.org|right|48px]]&lt;br /&gt;
&lt;br /&gt;
Con calma stiamo anche raccogliendo [[SanboxManuali|qui]] link a documentazione, pinout e tutto quanto serve avere sottomano quando si sperimenta.&lt;br /&gt;
&lt;br /&gt;
= la mailing list =&lt;br /&gt;
&lt;br /&gt;
Il nostro principale strumento di comunicazione è la '''[http://liste.raspibo.org/wws/subscribe/agora mailing list agora]''', i cui archivi sono [http://liste.raspibo.org/wws/arc/agora consultabili da qui].&lt;br /&gt;
&lt;br /&gt;
Se invece preferite ricevere periodicamente nostre notizie via mail, potete [http://liste.raspibo.org/wws/subscribe/newsletter iscrivervi alla newsletter].&lt;br /&gt;
&lt;br /&gt;
[[File:Strumenti.png|link=http://social.raspibo.org|right|48px]]&lt;br /&gt;
&lt;br /&gt;
= Strumenti per la collaborazione =&lt;br /&gt;
&lt;br /&gt;
Se vi piace chattare o volete una info al volo vi suggeriamo di utilizzare il canale #raspibo sul server freenode.net anche in [https://webchat.freenode.net/?channels=raspibo&amp;amp;uio=d4 webchat].&lt;br /&gt;
&lt;br /&gt;
Alcuni software sviluppati per i nostri progetti li appoggiamo sul nostro [https://github.com/raspibo/ archivio github].&lt;br /&gt;
&lt;br /&gt;
= Un pochino di storia =&lt;br /&gt;
[http://www.raspibo.org/wiki/index.php/Chi_siamo Un piccolo riassunto]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- =====================  TABELLA CENTRALE - FINE COLONNA DI DESTRA  ==================== --&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- =====================  FINE TABELLA CENTRALE  ==================== --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- =====================  INIZIO TABELLA FOOTER  ==================== --&amp;gt;&lt;br /&gt;
{| id=&amp;quot;table-footer&amp;quot; style=&amp;quot;margin-top:10px; background:none;&amp;quot;&lt;br /&gt;
| style=&amp;quot;width:35%; border:1px solid #a7d7f9; background:#f5faff; vertical-align:top; padding: 5px 10px 10px 8px; -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius:10px;&amp;quot; |&lt;br /&gt;
&amp;lt;!-- =====================  TABELLA FOOTER - COLONNA SINISTRA  ==================== --&amp;gt;&lt;br /&gt;
{| id=&amp;quot;table-footer-left&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;5&amp;quot; style=&amp;quot;width:100%; vertical-align:top; background:#f5faff; background:transparent;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[File:Emblem-what.png|right|48px]]&lt;br /&gt;
&lt;br /&gt;
= Help! =&lt;br /&gt;
&lt;br /&gt;
Vuoi modificare una pagina di questo wiki ma non ci riesci? Assicurati di aver letto le [[Qui|istruzioni]] per sconfiggere il nostro potente sistema anti-bot. :-)&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- =====================  TABELLA FOOTER - FINE COLONNA SINISTRA  ==================== --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;!-- DIVISORE COLONNE --&amp;gt; style=&amp;quot;border:5px solid transparent;&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- =====================  TABELLA FOOTER - COLONNA DI DESTRA  ==================== --&amp;gt;&lt;br /&gt;
| style=&amp;quot;background:white; width:65%; border:1px solid #a7d7f9; vertical-align:top; color:#000; padding: 5px 10px 10px 8px; -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius:10px;&amp;quot; |&lt;br /&gt;
{| id=&amp;quot;table-footer-right&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;5&amp;quot; style=&amp;quot;width:100%; vertical-align:top; background:transparent;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
= Ringraziamenti =&lt;br /&gt;
&lt;br /&gt;
[[File:Stemma Comune Casalecchio.png|70px|right]]&lt;br /&gt;
&lt;br /&gt;
Si ringrazia il Centro Sociale Croce ed il [http://www.comune.casalecchio.bo.it Comune di Casalecchio di Reno] .&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- =====================  TABELLA FOOTER - FINE COLONNA SINISTRA  ==================== --&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- =====================  FINE TABELLA FOOTER  ==================== --&amp;gt;&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Prossimi_appuntamenti&amp;diff=7265</id>
		<title>Prossimi appuntamenti</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Prossimi_appuntamenti&amp;diff=7265"/>
		<updated>2020-03-31T10:38:57Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!-- === '''12 giugno 2018, ore 20:30''' === --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Io la data per gli appuntamenti fissi la eliminerei, tanto e` scritto due righe piu` giu`, altrimenti si deve sempre riscrivere, --~~~~ --&amp;gt;&lt;br /&gt;
&amp;lt;!-- Anche se è sempre da riscrivere penso sia un segno visibile. Magari scriviamo uno script che l'aggiorni.... (renzo) --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Chiusura temporanea del Centro Sociale Croce di Casalecchio di Reno.'''&lt;br /&gt;
&lt;br /&gt;
Come comunicato dalla direzione  vi segnaliamo che da Domenica 23.02.2020 fino alle ore 24,00 di Domenica 01.03.2020, il Centro Sociale Croce di Casalecchio di Reno sarà chiuso e saranno annullati a data da destinarsi tutti gli eventi programmati.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A presto&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Covid19&amp;diff=7264</id>
		<title>Covid19</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Covid19&amp;diff=7264"/>
		<updated>2020-03-31T10:37:46Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
'''Qui trovi tutti i progetti relativi al Corona Virus: {{Special:PrefixIndex/Covid19/ |hideredirects=1}}'''&lt;br /&gt;
&lt;br /&gt;
[https://pad.riseup.net/p/COVID-19_RaspiBO_Links-keep Link non revisionati che sono passati nelle mailing list e nelle chat.]&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=OttoBot&amp;diff=7101</id>
		<title>OttoBot</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=OttoBot&amp;diff=7101"/>
		<updated>2019-07-05T17:49:49Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* Aggiungere le opzioni alla IDE di Arduino */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;OttoBot è il risultato di un tentativo di usare un [http://www.atmel.com/devices/atmega8.aspx ATmega8] al posto di una board Arduino.&lt;br /&gt;
&lt;br /&gt;
= Le specifiche tecniche =&lt;br /&gt;
L'ATmega8, prodotto da Atmel, è piuttosto modesto.&lt;br /&gt;
&lt;br /&gt;
* Ha 8KB di memoria flash. Se usate il bootloader di Arduino allora ve ne rimarranno solo 7.&lt;br /&gt;
* Il clock è massimo 16Mhz usando un risuonatore esterno. Quello interno va a 8Mhz (ma vi risparmiate un bel po' di circuiteria). Per usare il risuonatore interno occorre cambiare un fuse.&lt;br /&gt;
* 23 pin programmabili.&lt;br /&gt;
* 2 interrupt.&lt;br /&gt;
* Porte SPI, I²C e seriale (ma non è possibile usare seriali software, presenti nella libreria di Arduino).&lt;br /&gt;
* Costa una bazzecola. &lt;br /&gt;
&lt;br /&gt;
Per essere acceso ha bisogno da 2,7 a 5,5 Volt.&lt;br /&gt;
Il prezzo oscilla attorno all'euro.&lt;br /&gt;
[[Category:Progetti]]&lt;br /&gt;
&lt;br /&gt;
= Prime versioni =&lt;br /&gt;
&lt;br /&gt;
[[File:8bot.jpg]]&lt;br /&gt;
&lt;br /&gt;
Come potete vedere, la dimensione è proprio mini. Si comanda tramite bluetooth. Ruote e chassis sono stampate 3d.&lt;br /&gt;
&lt;br /&gt;
[[File:8bots.JPG]]&lt;br /&gt;
&lt;br /&gt;
Da sinistra a destra, l'evoluzione di 8bot!&lt;br /&gt;
&lt;br /&gt;
= Modificare l'ATmega8 affinché sembri un Arduino =&lt;br /&gt;
&lt;br /&gt;
Per approfondire questo argomento leggete anche  [[Programmazione dei microcontrollori]].&lt;br /&gt;
&lt;br /&gt;
Per ottenere questo occorre fare tre cose:&lt;br /&gt;
* Trovare un programmatore (potete usare la [http://www.instructables.com/id/Simplest-AVR-Parallel-port-programmer/ porta parallela] oppure acquistarne uno, ma anche un normalissimo Arduino può essere usato come programmatore)&lt;br /&gt;
* Settare i fuses&lt;br /&gt;
* Caricare il bootloader&lt;br /&gt;
* Aggiungere l'ATmega8 nel file boards.txt di Arduino&lt;br /&gt;
&lt;br /&gt;
Una volta fatti questi passi, potrete usare l'IDE come per qualsiasi altra board.&lt;br /&gt;
&lt;br /&gt;
Di guide su come usare i programmatori ne trovate a bizzeffe su internet, noi ci concentreremo sull'utilizzo di Arduino come ISP, che è la procedura che ho usato io.&lt;br /&gt;
&lt;br /&gt;
== Arduino as ISP ==&lt;br /&gt;
&lt;br /&gt;
Negli sketch di esempio nella IDE di Arduino c'è &amp;quot;Arduino as ISP&amp;quot; (In-System Programmer). Caricatelo su un Arduino di vostra scelta con l'accortezza di controllare i pin da usare: sui Mega sono diversi. Dovrete usare la porta SPI e in genere avete: 10 reset, 11 MOSI, 12 MISO e 13 clock (SCK). Sui Mega le porte sono rispettivamente 53, 51, 50 e 52. Trovate tutto nei commenti dello sketch.&lt;br /&gt;
Altri pin, opzionali, sono il 9 (heartbeat, mostra se il programma sta girando), 8 (error, si accende se c'è un problema), 7 (programming, si accende durante le comunicazioni).&lt;br /&gt;
&lt;br /&gt;
La porta SPI va così collegata, MISO con MISO, MOSI con MOSI, SCK con SCK e reset con reset. Il datasheet lo trovate qui [http://www.atmel.com/Images/Atmel-2486-8-bit-AVR-microcontroller-ATmega8_L_datasheet.pdf]&lt;br /&gt;
&lt;br /&gt;
[[File:Atmega8 arduinopinout.png]]&lt;br /&gt;
&lt;br /&gt;
I pin che vedete sono quelli come da IDE di Arduino. Se lo programmate con altri sistemi (come Eclipse) i riferimenti possono essere diversi.&lt;br /&gt;
Se il vostro ATmega8 è settato per avere un risuonatore esterno, dovrete collegarlo con un pin XTAL1 e l'altro su XTAL2. Entrambi i pin XTAL1 e XTAL2 vanno poi collegati a terra con un condensatore da 22 picofarad. Ne avrete bisogno se volete raggiungere frequenze superiori agli 8 Mhz o se avete bisogno di maggiore stabilità (il risuonatore interno non è molto preciso). Per contro, il risuonatore interno non ha bisogno di collegare nulla. Per approfondire guardate questa guida [http://kskpages.weebly.com/clock-settings.html]&lt;br /&gt;
&lt;br /&gt;
== avrdude ==&lt;br /&gt;
&lt;br /&gt;
Per interagire con l'ATmega8 dovrete usare avrdude, questa è una riga di esempio:&lt;br /&gt;
 avrdude -p m8 -c arduino -P /dev/ttyACM1 -U flash:w:{bootloader}.hex -U hfuse:w:0xd9:m -U lfuse:w:0xe3:m -b 19200&lt;br /&gt;
&lt;br /&gt;
Per saperne di più [http://www.nongnu.org/avrdude/user-manual/avrdude_4.html]&lt;br /&gt;
&lt;br /&gt;
 -p m8 &lt;br /&gt;
dice che abbiamo a che fare con un ATmega8&lt;br /&gt;
&lt;br /&gt;
 -c arduino&lt;br /&gt;
segnala che stiamo usando un Arduino come programmatore, nelle nuove versioni della IDE, con il nuovo sketch ArduinoISP probabilmente il protocollo da usare è stk500v1&lt;br /&gt;
&lt;br /&gt;
 -P /dev/(porta)&lt;br /&gt;
è la porta dove avete collegato il programmatore, di solito per gli Arduino è ttyACMx o ttyUSBx; per conoscerla ci sono due modi: guardare nella IDE di Arduino le porte disponibili o collegare l'Arduino e guardare gli ultimi messaggi in dmesg&lt;br /&gt;
&lt;br /&gt;
 -U flash:w:{bootloader}.hex&lt;br /&gt;
scrive il bootloader, vedi sotto&lt;br /&gt;
 &lt;br /&gt;
 -U hfuse:w:0xd9:m -U lfuse:w:0xe3:m &lt;br /&gt;
modifica i fuse, vedi sotto&lt;br /&gt;
&lt;br /&gt;
 -b 19200&lt;br /&gt;
la velocità di comunicazione in baud&lt;br /&gt;
&lt;br /&gt;
== Caricare il bootloader ==&lt;br /&gt;
&lt;br /&gt;
Se volete usarlo come Arduino dovreste caricare il bootloader. Potete farne anche a meno e risparmiare 1Kb (su 8, non è poco). In teoria potreste farne a meno e continuare a caricare gli sketch sull'ATmega8 l'Arduino come programmatore. Fatto sta che l'ho caricato una volta e non ho mai provato a toglierlo (del resto: if ain't broke, don't fix it). I bootloader li trovate in {cartella di Arduino}/hardware/arduino/avr/bootloaders. Se non li avete li trovate qua [https://github.com/arduino/Arduino/tree/master/hardware/arduino/avr/bootloaders]&lt;br /&gt;
&lt;br /&gt;
== Settare i fuse ==&lt;br /&gt;
&lt;br /&gt;
Molte opzioni dell'ATmega8 sono settabili tramite dei fuse. I fuse sono dei bit su una memoria EEPROM che dicono al microcontrollore come deve comportarsi. Tramite i fuses è possibile settare il clock, se usare un oscillatore esterno o interno, quanto deve aspettare durante il boot per una nuova programmazione, etc. &lt;br /&gt;
Qui trovate due calcolatori di fuse, questo è più semplice da usare [https://elektronik-kompendium.de/public/arnerossius/programme/web/avrfuse/ avrfuse] questo è più completo [http://www.engbedded.com/fusecalc/ Engbedded AVR Fuse Calculator].&lt;br /&gt;
&lt;br /&gt;
== Aggiungere le opzioni alla IDE di Arduino ==&lt;br /&gt;
&lt;br /&gt;
Se siete affezionati alla IDE dovrete aggiungere al menu delle board l'ATmega8.&lt;br /&gt;
&lt;br /&gt;
In teoria, nel menu Tools/boards, c'è già &amp;quot;Arduino NG or older&amp;quot; che ha, fra le varie opzioni, anche la possibilità di usare l'ATmega8, ma io ho avuto una serie di problemi a usarla e alla fine non ho provato a capire perché non funzionasse.&lt;br /&gt;
&lt;br /&gt;
Andate in {cartella di Arduino}/hardware/arduino/avr e aprite il file boards.txt (se avete paura di fare dei danni, fate una copia di questo file prima, per precauzione).&lt;br /&gt;
&lt;br /&gt;
Per aggiungere l'ATmega8 basta aggiungere queste opzioni alla fine [https://github.com/chuckb/atmega/blob/master/atmega/avr/boards.txt].&lt;br /&gt;
&lt;br /&gt;
''In alternativa''&lt;br /&gt;
&lt;br /&gt;
Copiate i files dal repository https://github.com/chuckb/atmega, cartellle incluse, nella directory hardware del programma arduino, per esempio (nel mio caso):&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:blue;overflow:auto&amp;quot;&amp;gt;&lt;br /&gt;
ls ~/arduino-sketches/hardware/atmega/avr/&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
oppure:&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:blue;overflow:auto&amp;quot;&amp;gt;&lt;br /&gt;
ls /opt/arduino-1.8.7/hardware/atmega/avr/&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:green;overflow:auto&amp;quot;&amp;gt;&lt;br /&gt;
boards.txt  platform.txt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se caricate uno sketch sul microcontrollore con un clock sbagliato accadranno risultati imprevedibili, ad es. caricate dalla IDE usando ATmega8 a 4Mhz con i fuses settati in modo che vada a 8Mhz scoprirete che tutto andrà al doppio della velocità.&lt;br /&gt;
I secondi diventano mezzi secondi, 9600 baud diventano 19200 e così via. Non una gran cosa se state cercando di programmare, però può sfuggirvi perché non segnala nessun errore.&lt;br /&gt;
&lt;br /&gt;
Una volta editato boards.txt riavviate la IDE se l'avevate aperta e vedrete comparire nel menu Tools/board una nuova voce, quella dell'ATmega8.&lt;br /&gt;
&lt;br /&gt;
== Caricare uno sketch ==&lt;br /&gt;
&lt;br /&gt;
Collegate il programmatore (nei nostri esempi, l'Arduino) all'ATmega8 alla seriale (se avete caricato il bootloader) o alla SPI, collegate il reset (di default su Arduino as ISP è il pin 10), il +5v e la terra, andate sotto Sketch e usate &amp;quot;Upload Using Programmer&amp;quot;. Alternativamente potete cliccare shift+pulsante del caricamento dello sketch. Se tutto è andato come dovrebbe vedrete lampeggiare i LED della seriale dell'Arduino per qualche secondo fino a che l'IDE non ci comunicherà &amp;quot;done&amp;quot;.&lt;br /&gt;
Se invece non volete usare la IDE, potete compilare il vostro sketch con avr-gcc e uploadarlo direttamente con avrdude (ma di questo non tratteremo qui).&lt;br /&gt;
&lt;br /&gt;
Problemi più frequenti: cavetti non collegati bene, cavetti invertiti, alimentazione non sufficiente, oscillatore esterno previsto ma mancante.&lt;br /&gt;
&lt;br /&gt;
== Altri metodi ==&lt;br /&gt;
&lt;br /&gt;
Potete usare, ad esempio, la SPI del Raspberry Pi, guardate la pagina [[Programmazione_dei_microcontrollori]].&lt;br /&gt;
&lt;br /&gt;
= Lo schema elettrico =&lt;br /&gt;
&lt;br /&gt;
È estremamente banale. Collegate le batterie a modulo Bluetooth, integrato e motori, in parallelo, collegate i fili del segnale dei servo a un pin libero dell'ATmega8, collegate RX dell'integrato a TX del modulo Bluetooth. Se volete un feedback dall'integrato allora collegate anche il TX dell'integrato al RX del modulo Bluetooth.&lt;br /&gt;
&lt;br /&gt;
[[File:8botschema.png]]&lt;br /&gt;
&lt;br /&gt;
In sintesi:&lt;br /&gt;
* il + delle batterie va collegato a: vcc del modulo Bluetooth, vcc dell'ATmega8, + del servo 1 e 2&lt;br /&gt;
* il - delle batterie va collegato a: gnd del modulo Bluetooth, due gnd dell'ATmega8, - del servo 1 e 2&lt;br /&gt;
* TX del modulo Bluetooth va collegato a RX dell'ATmega8&lt;br /&gt;
* RX del modulo Bluetooth va collegato a TX dell'ATmega8&lt;br /&gt;
* i segnali dei servi vanno collegati a due pin liberi (nel nostro caso 14 e 15 ma potete benissimo sceglierne degli altri)&lt;br /&gt;
&lt;br /&gt;
= Lo sketch =&lt;br /&gt;
&lt;br /&gt;
Lo trovate sul repository:&lt;br /&gt;
[https://gitlab.com/oloturia/8bot]&lt;br /&gt;
&lt;br /&gt;
Vediamo un po' i punti più strani.&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Servo.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 Servo dx_servo;&lt;br /&gt;
 Servo sx_servo;&lt;br /&gt;
 &lt;br /&gt;
 const int dx_pin = 8;&lt;br /&gt;
 const int sx_pin = 9;&lt;br /&gt;
 int fd_spd_dx = 180; //initial values&lt;br /&gt;
 int bk_spd_dx = 0;   //180 is full forward, 0 full backward&lt;br /&gt;
 int fd_spd_sx = 0;   //stop is somewhere in the middle &lt;br /&gt;
 int bk_spd_sx = 180; //but the motors keep running&lt;br /&gt;
&lt;br /&gt;
Per far funzionare il nostro robottino servirà la libreria Servo. La EEPROM ci servirà per mantenere la calibrazione da spento. Ci sono due costanti, i pin a cui sono collegati il segnale dei servi, e i valori che passeremo al metodo write degli oggetti dx_servo e sx_servo. Nei servo continui 0 è antiorario e 180 orario, lo stato fermo è più o meno 90. In questo caso però li staccheremo con detach così da non mantenerli in tensione. Se il vostro progetto non ha bisogno che il servo faccia resistenza (ad es. deve tenere un peso) allora è meglio staccarlo. Non è solo una questione di risparmio energetico: i piccoli servo e quelli di scarsa qualità quando sono in tensione tendono a scaldare.&lt;br /&gt;
Le quattro variabili sono rispettivamente il valore avanti e indietro del motore a destra e il valore avanti e indietro del motore a sinistra.&lt;br /&gt;
&lt;br /&gt;
 void setup() {&lt;br /&gt;
   Serial.begin(9600);&lt;br /&gt;
   Serial.println(&amp;quot;READY&amp;quot;);&lt;br /&gt;
   if (EEPROM.read(4) == 1) {&lt;br /&gt;
     fd_spd_dx = EEPROM.read(0);//reserve 4 bytes &lt;br /&gt;
     bk_spd_dx = EEPROM.read(1);//for saved calibration&lt;br /&gt;
     fd_spd_sx = EEPROM.read(2);&lt;br /&gt;
     bk_spd_sx = EEPROM.read(3);&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Accende la seriale e si legge la EEPROM. La memoria non scritta ha come valore 255 quindi serve un quinto elemento che comunichi se la calibrazione è stata fatta o meno. Scrivere e aggiornare la EEPROM è facilissimo. Vi consiglio di leggere la guida ufficiale [https://www.arduino.cc/en/Reference/EEPROM]. Ricordate che l'ATmega8 ha 512 bytes a disposizione nella EEPROM.&lt;br /&gt;
&lt;br /&gt;
 void loop() {&lt;br /&gt;
   if(Serial.available()){&lt;br /&gt;
     char command = Serial.read(); //every command is a char&lt;br /&gt;
     if (command == 's') {         //it is possible to write to  the bot&lt;br /&gt;
       turnOnServo();              //using a keyboard&lt;br /&gt;
       dx_servo.write(fd_spd_dx);&lt;br /&gt;
       sx_servo.write(fd_spd_sx);&lt;br /&gt;
  } else if (command == 'd') {&lt;br /&gt;
  [...]&lt;br /&gt;
&lt;br /&gt;
Ogni comando ricevuto dalla seriale è un char. Si potrebbe eventualmente mandare un byte, ma così è più comodo soprattutto quando ancora non avevo pronta la app e dovevo pilotare il piccolo bot con la tastiera. Si può ancora fare: i tasti sono wasd. Sulla funzione turnOnServo() torneremo dopo.&lt;br /&gt;
&lt;br /&gt;
  [...]&lt;br /&gt;
  } else if (command == 'h') {&lt;br /&gt;
       if (fd_spd_dx &amp;gt; 90) {&lt;br /&gt;
         fd_spd_dx --;        &lt;br /&gt;
  }&lt;br /&gt;
  [...]&lt;br /&gt;
&lt;br /&gt;
Altri comandi servono per la calibrazione. Purtroppo nella app la calibrazione è ancora molto confusionaria. Ogni variabile può diventare da 0 a 90 e da 91 a 180.&lt;br /&gt;
&lt;br /&gt;
    [...]&lt;br /&gt;
    } else if (command == 'z') { //save calibration into eeprom&lt;br /&gt;
      EEPROM.update(0,fd_spd_dx);&lt;br /&gt;
      EEPROM.update(1,bk_spd_dx); &lt;br /&gt;
      EEPROM.update(2,fd_spd_sx);&lt;br /&gt;
      EEPROM.update(3,bk_spd_sx);&lt;br /&gt;
      EEPROM.update(4,1);&lt;br /&gt;
      Serial.println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      stopServo(); //if the serial is empty, stop the motors&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Infine, ecco dove la EEPROM viene scritta, incluso l'indirizzo 4 che diventa 1 e segnala al prossimo riavvio di leggersi i valori che avevamo salvato. Se non arriva nessun comando i servo vengono staccati.&lt;br /&gt;
&lt;br /&gt;
 void turnOnServo() {&lt;br /&gt;
   dx_servo.attach(dx_pin);&lt;br /&gt;
   sx_servo.attach(sx_pin);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 void stopServo() {&lt;br /&gt;
   dx_servo.detach();&lt;br /&gt;
   sx_servo.detach();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Ogni volta che arriva un comando vengono riattaccati. In questo modo non rimarranno sotto tensione.&lt;br /&gt;
&lt;br /&gt;
= Il bluetooth = &lt;br /&gt;
&lt;br /&gt;
Il collegamento fra l'Ottobot e il vostro smartphone o il vostro computer avverrà tramite il modulo HC-05 o HC-06. Il modulo è molto semplice da usare: ha una porta seriale fisica dove legge e scrive tutto ciò che arriva via il servizio di porta seriale via Bluetooth. Nel nostro caso sarà attaccato direttamente ai pin RX e TX del nostro ATmega8 e farà come da ponte fra il nostro dispositivo e il microcontrollore. Potete leggere più informazioni su come giocare con questo tipo di moduli nella pagina [[HC-05 e HC-06]].&lt;br /&gt;
&lt;br /&gt;
= L'app =&lt;br /&gt;
&lt;br /&gt;
Potete scaricarla, guardarla e modificarla all'indirizzo di App Inventor (serve account Google) [http://ai2.appinventor.mit.edu/?locale=en&amp;amp;galleryId=5162309564235776 qua].&lt;br /&gt;
&lt;br /&gt;
L'app è stata scritta con il MIT App Inventor 2. È un tool molto potente utile per chi, come me, è ancora fermo a cercare di fare un &amp;quot;Hello World&amp;quot; decente su Android. Non è la soluzione più efficace, ma nell'attesa di imparare qualcosa di migliore, è la più semplice.&lt;br /&gt;
&lt;br /&gt;
L'App Inventor è basato sul popolare linguaggio educativo Scratch. Permette di inserire pulsanti, grafica e di interagire con i sensori e, nel nostro caso, con dispositivi Bluetooth. Permette di collegarsi a un dispositivo Android (anche emulato) per fare dei test in real-time e fare correzioni al volo. Quando avrete finito potrete creare un .apk da installare così non avrete più bisogno dell'App Inventor per usarla.&lt;br /&gt;
&lt;br /&gt;
Tutte le informazioni su come utilizzarlo le trovate nel sito ufficiale [http://appinventor.mit.edu/explore/ai2/setup.html].&lt;br /&gt;
&lt;br /&gt;
Nel repository c'è il sorgente in formato .aia, che potete caricare sull'App Inventor con Import.&lt;br /&gt;
&lt;br /&gt;
Per prima cosa ho creato, nello Screen 1, una lista che si carica con la lista dei dispositivi Bluetooth che sono nel range del nostro tablet o telefono. Nella schermata c'è solo una lista e un componente &amp;quot;Bluetooth Client&amp;quot; chiamato BluetoothClient1.&lt;br /&gt;
&lt;br /&gt;
[[File:Initbt.png]]&lt;br /&gt;
&lt;br /&gt;
AfterPicking, ovvero dopo aver scelto un dispositivo, andrà nello screen &amp;quot;Controls&amp;quot; portandosi dietro il nome del dispositivo a cui ci vogliamo connettere. &lt;br /&gt;
&lt;br /&gt;
Andiamo ora nella schermata &amp;quot;Controls&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Controls_8bot.png]]&lt;br /&gt;
&lt;br /&gt;
Ci sono i pulsanti per le direzioni, un pulsante per connettersi a un altro dispositivo (che non fa altro che tornare a Screen1), e i pulsanti per la taratura (ancora in beta). Anche qui c'è BluetoothClient1. Appena arriva in questa schermata l'app si fermerà per permettere di fare l'accoppiamento tramite Bluetooth. Il pin è di solito 1234.&lt;br /&gt;
&lt;br /&gt;
[[File:Initcontr.png]]&lt;br /&gt;
&lt;br /&gt;
Se non riesce a connettersi o se clicchiamo &amp;quot;Connect&amp;quot; tornerà nella schermata di selezione precedente.&lt;br /&gt;
&lt;br /&gt;
[[File:Controlscomm.png]]&lt;br /&gt;
&lt;br /&gt;
I controlli sono molto semplici: ogni tasto invia un carattere. Quando viene rilasciato manda un carattere che spegne i servo. Non è ancora perfetto perché se perde la connessione i motori rimangono accesi, in futuro questo problema sarà corretto.&lt;br /&gt;
&lt;br /&gt;
[[File:Trim8bot.png]]&lt;br /&gt;
&lt;br /&gt;
Infine il codice per la calibrazione. A seconda se il robot sta andando avanti oppure indietro saranno calibrati i valori che vengono usati per muovere i motori. Purtroppo questa parte non è ancora scritta in modo efficace (ad es. il motore che va avanti in senso antiorario va più veloce con un valore INFERIORE, quindi per farlo andare più veloce occorre premere il tasto MENO). Quando la calibrazione è soddisfacente, con il tasto &amp;quot;Write&amp;quot; la si memorizza nella EEPROM dell'ATmega8.&lt;br /&gt;
&lt;br /&gt;
= I motori =&lt;br /&gt;
&lt;br /&gt;
L'8bot ha bisogno di due servo motori 9g continui, detti anche servo a 360°. Se volete risparmiare ulteriormente potete acquistare dei normalissimi servo a 180° e fare qualche modifica per trasformarli in 360°.&lt;br /&gt;
Per effettuare la modifica seguite [[Modifica_servo_rc_per_rotazione_continua|questa guida]].&lt;br /&gt;
&lt;br /&gt;
= Lo chassis =&lt;br /&gt;
Tutti gli .stl di 8bot li trovate su git [https://gitlab.com/oloturia/8bot]&lt;br /&gt;
&lt;br /&gt;
== Le ruote ==&lt;br /&gt;
Per le ruote ci sono due modelli, uno è della dimensione delle gomme delle mini4wd Tamiya[https://gitlab.com/oloturia/8bot/blob/master/wheel-mini4wd.stl]:&lt;br /&gt;
&lt;br /&gt;
[[File:8bot4wd.png]]&lt;br /&gt;
&lt;br /&gt;
mentre l'altro è della dimensione di un o-ring[https://gitlab.com/oloturia/8bot/blob/master/wheel0ring.stl]:&lt;br /&gt;
&lt;br /&gt;
[[File:8botoring.png]]&lt;br /&gt;
&lt;br /&gt;
entrambe si incastrano sul pignone del servo senza bisogno di viti o altro (ma se volete metterne una, male non fa).&lt;br /&gt;
&lt;br /&gt;
== Il telaio ==&lt;br /&gt;
Il telaio è una piccola piattaforma con due fessure per inserire un'aletta del servi e un foro per la casterball. Recentemente ho aggiunto altre due alette per tenere fermo il portabatterie[https://gitlab.com/oloturia/8bot/blob/master/body.stl].&lt;br /&gt;
&lt;br /&gt;
[[File:Chass.png]]&lt;br /&gt;
&lt;br /&gt;
= Corso di costruzione Ottobot =&lt;br /&gt;
Nell'autunno 2016 a Raspibo un gruppo di makers si e' riunito specificamente per costruire Ottobot e programmarli sotto la guida paziente di Oloturia, creatore del progetto.&lt;br /&gt;
&lt;br /&gt;
== Materiale ==&lt;br /&gt;
Il materiale e' stato procurato dallo stesso Oloturia da vari fornitori durante l'estate con un occhio particolare ai costi per permettera tutti di realizzare un piccolo robot didattico.&lt;br /&gt;
&lt;br /&gt;
Alcune parti progettate appositamente, sono state stampate in 3D.&lt;br /&gt;
&lt;br /&gt;
Ad ogni partecipante del corso e' stato fornito un kit, oltre a questo ogni partecipante ha portato un po' di attrezzi ed un pc.&lt;br /&gt;
&lt;br /&gt;
[[File:Ottobot kit.jpg|600px|thumb|center|Il kit completo del corso ottobot]]&lt;br /&gt;
&lt;br /&gt;
== Preparazione dei motori ==&lt;br /&gt;
Nel kit i due servo possono essere sia a rotazione continua quindi gia' pronti oppure standard.&lt;br /&gt;
&lt;br /&gt;
Per i motori standard e' neccessario procedere ad una modifica vedi [[Modifica_servo_rc_per_rotazione_continua]]&lt;br /&gt;
&lt;br /&gt;
== Assemblaggio del robot ==&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;margin-top:2px; background:none;align:center;width:100%;border:1px solid red;-moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius:10px;&amp;quot;&lt;br /&gt;
|[[File:Ottobot assemblaggio 10.jpg|400px|thumb|left|Montare le ruote sul microservo modificato per rotazione continua]] &lt;br /&gt;
|Le ruote vanno montate sull'asse con una vite che si trova nel sacchetto degli accessori del servo. Il tutto va poi incastrato sulla base. Se la stampa e' perfetta i motori si incastrano perfettamete sulla base altrimenti ci si puo' aiutare con colla, viti o nastro biadesivo.&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;margin-top:2px; background:none;align:center;width:100%;border:1px solid red;-moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius:10px;&amp;quot;&lt;br /&gt;
|[[File:Ottobot assemblaggio 20.jpg|400px|thumb|left|Fissare la ball caster]] &lt;br /&gt;
|Come terzo appoggio utilizziamo una ballcaster che consente liberta' di movimento e di sterzata. Inserire il pezzo nel foro centrale e fissarlo con tre viti, oppure colla.&lt;br /&gt;
|&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Gruppo_Meteo/HowTo/StimaVersione2&amp;diff=6911</id>
		<title>Gruppo Meteo/HowTo/StimaVersione2</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Gruppo_Meteo/HowTo/StimaVersione2&amp;diff=6911"/>
		<updated>2019-04-09T19:31:35Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* Upload del firmware */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= How To =&lt;br /&gt;
&lt;br /&gt;
== Guida pubblicata su ElettronicaIn ==&lt;br /&gt;
Gli articoli pubblicati nel 2016:&lt;br /&gt;
# [http://liste.raspibo.org/wws/d_read/meteo/elettronicain/prima_puntata.pdf Prima puntata]&lt;br /&gt;
# [http://liste.raspibo.org/wws/d_read/meteo/elettronicain/seconda_puntata.pdf Seconda puntata]&lt;br /&gt;
# [http://liste.raspibo.org/wws/d_read/meteo/elettronicain/terza_puntata.pdf Terza puntata]&lt;br /&gt;
&lt;br /&gt;
La guida aggiornata su WIKI la puoi trovare qui divisa in tre sezioni:&lt;br /&gt;
&lt;br /&gt;
# http://bfsf.it/wiki/FuturaStima1&lt;br /&gt;
# http://bfsf.it/wiki/FuturaStima2&lt;br /&gt;
# http://bfsf.it/wiki/FuturaStima3&lt;br /&gt;
&lt;br /&gt;
== HowTo per Stima-wifi == &lt;br /&gt;
&lt;br /&gt;
[[File:stima_wifi.jpg|none|400px|thumb|left|Stima wifi con Honeywell HPM e sensore Temperatura e Umidità]] &amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Elenco materiali ===&lt;br /&gt;
&lt;br /&gt;
* [https://www.homotix.it/vendita/wemos/wemos-mini-v300 Wemos D1 mini V3]&lt;br /&gt;
* [https://www.homotix.it/vendita/wemos/oled-shield-v110-for-wemos-mini  OLED Shield V2.0.0 for Wemos D1 mini]&lt;br /&gt;
* [https://www.homotix.it/vendita/wemos-shield-alimentazione/power-shield Wemos DC Power Shield V1.1.0]&lt;br /&gt;
* [https://www.homotix.it/vendita/wemos-shield-prototipazione-cavi/connettori connettori] (quando necessari)&lt;br /&gt;
&lt;br /&gt;
sensore polveri:&lt;br /&gt;
* [http://www.plantower.com/en/content/?108.html Plantower pms5003]&lt;br /&gt;
&lt;br /&gt;
in alternativa:&lt;br /&gt;
* [https://it.rs-online.com/web/p/sensori-di-luce-e-colore/1454279/ Honeywell HPM-115S0]&lt;br /&gt;
* [https://it.rs-online.com/web/p/wire-to-board-cable-assemblies/1250750/ Cavo connessione PicoBlade Molex 8 vie]&lt;br /&gt;
&lt;br /&gt;
* [https://www.homotix.it/vendita/sensori-polveri-sottili/sensore-polveri-sottili-sds011 SDS011]&lt;br /&gt;
&lt;br /&gt;
NOTA BENE&lt;br /&gt;
&lt;br /&gt;
In particolare il sensore Honeywell HPMA richiede una alimentazione a 5V stabilizzata e molto precisa&lt;br /&gt;
&lt;br /&gt;
Alimentazione per distanze fino a circa 50m. dall'alimentazione di rete a 220V:&lt;br /&gt;
* [https://www.homotix.it/vendita/alimentatori/alimentatore-12v-2a Alimentatore-12v-2a]&lt;br /&gt;
* cavo bipolare della lunghezza opportuna&lt;br /&gt;
&lt;br /&gt;
=== Configurazioni sul server ===&lt;br /&gt;
&lt;br /&gt;
==== Registrazione ====&lt;br /&gt;
[http://rmap.cc/registrazione/register/ Registrasi] o fare [http://rmap.cc/registrazione/login] login sul server.&lt;br /&gt;
==== Configurazione stazione ====&lt;br /&gt;
Registrare una nuova stazione sul [http://rmap.cc/insertdata/newstation server]; dopo aver selezionato le coordinate utilizzando l'indirizzo o selezionandole dalla mappa inserire il nome stazione ( nome consigliato come predefinito &amp;quot;stimaesp&amp;quot;) &lt;br /&gt;
e il modello stazione che sarà &lt;br /&gt;
* &amp;quot;airquality_sds&amp;quot; se è collegato solo il sensore delle polveri SDS011.&lt;br /&gt;
* &amp;quot;airquality_hpm&amp;quot; se è collegato solo il sensore delle polveri Honeywell HPM&lt;br /&gt;
* &amp;quot;airquality_pms&amp;quot; se è collegato solo il sensore delle polveri Plantower pms5003&lt;br /&gt;
* &amp;quot;stima_thd&amp;quot; se sono collegati il sensore delle polveri Honeywell HPM e il modulo stima_th&lt;br /&gt;
* &amp;quot;stima_thdm&amp;quot; se sono collegati il sensore delle polveri Honeywell HPM, il modulo stima_th, il modulo stima_gas&lt;br /&gt;
&lt;br /&gt;
=== Attivazione stazione ===&lt;br /&gt;
Accendere la stazione collegandola tramite l'apposito alimentatore a una alimentazione USB.&lt;br /&gt;
&lt;br /&gt;
==== Se si ha il display ====&lt;br /&gt;
Tenendo premuto il pulsante A premere il pulsante Reset.&lt;br /&gt;
Dovranno apparire le seguenti scritte:&lt;br /&gt;
 Clean FS&lt;br /&gt;
 Reset wifi configuration&lt;br /&gt;
&lt;br /&gt;
Con un PC o uno smathphone collegarsi al WIFI con ssed &amp;quot;STIMA-config&amp;quot; e password &amp;quot;bellastima&amp;quot; come indicato sul display.&lt;br /&gt;
&lt;br /&gt;
Una volta attivata la connessione dovrà comparire una pagina di configurazione intitolata &amp;quot;STIMA-config&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Se questo non avviene automaticamente puntare il browser all'indirizzo http://192.168.4.1/&lt;br /&gt;
&lt;br /&gt;
Selezionare la prima voce &amp;quot;Configure WiFi&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Selezionare dall'elenco l'ssed della rete WiFi di accesso alla rete che dovrà essere utilizzata dalla stazione e inserire nell'apposita casella la relativa password di accesso se necessaria.&lt;br /&gt;
Nella casella &amp;quot;rmap user&amp;quot; inserire il nome utente utilizzato nella registrazione sul server e nella casella &amp;quot;rmap password&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Lasciare &amp;quot;stimaesp&amp;quot; come nome stazione se non è sttao precedentemente personalizzato.&lt;br /&gt;
&lt;br /&gt;
premere il tasto &amp;quot;save&amp;quot; per salvare.&lt;br /&gt;
&lt;br /&gt;
Se si ottiene la pagina con la scritta &amp;quot;Credentials Saved&amp;quot; la procedura ha avuto successo.&lt;br /&gt;
&lt;br /&gt;
A questo punto sul display dopo la pagina con la scritta &amp;quot;Starting up!&amp;quot; e la versione del firmware dovrà comparire la scritta &amp;quot;WIFI OK&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Se questo non avviene rieseguire le istruzioni di questa sezione.&lt;br /&gt;
&lt;br /&gt;
==== Se non si ha il display ====&lt;br /&gt;
Con un filo connettere il pin 7 a massa e premere il pulsante Reset e attendere 5 secondi prima di scollegare il filo dal pin 7.&lt;br /&gt;
&lt;br /&gt;
Con un PC o uno smathphone collegarsi al WIFI con ssed &amp;quot;STIMA-config&amp;quot; e password &amp;quot;bellastima&amp;quot; come indicato sul display.&lt;br /&gt;
&lt;br /&gt;
Una volta attivata la connessione dovrà comparire una pagina di configurazione intitolata &amp;quot;STIMA-config&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Se questo non avviene automaticamente puntare il browser all'indirizzo http://192.168.4.1/&lt;br /&gt;
&lt;br /&gt;
Selezionare la prima voce &amp;quot;Configure WiFi&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Selezionare dall'elenco l'ssed della rete WiFi di accesso alla rete che dovrà essere utilizzata dalla stazione e inserire nell'apposita casella la relativa password di accesso se necessaria.&lt;br /&gt;
&lt;br /&gt;
Nella casella &amp;quot;rmap user&amp;quot; inserire il nome utente utilizzato nella registrazione sul server e nella casella &amp;quot;rmap password&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Lasciare &amp;quot;stimaesp&amp;quot; come nome stazione se non è sttao precedentemente personalizzato.&lt;br /&gt;
&lt;br /&gt;
premere il tasto &amp;quot;save&amp;quot; per salvare.&lt;br /&gt;
&lt;br /&gt;
Se entro 60 secondi si accenderà un led blu per una decina di secondi tutto è andato a buon fine.&lt;br /&gt;
&lt;br /&gt;
Se questo non avviene rieseguire le istruzioni di questa sezione.&lt;br /&gt;
&lt;br /&gt;
=== Legenda segnalazioni tramite LED blu onboard ===&lt;br /&gt;
&lt;br /&gt;
* riavvio: 3 impulsi luminosi di 1 secondo &lt;br /&gt;
* tentativo aggiornamento firmware in corso: led lampeggiante a 1Hz&lt;br /&gt;
* risultato aggiornamento firmware:&lt;br /&gt;
** nessun aggiornamento disponibile: 1 impulso luminosi di 1 secondo&lt;br /&gt;
** aggiornamento firmware fallito: 2 impulsi luminosi di 1 secondo&lt;br /&gt;
** firmware aggiornato:  3 impulsi luminosi di 1 secondo&lt;br /&gt;
* in attesa di configurazione: led lampeggiante a 1Hz per tutto il periodo di configurazione&lt;br /&gt;
* configurazione remota fallita:  led lampeggiante a 1Hz per 5 secondi&lt;br /&gt;
* connect MQTT fallita/errore pubblicazione: impulso medio a 1Hz per 5 secondi&lt;br /&gt;
* sensore assente o rotto/errore comunicazione: impulso lungo a 1Hz per 5 secondi&lt;br /&gt;
* dato mancante: un impulso luminoso di 1 secondo a 2Hz&lt;br /&gt;
&lt;br /&gt;
Un corretto funzionamento della stazione viene evidenziato dal led blu che si accende per circa 5 secondi ogni 60 secondi.&lt;br /&gt;
&lt;br /&gt;
=== Visualizzazione dei dati ===&lt;br /&gt;
[http://rmapv.rmap.cc/accounts/profile/ Dati stazione] &amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Cancellazione delle configurazioni e reset alle condizioni di &amp;quot;fabbrica&amp;quot; ===&lt;br /&gt;
==== Se si ha il display ====&lt;br /&gt;
Tenendo premuto il pulsante A premere il pulsante Reset.&lt;br /&gt;
Dovranno apparire le seguenti scritte:&lt;br /&gt;
 Clean FS&lt;br /&gt;
 Reset wifi configuration&lt;br /&gt;
&lt;br /&gt;
Potranno essere necessarie alcune decine di secondi prima che queste scritte scompaiano e si possa procedere.&lt;br /&gt;
&lt;br /&gt;
==== Se non si ha il display ====&lt;br /&gt;
Con un filo connettere il pin 7 a massa e premere il pulsante Reset e attendere 5 secondi prima di scollegare il filo dal pin 7 e attendere ulteriori 60 secondi.&lt;br /&gt;
&lt;br /&gt;
=== Assemblaggio ===&lt;br /&gt;
Infilare i connettori con i pin lunghi e saldarli sul modulo Wemos D1 mini.&lt;br /&gt;
Se si dispone di un display Wemos v2 impilarlo sul modulo Wemos D1 mini.&lt;br /&gt;
AggiungereWemos il DC Power Shield&lt;br /&gt;
&lt;br /&gt;
==== opzione display oled ====&lt;br /&gt;
Se si possiede la versione v2.0.0 sul circuito stampato dal lato opposto del display interrompere la piazzola sulla destra indicata con D3 (pulsante A, piazzola indicata con la freccia) e della stessa colonna di piazzole saldare quella indicata con D7.&lt;br /&gt;
Se si possiede la versione v1.x (senza pulsanti A e B) è necessario realizzare una saldatura dove previsto (sul retro del circuito stampato rispetto al display) selezionando l'indirizzo I2C corrispondente a 0x3C.&lt;br /&gt;
&lt;br /&gt;
==== opzione Plantower PMS5003 ====&lt;br /&gt;
numbering pins from left to right with &amp;quot;plantower&amp;quot; stamps on the floor&lt;br /&gt;
&lt;br /&gt;
Effettuare i seguenti collegamenti tra Wemos e [https://github.com/r-map/rmap/blob/master/arduino/sketchbook/libraries/pms/doc/pms5003-manual_v2-3.pdf PMS5003]:&lt;br /&gt;
Connettere:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Wemos D1 mini &lt;br /&gt;
! &lt;br /&gt;
! PMS5003&lt;br /&gt;
|-&lt;br /&gt;
| GND || &amp;lt;-&amp;gt; || PIN 2&lt;br /&gt;
|-&lt;br /&gt;
| 5V  || &amp;lt;-&amp;gt; || PIN 1&lt;br /&gt;
|-&lt;br /&gt;
| D5  || &amp;lt;-&amp;gt; || PIN 5&lt;br /&gt;
|-&lt;br /&gt;
| D6  || &amp;lt;-&amp;gt; || PIN 4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
eventualmente connettere anche il PIN 6 (reset) e PIN 3 (SET) (DA FARE)&lt;br /&gt;
&lt;br /&gt;
==== opzione SDS011 ====&lt;br /&gt;
Effettuare i seguenti collegamenti tra Wemos e SDS011:&lt;br /&gt;
Connettere:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Wemos D1 mini &lt;br /&gt;
! &lt;br /&gt;
! SDS011&lt;br /&gt;
|-&lt;br /&gt;
| GND || &amp;lt;-&amp;gt; || GND&lt;br /&gt;
|-&lt;br /&gt;
| 5V  || &amp;lt;-&amp;gt; || 5V&lt;br /&gt;
|-&lt;br /&gt;
| D5  || &amp;lt;-&amp;gt; || TXD&lt;br /&gt;
|-&lt;br /&gt;
| D6  || &amp;lt;-&amp;gt; || RXD&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== opzione Honeywell HPM ====&lt;br /&gt;
Effettuare i seguenti collegamenti tra Wemos e Honeywell hpm:&lt;br /&gt;
[[File:Honeywell_hpm_pinout.png|300px|thumb|left|Honeywell pinout]] &amp;lt;br clear=all&amp;gt;&lt;br /&gt;
Connettere:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Wemos D1 mini &lt;br /&gt;
! &lt;br /&gt;
! Honeywell HPM&lt;br /&gt;
|-&lt;br /&gt;
| GND || &amp;lt;-&amp;gt; || PIN 8 GND&lt;br /&gt;
|-&lt;br /&gt;
| 5V  || &amp;lt;-&amp;gt; || PIN 2 5V&lt;br /&gt;
|-&lt;br /&gt;
| D5  || &amp;lt;-&amp;gt; || PIN 6 TX&lt;br /&gt;
|-&lt;br /&gt;
| D6  || &amp;lt;-&amp;gt; || PIN 7 RX&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:assemblaggioinscatolaelettrica.jpg|400px|thumb|left|Assemblaggio moduli in scatola elettrica]] &amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:assemblaggioinscatolaelettricaflusso.jpg|400px|thumb|left|Assemblaggio materiale espanso per flusso aria]] &amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:presearia.jpg|400px|thumb|left|Messa in opera con canaletta angolo a 90 gradi per flusso aria in/out antipioggia]] &amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:filtroinsetti.jpg|400px|thumb|left|Uso di rete zanzariera per filtro contro gli insetti]] &amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Opzione modulo Stima-th ====&lt;br /&gt;
&lt;br /&gt;
[[File:sensoretemperaturaeumidita.jpg|400px|thumb|left|Sensore temperatura e umidità all'interno di apposito schermo per le radiazioni]] &amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ponticellare (con un resistore)  A1-centrale con  A1-&lt;br /&gt;
* ponticellare (con un resistore)  A0-centrale con  A0+&lt;br /&gt;
&lt;br /&gt;
Una volta saldati i terminali dei cavi e protetti con nastro autoagglomerante è importante preservare le connessioni dalla corrosione degli agenti atmosferici e consigliamo uno strato di silicone protettivo spray del tipo Electrolube DCR200H; solo una volta asciugato lo strato di vernice protettiva rimuovere la protezione adesiva del sensore HIH&lt;br /&gt;
&lt;br /&gt;
Connettere:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Wemos D1 mini &lt;br /&gt;
! &lt;br /&gt;
! modulo Stima-th&lt;br /&gt;
|-&lt;br /&gt;
| GND || &amp;lt;-&amp;gt; || GND&lt;br /&gt;
|-&lt;br /&gt;
| 3V3  || &amp;lt;-&amp;gt; || VCC&lt;br /&gt;
|-&lt;br /&gt;
| D1  || &amp;lt;-&amp;gt; || SCL&lt;br /&gt;
|-&lt;br /&gt;
| D2  || &amp;lt;-&amp;gt; || SDA&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
E' necessario fare una modifica al modulo wemos per aggiungere un pin di collegamento a GND.&lt;br /&gt;
Saldare a 45 gradi di inclinazione un pin aggiuntivo per connettore Dupont a GND come da figura:&lt;br /&gt;
[[File:stima_wifi_addpintognd.jpg|300px|thumb|center|Pin aggiunto a GND]] &amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Opzione modulo Stima-i2c-sdsmics ====&lt;br /&gt;
&lt;br /&gt;
vedi:&lt;br /&gt;
http://www.raspibo.org/wiki/index.php?title=Gruppo_Meteo/HowTo#Modulo_Stima-i2c-sdsmics&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Opzione per alimentazione con cavo di lunghezza superiore a 2m. ====&lt;br /&gt;
Tagliare il cavo dell'alimentatore e inserire una piattina bipolare con rame di diametro opportuno ovviamente della lunghezza necessaria.&lt;br /&gt;
&lt;br /&gt;
==== Per caricare il firmware ====&lt;br /&gt;
&lt;br /&gt;
===== Installare il driver USB2Serial =====&lt;br /&gt;
&lt;br /&gt;
====== Windows ======&lt;br /&gt;
Per comunicare col Wemos c’è bisogno del driver usb2serial.&lt;br /&gt;
&lt;br /&gt;
====== Linux ======&lt;br /&gt;
Nessuna installazione necessaria.&lt;br /&gt;
&lt;br /&gt;
====== MacOS ======&lt;br /&gt;
Per Sierra vedere queste instruzioni che sono state testate: https://github.com/adrianmihalko/ch340g-ch34g-ch34x-mac-os-driver&lt;br /&gt;
&lt;br /&gt;
===== Upload del firmware =====&lt;br /&gt;
&lt;br /&gt;
Effettuare il download del firmware da http://rmap.cc/media/firmware/rmap_esp8266.ino.d1_mini_yhbp7E2.bin&lt;br /&gt;
e caricarlo sul Wemos dopo averlo connesso tramite cavetto USB.&lt;br /&gt;
Per fare questo seguire le istruzioni a:&lt;br /&gt;
https://github.com/espressif/esptool&lt;br /&gt;
e in particolare:&lt;br /&gt;
https://github.com/espressif/esptool#writing-binaries-to-flash&lt;br /&gt;
&lt;br /&gt;
== HowTo per il bando di gara ARPAE 2016 ==&lt;br /&gt;
&lt;br /&gt;
=== Installazione ambiente di sviluppo ===&lt;br /&gt;
&lt;br /&gt;
==== SDK Arduino ====&lt;br /&gt;
* Installare arduino 1.8.1 da https://www.arduino.cc/en/Main/Software&lt;br /&gt;
* scaricare l'ultima versione del software stima (file stimasketchbookbluetooth) da https://github.com/r-map/rmap/releases&lt;br /&gt;
* scompattare il file zip&lt;br /&gt;
&lt;br /&gt;
* aprire l'ide arduino e in file -&amp;gt; impostazioni -&amp;gt; percorso della cartella degli sketch selezionare la cartella sketchbook appena scompattata dal file scaricato&lt;br /&gt;
* chiudere e riaprire l'ide&lt;br /&gt;
&lt;br /&gt;
* sezionare in -&amp;gt; strumenti&lt;br /&gt;
        Scheda: Microduino Core+ (644pa)&lt;br /&gt;
        Processore: ATmega644pa@16M5V&lt;br /&gt;
        Porta: (quella disponibile) &lt;br /&gt;
&lt;br /&gt;
* selezionare in -&amp;gt; Sketch -&amp;gt; Verifica e compila &lt;br /&gt;
&lt;br /&gt;
Ora per uplodare il firmware sul microprocessore dovrete collegare tra loro SOLO&lt;br /&gt;
&lt;br /&gt;
* MICRODUINO Core+ ATMEGA644PA&lt;br /&gt;
* MICRODUINO Shield USB/TTL &lt;br /&gt;
&lt;br /&gt;
poi selezionate nella IDE di arduino:&lt;br /&gt;
&lt;br /&gt;
* selezionare in -&amp;gt; Sketch -&amp;gt; Carica &lt;br /&gt;
&lt;br /&gt;
Utilizzando MICRODUINO Core+ con ATMEGA 1284 sostituire 1284 a 644 nei passi precedenti.&lt;br /&gt;
&lt;br /&gt;
==== Pacchetto python RMAP ====&lt;br /&gt;
&lt;br /&gt;
Queste istruzioni permettono di installare il pacchetto RMAP scritto in python utile alla configurazione delle stazioni:&lt;br /&gt;
&lt;br /&gt;
 mkdir rmap&lt;br /&gt;
 cd rmap&lt;br /&gt;
 virtualenv myrmap&lt;br /&gt;
 source myrmap/bin/activate&lt;br /&gt;
 pip install rmap&lt;br /&gt;
&lt;br /&gt;
successivamente ogni volta che si vuole eseguire un comando rmap eseguire preventivamente:&lt;br /&gt;
&lt;br /&gt;
 cd rmap&lt;br /&gt;
 source myrmap/bin/activate&lt;br /&gt;
&lt;br /&gt;
=== Modulo Stima-th ===&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
* ponticellare con un resistore A1-centrale con  A1-&lt;br /&gt;
* ponticellare con un resistore A0-centrale con  A0+&lt;br /&gt;
&lt;br /&gt;
Una volta saldati i terminali dei cavi e protetti con nastro autoagglomerante è importante preservare le connessioni dalla corrosione degli agenti atmosferici e consigliamo uno strato di silicone protettivo spray del tipo Electrolube DCR200H; solo una volta asciugato lo strato di vernice protettiva rimuovere la protezione adesiva del sensore HIH&lt;br /&gt;
&lt;br /&gt;
==== Configurazione ====&lt;br /&gt;
Bisogna modificare l'indirizzo i2c del sensore hih.&lt;br /&gt;
&lt;br /&gt;
* Assemblare microduino core+ con microduino FT232RL con Stima-i2c &lt;br /&gt;
* Caricare il firmware sensor_config&lt;br /&gt;
* connettere:&lt;br /&gt;
 * Stima-th VCC  -&amp;gt;  Stima-i2c rl2&lt;br /&gt;
 * Stima-th GND  -&amp;gt;  Stima-i2c GND&lt;br /&gt;
 * Stima-th SDA  -&amp;gt;  Stima-i2c SDA&lt;br /&gt;
 * Stima-th SCL  -&amp;gt;  Stima-i2c SCL&lt;br /&gt;
&lt;br /&gt;
alla porta seriale inviare i comandi:&lt;br /&gt;
&lt;br /&gt;
 Sensor to config:&lt;br /&gt;
  w = i2c-wind&lt;br /&gt;
  s = i2c-windsonic&lt;br /&gt;
  t = i2c-th&lt;br /&gt;
  r = i2c-rain&lt;br /&gt;
  h = hih humidity sensor&lt;br /&gt;
 &lt;br /&gt;
 ? = help - this page&lt;br /&gt;
h&lt;br /&gt;
 If you want to use Command Mode to setup HIH61xx sensor you MUST use one pin to power the HIH!&lt;br /&gt;
 If not this will not work!&lt;br /&gt;
 digit old i2c address for HIH sensor (1-127)&lt;br /&gt;
39&lt;br /&gt;
 digit the pin number for power HIH sensor (1-127)&lt;br /&gt;
4&lt;br /&gt;
 started HIH fo command mode&lt;br /&gt;
 digit new i2c address for HIH sensor (1-127)&lt;br /&gt;
38&lt;br /&gt;
 Done; switch off&lt;br /&gt;
&lt;br /&gt;
==== Assemblaggio ====&lt;br /&gt;
&lt;br /&gt;
Utilizzare un cavo quadripolare a bassa capacità se possibile schermato da esterno con da un lato connettore rj45 e dall'altro la connssione a Stima-th.&lt;br /&gt;
&lt;br /&gt;
Per questi sensori installati all'esterno è importante preservare le connessioni dalla corrosione degli agenti atmosferici e consigliamo uno strato di silicone protettivo spray del tipo Electrolube DCR200H.&lt;br /&gt;
&lt;br /&gt;
Inserire Stima-th nell'apposito schermo per le radiazioni.&lt;br /&gt;
&lt;br /&gt;
=== Modulo Stima-I2C-th ===&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
Assemblare le schede impilabili: &lt;br /&gt;
* Board microduino core+ 644 &lt;br /&gt;
* Board microduino SD &lt;br /&gt;
* Board STIMA-I2C &lt;br /&gt;
* Microduino FT232RL&lt;br /&gt;
&lt;br /&gt;
==== Software ====&lt;br /&gt;
* Caricare il firmware i2c-th tramite microduino FT232RL&lt;br /&gt;
&lt;br /&gt;
==== Configurazione ====&lt;br /&gt;
&lt;br /&gt;
Bisogna configurare l'indirizzo i2c del sensore hih.&lt;br /&gt;
&lt;br /&gt;
* Assemblare microduino core+ con microduino FT232RL con Stima-i2c&lt;br /&gt;
* Caricare il firmware sensor_config&lt;br /&gt;
* connettere: &lt;br /&gt;
&lt;br /&gt;
 * Stima-i2c modulo configurazione +5  -&amp;gt;  Stima-i2c modulo stima +5&lt;br /&gt;
 * Stima-th modulo configurazione GND  -&amp;gt;  Stima-i2c modulo stima GND&lt;br /&gt;
 * Stima-th modulo configurazione SDA  -&amp;gt;  Stima-i2c modulo stima SDA&lt;br /&gt;
 * Stima-th modulo configurazione SCL  -&amp;gt;  Stima-i2c modulo stima SCL&lt;br /&gt;
&lt;br /&gt;
alla porta seriale inviare i comandi: &lt;br /&gt;
 Terminal ready&lt;br /&gt;
 Start sensor config&lt;br /&gt;
        Sensor configuration - 1.0&lt;br /&gt;
 &lt;br /&gt;
 scan I2C bus:&lt;br /&gt;
   i = scan one time&lt;br /&gt;
 &lt;br /&gt;
 Sensor to config:&lt;br /&gt;
   w = i2c-wind&lt;br /&gt;
   s = i2c-windsonic&lt;br /&gt;
   t = i2c-th&lt;br /&gt;
   r = i2c-rain&lt;br /&gt;
   h = hih humidity sensor&lt;br /&gt;
 &lt;br /&gt;
 ? = help - this page&lt;br /&gt;
&lt;br /&gt;
 digit new i2c address for i2c-th (1-127)&lt;br /&gt;
&lt;br /&gt;
35&lt;br /&gt;
&lt;br /&gt;
 digit new i2c_temperature address for i2c-th (1-127)&lt;br /&gt;
&lt;br /&gt;
73&lt;br /&gt;
&lt;br /&gt;
 digit new i2c_humidity address for i2c-th (1-127)&lt;br /&gt;
&lt;br /&gt;
38&lt;br /&gt;
&lt;br /&gt;
 digit 1 for oneshotmode; 0 for continous mode for i2c-th (0/1)&lt;br /&gt;
&lt;br /&gt;
0&lt;br /&gt;
&lt;br /&gt;
 Done; switch off&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Assemblaggio =====&lt;br /&gt;
&lt;br /&gt;
* connettere: &lt;br /&gt;
&lt;br /&gt;
 * Stima-i2c modulo configurazione +5  -&amp;gt;  Stima-i2c modulo stima +5&lt;br /&gt;
 * Stima-th modulo configurazione GND  -&amp;gt;  Stima-i2c modulo stima GND&lt;br /&gt;
 * Stima-th modulo configurazione SDA  -&amp;gt;  Stima-i2c modulo stima SDA&lt;br /&gt;
 * Stima-th modulo configurazione SCL  -&amp;gt;  Stima-i2c modulo stima SCL&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Modulo Stima-I2C-rain ===&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
&lt;br /&gt;
* Assemblare le schede impilabili: &lt;br /&gt;
* Board microduino core+ 644&lt;br /&gt;
* Board microduino SD&lt;br /&gt;
* Board STIMA-I2C&lt;br /&gt;
* Microduino FT232RL&lt;br /&gt;
&lt;br /&gt;
==== Software ====&lt;br /&gt;
&lt;br /&gt;
* Caricare il firmware i2c-rain tramite microduino FT232RL &lt;br /&gt;
&lt;br /&gt;
==== Configurazione ====&lt;br /&gt;
&lt;br /&gt;
Nessuna necessaria.&lt;br /&gt;
&lt;br /&gt;
==== Assemblaggio ====&lt;br /&gt;
&lt;br /&gt;
Il due poli del contatto della bascula vanno collegati l'uno a massa e l'altro al pin D2 del microcontrollore.&lt;br /&gt;
Aggiungere una resistenza di pullup di qualche migliaio di ohm tra il pin D2 e +5V.&lt;br /&gt;
&lt;br /&gt;
=== Scheda STIMA-I2C-Hub ===&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
&lt;br /&gt;
* Segare il circuito stampato seguendo i fori guida dopo il secondo connettore RJ45.&lt;br /&gt;
* Ponticellare con saldature per ottenere 4 file di dupoint a 5V e uno a 3.3V&lt;br /&gt;
* Ponticellare con saldature per ottenere un rj45 a 5V e un rg45 a 3.3v.&lt;br /&gt;
&lt;br /&gt;
==== Assemblaggio ====&lt;br /&gt;
&lt;br /&gt;
Collegare i moduli Stima-th Stima-rain Stima-GSM e il display LCDtramite cavo quadripolare alle file di dupoint su Stima-i2c-hub impostati a 5V.&lt;br /&gt;
&lt;br /&gt;
Collegare i sensori Stima-th al connettore RJ45 alimentato a 3.3V.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== stazione STIMA GSM THP ===&lt;br /&gt;
==== Modulo Stima-GSM ====&lt;br /&gt;
&lt;br /&gt;
===== Hardware =====&lt;br /&gt;
Apportare queste due modifiche  al modulo microduino GPRS/GSM:&lt;br /&gt;
* cortocircuitare con una saldatura i due terminali del pulsante di accensione &amp;quot;POWR KEY&amp;quot;&lt;br /&gt;
* connettere il punto &amp;quot;RST&amp;quot; al pin D6&lt;br /&gt;
* saldare i ponticelli per portarli a TX1,RX1 (jumper for tx, jumper for rx)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Assemblare le schede impilabili:&lt;br /&gt;
* Board microduino core+ 1284&lt;br /&gt;
* Board microduino GPRS/GSM&lt;br /&gt;
* Board microduino SD &lt;br /&gt;
* Board STIMA-I2C&lt;br /&gt;
* Microduino FT232RL&lt;br /&gt;
&lt;br /&gt;
===== Software =====&lt;br /&gt;
In arduino/sketchbook/rmap/rmap copiare il file stima_gsm_report.h in rmap_config.h&lt;br /&gt;
&lt;br /&gt;
In sketchbook/libraries/PubSubClient/PubSubClient.h modificare come segue: &lt;br /&gt;
&lt;br /&gt;
 // if use sim800 client&lt;br /&gt;
 #include &amp;quot;sim800Client.h&amp;quot;&lt;br /&gt;
 #define TCPCLIENT sim800Client&lt;br /&gt;
 &lt;br /&gt;
 // if use arduino_uip or etherclient&lt;br /&gt;
 //#include &amp;quot;Client.h&amp;quot;&lt;br /&gt;
 //#include &amp;quot;Stream.h&amp;quot;&lt;br /&gt;
 //#define TCPCLIENT Client&lt;br /&gt;
&lt;br /&gt;
Caricare il firmware rmap tramite microduino FT232RL.&lt;br /&gt;
&lt;br /&gt;
==== Assemblaggio ====&lt;br /&gt;
&lt;br /&gt;
Collegare tutti i moduli tramite l'hub i2c rispettando le corrette tensioni di alimentazione (STIMA-TH a 3.3V).&lt;br /&gt;
Collegare all'HUB i2c anche il Display LCD 20x4 con interfaccia I²C alimentandolo a 5V.&lt;br /&gt;
&lt;br /&gt;
Inserire la SIM della TIM senza richiesta di PIN e la scheda SD nel modulo Stima-GSM.&lt;br /&gt;
&lt;br /&gt;
Alimentare il modulo Stima-GSM tramite il connettore micro USB della scheda Stima-i2c con un alimentatore a 5V 2A o in alternativa tramite i pin GND e +5 della scheda Stima-i2c.&lt;br /&gt;
Collegare i pin denominati &amp;quot;LED&amp;quot; della scheda del display LCD a un pulsante per l'attivazione della retroilluminazione.&lt;br /&gt;
&lt;br /&gt;
E' possibile utilizzare il connettore micro USB della scheda Microduino FT232RL dei vari moduli per ottenere su porta &lt;br /&gt;
seriale messaggi di debug.&lt;br /&gt;
&lt;br /&gt;
===== Configurazione =====&lt;br /&gt;
&lt;br /&gt;
Per ottenere una username e una password iscriversi al sito http://rmap.cc/registrazione/register/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Eventualmente (dopo la prima configurazione) ponticellare sulla scheda Stima-i2c i pin &amp;quot;Set&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
eseguire i comandi:&lt;br /&gt;
&lt;br /&gt;
 rmapctrl --syncdb&lt;br /&gt;
 rmap-configure --wizard --station_slug=&amp;lt;nome_stazione&amp;gt; --height=&amp;lt;height&amp;gt; --stationname=&amp;lt;nome_descrittivo&amp;gt; --username=&amp;lt;username&amp;gt; --password=&amp;lt;password&amp;gt; --server=rmap.cc --lat=&amp;lt;xx.xxxxx&amp;gt; --lon=&amp;lt;xx.xxxxx&amp;gt; --mqttrootpath=report --mqttmaintpath=report&lt;br /&gt;
 rmap-configure --addboard --station_slug=&amp;lt;nome_stazione&amp;gt; --board_slug=&amp;lt;board_name&amp;gt; --user=&amp;lt;username&amp;gt; --serialactivate --mqttactivate --mqttuser=&amp;lt;username&amp;gt; --mqttpassword=&amp;lt;password&amp;gt; --mqttsamplerate=900&lt;br /&gt;
 rmap-configure --addsensors_by_template=stima_report_thp --station_slug=&amp;lt;nome_stazione&amp;gt; --board_slug=&amp;lt;nome_board&amp;gt; --user=&amp;lt;username&amp;gt; --password=&amp;lt;password&amp;gt; --upload_to_server&lt;br /&gt;
 rmap-configure --config_station --station_slug=&amp;lt;nome_stazione&amp;gt; --board_slug=&amp;lt;nome_board&amp;gt; --username=&amp;lt;username&amp;gt; --baudrate 115200&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sostituendo i valori &amp;lt;&amp;gt; con opportuni valori.&lt;br /&gt;
&lt;br /&gt;
Rimuovere il ponticello ai pin &amp;quot;Set&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Operazioni finali ====&lt;br /&gt;
Una volta verificato il corretto funzionamento della stazione è possibile ricaricare i firmware con l'opzione di debug disabilitata commentando l'apposita variabile del preprocessore C nei file config.h presenti nelle cartelle dei firmware; in questo caso sarà anche possibile rimuovere le schede Microduino FT232RL dai moduli.&lt;br /&gt;
&lt;br /&gt;
=== stazione STIMA MASTER THP ===&lt;br /&gt;
==== Modulo Stima-master ====&lt;br /&gt;
&lt;br /&gt;
===== Hardware =====&lt;br /&gt;
&lt;br /&gt;
Assemblare le schede impilabili:&lt;br /&gt;
* Board microduino core+ 1284&lt;br /&gt;
* Board microduino wiz W5500 oppure microduino ENC28j60&lt;br /&gt;
* Board microduino SD &lt;br /&gt;
* Board microduino RJ45-POE&lt;br /&gt;
* Board STIMA-I2C&lt;br /&gt;
* Microduino FT232RL&lt;br /&gt;
&lt;br /&gt;
===== Software =====&lt;br /&gt;
In arduino/sketchbook/rmap/rmap copiare il file stima_master_report.h in rmap_config.h&lt;br /&gt;
&lt;br /&gt;
In sketchbook/libraries/PubSubClient/PubSubClient.h modificare come segue: &lt;br /&gt;
&lt;br /&gt;
 // if use sim800 client&lt;br /&gt;
 //#include &amp;quot;sim800Client.h&amp;quot;&lt;br /&gt;
 //#define TCPCLIENT sim800Client&lt;br /&gt;
 &lt;br /&gt;
 // if use arduino_uip or etherclient&lt;br /&gt;
 #include &amp;quot;Client.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;Stream.h&amp;quot;&lt;br /&gt;
 #define TCPCLIENT Client&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Caricare il firmware rmap tramite microduino FT232RL.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Assemblaggio ====&lt;br /&gt;
&lt;br /&gt;
Collegare tutti i moduli tramite l'hub i2c rispettando le corrette tensioni di alimentazione (STIMA-TH a 3.3V).&lt;br /&gt;
Collegare all'HUB i2c anche il Display LCD 20x4 con interfaccia I²C  e Modulo Tiny RTC I²C Real Time Clock con DS1307 alimentandoli a 5V&lt;br /&gt;
&lt;br /&gt;
Alimentare il modulo Stima-master tramite il cavo ethernet con power over ethernet  con opportuno injector e alimentazione.&lt;br /&gt;
Ponticellare i pin denominati &amp;quot;LED&amp;quot; della scheda del display LCD.&lt;br /&gt;
&lt;br /&gt;
E' possibile utilizzare il connettore micro USB della scheda Microduino FT232RL dei vari moduli per ottenere su porta seriale messaggi di debug.&lt;br /&gt;
&lt;br /&gt;
===== Configurazione =====&lt;br /&gt;
&lt;br /&gt;
Per ottenere una username e una password iscriversi al sito http://rmap.cc/registrazione/register/&lt;br /&gt;
&lt;br /&gt;
Eventualmente (dopo la prima configurazione) ponticellare sulla scheda Stima-i2c i pin &amp;quot;Set&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Eseguire i comandi:&lt;br /&gt;
&lt;br /&gt;
 rmapctrl --syncdb&lt;br /&gt;
 rmap-configure --wizard --station_slug=&amp;lt;nome_stazione&amp;gt; --height=&amp;lt;height&amp;gt; --stationname=&amp;lt;nome_descrittivo&amp;gt; --username=&amp;lt;username&amp;gt; --password=&amp;lt;password&amp;gt; --server=rmap.cc --lat=&amp;lt;xx.xxxxx&amp;gt; --lon=&amp;lt;xx.xxxxx&amp;gt;  --mqttrootpath=report --mqttmaintpath=report&lt;br /&gt;
 rmap-configure --addboard --station_slug=&amp;lt;nome_stazione&amp;gt; --board_slug=&amp;lt;nome_board&amp;gt; --user=&amp;lt;username&amp;gt; --serialactivate --mqttactivate --mqttuser=&amp;lt;username&amp;gt; --mqttpassword=&amp;lt;password&amp;gt; --mqttsamplerate=900 --tcpipactivate --tcpipntpserver=&amp;quot;it.pool.ntp.org&amp;quot; --tcpipname=stima&lt;br /&gt;
 rmap-configure --addsensors_by_template=stima_report_thp --station_slug=&amp;lt;nome_stazione&amp;gt; --board_slug=&amp;lt;nome_board&amp;gt; --user=&amp;lt;username&amp;gt; --password=&amp;lt;password&amp;gt; --upload_to_server&lt;br /&gt;
 rmap-configure --config_station --station_slug=&amp;lt;nome_stazione&amp;gt;  --board_slug=&amp;lt;nome_board&amp;gt; --username=&amp;lt;username&amp;gt; --baudrate 115200&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sostituendo i valori tra &amp;lt;&amp;gt; con opportuni valori.&lt;br /&gt;
&lt;br /&gt;
Rimuovere il ponticello ai pin &amp;quot;Set&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Operazioni finali ====&lt;br /&gt;
&lt;br /&gt;
Una volta verificato il corretto funzionamento della stazione è possibile ricaricare i firmware con l'opzione di debug disabilitata commentando l'apposita variabile del preprocessore C nei file config.h presenti nelle cartelle dei firmware; in questo caso sarà anche possibile rimuovere le schede Microduino FT232RL dai moduli.&lt;br /&gt;
&lt;br /&gt;
== HowTo in sintesi sempre aggiornato per gli altri moduli ==&lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
==== Modulo Stima-bluetooth ====&lt;br /&gt;
E' composto dalle seguenti schede:&lt;br /&gt;
* Board microduino core+ 644&lt;br /&gt;
* Board stima-bluetooth&lt;br /&gt;
* Board STIMA-I2C&lt;br /&gt;
* Board microduino nRF24 (opzionale)&lt;br /&gt;
&lt;br /&gt;
==== Modulo Stima-Master ====&lt;br /&gt;
E' composto dalle seguenti schede:&lt;br /&gt;
* Board microduino core+ 1284&lt;br /&gt;
* Board microduino ENC&lt;br /&gt;
* Board STIMA-I2C&lt;br /&gt;
* Board microduino nRF24 (opzionale)&lt;br /&gt;
&lt;br /&gt;
==== Modulo Stima-Satellite ====&lt;br /&gt;
E' composto dalle seguenti schede:&lt;br /&gt;
* Board microduino core+ 644&lt;br /&gt;
* Board microduino nRF24&lt;br /&gt;
* Board STIMA-I2C&lt;br /&gt;
&lt;br /&gt;
==== Modulo Stima-GSM/GPRS ====&lt;br /&gt;
E' composto dalle seguenti schede:&lt;br /&gt;
* Board microduino core+ 1284&lt;br /&gt;
* Board microduino nRF24&lt;br /&gt;
* Board microduino sim800&lt;br /&gt;
* Board microduino SD&lt;br /&gt;
* Board STIMA-I2C&lt;br /&gt;
&lt;br /&gt;
==== Modulo Stima-i2c-sdsmics ====&lt;br /&gt;
&lt;br /&gt;
E' composto dalle seguenti schede:&lt;br /&gt;
* Board microduino core+ 644 5V&lt;br /&gt;
* Board STIMA-AirQuality_Connector&lt;br /&gt;
&lt;br /&gt;
* Board STIMA-NO2-CO&lt;br /&gt;
&lt;br /&gt;
questa la disposizione dei pin dell'hardware versione 2 osservata dal lato dei connettori:&lt;br /&gt;
&lt;br /&gt;
Board STIMA-NO2-CO&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  GND  || PWM&lt;br /&gt;
|- &lt;br /&gt;
|  GNDD || SCALE1&lt;br /&gt;
|-&lt;br /&gt;
|  VREF || SCALE2&lt;br /&gt;
|-&lt;br /&gt;
|  VDD  || NO2&lt;br /&gt;
|- &lt;br /&gt;
|  +5   || CO&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Board STIMA-AirQuality_Connector&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  GND  || GND    || VREF || NONE || +5V&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|  +3.3V || || +5V || || PWM &lt;br /&gt;
|-&lt;br /&gt;
|  GND   || || GND || || SCALE1&lt;br /&gt;
|-&lt;br /&gt;
|  SDA   || || TX  || || SCALE2&lt;br /&gt;
|- &lt;br /&gt;
|  SCL   || || RX  || || CO&lt;br /&gt;
|-&lt;br /&gt;
|  +5V   || ||     || || NO2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Connettere:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! STIMA-NO2-CO &lt;br /&gt;
! &lt;br /&gt;
! STIMA-AirQuality_Connector&lt;br /&gt;
|-&lt;br /&gt;
| GNDD || &amp;lt;-&amp;gt; || GND&lt;br /&gt;
|-&lt;br /&gt;
| VREF || &amp;lt;-&amp;gt; || VREF&lt;br /&gt;
|-&lt;br /&gt;
| VDD  || &amp;lt;-&amp;gt; || +5V&lt;br /&gt;
|-&lt;br /&gt;
| PWM  || &amp;lt;-&amp;gt; || PWM&lt;br /&gt;
|-&lt;br /&gt;
| SCALE1 || &amp;lt;-&amp;gt; || SCALE1&lt;br /&gt;
|-&lt;br /&gt;
| SCALE2 || &amp;lt;-&amp;gt; || SCALE2&lt;br /&gt;
|-&lt;br /&gt;
| NO2  || &amp;lt;-&amp;gt; || NO2&lt;br /&gt;
|-&lt;br /&gt;
| CO   || &amp;lt;-&amp;gt; || CO&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Firmware STIMA-BlueTooth ===&lt;br /&gt;
&lt;br /&gt;
    installare arduino 1.6.5 da https://www.arduino.cc/en/Main/Software o tramite la propria distribuzione&lt;br /&gt;
&lt;br /&gt;
    scaricare l'ultima versione del software stima (file stimasketchbook) da https://github.com/r-map/rmap/releases&lt;br /&gt;
    scompattare il file zip&lt;br /&gt;
&lt;br /&gt;
    aprire l'ide arduino e in file -&amp;gt; impostazioni -&amp;gt; percorso della cartella degli sketch selezionare la cartella sketchbook appena scompattata dal file scaricato&lt;br /&gt;
    chiudere e riaprire l'ide&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== modulo Stima-bluetooth ====&lt;br /&gt;
&lt;br /&gt;
Se in questo modulo avete montato anche la board microduino nRF24 e quindi volete utilizzare anche il modulo Stima-Satellite con un editor modificate il file sketchbook/libraries/SensorDriver/SensorDriver_config.h scommentando l'opzione &lt;br /&gt;
 #define RADIORF24&lt;br /&gt;
scommentando anche l'opzione&lt;br /&gt;
 #define AES&lt;br /&gt;
abiliterete anche la crittografia AES ma consigliamo questa ultima opzione solo ai più esperti.&lt;br /&gt;
&lt;br /&gt;
In sketchbook/rmap/rmap copiare il file stima_bluetooth.h in rmap_config.h &lt;br /&gt;
&lt;br /&gt;
    sezionare in -&amp;gt; strumenti&lt;br /&gt;
        Scheda: Microduino Core+ (644pa)&lt;br /&gt;
        Processore: ATmega644pa@16M5V&lt;br /&gt;
        Porta: (quella disponibile) &lt;br /&gt;
&lt;br /&gt;
    selezionare in -&amp;gt; Sketch -&amp;gt; Verifica e compila &lt;br /&gt;
&lt;br /&gt;
Ora per uplodare il firmware sul microprocessore dovrete collegare tra loro SOLO&lt;br /&gt;
&lt;br /&gt;
    MICRODUINO Core+ ATMEGA644PA&lt;br /&gt;
    MICRODUINO Shield USB/TTL &lt;br /&gt;
&lt;br /&gt;
poi selezionate nella IDE di arduino:&lt;br /&gt;
&lt;br /&gt;
    selezionare in -&amp;gt; Sketch -&amp;gt; Carica&lt;br /&gt;
&lt;br /&gt;
==== modulo Stima-master ====&lt;br /&gt;
Se in questo modulo avete montato anche la board microduino nRF24 e quindi volete utilizzare anche il modulo Stima-Satellite con un editor modificate il file sketchbook/libraries/SensorDriver/SensorDriver_config.h scommentando l'opzione &amp;quot;#define RADIORF24&amp;quot; ; scommentando anche l'opzione #define AES abiliterete anche la crittografia AES ma consigliamo questa ultima opzione solo ai più esperti.&lt;br /&gt;
&lt;br /&gt;
In sketchbook/rmap/rmap copiare il file stima_master.h in rmap_config.h&lt;br /&gt;
&lt;br /&gt;
sezionare in -&amp;gt; strumenti&lt;br /&gt;
&lt;br /&gt;
    Scheda: Microduino Core+ (1284pa)&lt;br /&gt;
    Processore: ATmega1284pa@16M5V&lt;br /&gt;
    Porta: (quella disponibile) &lt;br /&gt;
&lt;br /&gt;
sezionare in -&amp;gt; strumenti -&amp;gt; cartella degli sketch -&amp;gt; rmap -&amp;gt; rmap&lt;br /&gt;
&lt;br /&gt;
selezionare in -&amp;gt; Sketch -&amp;gt; Carica&lt;br /&gt;
&lt;br /&gt;
==== modulo Stima-satellite ====&lt;br /&gt;
In sketchbook/rmap/rmap copiare il file stima_satellite.h in rmap_config.h&lt;br /&gt;
&lt;br /&gt;
sezionare in -&amp;gt; strumenti&lt;br /&gt;
&lt;br /&gt;
    Scheda: Microduino Core+ (644pa)&lt;br /&gt;
    Processore: ATmega644pa@16M5V&lt;br /&gt;
    Porta: (quella disponibile) &lt;br /&gt;
&lt;br /&gt;
sezionare in -&amp;gt; strumenti -&amp;gt; cartella degli sketch -&amp;gt; rmap -&amp;gt; rmap&lt;br /&gt;
&lt;br /&gt;
selezionare in -&amp;gt; Sketch -&amp;gt; Carica&lt;br /&gt;
&lt;br /&gt;
==== modulo Stima-gsm ====&lt;br /&gt;
In sketchbook/rmap/rmap copiare il file stima_gsm.h in rmap_config.h Se non utilizzerete una SIM card della TIM inserite in fondo al file rmap_config.h:&lt;br /&gt;
&lt;br /&gt;
#define GSMAPN &amp;quot;&amp;quot;&lt;br /&gt;
#define GSMUSER &amp;quot;&amp;quot;&lt;br /&gt;
#define GSMPASSWORD &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
con gli opportuni valori.&lt;br /&gt;
&lt;br /&gt;
In sketchbook/libraries/PubSubClient/PubSubClient.h modificare come segue:&lt;br /&gt;
&lt;br /&gt;
 // if use sim800 client&lt;br /&gt;
 #include &amp;quot;sim800Client.h&amp;quot;&lt;br /&gt;
 #define TCPCLIENT sim800Client&lt;br /&gt;
&lt;br /&gt;
 // if use arduino_uip or etherclient&lt;br /&gt;
 //#include &amp;quot;Client.h&amp;quot;&lt;br /&gt;
 //#include &amp;quot;Stream.h&amp;quot;&lt;br /&gt;
 //#define TCPCLIENT Client&lt;br /&gt;
&lt;br /&gt;
sezionare in -&amp;gt; strumenti&lt;br /&gt;
&lt;br /&gt;
    Scheda: Microduino Core+ (1284pa)&lt;br /&gt;
    Processore: ATmega1284pa@16M5V&lt;br /&gt;
    Porta: (quella disponibile) &lt;br /&gt;
&lt;br /&gt;
sezionare in -&amp;gt; strumenti -&amp;gt; cartella degli sketch -&amp;gt; rmap -&amp;gt; rmap&lt;br /&gt;
&lt;br /&gt;
selezionare in -&amp;gt; Sketch -&amp;gt; Carica&lt;br /&gt;
&lt;br /&gt;
=== Applicazione Rmap ===&lt;br /&gt;
&lt;br /&gt;
==== Android ====&lt;br /&gt;
&lt;br /&gt;
L'installazione su android è semplicissima; è sufficiente ricercare tra le app su google play &amp;quot;rmap&amp;quot; e procedere all'installazione: https://play.google.com/store/apps/details?id=org.test.rmap.&lt;br /&gt;
&lt;br /&gt;
==== Linux ====&lt;br /&gt;
&lt;br /&gt;
L'installazione in ambiente Linux richiede la disponibilità di alcuni pacchetti e del comando pip. Prima di tutto bisogna installare Kivy seguendo le istruzioni sul sito di Kivy http://kivy.org/docs/installation/installation-linux.html. Per il comando pip nelle distribuzioni Linux più diffure lo si ottiene installando il pacchetto python-pip. Per installare da utente non privilegiato l'ambiente rmap si può usare virtualenv e pip; da terminale eseguire:&lt;br /&gt;
&lt;br /&gt;
 virtualenv --system-site-packages rmap&lt;br /&gt;
 source rmap/bin/activate&lt;br /&gt;
&lt;br /&gt;
 pip install --upgrade rmap&lt;br /&gt;
&lt;br /&gt;
Poi attivare l'interfaccia utente grafica:&lt;br /&gt;
&lt;br /&gt;
 source rmap/bin/activate&lt;br /&gt;
 rmapgui&lt;br /&gt;
&lt;br /&gt;
In alternativa si può provare a installare Kivy tramite pip:&lt;br /&gt;
&lt;br /&gt;
 pip install cython&lt;br /&gt;
 pip install kivy&lt;br /&gt;
&lt;br /&gt;
Per aggiornare l'App una volta chiusa la finestra grafica nella finestra dei comandi al prompt digitare:&lt;br /&gt;
&lt;br /&gt;
 pip install --upgrade rmap&lt;br /&gt;
&lt;br /&gt;
==== Windows ====&lt;br /&gt;
&lt;br /&gt;
Seguire le istruzioni a https://kivy.org/docs/installation/installation-windows.html &lt;br /&gt;
&lt;br /&gt;
poi:&lt;br /&gt;
 python -m pip install rmap&lt;br /&gt;
&lt;br /&gt;
Le istruzioni che seguono sono per una vecchia modalità per un vecchio pacchetto:&lt;br /&gt;
&lt;br /&gt;
 L'installazione in windows è molto semplice in quanto il file d scaricare è autoscompattante e comprende tutto l'ambiente necessario a&lt;br /&gt;
 Rmap. Sacricare quindi il file rmapwindows da: https://github.com/r-map/rmap/releases/ ed eseguirlo per scompattarlo.&lt;br /&gt;
 Per far partire l'applicazione a questo punto basterà eseguire il file rmapgui contenuto nella cartella rmap&lt;br /&gt;
 Per aggiornare l'App una volta chiusa la finestra grafica nella finestra dei comandi al prompt digitare:&lt;br /&gt;
 pip install --upgrade rmap&lt;br /&gt;
&lt;br /&gt;
==== Mac OSX ====&lt;br /&gt;
&lt;br /&gt;
Prima di tutto bisogna installare Kivy su Macosx seguendo le istruzioni https://kivy.org/docs/installation/installation-osx.html e installere gettext da http://www.ellert.se/twain-sane/&lt;br /&gt;
&lt;br /&gt;
poi:&lt;br /&gt;
&lt;br /&gt;
 kivi -m pip install --upgrade rmap&lt;br /&gt;
&lt;br /&gt;
si può attivare il programma:&lt;br /&gt;
&lt;br /&gt;
 /Applications/Kivy.app/Contents/Resources/venv/bin/rmapgui&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Per aggiornare l'App una volta chiusa la finestra grafica nella finestra dei comandi al prompt digitare:&lt;br /&gt;
&lt;br /&gt;
 pip install --upgrade rmap&lt;br /&gt;
&lt;br /&gt;
=== Configurazione moduli ===&lt;br /&gt;
&lt;br /&gt;
Per pubblicare i dati sul server RMAP.cc bisogna registrarsi al sito; il bottone &amp;quot;Registrazione&amp;quot; dell'app dovrebbe aprire un browser alla url della registrazione che comunque è http://rmap.cc/registrazione/register/ Una volta fatta la registrazione sarete in possesso di uno user e di una password.&lt;br /&gt;
&lt;br /&gt;
A questo punto dovrete trasferire la vostra configurazione sulla eeprom del microcontrollore; per farlo:&lt;br /&gt;
&lt;br /&gt;
    ponticellate sulla board Stima-I2C i pin contrassegnati con &amp;quot;SET&amp;quot; con un jumper.&lt;br /&gt;
    collegate il modulo con la board Microduino FT232RL alla USB del vostro PC. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Configurazione tramite l'applicazione grafica ====&lt;br /&gt;
&lt;br /&gt;
Dovrete accedere al menu &amp;quot;Impostazioni&amp;quot; che si aprirà automaticamente al primo avvio e accedere alle sottosezioni:&lt;br /&gt;
&lt;br /&gt;
    Nella sezione &amp;quot;Rmap&amp;quot; dovrete inserire &amp;quot;RMAP user&amp;quot; e &amp;quot;RMAP password&amp;quot; ottenuti durante la registrazione a rmap.cc &lt;br /&gt;
&lt;br /&gt;
Dopo aver accoppiato il dispositivo bluetooth (dispositivo HC-05 inserendo come pin &amp;quot;1234&amp;quot;) si può attivare il programma. In windows tramite le apposite interfacce di windows procedere all'accoppiamento del dispositivo blue-tooth (dispositivo HC-05 inserendo come pin &amp;quot;1234&amp;quot;) e richiedere la creazione della relativa porta seriale COM13; in Linux per accoppiare il dispositivo stima-bluetooth cosigliamo di utilizzare blueman-manager contenuto nel pacchetto blueman; seguendo pochi passi con l'interfaccia grafica risulta molto facile accoppiare il dispositivo HC-05 inserendo come pin &amp;quot;1234&amp;quot;; il device RFCOM0 viene utilizzato per la comunicazione seriale. &lt;br /&gt;
&lt;br /&gt;
Ora dal menu Impostazioni selezionate la sezione &amp;quot;Sensors&amp;quot; e impostate:&lt;br /&gt;
&lt;br /&gt;
    per il modulo Stima-Bluetooth&lt;br /&gt;
        Name: HC-05&lt;br /&gt;
        Station: BT_fixed&lt;br /&gt;
        Board:&lt;br /&gt;
            su android: BT_fixed&lt;br /&gt;
            su linux: BT_fixed_LINUX&lt;br /&gt;
            su windows: BT_fixed_WINDOWS&lt;br /&gt;
            su OSX: BT_fixed_OSX &lt;br /&gt;
        Template: test_indirect&lt;br /&gt;
        Remote Board: stima_bt&lt;br /&gt;
        Remote Template: test &lt;br /&gt;
    per il modulo Stima-Master o Stima-gsm&lt;br /&gt;
        Station: ETH_fixed&lt;br /&gt;
        Board:&lt;br /&gt;
            su linux: rmapgui_LINUX&lt;br /&gt;
            su windows: rmapgui_WINDOWS&lt;br /&gt;
            su OSX: rmapgui_OSX &lt;br /&gt;
        Template: test_indirect&lt;br /&gt;
        Remote Board: master_eth_fixed&lt;br /&gt;
        Remote Template: test (test_master se avete la board nRF24) &lt;br /&gt;
    per il modulo Stima-Satellite&lt;br /&gt;
        come per il modulo Stima-Master ma come Remote Board: satellite_eth_fixed &lt;br /&gt;
&lt;br /&gt;
Nella sezione &amp;quot;Location&amp;quot; potete inserire manualmente le vostre coordinate e selezionare &amp;quot;Close&amp;quot; attivando la stazione. Se non conoscete le vostre coordinate dalla pagina &amp;quot;Posizione&amp;quot; selezionate accuratamente la vostra posizione e salvatela con il tasto &amp;quot;Salva posizione&amp;quot;. La prima pagina dell'App &amp;quot;Avvia&amp;quot; presenta un manuale che potrà aiutarvi.&lt;br /&gt;
&lt;br /&gt;
Dalla pagina &amp;quot;Dati automatici&amp;quot; premere il bottone &amp;quot;configura&amp;quot; e verificate che tutto vada a buon fine.&lt;br /&gt;
&lt;br /&gt;
==== Configurazione a linea di comando ====&lt;br /&gt;
&lt;br /&gt;
E' possibile fare tutte le funzioni di configurazioni con due comandi da terminale: nel caso di windows utilizzate la finestra che rimane aperta dopo aver eseguito rmap-configure.bat; su Linux o OSX attivate il virtualenv di python come per eseguire l'App grafica. Il primo comando inizializza il DB. Il secondo con l'opzione --wizard inserisce tutti i metadati nel DB, --config_station trasferisce la configurazione sulla eeprom del microcontrollore e --upload_to_server comunica i metadati al server:&lt;br /&gt;
&lt;br /&gt;
 rmapctrl --syncdb&lt;br /&gt;
 rmap-configure --station_slug=ETH_fixed --board_slug=master_eth_fixed --height=&amp;lt;altezza stazione in metri&amp;gt; --stationname=&amp;quot;&amp;lt;descrizione della stazione&amp;gt;&amp;quot; --username=&amp;lt;il vostro utente&amp;gt; --password=&amp;lt;la vostra password&amp;gt; --server=rmap.cc --samplerate=5 --lat=&amp;lt;latitudine stazione&amp;gt; --lon=&amp;lt;longitudine stazione&amp;gt; --addsensors_by_template=&amp;lt;sensortemplate&amp;gt; --wizard --config_station --upload_to_server&lt;br /&gt;
&lt;br /&gt;
Ovviamente sostituite il contenuto tra &amp;lt;&amp;gt; con i vostri dati; cercate di avere latitudine e longitudine definita fino alla quinta cifra decimale; &amp;lt;sensortemplate&amp;gt; dovrà essere &amp;quot;test_master&amp;quot; se il vostro modulo Stima-master o Stima-gsm comprende una board microduino nRF24, &amp;quot;test&amp;quot; in tutti gli altri casi.&lt;br /&gt;
&lt;br /&gt;
=== Operazioni finali ===&lt;br /&gt;
&lt;br /&gt;
Scollegare il modulo dalla USB, rimuovete la board Microduino FT232RL e attivate l'alimentazione saldando insieme il ponticello della board Stima-I2C come da figura. attachment:microduino_r_freccia.png Ricordatevi di rimuovere il jumper dai pin contrassegnati con &amp;quot;SET&amp;quot; sulla board Stima-I2C.&lt;br /&gt;
Messa in opera&lt;br /&gt;
&lt;br /&gt;
Ai moduli potete collegare il display LCD e/o i relays. Sul modulo Stima-gsm inserite una micro SD formattata FAT; dovete inserire anche una SIM card; tutto è preconfigurato per una sim della TIM. Alimentate i moduli tramite il connettore micro-USB sulla board Stima-I2C; il modulo Stima-master potete alimentarlo con l'apposito Injector e un alimentatore da 12 a 24V (connettore con positivo al centro). Sul modulo Stima-gsm il sim800 va acceso manualmente tenendo premuto l'apposito switch. Se tutto funziona regolarmente ogni 5 secondi i dati della temperatura del modulo verranno inviati a rmap.cc. Se sul server rmap.cc a questo punto fate login con il vostro utente accederete alla vostra pagina personale con l'elenco delle vostre stazioni di misura e la possibilità di visualizzare i grafici dei vostri dati. Ma per ora potete inviare solo i dati di test (temperatura del modulo); nella prossima puntata impareremo ad aggiungere sensori e navigare il server per la visualizzazione dei dati. &lt;br /&gt;
&lt;br /&gt;
=== Messa in opera ===&lt;br /&gt;
&lt;br /&gt;
Ai moduli potete collegare il display LCD e/o i relays. Sul modulo Stima-GSM/GPRS inserite una micro SD formattata FAT; dovete inserire anche una SIM card; tutto è preconfigurato per una sim della TIM. Alimentate i moduli tramite il connettore micro-USB sulla board Stima-I2C; il modulo Stima-master potete alimentarlo con l'apposito Injector e un alimentatore da 12 a 24V (connettore con positivo al centro). Sul modulo Stima-GSM/GPRS il sim800 va acceso manualmente tenendo premuto l'apposito switch. Sulla rete ethernet dovrte avere un server DHCP in quanto STIMA-Master lo richiede. Se tutto funziona regolarmente ogni 5 secondi i dati della temperatura di test del modulo verranno inviati a rmap.cc. Se sul server rmap.cc a questo punto fate login con il vostro utente accederete alla vostra pagina personale con l'elenco delle vostre stazioni di misura e la possibilità di visualizzare i grafici dei vostri dati. Ma per ora potete inviare solo i dati di test (temperatura del modulo); nella prossima puntata impareremo ad aggiungere sensori e navigare il server per la visualizzazione dei dati.&lt;br /&gt;
&lt;br /&gt;
=== Box ===&lt;br /&gt;
&lt;br /&gt;
Abbiamo progettato un interessante box per il modulo Stima-bluetooth e i sensori di temperatura e umidità (presentati nella prossima puntata); é composto da alcuni elementi impilabili a seconda delle esigenze. Ora lo presentiamo nella versione con un comodo attacco a elastico da usare ad esempio sul manubrio della bici per monitorare il percorso delle nostre escursioni.&lt;br /&gt;
Sono disponibili i file stl per stamparlo con una stampante 3D. I file per il box progettato da Mirco Bergamini si scaricano da https://github.com/r-map/rmap/releases ; è consigliato stamparlo in PLA bianco per ridurre gli effetti della radiazione solare. attachment:box.jpg Il box è composto da tre pezzi: un attacco &amp;quot;a elastico&amp;quot;, un contenitore per il modulo stima, uno schermo per le radiazioni per l'alloggiamento dei sensori. Gli ultimi due pezzi posso essere montati a due a due permettendo di aumentare lo spazio contenuto dal box; Sarà poi necessario praticare un foro tra il contenitore del modulo stima e lo schermo pr i sensori per il passaggio dei 4 fili del bus I2C; barre filettate e dadi completano l'assemblaggio. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Vedi anche: [[Gruppo Meteo/HowToOld]]&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6839</id>
		<title>Installare MicroPython su NUCLEO-F401RE</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6839"/>
		<updated>2019-03-10T00:46:38Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* Test! */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questa guida è basata quasi tutta su quella di Carmine Noviello https://www.carminenoviello.com/2015/06/03/running-micropyton-stm32nucleo-f4/ che peraltro trovate anche in italiano https://www.carminenoviello.com/it/2015/08/11/compilare-micropython-una-scheda-stm32nucleo-f4/ per cui scriverò solo le differenze.&lt;br /&gt;
&lt;br /&gt;
La versione di Carmine di micropython, che si trova sul suo [https://github.com/cnoviello/micropython github], risolve il problema relativo alla mancanza di memoria SD della scheda Nucleo. Il file con il programma .py sarà caricato direttamente sulla flash.&lt;br /&gt;
&lt;br /&gt;
= La scheda =&lt;br /&gt;
&lt;br /&gt;
NUCLEO-F401RE della STMicroelectronics è una scheda basata su ARM Cortex M4 e fa parte della famiglia STM32 Nucleo Boards. Ha 512KB di Flash, 96 KB di SRAM, un clock di 84MHz, 50 GPIO, RTC, supporto I²C, SPI, USART e molto altro ([https://os.mbed.com/platforms/ST-Nucleo-F401RE/ maggiori info]). La sua forma le permette di alloggiare sia gli shield per Arduino che le estensioni Morpho di STMicroelectronics.&lt;br /&gt;
Il prezzo è abbastanza contenuto (attorno ai 12€ su Mouser) il che ne fa una scheda piuttosto interessante.&lt;br /&gt;
&lt;br /&gt;
Normalmente si programmerebbe tramite l'[https://ide.mbed.com/compiler editor online di Mbed]. Il compilatore genererà dal nostro codice un file con estensione bin. Collegando la scheda verrà montato un volume, chiamato &amp;quot;NUCLEO&amp;quot; sul quale caricare il file bin. Quando la scheda verrà resettata, il codice verrà eseguito. È possibile anche usare editor offline con toolchain di compilazione come Eclipse.&lt;br /&gt;
&lt;br /&gt;
= Installazione MicroPython =&lt;br /&gt;
&lt;br /&gt;
== Primo tentativo ==&lt;br /&gt;
&lt;br /&gt;
=== Toolchain e OpenOCD ===&lt;br /&gt;
&lt;br /&gt;
Per compilare vi servirà la toolchain gcc-arm-embedded. Non è nei repo ufficiali quindi la dovete installare a mano oppure aggiungere un PPA. https://launchpad.net/gcc-arm-embedded&lt;br /&gt;
Il programma per comunicare col debugger della scheda, openocd, invece è nei repo di Debian.&lt;br /&gt;
 &lt;br /&gt;
=== Come installare MicroPython ===&lt;br /&gt;
&lt;br /&gt;
Potete seguire la [https://www.carminenoviello.com/it/2015/08/11/compilare-micropython-una-scheda-stm32nucleo-f4/ guida di Carmine Noviello] per la compilazione. Ovviamente se avete installato la toolchain con apt non è necessario aggiungere il path a tutti i comandi, perché sono già dentro a /usr/bin.&lt;br /&gt;
&lt;br /&gt;
OpenOCD ci permette di caricare il firmware che abbiamo crosscompilato. Basterà lanciare il comando:&lt;br /&gt;
 $ openocd  -f board/st_nucleo_f4.cfg&lt;br /&gt;
Un LED della scheda dovrebbe lampeggiare rosso/verde. Il debugger è attivo. Per collegarcisi:&lt;br /&gt;
 $ telnet localhost 4444&lt;br /&gt;
e poi scrivete:&lt;br /&gt;
 &amp;gt; reset halt&lt;br /&gt;
e infine:&lt;br /&gt;
 &amp;gt; flash write_image erase &amp;lt;file .elf da flashare&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inizialmente non sembrava funzionare. Il tentativo finale che ha sbloccato la situazione è stato dare il comando shutdown. Non sono sicuro però che sia stato proprio quel comando e bisognerebbe indagare meglio.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dall'interprete ===&lt;br /&gt;
&lt;br /&gt;
Aprendo la porta della nostra scheda (la trovate su dmesg non appena la attaccate, è /dev/ttyACMx dove x è un numero che parte da 0) con un emulatore di terminale (come screen, picocom o minicom) alla velocità di 115200 baud, dovreste vedere l'interprete dei comandi (REPL, ovvero Read, Eval, Print and Loop) di MicroPython. Provate a dare il comando:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pyb.LED(1).on()&lt;br /&gt;
per vedere se si accende il LED onboard.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dal PC ===&lt;br /&gt;
&lt;br /&gt;
Fra i tool di MicroPython, che trovate nella cartella di git micropython/tools, c'è pyboard.py, un programma che vi permette di eseguire uno script in MicroPython. Se la vostra porta non è accessibile dall'utente dovrete usare sudo.&lt;br /&gt;
 # ./pyboard.py --device=/dev/ttyACMx &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Carmine ha fatto una modifica a pyboard in modo che possa caricare un file sulla board.&lt;br /&gt;
 # ./pyboard.py --device=/dev/ttyACMx --send &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
MicroPython ha due file di default quando viene installato: boot.py e main.py. Il primo è un file di sistema che serve allo stesso MicroPython di partire. Non occorre di solito modificarlo. Il secondo, main.py, è uno script che viene eseguito all'avvio. Se carichiamo un file main.py questo verrà eseguito all'accensione.&lt;br /&gt;
&lt;br /&gt;
=== Considerazioni finali ===&lt;br /&gt;
&lt;br /&gt;
Molto bene, ma la versione di micropython non è aggiornata. Forse è per questo che non riesco a far funzionare la porta I²C?&lt;br /&gt;
&lt;br /&gt;
== Secondo tentativo ==&lt;br /&gt;
&lt;br /&gt;
Boochow fornisce dei firmware già compilati su https://blog.boochow.com/micropython-firmware-for-mbed-boards basta scegliere la board giusta e caricare il file .bin nel volume &amp;quot;NUCLEO&amp;quot; che si monta quando si collega la USB.&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Un modo piuttosto comodo di inviare e ricevere file sulla flash della Nucleo è usare uPyLoader:&lt;br /&gt;
https://github.com/BetaRavener/uPyLoader/&lt;br /&gt;
ma quasi sempre dà un errore di timeout.&lt;br /&gt;
&lt;br /&gt;
Il programma fornito da Adafruit sembra funzionare decisamente meglio&lt;br /&gt;
https://learn.adafruit.com/micropython-basics-load-files-and-run-code/install-ampy&lt;br /&gt;
&lt;br /&gt;
Per installarlo usare pip (o pip3):&lt;br /&gt;
 pip install adafruit-ampy&lt;br /&gt;
&lt;br /&gt;
Per usarlo:&lt;br /&gt;
 ampy -p &amp;lt;porta seriale&amp;gt; put &amp;lt;nome file&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Display OLED I²C =&lt;br /&gt;
&lt;br /&gt;
Per testare il funzionamento di MicroPython, proviamo a usare un piccolo display OLED I²C.&lt;br /&gt;
&lt;br /&gt;
== Caricare la libreria ==&lt;br /&gt;
&lt;br /&gt;
Con ampy carichiamo la [https://github.com/micropython/micropython/blob/master/drivers/display/ssd1306.py libreria ssd1306].&lt;br /&gt;
&lt;br /&gt;
 ampy -p /dev/ttyACM0 put ssd1306.py &lt;br /&gt;
&lt;br /&gt;
== Manovrare il display da REPL ==&lt;br /&gt;
&lt;br /&gt;
Se la libreria è stata caricata si può importare scrivendo:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import ssd1306&lt;br /&gt;
&lt;br /&gt;
Occorre poi creare un oggetto I2C specificando quali pin usare per SCL e SDA (in teoria dovrebbe essere automatico, ma secondo [https://forum.micropython.org/viewtopic.php?t=4663 questo post sul forum di micropython] l'automatismo non funziona), la libreria machine dovrebbe essere già importata di default:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pscl = machine.Pin('D15',machine.Pin.OUT_PP)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; psda = machine.Pin('D14',machine.Pin.OUT_PP)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; i2c = machine.I2C(scl=pscl,sda=psda)&lt;br /&gt;
&lt;br /&gt;
e poi creare un oggetto che gestisca il display:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled = ssd1306.SSD1306_I2C(128,64,i2c)&lt;br /&gt;
&lt;br /&gt;
dove 128 e 64 sono le dimensioni.&lt;br /&gt;
&lt;br /&gt;
== Test! ==&lt;br /&gt;
&lt;br /&gt;
Per prima cosa occorre cancellare un'eventuale scritta precedente:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled.fill(0)&lt;br /&gt;
&lt;br /&gt;
Poi scriviamo qualcosa, nella posizione x 0, y 0:&lt;br /&gt;
 &lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled.text('qualcosa',0,0)&lt;br /&gt;
&lt;br /&gt;
e infine lo mostriamo:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled.show()&lt;br /&gt;
&lt;br /&gt;
et voilà!&lt;br /&gt;
&lt;br /&gt;
[[File:Micropython_test_oled.jpg]]&lt;br /&gt;
&lt;br /&gt;
Più informazioni su come funziona la libreria, corredata da esempi, le potete trovare sul [https://learn.adafruit.com/micropython-hardware-ssd1306-oled-display/circuitpython sito di Adafruit].&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6838</id>
		<title>Installare MicroPython su NUCLEO-F401RE</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6838"/>
		<updated>2019-03-10T00:18:25Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* Usare MicroPython dal PC */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questa guida è basata quasi tutta su quella di Carmine Noviello https://www.carminenoviello.com/2015/06/03/running-micropyton-stm32nucleo-f4/ che peraltro trovate anche in italiano https://www.carminenoviello.com/it/2015/08/11/compilare-micropython-una-scheda-stm32nucleo-f4/ per cui scriverò solo le differenze.&lt;br /&gt;
&lt;br /&gt;
La versione di Carmine di micropython, che si trova sul suo [https://github.com/cnoviello/micropython github], risolve il problema relativo alla mancanza di memoria SD della scheda Nucleo. Il file con il programma .py sarà caricato direttamente sulla flash.&lt;br /&gt;
&lt;br /&gt;
= La scheda =&lt;br /&gt;
&lt;br /&gt;
NUCLEO-F401RE della STMicroelectronics è una scheda basata su ARM Cortex M4 e fa parte della famiglia STM32 Nucleo Boards. Ha 512KB di Flash, 96 KB di SRAM, un clock di 84MHz, 50 GPIO, RTC, supporto I²C, SPI, USART e molto altro ([https://os.mbed.com/platforms/ST-Nucleo-F401RE/ maggiori info]). La sua forma le permette di alloggiare sia gli shield per Arduino che le estensioni Morpho di STMicroelectronics.&lt;br /&gt;
Il prezzo è abbastanza contenuto (attorno ai 12€ su Mouser) il che ne fa una scheda piuttosto interessante.&lt;br /&gt;
&lt;br /&gt;
Normalmente si programmerebbe tramite l'[https://ide.mbed.com/compiler editor online di Mbed]. Il compilatore genererà dal nostro codice un file con estensione bin. Collegando la scheda verrà montato un volume, chiamato &amp;quot;NUCLEO&amp;quot; sul quale caricare il file bin. Quando la scheda verrà resettata, il codice verrà eseguito. È possibile anche usare editor offline con toolchain di compilazione come Eclipse.&lt;br /&gt;
&lt;br /&gt;
= Installazione MicroPython =&lt;br /&gt;
&lt;br /&gt;
== Primo tentativo ==&lt;br /&gt;
&lt;br /&gt;
=== Toolchain e OpenOCD ===&lt;br /&gt;
&lt;br /&gt;
Per compilare vi servirà la toolchain gcc-arm-embedded. Non è nei repo ufficiali quindi la dovete installare a mano oppure aggiungere un PPA. https://launchpad.net/gcc-arm-embedded&lt;br /&gt;
Il programma per comunicare col debugger della scheda, openocd, invece è nei repo di Debian.&lt;br /&gt;
 &lt;br /&gt;
=== Come installare MicroPython ===&lt;br /&gt;
&lt;br /&gt;
Potete seguire la [https://www.carminenoviello.com/it/2015/08/11/compilare-micropython-una-scheda-stm32nucleo-f4/ guida di Carmine Noviello] per la compilazione. Ovviamente se avete installato la toolchain con apt non è necessario aggiungere il path a tutti i comandi, perché sono già dentro a /usr/bin.&lt;br /&gt;
&lt;br /&gt;
OpenOCD ci permette di caricare il firmware che abbiamo crosscompilato. Basterà lanciare il comando:&lt;br /&gt;
 $ openocd  -f board/st_nucleo_f4.cfg&lt;br /&gt;
Un LED della scheda dovrebbe lampeggiare rosso/verde. Il debugger è attivo. Per collegarcisi:&lt;br /&gt;
 $ telnet localhost 4444&lt;br /&gt;
e poi scrivete:&lt;br /&gt;
 &amp;gt; reset halt&lt;br /&gt;
e infine:&lt;br /&gt;
 &amp;gt; flash write_image erase &amp;lt;file .elf da flashare&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inizialmente non sembrava funzionare. Il tentativo finale che ha sbloccato la situazione è stato dare il comando shutdown. Non sono sicuro però che sia stato proprio quel comando e bisognerebbe indagare meglio.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dall'interprete ===&lt;br /&gt;
&lt;br /&gt;
Aprendo la porta della nostra scheda (la trovate su dmesg non appena la attaccate, è /dev/ttyACMx dove x è un numero che parte da 0) con un emulatore di terminale (come screen, picocom o minicom) alla velocità di 115200 baud, dovreste vedere l'interprete dei comandi (REPL, ovvero Read, Eval, Print and Loop) di MicroPython. Provate a dare il comando:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pyb.LED(1).on()&lt;br /&gt;
per vedere se si accende il LED onboard.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dal PC ===&lt;br /&gt;
&lt;br /&gt;
Fra i tool di MicroPython, che trovate nella cartella di git micropython/tools, c'è pyboard.py, un programma che vi permette di eseguire uno script in MicroPython. Se la vostra porta non è accessibile dall'utente dovrete usare sudo.&lt;br /&gt;
 # ./pyboard.py --device=/dev/ttyACMx &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Carmine ha fatto una modifica a pyboard in modo che possa caricare un file sulla board.&lt;br /&gt;
 # ./pyboard.py --device=/dev/ttyACMx --send &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
MicroPython ha due file di default quando viene installato: boot.py e main.py. Il primo è un file di sistema che serve allo stesso MicroPython di partire. Non occorre di solito modificarlo. Il secondo, main.py, è uno script che viene eseguito all'avvio. Se carichiamo un file main.py questo verrà eseguito all'accensione.&lt;br /&gt;
&lt;br /&gt;
=== Considerazioni finali ===&lt;br /&gt;
&lt;br /&gt;
Molto bene, ma la versione di micropython non è aggiornata. Forse è per questo che non riesco a far funzionare la porta I²C?&lt;br /&gt;
&lt;br /&gt;
== Secondo tentativo ==&lt;br /&gt;
&lt;br /&gt;
Boochow fornisce dei firmware già compilati su https://blog.boochow.com/micropython-firmware-for-mbed-boards basta scegliere la board giusta e caricare il file .bin nel volume &amp;quot;NUCLEO&amp;quot; che si monta quando si collega la USB.&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Un modo piuttosto comodo di inviare e ricevere file sulla flash della Nucleo è usare uPyLoader:&lt;br /&gt;
https://github.com/BetaRavener/uPyLoader/&lt;br /&gt;
ma quasi sempre dà un errore di timeout.&lt;br /&gt;
&lt;br /&gt;
Il programma fornito da Adafruit sembra funzionare decisamente meglio&lt;br /&gt;
https://learn.adafruit.com/micropython-basics-load-files-and-run-code/install-ampy&lt;br /&gt;
&lt;br /&gt;
Per installarlo usare pip (o pip3):&lt;br /&gt;
 pip install adafruit-ampy&lt;br /&gt;
&lt;br /&gt;
Per usarlo:&lt;br /&gt;
 ampy -p &amp;lt;porta seriale&amp;gt; put &amp;lt;nome file&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Display OLED I²C =&lt;br /&gt;
&lt;br /&gt;
Per testare il funzionamento di MicroPython, proviamo a usare un piccolo display OLED I²C.&lt;br /&gt;
&lt;br /&gt;
== Caricare la libreria ==&lt;br /&gt;
&lt;br /&gt;
Con ampy carichiamo la [https://github.com/micropython/micropython/blob/master/drivers/display/ssd1306.py libreria ssd1306].&lt;br /&gt;
&lt;br /&gt;
 ampy -p /dev/ttyACM0 put ssd1306.py &lt;br /&gt;
&lt;br /&gt;
== Manovrare il display da REPL ==&lt;br /&gt;
&lt;br /&gt;
Se la libreria è stata caricata si può importare scrivendo:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import ssd1306&lt;br /&gt;
&lt;br /&gt;
Occorre poi creare un oggetto I2C specificando quali pin usare per SCL e SDA (in teoria dovrebbe essere automatico, ma secondo [https://forum.micropython.org/viewtopic.php?t=4663 questo post sul forum di micropython] l'automatismo non funziona), la libreria machine dovrebbe essere già importata di default:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pscl = machine.Pin('D15',machine.Pin.OUT_PP)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; psda = machine.Pin('D14',machine.Pin.OUT_PP)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; i2c = machine.I2C(scl=pscl,sda=psda)&lt;br /&gt;
&lt;br /&gt;
e poi creare un oggetto che gestisca il display:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled = ssd1306.SSD1306_I2C(128,64,i2c)&lt;br /&gt;
&lt;br /&gt;
dove 128 e 64 sono le dimensioni.&lt;br /&gt;
&lt;br /&gt;
== Test! ==&lt;br /&gt;
&lt;br /&gt;
Per prima cosa occorre cancellare un'eventuale scritta precedente:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled.fill(0)&lt;br /&gt;
&lt;br /&gt;
Poi scriviamo qualcosa:&lt;br /&gt;
 &lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled.text('qualcosa',0,0)&lt;br /&gt;
&lt;br /&gt;
e infine lo mostriamo:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled.show()&lt;br /&gt;
&lt;br /&gt;
et voilà!&lt;br /&gt;
&lt;br /&gt;
[[File:Micropython_test_oled.jpg]]&lt;br /&gt;
&lt;br /&gt;
Più informazioni su come funziona la libreria, corredata da esempi, le potete trovare sul [https://learn.adafruit.com/micropython-hardware-ssd1306-oled-display/circuitpython sito di Adafruit].&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6837</id>
		<title>Installare MicroPython su NUCLEO-F401RE</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6837"/>
		<updated>2019-03-10T00:17:11Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* Usare MicroPython dall'interprete */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questa guida è basata quasi tutta su quella di Carmine Noviello https://www.carminenoviello.com/2015/06/03/running-micropyton-stm32nucleo-f4/ che peraltro trovate anche in italiano https://www.carminenoviello.com/it/2015/08/11/compilare-micropython-una-scheda-stm32nucleo-f4/ per cui scriverò solo le differenze.&lt;br /&gt;
&lt;br /&gt;
La versione di Carmine di micropython, che si trova sul suo [https://github.com/cnoviello/micropython github], risolve il problema relativo alla mancanza di memoria SD della scheda Nucleo. Il file con il programma .py sarà caricato direttamente sulla flash.&lt;br /&gt;
&lt;br /&gt;
= La scheda =&lt;br /&gt;
&lt;br /&gt;
NUCLEO-F401RE della STMicroelectronics è una scheda basata su ARM Cortex M4 e fa parte della famiglia STM32 Nucleo Boards. Ha 512KB di Flash, 96 KB di SRAM, un clock di 84MHz, 50 GPIO, RTC, supporto I²C, SPI, USART e molto altro ([https://os.mbed.com/platforms/ST-Nucleo-F401RE/ maggiori info]). La sua forma le permette di alloggiare sia gli shield per Arduino che le estensioni Morpho di STMicroelectronics.&lt;br /&gt;
Il prezzo è abbastanza contenuto (attorno ai 12€ su Mouser) il che ne fa una scheda piuttosto interessante.&lt;br /&gt;
&lt;br /&gt;
Normalmente si programmerebbe tramite l'[https://ide.mbed.com/compiler editor online di Mbed]. Il compilatore genererà dal nostro codice un file con estensione bin. Collegando la scheda verrà montato un volume, chiamato &amp;quot;NUCLEO&amp;quot; sul quale caricare il file bin. Quando la scheda verrà resettata, il codice verrà eseguito. È possibile anche usare editor offline con toolchain di compilazione come Eclipse.&lt;br /&gt;
&lt;br /&gt;
= Installazione MicroPython =&lt;br /&gt;
&lt;br /&gt;
== Primo tentativo ==&lt;br /&gt;
&lt;br /&gt;
=== Toolchain e OpenOCD ===&lt;br /&gt;
&lt;br /&gt;
Per compilare vi servirà la toolchain gcc-arm-embedded. Non è nei repo ufficiali quindi la dovete installare a mano oppure aggiungere un PPA. https://launchpad.net/gcc-arm-embedded&lt;br /&gt;
Il programma per comunicare col debugger della scheda, openocd, invece è nei repo di Debian.&lt;br /&gt;
 &lt;br /&gt;
=== Come installare MicroPython ===&lt;br /&gt;
&lt;br /&gt;
Potete seguire la [https://www.carminenoviello.com/it/2015/08/11/compilare-micropython-una-scheda-stm32nucleo-f4/ guida di Carmine Noviello] per la compilazione. Ovviamente se avete installato la toolchain con apt non è necessario aggiungere il path a tutti i comandi, perché sono già dentro a /usr/bin.&lt;br /&gt;
&lt;br /&gt;
OpenOCD ci permette di caricare il firmware che abbiamo crosscompilato. Basterà lanciare il comando:&lt;br /&gt;
 $ openocd  -f board/st_nucleo_f4.cfg&lt;br /&gt;
Un LED della scheda dovrebbe lampeggiare rosso/verde. Il debugger è attivo. Per collegarcisi:&lt;br /&gt;
 $ telnet localhost 4444&lt;br /&gt;
e poi scrivete:&lt;br /&gt;
 &amp;gt; reset halt&lt;br /&gt;
e infine:&lt;br /&gt;
 &amp;gt; flash write_image erase &amp;lt;file .elf da flashare&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inizialmente non sembrava funzionare. Il tentativo finale che ha sbloccato la situazione è stato dare il comando shutdown. Non sono sicuro però che sia stato proprio quel comando e bisognerebbe indagare meglio.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dall'interprete ===&lt;br /&gt;
&lt;br /&gt;
Aprendo la porta della nostra scheda (la trovate su dmesg non appena la attaccate, è /dev/ttyACMx dove x è un numero che parte da 0) con un emulatore di terminale (come screen, picocom o minicom) alla velocità di 115200 baud, dovreste vedere l'interprete dei comandi (REPL, ovvero Read, Eval, Print and Loop) di MicroPython. Provate a dare il comando:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pyb.LED(1).on()&lt;br /&gt;
per vedere se si accende il LED onboard.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dal PC ===&lt;br /&gt;
&lt;br /&gt;
Fra i tool di MicroPython, che trovate nella cartella di git micropython/tools, c'è pyboard.py, un programma che vi permette di eseguire uno script in MicroPython. Se la vostra porta non è accessibile dall'utente dovrete usare sudo.&lt;br /&gt;
 # ./pyboard.py &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Carmine ha fatto una modifica a pyboard in modo che possa caricare un file sulla board.&lt;br /&gt;
 # ./pyboard.py --device=/dev/ttyACMx --send &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
MicroPython ha due file di default quando viene installato: boot.py e main.py. Il primo è un file di sistema che serve allo stesso MicroPython di partire. Non occorre di solito modificarlo. Il secondo, main.py, è uno script che viene eseguito all'avvio. Se carichiamo un file main.py questo verrà eseguito all'accensione.&lt;br /&gt;
&lt;br /&gt;
=== Considerazioni finali ===&lt;br /&gt;
&lt;br /&gt;
Molto bene, ma la versione di micropython non è aggiornata. Forse è per questo che non riesco a far funzionare la porta I²C?&lt;br /&gt;
&lt;br /&gt;
== Secondo tentativo ==&lt;br /&gt;
&lt;br /&gt;
Boochow fornisce dei firmware già compilati su https://blog.boochow.com/micropython-firmware-for-mbed-boards basta scegliere la board giusta e caricare il file .bin nel volume &amp;quot;NUCLEO&amp;quot; che si monta quando si collega la USB.&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Un modo piuttosto comodo di inviare e ricevere file sulla flash della Nucleo è usare uPyLoader:&lt;br /&gt;
https://github.com/BetaRavener/uPyLoader/&lt;br /&gt;
ma quasi sempre dà un errore di timeout.&lt;br /&gt;
&lt;br /&gt;
Il programma fornito da Adafruit sembra funzionare decisamente meglio&lt;br /&gt;
https://learn.adafruit.com/micropython-basics-load-files-and-run-code/install-ampy&lt;br /&gt;
&lt;br /&gt;
Per installarlo usare pip (o pip3):&lt;br /&gt;
 pip install adafruit-ampy&lt;br /&gt;
&lt;br /&gt;
Per usarlo:&lt;br /&gt;
 ampy -p &amp;lt;porta seriale&amp;gt; put &amp;lt;nome file&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Display OLED I²C =&lt;br /&gt;
&lt;br /&gt;
Per testare il funzionamento di MicroPython, proviamo a usare un piccolo display OLED I²C.&lt;br /&gt;
&lt;br /&gt;
== Caricare la libreria ==&lt;br /&gt;
&lt;br /&gt;
Con ampy carichiamo la [https://github.com/micropython/micropython/blob/master/drivers/display/ssd1306.py libreria ssd1306].&lt;br /&gt;
&lt;br /&gt;
 ampy -p /dev/ttyACM0 put ssd1306.py &lt;br /&gt;
&lt;br /&gt;
== Manovrare il display da REPL ==&lt;br /&gt;
&lt;br /&gt;
Se la libreria è stata caricata si può importare scrivendo:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import ssd1306&lt;br /&gt;
&lt;br /&gt;
Occorre poi creare un oggetto I2C specificando quali pin usare per SCL e SDA (in teoria dovrebbe essere automatico, ma secondo [https://forum.micropython.org/viewtopic.php?t=4663 questo post sul forum di micropython] l'automatismo non funziona), la libreria machine dovrebbe essere già importata di default:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pscl = machine.Pin('D15',machine.Pin.OUT_PP)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; psda = machine.Pin('D14',machine.Pin.OUT_PP)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; i2c = machine.I2C(scl=pscl,sda=psda)&lt;br /&gt;
&lt;br /&gt;
e poi creare un oggetto che gestisca il display:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled = ssd1306.SSD1306_I2C(128,64,i2c)&lt;br /&gt;
&lt;br /&gt;
dove 128 e 64 sono le dimensioni.&lt;br /&gt;
&lt;br /&gt;
== Test! ==&lt;br /&gt;
&lt;br /&gt;
Per prima cosa occorre cancellare un'eventuale scritta precedente:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled.fill(0)&lt;br /&gt;
&lt;br /&gt;
Poi scriviamo qualcosa:&lt;br /&gt;
 &lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled.text('qualcosa',0,0)&lt;br /&gt;
&lt;br /&gt;
e infine lo mostriamo:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled.show()&lt;br /&gt;
&lt;br /&gt;
et voilà!&lt;br /&gt;
&lt;br /&gt;
[[File:Micropython_test_oled.jpg]]&lt;br /&gt;
&lt;br /&gt;
Più informazioni su come funziona la libreria, corredata da esempi, le potete trovare sul [https://learn.adafruit.com/micropython-hardware-ssd1306-oled-display/circuitpython sito di Adafruit].&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6836</id>
		<title>Installare MicroPython su NUCLEO-F401RE</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6836"/>
		<updated>2019-03-10T00:14:39Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* Come installare MicroPython */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questa guida è basata quasi tutta su quella di Carmine Noviello https://www.carminenoviello.com/2015/06/03/running-micropyton-stm32nucleo-f4/ che peraltro trovate anche in italiano https://www.carminenoviello.com/it/2015/08/11/compilare-micropython-una-scheda-stm32nucleo-f4/ per cui scriverò solo le differenze.&lt;br /&gt;
&lt;br /&gt;
La versione di Carmine di micropython, che si trova sul suo [https://github.com/cnoviello/micropython github], risolve il problema relativo alla mancanza di memoria SD della scheda Nucleo. Il file con il programma .py sarà caricato direttamente sulla flash.&lt;br /&gt;
&lt;br /&gt;
= La scheda =&lt;br /&gt;
&lt;br /&gt;
NUCLEO-F401RE della STMicroelectronics è una scheda basata su ARM Cortex M4 e fa parte della famiglia STM32 Nucleo Boards. Ha 512KB di Flash, 96 KB di SRAM, un clock di 84MHz, 50 GPIO, RTC, supporto I²C, SPI, USART e molto altro ([https://os.mbed.com/platforms/ST-Nucleo-F401RE/ maggiori info]). La sua forma le permette di alloggiare sia gli shield per Arduino che le estensioni Morpho di STMicroelectronics.&lt;br /&gt;
Il prezzo è abbastanza contenuto (attorno ai 12€ su Mouser) il che ne fa una scheda piuttosto interessante.&lt;br /&gt;
&lt;br /&gt;
Normalmente si programmerebbe tramite l'[https://ide.mbed.com/compiler editor online di Mbed]. Il compilatore genererà dal nostro codice un file con estensione bin. Collegando la scheda verrà montato un volume, chiamato &amp;quot;NUCLEO&amp;quot; sul quale caricare il file bin. Quando la scheda verrà resettata, il codice verrà eseguito. È possibile anche usare editor offline con toolchain di compilazione come Eclipse.&lt;br /&gt;
&lt;br /&gt;
= Installazione MicroPython =&lt;br /&gt;
&lt;br /&gt;
== Primo tentativo ==&lt;br /&gt;
&lt;br /&gt;
=== Toolchain e OpenOCD ===&lt;br /&gt;
&lt;br /&gt;
Per compilare vi servirà la toolchain gcc-arm-embedded. Non è nei repo ufficiali quindi la dovete installare a mano oppure aggiungere un PPA. https://launchpad.net/gcc-arm-embedded&lt;br /&gt;
Il programma per comunicare col debugger della scheda, openocd, invece è nei repo di Debian.&lt;br /&gt;
 &lt;br /&gt;
=== Come installare MicroPython ===&lt;br /&gt;
&lt;br /&gt;
Potete seguire la [https://www.carminenoviello.com/it/2015/08/11/compilare-micropython-una-scheda-stm32nucleo-f4/ guida di Carmine Noviello] per la compilazione. Ovviamente se avete installato la toolchain con apt non è necessario aggiungere il path a tutti i comandi, perché sono già dentro a /usr/bin.&lt;br /&gt;
&lt;br /&gt;
OpenOCD ci permette di caricare il firmware che abbiamo crosscompilato. Basterà lanciare il comando:&lt;br /&gt;
 $ openocd  -f board/st_nucleo_f4.cfg&lt;br /&gt;
Un LED della scheda dovrebbe lampeggiare rosso/verde. Il debugger è attivo. Per collegarcisi:&lt;br /&gt;
 $ telnet localhost 4444&lt;br /&gt;
e poi scrivete:&lt;br /&gt;
 &amp;gt; reset halt&lt;br /&gt;
e infine:&lt;br /&gt;
 &amp;gt; flash write_image erase &amp;lt;file .elf da flashare&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inizialmente non sembrava funzionare. Il tentativo finale che ha sbloccato la situazione è stato dare il comando shutdown. Non sono sicuro però che sia stato proprio quel comando e bisognerebbe indagare meglio.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dall'interprete ===&lt;br /&gt;
&lt;br /&gt;
Aprendo la porta della nostra scheda (la trovate su dmesg non appena la attaccate, è /dev/ttyACMx dove x è un numero che parte da 0) con un emulatore di terminale (come console) alla velocità di 115200 baud, dovreste vedere l'interprete dei comandi (REPL, ovvero Read, Eval, Print and Loop) di MicroPython. Provate a dare il comando:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pyb.LED(1).on()&lt;br /&gt;
per vedere se si accende il LED onboard.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dal PC ===&lt;br /&gt;
&lt;br /&gt;
Fra i tool di MicroPython, che trovate nella cartella di git micropython/tools, c'è pyboard.py, un programma che vi permette di eseguire uno script in MicroPython. Se la vostra porta non è accessibile dall'utente dovrete usare sudo.&lt;br /&gt;
 # ./pyboard.py &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Carmine ha fatto una modifica a pyboard in modo che possa caricare un file sulla board.&lt;br /&gt;
 # ./pyboard.py --device=/dev/ttyACMx --send &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
MicroPython ha due file di default quando viene installato: boot.py e main.py. Il primo è un file di sistema che serve allo stesso MicroPython di partire. Non occorre di solito modificarlo. Il secondo, main.py, è uno script che viene eseguito all'avvio. Se carichiamo un file main.py questo verrà eseguito all'accensione.&lt;br /&gt;
&lt;br /&gt;
=== Considerazioni finali ===&lt;br /&gt;
&lt;br /&gt;
Molto bene, ma la versione di micropython non è aggiornata. Forse è per questo che non riesco a far funzionare la porta I²C?&lt;br /&gt;
&lt;br /&gt;
== Secondo tentativo ==&lt;br /&gt;
&lt;br /&gt;
Boochow fornisce dei firmware già compilati su https://blog.boochow.com/micropython-firmware-for-mbed-boards basta scegliere la board giusta e caricare il file .bin nel volume &amp;quot;NUCLEO&amp;quot; che si monta quando si collega la USB.&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Un modo piuttosto comodo di inviare e ricevere file sulla flash della Nucleo è usare uPyLoader:&lt;br /&gt;
https://github.com/BetaRavener/uPyLoader/&lt;br /&gt;
ma quasi sempre dà un errore di timeout.&lt;br /&gt;
&lt;br /&gt;
Il programma fornito da Adafruit sembra funzionare decisamente meglio&lt;br /&gt;
https://learn.adafruit.com/micropython-basics-load-files-and-run-code/install-ampy&lt;br /&gt;
&lt;br /&gt;
Per installarlo usare pip (o pip3):&lt;br /&gt;
 pip install adafruit-ampy&lt;br /&gt;
&lt;br /&gt;
Per usarlo:&lt;br /&gt;
 ampy -p &amp;lt;porta seriale&amp;gt; put &amp;lt;nome file&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Display OLED I²C =&lt;br /&gt;
&lt;br /&gt;
Per testare il funzionamento di MicroPython, proviamo a usare un piccolo display OLED I²C.&lt;br /&gt;
&lt;br /&gt;
== Caricare la libreria ==&lt;br /&gt;
&lt;br /&gt;
Con ampy carichiamo la [https://github.com/micropython/micropython/blob/master/drivers/display/ssd1306.py libreria ssd1306].&lt;br /&gt;
&lt;br /&gt;
 ampy -p /dev/ttyACM0 put ssd1306.py &lt;br /&gt;
&lt;br /&gt;
== Manovrare il display da REPL ==&lt;br /&gt;
&lt;br /&gt;
Se la libreria è stata caricata si può importare scrivendo:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import ssd1306&lt;br /&gt;
&lt;br /&gt;
Occorre poi creare un oggetto I2C specificando quali pin usare per SCL e SDA (in teoria dovrebbe essere automatico, ma secondo [https://forum.micropython.org/viewtopic.php?t=4663 questo post sul forum di micropython] l'automatismo non funziona), la libreria machine dovrebbe essere già importata di default:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pscl = machine.Pin('D15',machine.Pin.OUT_PP)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; psda = machine.Pin('D14',machine.Pin.OUT_PP)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; i2c = machine.I2C(scl=pscl,sda=psda)&lt;br /&gt;
&lt;br /&gt;
e poi creare un oggetto che gestisca il display:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled = ssd1306.SSD1306_I2C(128,64,i2c)&lt;br /&gt;
&lt;br /&gt;
dove 128 e 64 sono le dimensioni.&lt;br /&gt;
&lt;br /&gt;
== Test! ==&lt;br /&gt;
&lt;br /&gt;
Per prima cosa occorre cancellare un'eventuale scritta precedente:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled.fill(0)&lt;br /&gt;
&lt;br /&gt;
Poi scriviamo qualcosa:&lt;br /&gt;
 &lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled.text('qualcosa',0,0)&lt;br /&gt;
&lt;br /&gt;
e infine lo mostriamo:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled.show()&lt;br /&gt;
&lt;br /&gt;
et voilà!&lt;br /&gt;
&lt;br /&gt;
[[File:Micropython_test_oled.jpg]]&lt;br /&gt;
&lt;br /&gt;
Più informazioni su come funziona la libreria, corredata da esempi, le potete trovare sul [https://learn.adafruit.com/micropython-hardware-ssd1306-oled-display/circuitpython sito di Adafruit].&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6835</id>
		<title>Installare MicroPython su NUCLEO-F401RE</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6835"/>
		<updated>2019-03-10T00:13:27Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* La scheda */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questa guida è basata quasi tutta su quella di Carmine Noviello https://www.carminenoviello.com/2015/06/03/running-micropyton-stm32nucleo-f4/ che peraltro trovate anche in italiano https://www.carminenoviello.com/it/2015/08/11/compilare-micropython-una-scheda-stm32nucleo-f4/ per cui scriverò solo le differenze.&lt;br /&gt;
&lt;br /&gt;
La versione di Carmine di micropython, che si trova sul suo [https://github.com/cnoviello/micropython github], risolve il problema relativo alla mancanza di memoria SD della scheda Nucleo. Il file con il programma .py sarà caricato direttamente sulla flash.&lt;br /&gt;
&lt;br /&gt;
= La scheda =&lt;br /&gt;
&lt;br /&gt;
NUCLEO-F401RE della STMicroelectronics è una scheda basata su ARM Cortex M4 e fa parte della famiglia STM32 Nucleo Boards. Ha 512KB di Flash, 96 KB di SRAM, un clock di 84MHz, 50 GPIO, RTC, supporto I²C, SPI, USART e molto altro ([https://os.mbed.com/platforms/ST-Nucleo-F401RE/ maggiori info]). La sua forma le permette di alloggiare sia gli shield per Arduino che le estensioni Morpho di STMicroelectronics.&lt;br /&gt;
Il prezzo è abbastanza contenuto (attorno ai 12€ su Mouser) il che ne fa una scheda piuttosto interessante.&lt;br /&gt;
&lt;br /&gt;
Normalmente si programmerebbe tramite l'[https://ide.mbed.com/compiler editor online di Mbed]. Il compilatore genererà dal nostro codice un file con estensione bin. Collegando la scheda verrà montato un volume, chiamato &amp;quot;NUCLEO&amp;quot; sul quale caricare il file bin. Quando la scheda verrà resettata, il codice verrà eseguito. È possibile anche usare editor offline con toolchain di compilazione come Eclipse.&lt;br /&gt;
&lt;br /&gt;
= Installazione MicroPython =&lt;br /&gt;
&lt;br /&gt;
== Primo tentativo ==&lt;br /&gt;
&lt;br /&gt;
=== Toolchain e OpenOCD ===&lt;br /&gt;
&lt;br /&gt;
Per compilare vi servirà la toolchain gcc-arm-embedded. Non è nei repo ufficiali quindi la dovete installare a mano oppure aggiungere un PPA. https://launchpad.net/gcc-arm-embedded&lt;br /&gt;
Il programma per comunicare col debugger della scheda, openocd, invece è nei repo di Debian.&lt;br /&gt;
 &lt;br /&gt;
=== Come installare MicroPython ===&lt;br /&gt;
&lt;br /&gt;
Potete seguire la guida di Carmine per la compilazione. Ovviamente se avete installato la toolchain con apt non è necessario aggiungere il path a tutti i comandi, perché sono già dentro a /usr/bin.&lt;br /&gt;
&lt;br /&gt;
OpenOCD ci permette di caricare il firmware che abbiamo crosscompilato. Basterà lanciare il comando:&lt;br /&gt;
 $ openocd  -f board/st_nucleo_f4.cfg&lt;br /&gt;
Un LED della scheda dovrebbe lampeggiare rosso/verde. Il debugger è attivo. Per collegarcisi:&lt;br /&gt;
 $ telnet localhost 4444&lt;br /&gt;
e poi scrivete:&lt;br /&gt;
 &amp;gt; reset halt&lt;br /&gt;
e infine:&lt;br /&gt;
 &amp;gt; flash write_image erase &amp;lt;file .elf da flashare&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inizialmente non sembrava funzionare. Il tentativo finale che ha sbloccato la situazione è stato dare il comando shutdown. Non sono sicuro però che sia stato proprio quel comando e bisognerebbe indagare meglio.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dall'interprete ===&lt;br /&gt;
&lt;br /&gt;
Aprendo la porta della nostra scheda (la trovate su dmesg non appena la attaccate, è /dev/ttyACMx dove x è un numero che parte da 0) con un emulatore di terminale (come console) alla velocità di 115200 baud, dovreste vedere l'interprete dei comandi (REPL, ovvero Read, Eval, Print and Loop) di MicroPython. Provate a dare il comando:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pyb.LED(1).on()&lt;br /&gt;
per vedere se si accende il LED onboard.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dal PC ===&lt;br /&gt;
&lt;br /&gt;
Fra i tool di MicroPython, che trovate nella cartella di git micropython/tools, c'è pyboard.py, un programma che vi permette di eseguire uno script in MicroPython. Se la vostra porta non è accessibile dall'utente dovrete usare sudo.&lt;br /&gt;
 # ./pyboard.py &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Carmine ha fatto una modifica a pyboard in modo che possa caricare un file sulla board.&lt;br /&gt;
 # ./pyboard.py --device=/dev/ttyACMx --send &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
MicroPython ha due file di default quando viene installato: boot.py e main.py. Il primo è un file di sistema che serve allo stesso MicroPython di partire. Non occorre di solito modificarlo. Il secondo, main.py, è uno script che viene eseguito all'avvio. Se carichiamo un file main.py questo verrà eseguito all'accensione.&lt;br /&gt;
&lt;br /&gt;
=== Considerazioni finali ===&lt;br /&gt;
&lt;br /&gt;
Molto bene, ma la versione di micropython non è aggiornata. Forse è per questo che non riesco a far funzionare la porta I²C?&lt;br /&gt;
&lt;br /&gt;
== Secondo tentativo ==&lt;br /&gt;
&lt;br /&gt;
Boochow fornisce dei firmware già compilati su https://blog.boochow.com/micropython-firmware-for-mbed-boards basta scegliere la board giusta e caricare il file .bin nel volume &amp;quot;NUCLEO&amp;quot; che si monta quando si collega la USB.&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Un modo piuttosto comodo di inviare e ricevere file sulla flash della Nucleo è usare uPyLoader:&lt;br /&gt;
https://github.com/BetaRavener/uPyLoader/&lt;br /&gt;
ma quasi sempre dà un errore di timeout.&lt;br /&gt;
&lt;br /&gt;
Il programma fornito da Adafruit sembra funzionare decisamente meglio&lt;br /&gt;
https://learn.adafruit.com/micropython-basics-load-files-and-run-code/install-ampy&lt;br /&gt;
&lt;br /&gt;
Per installarlo usare pip (o pip3):&lt;br /&gt;
 pip install adafruit-ampy&lt;br /&gt;
&lt;br /&gt;
Per usarlo:&lt;br /&gt;
 ampy -p &amp;lt;porta seriale&amp;gt; put &amp;lt;nome file&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Display OLED I²C =&lt;br /&gt;
&lt;br /&gt;
Per testare il funzionamento di MicroPython, proviamo a usare un piccolo display OLED I²C.&lt;br /&gt;
&lt;br /&gt;
== Caricare la libreria ==&lt;br /&gt;
&lt;br /&gt;
Con ampy carichiamo la [https://github.com/micropython/micropython/blob/master/drivers/display/ssd1306.py libreria ssd1306].&lt;br /&gt;
&lt;br /&gt;
 ampy -p /dev/ttyACM0 put ssd1306.py &lt;br /&gt;
&lt;br /&gt;
== Manovrare il display da REPL ==&lt;br /&gt;
&lt;br /&gt;
Se la libreria è stata caricata si può importare scrivendo:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import ssd1306&lt;br /&gt;
&lt;br /&gt;
Occorre poi creare un oggetto I2C specificando quali pin usare per SCL e SDA (in teoria dovrebbe essere automatico, ma secondo [https://forum.micropython.org/viewtopic.php?t=4663 questo post sul forum di micropython] l'automatismo non funziona), la libreria machine dovrebbe essere già importata di default:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pscl = machine.Pin('D15',machine.Pin.OUT_PP)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; psda = machine.Pin('D14',machine.Pin.OUT_PP)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; i2c = machine.I2C(scl=pscl,sda=psda)&lt;br /&gt;
&lt;br /&gt;
e poi creare un oggetto che gestisca il display:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled = ssd1306.SSD1306_I2C(128,64,i2c)&lt;br /&gt;
&lt;br /&gt;
dove 128 e 64 sono le dimensioni.&lt;br /&gt;
&lt;br /&gt;
== Test! ==&lt;br /&gt;
&lt;br /&gt;
Per prima cosa occorre cancellare un'eventuale scritta precedente:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled.fill(0)&lt;br /&gt;
&lt;br /&gt;
Poi scriviamo qualcosa:&lt;br /&gt;
 &lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled.text('qualcosa',0,0)&lt;br /&gt;
&lt;br /&gt;
e infine lo mostriamo:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled.show()&lt;br /&gt;
&lt;br /&gt;
et voilà!&lt;br /&gt;
&lt;br /&gt;
[[File:Micropython_test_oled.jpg]]&lt;br /&gt;
&lt;br /&gt;
Più informazioni su come funziona la libreria, corredata da esempi, le potete trovare sul [https://learn.adafruit.com/micropython-hardware-ssd1306-oled-display/circuitpython sito di Adafruit].&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6834</id>
		<title>Installare MicroPython su NUCLEO-F401RE</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6834"/>
		<updated>2019-03-09T17:03:00Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* Test! */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questa guida è basata quasi tutta su quella di Carmine Noviello https://www.carminenoviello.com/2015/06/03/running-micropyton-stm32nucleo-f4/ che peraltro trovate anche in italiano https://www.carminenoviello.com/it/2015/08/11/compilare-micropython-una-scheda-stm32nucleo-f4/ per cui scriverò solo le differenze.&lt;br /&gt;
&lt;br /&gt;
La versione di Carmine di micropython, che si trova sul suo [https://github.com/cnoviello/micropython github], risolve il problema relativo alla mancanza di memoria SD della scheda Nucleo. Il file con il programma .py sarà caricato direttamente sulla flash.&lt;br /&gt;
&lt;br /&gt;
= La scheda =&lt;br /&gt;
&lt;br /&gt;
NUCLEO-F401RE della STMicroelectronics è una scheda basata su ARM Cortex M4 e fa parte della famiglia STM32 Nucleo Boards. Ha 512KB di Flash, 96 KB di SRAM, un clock di 84MHz, 50 GPIO, RTC, supporto I²C, SPI, USART e molto altro ([https://os.mbed.com/platforms/ST-Nucleo-F401RE/ maggiori info]). La sua forma le permette di alloggiare sia gli shield per Arduino che le estensioni Morpho di STMicroelectronics.&lt;br /&gt;
Il prezzo è abbastanza contenuto (attorno ai 12€ su Mouser) il che ne fa una scheda piuttosto interessante.&lt;br /&gt;
&lt;br /&gt;
Normalmente si programmerebbe tramite l'[https://ide.mbed.com/compiler editor online di Mbed]. Il compilatore genererà dal nostro codice un file con estensione bin. Collegando la scheda verrà montato un volume, chiamato &amp;quot;NUCLEO&amp;quot; sul quale caricare il file bin. Quando la scheda verrà resettata, il codice verrà eseguito. È possibile anche usare editor offline con toolchain di compilazione come Eclipse. Non credo sia possibile usare la IDE di Arduino.&lt;br /&gt;
&lt;br /&gt;
= Installazione MicroPython =&lt;br /&gt;
&lt;br /&gt;
== Primo tentativo ==&lt;br /&gt;
&lt;br /&gt;
=== Toolchain e OpenOCD ===&lt;br /&gt;
&lt;br /&gt;
Per compilare vi servirà la toolchain gcc-arm-embedded. Non è nei repo ufficiali quindi la dovete installare a mano oppure aggiungere un PPA. https://launchpad.net/gcc-arm-embedded&lt;br /&gt;
Il programma per comunicare col debugger della scheda, openocd, invece è nei repo di Debian.&lt;br /&gt;
 &lt;br /&gt;
=== Come installare MicroPython ===&lt;br /&gt;
&lt;br /&gt;
Potete seguire la guida di Carmine per la compilazione. Ovviamente se avete installato la toolchain con apt non è necessario aggiungere il path a tutti i comandi, perché sono già dentro a /usr/bin.&lt;br /&gt;
&lt;br /&gt;
OpenOCD ci permette di caricare il firmware che abbiamo crosscompilato. Basterà lanciare il comando:&lt;br /&gt;
 $ openocd  -f board/st_nucleo_f4.cfg&lt;br /&gt;
Un LED della scheda dovrebbe lampeggiare rosso/verde. Il debugger è attivo. Per collegarcisi:&lt;br /&gt;
 $ telnet localhost 4444&lt;br /&gt;
e poi scrivete:&lt;br /&gt;
 &amp;gt; reset halt&lt;br /&gt;
e infine:&lt;br /&gt;
 &amp;gt; flash write_image erase &amp;lt;file .elf da flashare&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inizialmente non sembrava funzionare. Il tentativo finale che ha sbloccato la situazione è stato dare il comando shutdown. Non sono sicuro però che sia stato proprio quel comando e bisognerebbe indagare meglio.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dall'interprete ===&lt;br /&gt;
&lt;br /&gt;
Aprendo la porta della nostra scheda (la trovate su dmesg non appena la attaccate, è /dev/ttyACMx dove x è un numero che parte da 0) con un emulatore di terminale (come console) alla velocità di 115200 baud, dovreste vedere l'interprete dei comandi (REPL, ovvero Read, Eval, Print and Loop) di MicroPython. Provate a dare il comando:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pyb.LED(1).on()&lt;br /&gt;
per vedere se si accende il LED onboard.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dal PC ===&lt;br /&gt;
&lt;br /&gt;
Fra i tool di MicroPython, che trovate nella cartella di git micropython/tools, c'è pyboard.py, un programma che vi permette di eseguire uno script in MicroPython. Se la vostra porta non è accessibile dall'utente dovrete usare sudo.&lt;br /&gt;
 # ./pyboard.py &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Carmine ha fatto una modifica a pyboard in modo che possa caricare un file sulla board.&lt;br /&gt;
 # ./pyboard.py --device=/dev/ttyACMx --send &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
MicroPython ha due file di default quando viene installato: boot.py e main.py. Il primo è un file di sistema che serve allo stesso MicroPython di partire. Non occorre di solito modificarlo. Il secondo, main.py, è uno script che viene eseguito all'avvio. Se carichiamo un file main.py questo verrà eseguito all'accensione.&lt;br /&gt;
&lt;br /&gt;
=== Considerazioni finali ===&lt;br /&gt;
&lt;br /&gt;
Molto bene, ma la versione di micropython non è aggiornata. Forse è per questo che non riesco a far funzionare la porta I²C?&lt;br /&gt;
&lt;br /&gt;
== Secondo tentativo ==&lt;br /&gt;
&lt;br /&gt;
Boochow fornisce dei firmware già compilati su https://blog.boochow.com/micropython-firmware-for-mbed-boards basta scegliere la board giusta e caricare il file .bin nel volume &amp;quot;NUCLEO&amp;quot; che si monta quando si collega la USB.&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Un modo piuttosto comodo di inviare e ricevere file sulla flash della Nucleo è usare uPyLoader:&lt;br /&gt;
https://github.com/BetaRavener/uPyLoader/&lt;br /&gt;
ma quasi sempre dà un errore di timeout.&lt;br /&gt;
&lt;br /&gt;
Il programma fornito da Adafruit sembra funzionare decisamente meglio&lt;br /&gt;
https://learn.adafruit.com/micropython-basics-load-files-and-run-code/install-ampy&lt;br /&gt;
&lt;br /&gt;
Per installarlo usare pip (o pip3):&lt;br /&gt;
 pip install adafruit-ampy&lt;br /&gt;
&lt;br /&gt;
Per usarlo:&lt;br /&gt;
 ampy -p &amp;lt;porta seriale&amp;gt; put &amp;lt;nome file&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Display OLED I²C =&lt;br /&gt;
&lt;br /&gt;
Per testare il funzionamento di MicroPython, proviamo a usare un piccolo display OLED I²C.&lt;br /&gt;
&lt;br /&gt;
== Caricare la libreria ==&lt;br /&gt;
&lt;br /&gt;
Con ampy carichiamo la [https://github.com/micropython/micropython/blob/master/drivers/display/ssd1306.py libreria ssd1306].&lt;br /&gt;
&lt;br /&gt;
 ampy -p /dev/ttyACM0 put ssd1306.py &lt;br /&gt;
&lt;br /&gt;
== Manovrare il display da REPL ==&lt;br /&gt;
&lt;br /&gt;
Se la libreria è stata caricata si può importare scrivendo:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import ssd1306&lt;br /&gt;
&lt;br /&gt;
Occorre poi creare un oggetto I2C specificando quali pin usare per SCL e SDA (in teoria dovrebbe essere automatico, ma secondo [https://forum.micropython.org/viewtopic.php?t=4663 questo post sul forum di micropython] l'automatismo non funziona), la libreria machine dovrebbe essere già importata di default:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pscl = machine.Pin('D15',machine.Pin.OUT_PP)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; psda = machine.Pin('D14',machine.Pin.OUT_PP)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; i2c = machine.I2C(scl=pscl,sda=psda)&lt;br /&gt;
&lt;br /&gt;
e poi creare un oggetto che gestisca il display:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled = ssd1306.SSD1306_I2C(128,64,i2c)&lt;br /&gt;
&lt;br /&gt;
dove 128 e 64 sono le dimensioni.&lt;br /&gt;
&lt;br /&gt;
== Test! ==&lt;br /&gt;
&lt;br /&gt;
Per prima cosa occorre cancellare un'eventuale scritta precedente:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled.fill(0)&lt;br /&gt;
&lt;br /&gt;
Poi scriviamo qualcosa:&lt;br /&gt;
 &lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled.text('qualcosa',0,0)&lt;br /&gt;
&lt;br /&gt;
e infine lo mostriamo:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled.show()&lt;br /&gt;
&lt;br /&gt;
et voilà!&lt;br /&gt;
&lt;br /&gt;
[[File:Micropython_test_oled.jpg]]&lt;br /&gt;
&lt;br /&gt;
Più informazioni su come funziona la libreria, corredata da esempi, le potete trovare sul [https://learn.adafruit.com/micropython-hardware-ssd1306-oled-display/circuitpython sito di Adafruit].&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6833</id>
		<title>Installare MicroPython su NUCLEO-F401RE</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6833"/>
		<updated>2019-03-09T17:02:41Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questa guida è basata quasi tutta su quella di Carmine Noviello https://www.carminenoviello.com/2015/06/03/running-micropyton-stm32nucleo-f4/ che peraltro trovate anche in italiano https://www.carminenoviello.com/it/2015/08/11/compilare-micropython-una-scheda-stm32nucleo-f4/ per cui scriverò solo le differenze.&lt;br /&gt;
&lt;br /&gt;
La versione di Carmine di micropython, che si trova sul suo [https://github.com/cnoviello/micropython github], risolve il problema relativo alla mancanza di memoria SD della scheda Nucleo. Il file con il programma .py sarà caricato direttamente sulla flash.&lt;br /&gt;
&lt;br /&gt;
= La scheda =&lt;br /&gt;
&lt;br /&gt;
NUCLEO-F401RE della STMicroelectronics è una scheda basata su ARM Cortex M4 e fa parte della famiglia STM32 Nucleo Boards. Ha 512KB di Flash, 96 KB di SRAM, un clock di 84MHz, 50 GPIO, RTC, supporto I²C, SPI, USART e molto altro ([https://os.mbed.com/platforms/ST-Nucleo-F401RE/ maggiori info]). La sua forma le permette di alloggiare sia gli shield per Arduino che le estensioni Morpho di STMicroelectronics.&lt;br /&gt;
Il prezzo è abbastanza contenuto (attorno ai 12€ su Mouser) il che ne fa una scheda piuttosto interessante.&lt;br /&gt;
&lt;br /&gt;
Normalmente si programmerebbe tramite l'[https://ide.mbed.com/compiler editor online di Mbed]. Il compilatore genererà dal nostro codice un file con estensione bin. Collegando la scheda verrà montato un volume, chiamato &amp;quot;NUCLEO&amp;quot; sul quale caricare il file bin. Quando la scheda verrà resettata, il codice verrà eseguito. È possibile anche usare editor offline con toolchain di compilazione come Eclipse. Non credo sia possibile usare la IDE di Arduino.&lt;br /&gt;
&lt;br /&gt;
= Installazione MicroPython =&lt;br /&gt;
&lt;br /&gt;
== Primo tentativo ==&lt;br /&gt;
&lt;br /&gt;
=== Toolchain e OpenOCD ===&lt;br /&gt;
&lt;br /&gt;
Per compilare vi servirà la toolchain gcc-arm-embedded. Non è nei repo ufficiali quindi la dovete installare a mano oppure aggiungere un PPA. https://launchpad.net/gcc-arm-embedded&lt;br /&gt;
Il programma per comunicare col debugger della scheda, openocd, invece è nei repo di Debian.&lt;br /&gt;
 &lt;br /&gt;
=== Come installare MicroPython ===&lt;br /&gt;
&lt;br /&gt;
Potete seguire la guida di Carmine per la compilazione. Ovviamente se avete installato la toolchain con apt non è necessario aggiungere il path a tutti i comandi, perché sono già dentro a /usr/bin.&lt;br /&gt;
&lt;br /&gt;
OpenOCD ci permette di caricare il firmware che abbiamo crosscompilato. Basterà lanciare il comando:&lt;br /&gt;
 $ openocd  -f board/st_nucleo_f4.cfg&lt;br /&gt;
Un LED della scheda dovrebbe lampeggiare rosso/verde. Il debugger è attivo. Per collegarcisi:&lt;br /&gt;
 $ telnet localhost 4444&lt;br /&gt;
e poi scrivete:&lt;br /&gt;
 &amp;gt; reset halt&lt;br /&gt;
e infine:&lt;br /&gt;
 &amp;gt; flash write_image erase &amp;lt;file .elf da flashare&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inizialmente non sembrava funzionare. Il tentativo finale che ha sbloccato la situazione è stato dare il comando shutdown. Non sono sicuro però che sia stato proprio quel comando e bisognerebbe indagare meglio.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dall'interprete ===&lt;br /&gt;
&lt;br /&gt;
Aprendo la porta della nostra scheda (la trovate su dmesg non appena la attaccate, è /dev/ttyACMx dove x è un numero che parte da 0) con un emulatore di terminale (come console) alla velocità di 115200 baud, dovreste vedere l'interprete dei comandi (REPL, ovvero Read, Eval, Print and Loop) di MicroPython. Provate a dare il comando:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pyb.LED(1).on()&lt;br /&gt;
per vedere se si accende il LED onboard.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dal PC ===&lt;br /&gt;
&lt;br /&gt;
Fra i tool di MicroPython, che trovate nella cartella di git micropython/tools, c'è pyboard.py, un programma che vi permette di eseguire uno script in MicroPython. Se la vostra porta non è accessibile dall'utente dovrete usare sudo.&lt;br /&gt;
 # ./pyboard.py &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Carmine ha fatto una modifica a pyboard in modo che possa caricare un file sulla board.&lt;br /&gt;
 # ./pyboard.py --device=/dev/ttyACMx --send &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
MicroPython ha due file di default quando viene installato: boot.py e main.py. Il primo è un file di sistema che serve allo stesso MicroPython di partire. Non occorre di solito modificarlo. Il secondo, main.py, è uno script che viene eseguito all'avvio. Se carichiamo un file main.py questo verrà eseguito all'accensione.&lt;br /&gt;
&lt;br /&gt;
=== Considerazioni finali ===&lt;br /&gt;
&lt;br /&gt;
Molto bene, ma la versione di micropython non è aggiornata. Forse è per questo che non riesco a far funzionare la porta I²C?&lt;br /&gt;
&lt;br /&gt;
== Secondo tentativo ==&lt;br /&gt;
&lt;br /&gt;
Boochow fornisce dei firmware già compilati su https://blog.boochow.com/micropython-firmware-for-mbed-boards basta scegliere la board giusta e caricare il file .bin nel volume &amp;quot;NUCLEO&amp;quot; che si monta quando si collega la USB.&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Un modo piuttosto comodo di inviare e ricevere file sulla flash della Nucleo è usare uPyLoader:&lt;br /&gt;
https://github.com/BetaRavener/uPyLoader/&lt;br /&gt;
ma quasi sempre dà un errore di timeout.&lt;br /&gt;
&lt;br /&gt;
Il programma fornito da Adafruit sembra funzionare decisamente meglio&lt;br /&gt;
https://learn.adafruit.com/micropython-basics-load-files-and-run-code/install-ampy&lt;br /&gt;
&lt;br /&gt;
Per installarlo usare pip (o pip3):&lt;br /&gt;
 pip install adafruit-ampy&lt;br /&gt;
&lt;br /&gt;
Per usarlo:&lt;br /&gt;
 ampy -p &amp;lt;porta seriale&amp;gt; put &amp;lt;nome file&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Display OLED I²C =&lt;br /&gt;
&lt;br /&gt;
Per testare il funzionamento di MicroPython, proviamo a usare un piccolo display OLED I²C.&lt;br /&gt;
&lt;br /&gt;
== Caricare la libreria ==&lt;br /&gt;
&lt;br /&gt;
Con ampy carichiamo la [https://github.com/micropython/micropython/blob/master/drivers/display/ssd1306.py libreria ssd1306].&lt;br /&gt;
&lt;br /&gt;
 ampy -p /dev/ttyACM0 put ssd1306.py &lt;br /&gt;
&lt;br /&gt;
== Manovrare il display da REPL ==&lt;br /&gt;
&lt;br /&gt;
Se la libreria è stata caricata si può importare scrivendo:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import ssd1306&lt;br /&gt;
&lt;br /&gt;
Occorre poi creare un oggetto I2C specificando quali pin usare per SCL e SDA (in teoria dovrebbe essere automatico, ma secondo [https://forum.micropython.org/viewtopic.php?t=4663 questo post sul forum di micropython] l'automatismo non funziona), la libreria machine dovrebbe essere già importata di default:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pscl = machine.Pin('D15',machine.Pin.OUT_PP)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; psda = machine.Pin('D14',machine.Pin.OUT_PP)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; i2c = machine.I2C(scl=pscl,sda=psda)&lt;br /&gt;
&lt;br /&gt;
e poi creare un oggetto che gestisca il display:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled = ssd1306.SSD1306_I2C(128,64,i2c)&lt;br /&gt;
&lt;br /&gt;
dove 128 e 64 sono le dimensioni.&lt;br /&gt;
&lt;br /&gt;
== Test! ==&lt;br /&gt;
&lt;br /&gt;
Per prima cosa occorre cancellare un'eventuale scritta precedente:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled.fill(0)&lt;br /&gt;
&lt;br /&gt;
Poi scriviamo qualcosa:&lt;br /&gt;
 &lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled.text('qualcosa',0,0)&lt;br /&gt;
&lt;br /&gt;
e infine lo mostriamo:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; oled.show()&lt;br /&gt;
&lt;br /&gt;
et voilà!&lt;br /&gt;
[[File:Micropython_test_oled.jpg]]&lt;br /&gt;
&lt;br /&gt;
Più informazioni su come funziona la libreria, corredata da esempi, le potete trovare sul [https://learn.adafruit.com/micropython-hardware-ssd1306-oled-display/circuitpython sito di Adafruit].&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=File:Micropython_test_oled.jpg&amp;diff=6832</id>
		<title>File:Micropython test oled.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=File:Micropython_test_oled.jpg&amp;diff=6832"/>
		<updated>2019-03-09T17:00:51Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Ardubottino&amp;diff=6830</id>
		<title>Ardubottino</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Ardubottino&amp;diff=6830"/>
		<updated>2019-03-05T15:44:03Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* Il codice */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ardubottino è stato creato soprattutto per testare tre componenti: l'Arduino, il sensore della distanza a ultrasuoni e il ponte ad H. Lo chassis e i motori sono Tamiya.&lt;br /&gt;
&lt;br /&gt;
[[File:Ardubottino.jpg]]&lt;br /&gt;
&lt;br /&gt;
= Prima Versione =&lt;br /&gt;
&lt;br /&gt;
== Componenti ==&lt;br /&gt;
Ardubottino ha questi componenti:&lt;br /&gt;
* Arduino UNO [http://arduino.cc/en/Main/arduinoBoardUno]&lt;br /&gt;
* Sensore di distanza a ultrasuoni SRF05 [http://www.robot-electronics.co.uk/htm/srf05tech.htm]&lt;br /&gt;
* Il board con montato il ponte ad H L298 [http://www.vetco.net/catalog/product_info.php?products_id=14337]&lt;br /&gt;
* Kit Tamiya per lo chassis e i motori&lt;br /&gt;
* Batteria da 9v&lt;br /&gt;
* Ulteriori batterie per il motore (inizialmente 4,5v, poi 4,8v)&lt;br /&gt;
&lt;br /&gt;
Il sensore di distanza è sprovvisto di pin, occorre quindi saldarne una strip prima di procedere.&lt;br /&gt;
&lt;br /&gt;
== Il sensore di distanza a ultrasuoni SRF05 ==&lt;br /&gt;
[[File:102_1298.JPG]]&lt;br /&gt;
&lt;br /&gt;
È piuttosto semplice da usare. Seguendo le istruzioni [ http://www.robot-electronics.co.uk/htm/srf05tech.htm trovate qui] si può notare che ha due modalità di comunicazioni, date dal pin Mode. Se questo pin è collegato alla 0v il sensore userà un solo pin per la comunicazione dei dati dell'eco (Echo) e la ricezione dei comandi (Trigger), se, al contrario, non è connesso a niente allora saranno usati due pin diversi. Nel caso dell'Ardubottino ho preferito usare la prima modalità, quella con un pin solo (soprattutto per pigrizia: perché è già così lo sketch di esempio &amp;quot;ping&amp;quot; nella libreria di Arduino!). Oltre al pin Mode e al pin Trigger/Echo occorre collegare il primo e l'ultimo pin rispettivamente a +5v e a terra.&lt;br /&gt;
Nella foto si può vedere, da sinistra: +5v, non usato, Trigger/Echo (collegato al pin 13 di Arduino), Mode (terra), Terra (terra).&lt;br /&gt;
&lt;br /&gt;
== Il board ponte ad H L298 ==&lt;br /&gt;
[[File:Ardubottino_dettagliol298.jpg]]&lt;br /&gt;
&lt;br /&gt;
Il ponte ad H L298 è utilissimo per manovrare due motori indipendenti. Può essere usato anche per muovere un motore passo-passo.&lt;br /&gt;
Ha due ingressi per la corrente: tramite un ponticello può essere separata fra corrente per la logica e corrente per i motori. La logica dev'essere alimentata da +5v; se l'alimentazione è separata, i motori possono ricevere fino a +12v. Per comodità (e anche dopo diversi goffi tentativi per capire come funzionava) ho preferito alimentare i motori solo con i 5v.&lt;br /&gt;
&lt;br /&gt;
Sui lati ci sono le connessioni per i motori mentre, a fianco dell'alimentazione, ci sono i pin che servono per comandarli. I pin sono sei, due sono gli enable per i motori e quattro servono per dare la direzione, due per motore. I pin dell'enable si possono chiudere con dei ponticelli, comandarli da Arduino/Raspberry Pi oppure gli si può mandare un impulso PWM per regolare la velocità.&lt;br /&gt;
&lt;br /&gt;
== Motori ad encoder, gioie (poche) e dolorer (tanto) ==&lt;br /&gt;
Il problema di Ardubottino è che non va dritto. Il motivo? Forse il ponte ad H non dà gli stessi voltaggi ai motori, forse i motori sono un po' diversi, forse si stanno usurando in modo diverso, forse i cingoli hanno qualche imperfezione, forse le ruote sono storte, forse è sbilanciato. Ad ogni modo ognuno di questi problemi (tranne le ruote storte e le imperfezioni dei cingoli) si sarebbero risolti scoprendo a che velocità vanno i motori. Per scoprire questo dato sono necessari gli encoder. Un encoder è una rotellina con dei fori e un sensore o due, composti da un LED e da un ricevitore a infrarossi, che sentono quando un foro è passato. Encoder di questo tipo si trovano ad esempio nelle rotelline dei mouse o in quelli che hanno ancora la pallina.&lt;br /&gt;
&lt;br /&gt;
[[File:EncoderArdubottino.JPG]]&lt;br /&gt;
&lt;br /&gt;
Ora: questi sarebbero degli encoder &amp;quot;fatti apposta&amp;quot; per il kit Tamiya. Uso il condizionale perché, se non sono stato io ad averli montati in modo approssimativo, il loro utilizzo è alquanto scomodo. Anzitutto la rotella non sta fissa sull'albero. Il foro esagonale è troppo grande e ha un notevole gioco. Il range del sensore è minimo e non tiene conto della struttura del kit Tamiya (la rotella va quasi a sfregare contro le viti che lo fissano allo chassis). Inoltre sono estremamente fragili: una delle rotelle si è spaccata subito in due. I sensori stessi, poi, non si incastrano nella sede e occorre incollarli.&lt;br /&gt;
La lettura degli encoder andrebbe fatta sfruttando gli interrupt di Arduino. Gli interrupt sono dei pin che restano in ascolto e fanno scattare degli eventi quando cambiano valore[http://arduino.cc/en/Reference/AttachInterrupt]. Purtroppo uno dei due pin (sull'Arduino Uno sono il pin 2 e il pin 3) dava dei risultati estremamente inaffidabili. Dopo varie prove, il risultato migliore l'ho ottenuto usando la libreria Encoder [http://www.pjrc.com/teensy/td_libs_Encoder.html] su due pin non di interrupt. Il risultato di tutta questa fatica è un robottino che grosso modo va dritto. Un risultato mediocre di molto inferiore alla calibrazione a occhio. Alla fine, infatti, ho preferito quest'ultima.&lt;br /&gt;
&lt;br /&gt;
== Lo sketch ==&lt;br /&gt;
&lt;br /&gt;
Lo sketch deriva per una parte dall'esempio ''Ping'' già presente nella libreria di Arduino. In pratica fa avanzare Ardubottino fino a che non incontra un ostacolo. Se lo incontra sterza in un senso e poi nell'altro e alla fine prosegue per la direzione dove ha trovato più campo libero.&lt;br /&gt;
4 7 6 5 sono i  pin a cui ho collegato il ponte ad H. Sterzo è il tempo che deve impiegare per sterzare. pinping è il pin a cui è attaccato il trigger/echo del sensore a ultrasuoni.&lt;br /&gt;
 long duration;&lt;br /&gt;
 long dursx;&lt;br /&gt;
 long durdx; &lt;br /&gt;
 const int en1 = 11; //pin enable&lt;br /&gt;
 const int en2 = 9;&lt;br /&gt;
 const int m1fd = 4; //controlli motore&lt;br /&gt;
 const int m2fd = 7;&lt;br /&gt;
 const int m1bk = 5;&lt;br /&gt;
 const int m2bk = 6;&lt;br /&gt;
 const int pinping = 13; //pin sensore distanza&lt;br /&gt;
 const int sterzo = 600; //durata dello sterzo&lt;br /&gt;
 const int distanza = 500; //distanza minima ostacoli&lt;br /&gt;
 int motore1 = 67;//pwm motore dx&lt;br /&gt;
 int motore2 = 74;//pwm motore sx&lt;br /&gt;
 &lt;br /&gt;
 void setup() {&lt;br /&gt;
  pinMode(m1fd, OUTPUT);&lt;br /&gt;
  pinMode(m1bk, OUTPUT);&lt;br /&gt;
  pinMode(m2fd, OUTPUT);&lt;br /&gt;
  pinMode(m2bk, OUTPUT);&lt;br /&gt;
  pinMode(en1, OUTPUT);&lt;br /&gt;
  pinMode(en2, OUTPUT);&lt;br /&gt;
  analogWrite(en1,motore1);&lt;br /&gt;
  analogWrite(en2,motore2);&lt;br /&gt;
  dritto();&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void loop() {&lt;br /&gt;
  if (echo() &amp;lt; distanza){ //trovato un ostacolo&lt;br /&gt;
   analogWrite(en1,170);&lt;br /&gt;
   analogWrite(en2,170);&lt;br /&gt;
   ferma();&lt;br /&gt;
   sinistra();&lt;br /&gt;
   delay(sterzo);&lt;br /&gt;
   ferma();&lt;br /&gt;
   dursx = echo(); //guarda a sinistra&lt;br /&gt;
   destra();&lt;br /&gt;
   delay(sterzo*2);&lt;br /&gt;
   ferma();&lt;br /&gt;
   durdx = echo(); //guarda a destra&lt;br /&gt;
   if (dursx &amp;lt; distanza &amp;amp;&amp;amp; durdx &amp;lt; distanza){&lt;br /&gt;
     destra();&lt;br /&gt;
     delay(sterzo);&lt;br /&gt;
   } else if (dursx &amp;gt; durdx) {&lt;br /&gt;
     sinistra();&lt;br /&gt;
     delay(sterzo*2);&lt;br /&gt;
   } //sceglie dove c'è più spazio&lt;br /&gt;
   dritto();&lt;br /&gt;
   analogWrite(en1,motore1);&lt;br /&gt;
   analogWrite(en2,motore2);&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void dritto() {&lt;br /&gt;
  digitalWrite(m1bk,LOW);&lt;br /&gt;
  digitalWrite(m2bk,LOW);&lt;br /&gt;
  digitalWrite(m2fd,HIGH);&lt;br /&gt;
  digitalWrite(m1fd,HIGH);   &lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void rovescia() {&lt;br /&gt;
  digitalWrite(m1fd,LOW);&lt;br /&gt;
  digitalWrite(m2fd,LOW);&lt;br /&gt;
  digitalWrite(m1bk,HIGH);&lt;br /&gt;
  digitalWrite(m2bk,HIGH);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void destra() {&lt;br /&gt;
  digitalWrite(m1fd,LOW);&lt;br /&gt;
  digitalWrite(m2fd,HIGH);&lt;br /&gt;
  digitalWrite(m1bk,HIGH);&lt;br /&gt;
  digitalWrite(m2bk,LOW);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sinistra() {&lt;br /&gt;
  digitalWrite(m1fd,HIGH);&lt;br /&gt;
  digitalWrite(m2fd,LOW);&lt;br /&gt;
  digitalWrite(m1bk,LOW);&lt;br /&gt;
  digitalWrite(m2bk,HIGH);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void ferma() {&lt;br /&gt;
  digitalWrite(m1fd,LOW);&lt;br /&gt;
  digitalWrite(m2fd,LOW);&lt;br /&gt;
  digitalWrite(m1bk,LOW);&lt;br /&gt;
  digitalWrite(m2bk,LOW);&lt;br /&gt;
  delay(50);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 long echo() {&lt;br /&gt;
  pinMode(pinping, OUTPUT);&lt;br /&gt;
  digitalWrite(pinping, LOW);&lt;br /&gt;
  delayMicroseconds(2);&lt;br /&gt;
  digitalWrite(pinping, HIGH);&lt;br /&gt;
  delayMicroseconds(5);&lt;br /&gt;
  digitalWrite(pinping, LOW);&lt;br /&gt;
  pinMode(pinping, INPUT);&lt;br /&gt;
  duration = pulseIn(pinping,HIGH);&lt;br /&gt;
  return duration;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
= Seconda Versione =&lt;br /&gt;
Ok, la modifica è un po' minima per essere una vera e propria seconda versione, ma dopo il fallimento degli encoder ero un po' giù di morale.&lt;br /&gt;
Il progetto era di rendere Ardubottino telecomandabile con qualche mezzo estremamente low cost e nella maniera più semplice possibile. La mia scelta è caduta sull'infrarosso.&lt;br /&gt;
&lt;br /&gt;
== Il sensore a infrarossi ==&lt;br /&gt;
[[File:Arduir.jpg]]&lt;br /&gt;
&lt;br /&gt;
Quello che potete vedere nella foto è un sensore a infrarossi come quelli che potreste recuperare in qualsivoglia elettrodomestico. I sensori IR hanno tre pin: +5v, terra e dati. Questo in particolare aveva le stesse specifiche di quest'altro[http://learn.adafruit.com/ir-sensor/testing-an-ir-sensor] usato nel tutorial di Adafruit per leggere gli impulsi infrarossi con Arduino. Potrebbero non essere tutti uguali, quindi cautela.&lt;br /&gt;
&lt;br /&gt;
== La libreria IRremote ==&lt;br /&gt;
Gran parte del lavoro lo fa la libreria IRremote (che trovate qui [https://github.com/shirriff/Arduino-IRremote]). Con questo sketch [http://www.mediafire.com/view/6qnsndqp9a838xe/Decode_IR.ino] si possono leggere, sotto forma di cifre, i codici del telecomando che volete usare. Tramite il monitor seriale noterete dapprincipio che ogni tasto ha assegnato due codici, questo per fare in modo che ci sia una differenza fra tenere premuto il tasto (dà lo stesso codice in uscita, in modo continuo) e dei clic ripetuti (ogni clic diverso il codice cambia). Con questo sketch sono riuscito a capire che il codice del tasto SU del telecomando era legato ai codici 2742014623 e 31889539.&lt;br /&gt;
La libreria IRremote permette anche di trasmettere, ma per ora non sfrutteremo questa sua proprietà. Potete trovare più informazioni qui [http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html]&lt;br /&gt;
&lt;br /&gt;
== Lo sketch finale ==&lt;br /&gt;
Non ho voluto togliere all'Ardubottino la possibilità di andarsene in giro da solo, quindi ho assegnato al tasto OK del telecomando la capacità di passare dallo stato manuale a quello automatico.&lt;br /&gt;
La libreria IRremote ci permette di creare la classe IRrecv che, tramite i suoi metodi, prepara (enableIrIN) , legge (decode), e aspetta il prossimo segnale (resume). I valori sono memorizzati nella struttura decode_results, il cui valore value è il codice del segnale del telecomando. La variabile booleana automat determina se Ardubottino è in modalità automatica o meno.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#FF0000&amp;quot;&amp;gt;ATTENZIONE: La libreria IRremote.h non è compatibile con la libreria RobotIRRemote fornita con l'ultima versione della IDE di Arduino. Per compilare questo sketch occorre prima disabilitare RobotIRRemote. Per disabilitare una libreria occorre andare in arduino/libraries e spostare la cartella della libreria in un altro posto.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  #include &amp;lt;IRremote.h&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  int IRpin =2; //pin del sensore IR&lt;br /&gt;
  IRrecv irrecv(IRpin);&lt;br /&gt;
  long duration;&lt;br /&gt;
  long dursx;&lt;br /&gt;
  long durdx;&lt;br /&gt;
  &lt;br /&gt;
  const int en1 = 10; //pin enable&lt;br /&gt;
  const int en2 = 9;&lt;br /&gt;
  const int m1fd = 4; //controlli motore&lt;br /&gt;
  const int m2fd = 7;&lt;br /&gt;
  const int m1bk = 5;&lt;br /&gt;
  const int m2bk = 6;&lt;br /&gt;
  const int pinping = 13; //pin sensore distanza&lt;br /&gt;
  const int sterzo = 600; //durata dello sterzo&lt;br /&gt;
  const int distanza = 500; //distanza minima ostacoli&lt;br /&gt;
  int motore1 = 66;//pwm motore dx&lt;br /&gt;
  int motore2 = 72;//pwm motore sx&lt;br /&gt;
  boolean automat = false;&lt;br /&gt;
  &lt;br /&gt;
  decode_results results;&lt;br /&gt;
  &lt;br /&gt;
  void setup() {&lt;br /&gt;
   pinMode(m1fd, OUTPUT);&lt;br /&gt;
   pinMode(m1bk, OUTPUT);&lt;br /&gt;
   pinMode(m2fd, OUTPUT);&lt;br /&gt;
   pinMode(m2bk, OUTPUT);&lt;br /&gt;
   pinMode(en1, OUTPUT);&lt;br /&gt;
   pinMode(en2, OUTPUT);&lt;br /&gt;
   analogWrite(en1,motore1);&lt;br /&gt;
   analogWrite(en2,motore2);&lt;br /&gt;
   irrecv.enableIRIn();&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  void loop() {&lt;br /&gt;
    if(irrecv.decode(&amp;amp;results)){&lt;br /&gt;
      if (!automat) {&lt;br /&gt;
        if(results.value == 2742014623 || results.value == 31889539){&lt;br /&gt;
          dritto();&lt;br /&gt;
        } else if (results.value == 2383694249 || results.value == 2039764837 ) {&lt;br /&gt;
          sinistra();&lt;br /&gt;
        } else if (results.value == 15111918 || results.value == 2725237002) {&lt;br /&gt;
          rovescia();&lt;br /&gt;
        } else if (results.value == 1665824360 || results.value == 3250666572 ) {&lt;br /&gt;
          destra();&lt;br /&gt;
        } else  {&lt;br /&gt;
          ferma();&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      if (results.value == 3969632309 || results.value == 18594425) {&lt;br /&gt;
        if (automat) {&lt;br /&gt;
          automat = false;&lt;br /&gt;
          ferma();&lt;br /&gt;
          delayMicroseconds(300000);  &lt;br /&gt;
        }else{&lt;br /&gt;
          automat = true;&lt;br /&gt;
          dritto();&lt;br /&gt;
          delayMicroseconds(300000);&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      irrecv.resume();&lt;br /&gt;
    }&lt;br /&gt;
    if (automat &amp;amp;&amp;amp; echo() &amp;lt; distanza){ //trovato un ostacolo&lt;br /&gt;
     analogWrite(en1,170);&lt;br /&gt;
     analogWrite(en2,170);&lt;br /&gt;
     ferma();&lt;br /&gt;
     sinistra();&lt;br /&gt;
     delay(sterzo);&lt;br /&gt;
     ferma();&lt;br /&gt;
     dursx = echo(); //guarda a sinistra&lt;br /&gt;
     destra();&lt;br /&gt;
     delay(sterzo*2);&lt;br /&gt;
     ferma();&lt;br /&gt;
     durdx = echo(); //guarda a destra&lt;br /&gt;
     if (dursx &amp;lt; distanza &amp;amp;&amp;amp; durdx &amp;lt; distanza){&lt;br /&gt;
       destra();&lt;br /&gt;
       delay(sterzo);&lt;br /&gt;
     } else if (dursx &amp;gt; durdx) {&lt;br /&gt;
       sinistra();&lt;br /&gt;
       delay(sterzo*2);&lt;br /&gt;
     } //sceglie dove c'è più spazio&lt;br /&gt;
     dritto();&lt;br /&gt;
     analogWrite(en1,motore1);&lt;br /&gt;
     analogWrite(en2,motore2);&lt;br /&gt;
   }&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  void dritto() {&lt;br /&gt;
   digitalWrite(m1bk,LOW);&lt;br /&gt;
   digitalWrite(m2bk,LOW);&lt;br /&gt;
   digitalWrite(m2fd,HIGH);&lt;br /&gt;
   digitalWrite(m1fd,HIGH);   &lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  void rovescia() {&lt;br /&gt;
   digitalWrite(m1fd,LOW);&lt;br /&gt;
   digitalWrite(m2fd,LOW);&lt;br /&gt;
   digitalWrite(m1bk,HIGH);&lt;br /&gt;
   digitalWrite(m2bk,HIGH);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  void destra() {&lt;br /&gt;
   digitalWrite(m1fd,LOW);&lt;br /&gt;
   digitalWrite(m2fd,HIGH);&lt;br /&gt;
   digitalWrite(m1bk,HIGH);&lt;br /&gt;
   digitalWrite(m2bk,LOW);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  void sinistra() {&lt;br /&gt;
   digitalWrite(m1fd,HIGH);&lt;br /&gt;
   digitalWrite(m2fd,LOW);&lt;br /&gt;
   digitalWrite(m1bk,LOW);&lt;br /&gt;
   digitalWrite(m2bk,HIGH);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  void ferma() {&lt;br /&gt;
   digitalWrite(m1fd,LOW);&lt;br /&gt;
   digitalWrite(m2fd,LOW);&lt;br /&gt;
   digitalWrite(m1bk,LOW);&lt;br /&gt;
   digitalWrite(m2bk,LOW);&lt;br /&gt;
   delay(50);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  long echo() {&lt;br /&gt;
   pinMode(pinping, OUTPUT);&lt;br /&gt;
   digitalWrite(pinping, LOW);&lt;br /&gt;
   delayMicroseconds(2);&lt;br /&gt;
   digitalWrite(pinping, HIGH);&lt;br /&gt;
   delayMicroseconds(5);&lt;br /&gt;
   digitalWrite(pinping, LOW);&lt;br /&gt;
   pinMode(pinping, INPUT);&lt;br /&gt;
   duration = pulseIn(pinping,HIGH);&lt;br /&gt;
   return duration;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
= Terza Versione =&lt;br /&gt;
Dopo l'ennesimo disastroso trasporto di Ardubottino, nel quale si è smontato tutto, ho deciso di dargli una sistemata definitiva. Saldature migliori, componenti fissati e meno fili volanti. Inoltre sono state fatte le seguenti modifiche.&lt;br /&gt;
&lt;br /&gt;
[[File:ardubottino_3ver.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Passaggio dal Micro al Pro Mini ==&lt;br /&gt;
Per ragioni di spazio sono passato dall'Arduino Micro al Pro Mini della Deek Robots.&lt;br /&gt;
&lt;br /&gt;
[[File:Newardbot2.JPG]]&lt;br /&gt;
&lt;br /&gt;
C'è poco da dire su questa board. È sotto tutti gli aspetti un Arduino Pro Mini. Per essere programmato ha bisogno dell'adattatore USB. Purtroppo, come si può vedere nell'immagine, l'ho montato alla rovescia sulla breadboard e così non è possibile capire il numero dei pin. Capirci qualcosa è stato particolarmente ostico.&lt;br /&gt;
&lt;br /&gt;
== Abbastanza batterie ==&lt;br /&gt;
Avere l'alimentazione separata motori/logica è una soluzione che non mi soddisfa per niente. Come fare però per fare in modo che gli spikes dei motori non facciano riavviare l'Arduino? La questione è stata risolta in questa maniera.&lt;br /&gt;
&lt;br /&gt;
=== Condensatori ===&lt;br /&gt;
Sono stati aggiunti dei condensatori ai motori. In questo modo lo spike dovrebbe essere assorbito in parte.&lt;br /&gt;
&lt;br /&gt;
=== L'Arduino e i motori hanno una sorgente comune ===&lt;br /&gt;
Le batterie dei motori, 4 stilo da 2100mAh l'una, hanno amperaggio più che sufficiente per tenere acceso Arduino e motori. Dal + delle batterie partono due fili, uno va all'Arduino e l'altro al ponte ad H. Nei tentativi precedenti, davo al ponte ad H l'uscita a 5v dell'Arduino. Evidentemente la richiesta dei motori era eccessiva per il regolatore a 5v.&lt;br /&gt;
&lt;br /&gt;
== Turbo! ==&lt;br /&gt;
Aggiunta la modalità turbo, che fa andare il ns. robot più veloce!&lt;br /&gt;
&lt;br /&gt;
== Altri problemi ==&lt;br /&gt;
Avrei voluto mettere il sensore a ultrasuoni su un servo ma un bug della libreria Servo blocca il PWM in alcuni pin[http://forum.arduino.cc/index.php?topic=243264.0] per cui ho lasciato perdere.&lt;br /&gt;
&lt;br /&gt;
== Nuovo codice! ==&lt;br /&gt;
Inutile incollarlo qui. Ho aperto uno spazio su GitHub:&lt;br /&gt;
&lt;br /&gt;
[https://github.com/raspibo/ardubottino Link]&lt;br /&gt;
&lt;br /&gt;
= Quarta versione =&lt;br /&gt;
Era giunto il momento di sfruttare un po' di roba che rimaneva inutilizzata.&lt;br /&gt;
Le modifiche sono state:&lt;br /&gt;
&lt;br /&gt;
* Encoder, stavolta funzionanti&lt;br /&gt;
* Calibrazione automatica&lt;br /&gt;
* Modalità programmazione&lt;br /&gt;
* Blocco quando una ruota non gira&lt;br /&gt;
* Sensore di caduta&lt;br /&gt;
&lt;br /&gt;
== Encoders ==&lt;br /&gt;
Nonostante abbia rotto le rondelle originali (che comunque erano fatte malissimo) sono riuscito a trovare alcuni modelli funzionanti. Il PLA azzurro, a differenza di quello bianco e di quello nero, sembra riflettere l'infrarosso dell'encoder. Tutto stava nel capire quale forma funzionasse meglio.&lt;br /&gt;
&lt;br /&gt;
[[File:Arduencoder.JPG]]&lt;br /&gt;
&lt;br /&gt;
La forma che funziona meglio (per ora) è quella a destra. Potete trovare l'STL nel [https://github.com/raspibo/ardubottino repository ardubottino su GitHub].&lt;br /&gt;
&lt;br /&gt;
Il problema principale, nel creare questo tipo di oggetto in 3D, è stato il foro a forma di prisma esagonale. In Blender occorre creare un cilindro, ridurre i vertici a 6 e poi modificarne la dimensione solo con lo strumento proporzionale, in modo da non deformarlo.&lt;br /&gt;
&lt;br /&gt;
[[File:Newardbot3.JPG]]&lt;br /&gt;
&lt;br /&gt;
Gli encoder permettono di fare diverse cose interessanti. Ora Ardubottino sente quando una ruota non sta girando, ad esempio, inoltre sono state aggiunte due nuove modalità: la modalità &amp;quot;programmazione&amp;quot; (vai avanti di 10, poi gira a destra di 5, ecc.) e la modalità &amp;quot;calibrazione&amp;quot; (modifica la velocità di un motore fino a che le ruote non girano più o meno uguali).&lt;br /&gt;
&lt;br /&gt;
Purtroppo gli encoder non sono tanto precisi, ogni tanto leggono male e segnano un passo in più o in meno. Questo però era così anche con le rotelle originali.&lt;br /&gt;
&lt;br /&gt;
== Il sensore di caduta ==&lt;br /&gt;
Posto sul davanti, sente quando ad Ardubottino manca la terra sotto i cingoli. Quando sente il vuoto ferma tutto.&lt;br /&gt;
&lt;br /&gt;
[[File:Newardbot1.JPG]]&lt;br /&gt;
&lt;br /&gt;
== Il codice ==&lt;br /&gt;
Il codice sta diventando veramente troppo lungo per essere incollato qui, su questa pagina, per cui ne commenterò solo alcune parti. Lo sketch completo lo trovate su [https://github.com/raspibo/ardubottino GitHub].&lt;br /&gt;
&lt;br /&gt;
 #include &amp;quot;ardubottino.h&amp;quot;&lt;br /&gt;
Sì, era ora che creassi un header con tutti i codici del telecomando. Per adattare Ardubottino a un altro telecomando basterà cambiare header.&lt;br /&gt;
&lt;br /&gt;
 volatile long right_interval = 0;&lt;br /&gt;
 volatile long left_interval = 0;&lt;br /&gt;
 volatile int right_count = 0;&lt;br /&gt;
 volatile int left_count = 0;&lt;br /&gt;
&lt;br /&gt;
Le variabili che sono modificate dagli encoder devono essere di tipo &amp;quot;volatile&amp;quot;. Le variabili volatile possono essere cambiate da un evento esterno, nel nostro caso da un evento scatenato da un interrupt.&lt;br /&gt;
  &lt;br /&gt;
 void right_encoder() {&lt;br /&gt;
  static unsigned long last_interrupt = 0;&lt;br /&gt;
  unsigned long time_interrupt = micros();&lt;br /&gt;
  if(time_interrupt - last_interrupt &amp;gt;5000){&lt;br /&gt;
    right_interval = time_interrupt - last_interrupt;&lt;br /&gt;
    next_check_right = micros()+right_interval*2;&lt;br /&gt;
    right_count +=1;&lt;br /&gt;
    last_interrupt = time_interrupt;&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 void left_encoder() {&lt;br /&gt;
  static unsigned long last_interrupt = 0;&lt;br /&gt;
  unsigned long time_interrupt = micros();&lt;br /&gt;
  if(time_interrupt - last_interrupt &amp;gt;5000) {&lt;br /&gt;
    left_interval = time_interrupt - last_interrupt;&lt;br /&gt;
    next_check_left = micros()+left_interval*2;&lt;br /&gt;
    left_count +=1;&lt;br /&gt;
    last_interrupt = time_interrupt;&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Ecco le brevi funzioni chiamate da &lt;br /&gt;
  attachInterrupt(0, right_encoder,RISING);&lt;br /&gt;
  attachInterrupt(1, left_encoder,RISING);&lt;br /&gt;
gli interrupt.&lt;br /&gt;
La variabile x_count conta quanti giri (quanti quarti di giro) ha fatto la ruota; x_interval l'intervallo, in millisecondi, fra un passaggio e l'altro; next_check_x è una stima massima di quando dovrebbe essere il prossimo passaggio, serve per capire se una ruota s'è inceppata.&lt;br /&gt;
&lt;br /&gt;
  if (irrecv.decode(&amp;amp;results)) {&lt;br /&gt;
   curr_result = results.value;&lt;br /&gt;
   if (curr_result == prev_result) {&lt;br /&gt;
     curr_result = 0;&lt;br /&gt;
   } else {&lt;br /&gt;
     prev_result = curr_result;&lt;br /&gt;
   }&lt;br /&gt;
 (...)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Ricordate quando vi dissi che il telecomando per ogni tasto ha due codici? Serve per distinguere se state tenendo premuto il tasto o se lo state premendo più volte contemporaneamente. Con questo piccolo brandello di codice faccio in modo di ignorare i codici ripetuti, visto che ad Ardubottino non servono. Non tutti i telecomandi funzionano così.&lt;br /&gt;
 if (program) {&lt;br /&gt;
      if (curr_result == OKA || curr_result == OKB) {&lt;br /&gt;
        blinkOK();&lt;br /&gt;
        executeProgram();&lt;br /&gt;
        clearMoves();&lt;br /&gt;
        noMotion();&lt;br /&gt;
      } else if (curr_result == NUM1A || curr_result == NUM1B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +1;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM2A || curr_result == NUM2A) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +2;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM3A || curr_result == NUM3B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +3;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM4A || curr_result == NUM4B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +4;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM5A || curr_result == NUM5B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +5;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM6A || curr_result == NUM6B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +6;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM7A || curr_result == NUM7B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +7;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM8A || curr_result == NUM8B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +8;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM9A || curr_result == NUM9B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +9;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM0A || curr_result == NUM0B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10);   &lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == FORWARDA || curr_result == FORWARDB) {&lt;br /&gt;
        moves[pointer][1] = 1;&lt;br /&gt;
        pointer ++;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == BACKA || curr_result == BACKB) {&lt;br /&gt;
        moves[pointer][1] = 2;&lt;br /&gt;
        pointer ++;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == LEFTA || curr_result == LEFTB) {&lt;br /&gt;
        moves[pointer][1] = 3;&lt;br /&gt;
        pointer ++;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == RIGHTA || curr_result == RIGHTB) {&lt;br /&gt;
        moves[pointer][1] = 4;&lt;br /&gt;
        pointer ++;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == WINA || curr_result == WINB) {&lt;br /&gt;
        clearMoves();&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else {&lt;br /&gt;
        blinkNO();&lt;br /&gt;
      }&lt;br /&gt;
      if(moves[pointer][0] &amp;gt; 99) {&lt;br /&gt;
       moves[pointer][0] = moves[pointer][0]-((moves[pointer][0]/100)*100);&lt;br /&gt;
      }&lt;br /&gt;
      if (pointer &amp;gt;49) {&lt;br /&gt;
        executeProgram();&lt;br /&gt;
      }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Et voilà: 50 mosse programmabili per il nostro robottino. Si scrive un numero di massimo 2 cifre e una direzione per massimo 50 istruzioni. Premendo OK si dà inizio al programma.&lt;br /&gt;
Ho anche aggiunto un lampeggiamento del LED di bordo in modo da dare un feedback visivo. Come ben saprete, i telecomandi a volte non trasmettono bene.&lt;br /&gt;
&lt;br /&gt;
 void executeProgram() {&lt;br /&gt;
  int right_count_program = right_count;&lt;br /&gt;
  &lt;br /&gt;
  for (int x=0;x&amp;lt;=49;x++){&lt;br /&gt;
    if (moves[x][1] == 0) {&lt;br /&gt;
      break;&lt;br /&gt;
    } else if (moves[x][1] == 1){&lt;br /&gt;
      forward();&lt;br /&gt;
    } else if (moves[x][1] == 2){&lt;br /&gt;
      backward();&lt;br /&gt;
    } else if (moves[x][1] == 3){&lt;br /&gt;
      left();&lt;br /&gt;
    } else if (moves[x][1] == 4){&lt;br /&gt;
      right();&lt;br /&gt;
    }&lt;br /&gt;
    while(moves[x][0] &amp;gt; 0) {&lt;br /&gt;
      if (right_count_program != right_count ) {&lt;br /&gt;
        moves[x][0] --;&lt;br /&gt;
        right_count_program = right_count;&lt;br /&gt;
        &lt;br /&gt;
      }&lt;br /&gt;
      if (digitalRead(fall)) {      &lt;br /&gt;
        noMotion();&lt;br /&gt;
        program = false;&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    moves[x][1] = 0;&lt;br /&gt;
  }&lt;br /&gt;
  program = false;&lt;br /&gt;
  noMotion();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Come potete vedere a metà c'è anche un check (c'è anche per le modalità automatica e manuale) sul sensore di caduta.&lt;br /&gt;
&lt;br /&gt;
 if (curr_result == BLUEA|| curr_result == BLUEB) { //calibration&lt;br /&gt;
      blinkOK();&lt;br /&gt;
      program = false;&lt;br /&gt;
      automat = false;&lt;br /&gt;
      noMotion();&lt;br /&gt;
      delay(500);&lt;br /&gt;
      forward();&lt;br /&gt;
      int loops = 0;&lt;br /&gt;
      int last_left = left_count;&lt;br /&gt;
      int last_right = right_count;&lt;br /&gt;
      bool left_pass = false;&lt;br /&gt;
      bool right_pass = false;&lt;br /&gt;
      while (loops &amp;lt; 12) {&lt;br /&gt;
        if (last_left != left_count) {&lt;br /&gt;
          left_pass = true;&lt;br /&gt;
        }&lt;br /&gt;
        if (last_right != right_count) {&lt;br /&gt;
          right_pass = true;&lt;br /&gt;
        }&lt;br /&gt;
        if (left_pass &amp;amp;&amp;amp; right_pass) {&lt;br /&gt;
          left_pass = false;&lt;br /&gt;
          right_pass = false;&lt;br /&gt;
          last_left = left_count;&lt;br /&gt;
          last_right = right_count;&lt;br /&gt;
          if (abs(right_interval - left_interval) &amp;lt; 80) {&lt;br /&gt;
            loops +=1;&lt;br /&gt;
          } else if (right_interval &amp;gt; left_interval) {&lt;br /&gt;
            motor1PWM += 1;&lt;br /&gt;
            analogWrite(en1,motor1PWM);&lt;br /&gt;
            loops = 0;&lt;br /&gt;
          } else {&lt;br /&gt;
            motor1PWM -= 1;&lt;br /&gt;
            analogWrite(en1,motor1PWM);&lt;br /&gt;
            loops = 0;&lt;br /&gt;
          }&lt;br /&gt;
          if(debug) {&lt;br /&gt;
            Serial.print(motor1PWM);&lt;br /&gt;
            Serial.print(&amp;quot; &amp;quot;);&lt;br /&gt;
            Serial.println(motor2PWM);&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      noMotion();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
La calibrazione: modifica la potenza di uno dei due motori fino a che gli intervalli degli encoder delle due ruote non sono quasi uguali. Occorre staccare i cingoli o mettere Ardubottino in un posto sopraelevato perché per funzionare ha bisogno di andare forward() per qualche minuto.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Progetti]]&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Ardubottino&amp;diff=6829</id>
		<title>Ardubottino</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Ardubottino&amp;diff=6829"/>
		<updated>2019-03-05T15:30:26Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ardubottino è stato creato soprattutto per testare tre componenti: l'Arduino, il sensore della distanza a ultrasuoni e il ponte ad H. Lo chassis e i motori sono Tamiya.&lt;br /&gt;
&lt;br /&gt;
[[File:Ardubottino.jpg]]&lt;br /&gt;
&lt;br /&gt;
= Prima Versione =&lt;br /&gt;
&lt;br /&gt;
== Componenti ==&lt;br /&gt;
Ardubottino ha questi componenti:&lt;br /&gt;
* Arduino UNO [http://arduino.cc/en/Main/arduinoBoardUno]&lt;br /&gt;
* Sensore di distanza a ultrasuoni SRF05 [http://www.robot-electronics.co.uk/htm/srf05tech.htm]&lt;br /&gt;
* Il board con montato il ponte ad H L298 [http://www.vetco.net/catalog/product_info.php?products_id=14337]&lt;br /&gt;
* Kit Tamiya per lo chassis e i motori&lt;br /&gt;
* Batteria da 9v&lt;br /&gt;
* Ulteriori batterie per il motore (inizialmente 4,5v, poi 4,8v)&lt;br /&gt;
&lt;br /&gt;
Il sensore di distanza è sprovvisto di pin, occorre quindi saldarne una strip prima di procedere.&lt;br /&gt;
&lt;br /&gt;
== Il sensore di distanza a ultrasuoni SRF05 ==&lt;br /&gt;
[[File:102_1298.JPG]]&lt;br /&gt;
&lt;br /&gt;
È piuttosto semplice da usare. Seguendo le istruzioni [ http://www.robot-electronics.co.uk/htm/srf05tech.htm trovate qui] si può notare che ha due modalità di comunicazioni, date dal pin Mode. Se questo pin è collegato alla 0v il sensore userà un solo pin per la comunicazione dei dati dell'eco (Echo) e la ricezione dei comandi (Trigger), se, al contrario, non è connesso a niente allora saranno usati due pin diversi. Nel caso dell'Ardubottino ho preferito usare la prima modalità, quella con un pin solo (soprattutto per pigrizia: perché è già così lo sketch di esempio &amp;quot;ping&amp;quot; nella libreria di Arduino!). Oltre al pin Mode e al pin Trigger/Echo occorre collegare il primo e l'ultimo pin rispettivamente a +5v e a terra.&lt;br /&gt;
Nella foto si può vedere, da sinistra: +5v, non usato, Trigger/Echo (collegato al pin 13 di Arduino), Mode (terra), Terra (terra).&lt;br /&gt;
&lt;br /&gt;
== Il board ponte ad H L298 ==&lt;br /&gt;
[[File:Ardubottino_dettagliol298.jpg]]&lt;br /&gt;
&lt;br /&gt;
Il ponte ad H L298 è utilissimo per manovrare due motori indipendenti. Può essere usato anche per muovere un motore passo-passo.&lt;br /&gt;
Ha due ingressi per la corrente: tramite un ponticello può essere separata fra corrente per la logica e corrente per i motori. La logica dev'essere alimentata da +5v; se l'alimentazione è separata, i motori possono ricevere fino a +12v. Per comodità (e anche dopo diversi goffi tentativi per capire come funzionava) ho preferito alimentare i motori solo con i 5v.&lt;br /&gt;
&lt;br /&gt;
Sui lati ci sono le connessioni per i motori mentre, a fianco dell'alimentazione, ci sono i pin che servono per comandarli. I pin sono sei, due sono gli enable per i motori e quattro servono per dare la direzione, due per motore. I pin dell'enable si possono chiudere con dei ponticelli, comandarli da Arduino/Raspberry Pi oppure gli si può mandare un impulso PWM per regolare la velocità.&lt;br /&gt;
&lt;br /&gt;
== Motori ad encoder, gioie (poche) e dolorer (tanto) ==&lt;br /&gt;
Il problema di Ardubottino è che non va dritto. Il motivo? Forse il ponte ad H non dà gli stessi voltaggi ai motori, forse i motori sono un po' diversi, forse si stanno usurando in modo diverso, forse i cingoli hanno qualche imperfezione, forse le ruote sono storte, forse è sbilanciato. Ad ogni modo ognuno di questi problemi (tranne le ruote storte e le imperfezioni dei cingoli) si sarebbero risolti scoprendo a che velocità vanno i motori. Per scoprire questo dato sono necessari gli encoder. Un encoder è una rotellina con dei fori e un sensore o due, composti da un LED e da un ricevitore a infrarossi, che sentono quando un foro è passato. Encoder di questo tipo si trovano ad esempio nelle rotelline dei mouse o in quelli che hanno ancora la pallina.&lt;br /&gt;
&lt;br /&gt;
[[File:EncoderArdubottino.JPG]]&lt;br /&gt;
&lt;br /&gt;
Ora: questi sarebbero degli encoder &amp;quot;fatti apposta&amp;quot; per il kit Tamiya. Uso il condizionale perché, se non sono stato io ad averli montati in modo approssimativo, il loro utilizzo è alquanto scomodo. Anzitutto la rotella non sta fissa sull'albero. Il foro esagonale è troppo grande e ha un notevole gioco. Il range del sensore è minimo e non tiene conto della struttura del kit Tamiya (la rotella va quasi a sfregare contro le viti che lo fissano allo chassis). Inoltre sono estremamente fragili: una delle rotelle si è spaccata subito in due. I sensori stessi, poi, non si incastrano nella sede e occorre incollarli.&lt;br /&gt;
La lettura degli encoder andrebbe fatta sfruttando gli interrupt di Arduino. Gli interrupt sono dei pin che restano in ascolto e fanno scattare degli eventi quando cambiano valore[http://arduino.cc/en/Reference/AttachInterrupt]. Purtroppo uno dei due pin (sull'Arduino Uno sono il pin 2 e il pin 3) dava dei risultati estremamente inaffidabili. Dopo varie prove, il risultato migliore l'ho ottenuto usando la libreria Encoder [http://www.pjrc.com/teensy/td_libs_Encoder.html] su due pin non di interrupt. Il risultato di tutta questa fatica è un robottino che grosso modo va dritto. Un risultato mediocre di molto inferiore alla calibrazione a occhio. Alla fine, infatti, ho preferito quest'ultima.&lt;br /&gt;
&lt;br /&gt;
== Lo sketch ==&lt;br /&gt;
&lt;br /&gt;
Lo sketch deriva per una parte dall'esempio ''Ping'' già presente nella libreria di Arduino. In pratica fa avanzare Ardubottino fino a che non incontra un ostacolo. Se lo incontra sterza in un senso e poi nell'altro e alla fine prosegue per la direzione dove ha trovato più campo libero.&lt;br /&gt;
4 7 6 5 sono i  pin a cui ho collegato il ponte ad H. Sterzo è il tempo che deve impiegare per sterzare. pinping è il pin a cui è attaccato il trigger/echo del sensore a ultrasuoni.&lt;br /&gt;
 long duration;&lt;br /&gt;
 long dursx;&lt;br /&gt;
 long durdx; &lt;br /&gt;
 const int en1 = 11; //pin enable&lt;br /&gt;
 const int en2 = 9;&lt;br /&gt;
 const int m1fd = 4; //controlli motore&lt;br /&gt;
 const int m2fd = 7;&lt;br /&gt;
 const int m1bk = 5;&lt;br /&gt;
 const int m2bk = 6;&lt;br /&gt;
 const int pinping = 13; //pin sensore distanza&lt;br /&gt;
 const int sterzo = 600; //durata dello sterzo&lt;br /&gt;
 const int distanza = 500; //distanza minima ostacoli&lt;br /&gt;
 int motore1 = 67;//pwm motore dx&lt;br /&gt;
 int motore2 = 74;//pwm motore sx&lt;br /&gt;
 &lt;br /&gt;
 void setup() {&lt;br /&gt;
  pinMode(m1fd, OUTPUT);&lt;br /&gt;
  pinMode(m1bk, OUTPUT);&lt;br /&gt;
  pinMode(m2fd, OUTPUT);&lt;br /&gt;
  pinMode(m2bk, OUTPUT);&lt;br /&gt;
  pinMode(en1, OUTPUT);&lt;br /&gt;
  pinMode(en2, OUTPUT);&lt;br /&gt;
  analogWrite(en1,motore1);&lt;br /&gt;
  analogWrite(en2,motore2);&lt;br /&gt;
  dritto();&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void loop() {&lt;br /&gt;
  if (echo() &amp;lt; distanza){ //trovato un ostacolo&lt;br /&gt;
   analogWrite(en1,170);&lt;br /&gt;
   analogWrite(en2,170);&lt;br /&gt;
   ferma();&lt;br /&gt;
   sinistra();&lt;br /&gt;
   delay(sterzo);&lt;br /&gt;
   ferma();&lt;br /&gt;
   dursx = echo(); //guarda a sinistra&lt;br /&gt;
   destra();&lt;br /&gt;
   delay(sterzo*2);&lt;br /&gt;
   ferma();&lt;br /&gt;
   durdx = echo(); //guarda a destra&lt;br /&gt;
   if (dursx &amp;lt; distanza &amp;amp;&amp;amp; durdx &amp;lt; distanza){&lt;br /&gt;
     destra();&lt;br /&gt;
     delay(sterzo);&lt;br /&gt;
   } else if (dursx &amp;gt; durdx) {&lt;br /&gt;
     sinistra();&lt;br /&gt;
     delay(sterzo*2);&lt;br /&gt;
   } //sceglie dove c'è più spazio&lt;br /&gt;
   dritto();&lt;br /&gt;
   analogWrite(en1,motore1);&lt;br /&gt;
   analogWrite(en2,motore2);&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void dritto() {&lt;br /&gt;
  digitalWrite(m1bk,LOW);&lt;br /&gt;
  digitalWrite(m2bk,LOW);&lt;br /&gt;
  digitalWrite(m2fd,HIGH);&lt;br /&gt;
  digitalWrite(m1fd,HIGH);   &lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void rovescia() {&lt;br /&gt;
  digitalWrite(m1fd,LOW);&lt;br /&gt;
  digitalWrite(m2fd,LOW);&lt;br /&gt;
  digitalWrite(m1bk,HIGH);&lt;br /&gt;
  digitalWrite(m2bk,HIGH);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void destra() {&lt;br /&gt;
  digitalWrite(m1fd,LOW);&lt;br /&gt;
  digitalWrite(m2fd,HIGH);&lt;br /&gt;
  digitalWrite(m1bk,HIGH);&lt;br /&gt;
  digitalWrite(m2bk,LOW);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sinistra() {&lt;br /&gt;
  digitalWrite(m1fd,HIGH);&lt;br /&gt;
  digitalWrite(m2fd,LOW);&lt;br /&gt;
  digitalWrite(m1bk,LOW);&lt;br /&gt;
  digitalWrite(m2bk,HIGH);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void ferma() {&lt;br /&gt;
  digitalWrite(m1fd,LOW);&lt;br /&gt;
  digitalWrite(m2fd,LOW);&lt;br /&gt;
  digitalWrite(m1bk,LOW);&lt;br /&gt;
  digitalWrite(m2bk,LOW);&lt;br /&gt;
  delay(50);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 long echo() {&lt;br /&gt;
  pinMode(pinping, OUTPUT);&lt;br /&gt;
  digitalWrite(pinping, LOW);&lt;br /&gt;
  delayMicroseconds(2);&lt;br /&gt;
  digitalWrite(pinping, HIGH);&lt;br /&gt;
  delayMicroseconds(5);&lt;br /&gt;
  digitalWrite(pinping, LOW);&lt;br /&gt;
  pinMode(pinping, INPUT);&lt;br /&gt;
  duration = pulseIn(pinping,HIGH);&lt;br /&gt;
  return duration;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
= Seconda Versione =&lt;br /&gt;
Ok, la modifica è un po' minima per essere una vera e propria seconda versione, ma dopo il fallimento degli encoder ero un po' giù di morale.&lt;br /&gt;
Il progetto era di rendere Ardubottino telecomandabile con qualche mezzo estremamente low cost e nella maniera più semplice possibile. La mia scelta è caduta sull'infrarosso.&lt;br /&gt;
&lt;br /&gt;
== Il sensore a infrarossi ==&lt;br /&gt;
[[File:Arduir.jpg]]&lt;br /&gt;
&lt;br /&gt;
Quello che potete vedere nella foto è un sensore a infrarossi come quelli che potreste recuperare in qualsivoglia elettrodomestico. I sensori IR hanno tre pin: +5v, terra e dati. Questo in particolare aveva le stesse specifiche di quest'altro[http://learn.adafruit.com/ir-sensor/testing-an-ir-sensor] usato nel tutorial di Adafruit per leggere gli impulsi infrarossi con Arduino. Potrebbero non essere tutti uguali, quindi cautela.&lt;br /&gt;
&lt;br /&gt;
== La libreria IRremote ==&lt;br /&gt;
Gran parte del lavoro lo fa la libreria IRremote (che trovate qui [https://github.com/shirriff/Arduino-IRremote]). Con questo sketch [http://www.mediafire.com/view/6qnsndqp9a838xe/Decode_IR.ino] si possono leggere, sotto forma di cifre, i codici del telecomando che volete usare. Tramite il monitor seriale noterete dapprincipio che ogni tasto ha assegnato due codici, questo per fare in modo che ci sia una differenza fra tenere premuto il tasto (dà lo stesso codice in uscita, in modo continuo) e dei clic ripetuti (ogni clic diverso il codice cambia). Con questo sketch sono riuscito a capire che il codice del tasto SU del telecomando era legato ai codici 2742014623 e 31889539.&lt;br /&gt;
La libreria IRremote permette anche di trasmettere, ma per ora non sfrutteremo questa sua proprietà. Potete trovare più informazioni qui [http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html]&lt;br /&gt;
&lt;br /&gt;
== Lo sketch finale ==&lt;br /&gt;
Non ho voluto togliere all'Ardubottino la possibilità di andarsene in giro da solo, quindi ho assegnato al tasto OK del telecomando la capacità di passare dallo stato manuale a quello automatico.&lt;br /&gt;
La libreria IRremote ci permette di creare la classe IRrecv che, tramite i suoi metodi, prepara (enableIrIN) , legge (decode), e aspetta il prossimo segnale (resume). I valori sono memorizzati nella struttura decode_results, il cui valore value è il codice del segnale del telecomando. La variabile booleana automat determina se Ardubottino è in modalità automatica o meno.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#FF0000&amp;quot;&amp;gt;ATTENZIONE: La libreria IRremote.h non è compatibile con la libreria RobotIRRemote fornita con l'ultima versione della IDE di Arduino. Per compilare questo sketch occorre prima disabilitare RobotIRRemote. Per disabilitare una libreria occorre andare in arduino/libraries e spostare la cartella della libreria in un altro posto.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  #include &amp;lt;IRremote.h&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  int IRpin =2; //pin del sensore IR&lt;br /&gt;
  IRrecv irrecv(IRpin);&lt;br /&gt;
  long duration;&lt;br /&gt;
  long dursx;&lt;br /&gt;
  long durdx;&lt;br /&gt;
  &lt;br /&gt;
  const int en1 = 10; //pin enable&lt;br /&gt;
  const int en2 = 9;&lt;br /&gt;
  const int m1fd = 4; //controlli motore&lt;br /&gt;
  const int m2fd = 7;&lt;br /&gt;
  const int m1bk = 5;&lt;br /&gt;
  const int m2bk = 6;&lt;br /&gt;
  const int pinping = 13; //pin sensore distanza&lt;br /&gt;
  const int sterzo = 600; //durata dello sterzo&lt;br /&gt;
  const int distanza = 500; //distanza minima ostacoli&lt;br /&gt;
  int motore1 = 66;//pwm motore dx&lt;br /&gt;
  int motore2 = 72;//pwm motore sx&lt;br /&gt;
  boolean automat = false;&lt;br /&gt;
  &lt;br /&gt;
  decode_results results;&lt;br /&gt;
  &lt;br /&gt;
  void setup() {&lt;br /&gt;
   pinMode(m1fd, OUTPUT);&lt;br /&gt;
   pinMode(m1bk, OUTPUT);&lt;br /&gt;
   pinMode(m2fd, OUTPUT);&lt;br /&gt;
   pinMode(m2bk, OUTPUT);&lt;br /&gt;
   pinMode(en1, OUTPUT);&lt;br /&gt;
   pinMode(en2, OUTPUT);&lt;br /&gt;
   analogWrite(en1,motore1);&lt;br /&gt;
   analogWrite(en2,motore2);&lt;br /&gt;
   irrecv.enableIRIn();&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  void loop() {&lt;br /&gt;
    if(irrecv.decode(&amp;amp;results)){&lt;br /&gt;
      if (!automat) {&lt;br /&gt;
        if(results.value == 2742014623 || results.value == 31889539){&lt;br /&gt;
          dritto();&lt;br /&gt;
        } else if (results.value == 2383694249 || results.value == 2039764837 ) {&lt;br /&gt;
          sinistra();&lt;br /&gt;
        } else if (results.value == 15111918 || results.value == 2725237002) {&lt;br /&gt;
          rovescia();&lt;br /&gt;
        } else if (results.value == 1665824360 || results.value == 3250666572 ) {&lt;br /&gt;
          destra();&lt;br /&gt;
        } else  {&lt;br /&gt;
          ferma();&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      if (results.value == 3969632309 || results.value == 18594425) {&lt;br /&gt;
        if (automat) {&lt;br /&gt;
          automat = false;&lt;br /&gt;
          ferma();&lt;br /&gt;
          delayMicroseconds(300000);  &lt;br /&gt;
        }else{&lt;br /&gt;
          automat = true;&lt;br /&gt;
          dritto();&lt;br /&gt;
          delayMicroseconds(300000);&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      irrecv.resume();&lt;br /&gt;
    }&lt;br /&gt;
    if (automat &amp;amp;&amp;amp; echo() &amp;lt; distanza){ //trovato un ostacolo&lt;br /&gt;
     analogWrite(en1,170);&lt;br /&gt;
     analogWrite(en2,170);&lt;br /&gt;
     ferma();&lt;br /&gt;
     sinistra();&lt;br /&gt;
     delay(sterzo);&lt;br /&gt;
     ferma();&lt;br /&gt;
     dursx = echo(); //guarda a sinistra&lt;br /&gt;
     destra();&lt;br /&gt;
     delay(sterzo*2);&lt;br /&gt;
     ferma();&lt;br /&gt;
     durdx = echo(); //guarda a destra&lt;br /&gt;
     if (dursx &amp;lt; distanza &amp;amp;&amp;amp; durdx &amp;lt; distanza){&lt;br /&gt;
       destra();&lt;br /&gt;
       delay(sterzo);&lt;br /&gt;
     } else if (dursx &amp;gt; durdx) {&lt;br /&gt;
       sinistra();&lt;br /&gt;
       delay(sterzo*2);&lt;br /&gt;
     } //sceglie dove c'è più spazio&lt;br /&gt;
     dritto();&lt;br /&gt;
     analogWrite(en1,motore1);&lt;br /&gt;
     analogWrite(en2,motore2);&lt;br /&gt;
   }&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  void dritto() {&lt;br /&gt;
   digitalWrite(m1bk,LOW);&lt;br /&gt;
   digitalWrite(m2bk,LOW);&lt;br /&gt;
   digitalWrite(m2fd,HIGH);&lt;br /&gt;
   digitalWrite(m1fd,HIGH);   &lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  void rovescia() {&lt;br /&gt;
   digitalWrite(m1fd,LOW);&lt;br /&gt;
   digitalWrite(m2fd,LOW);&lt;br /&gt;
   digitalWrite(m1bk,HIGH);&lt;br /&gt;
   digitalWrite(m2bk,HIGH);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  void destra() {&lt;br /&gt;
   digitalWrite(m1fd,LOW);&lt;br /&gt;
   digitalWrite(m2fd,HIGH);&lt;br /&gt;
   digitalWrite(m1bk,HIGH);&lt;br /&gt;
   digitalWrite(m2bk,LOW);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  void sinistra() {&lt;br /&gt;
   digitalWrite(m1fd,HIGH);&lt;br /&gt;
   digitalWrite(m2fd,LOW);&lt;br /&gt;
   digitalWrite(m1bk,LOW);&lt;br /&gt;
   digitalWrite(m2bk,HIGH);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  void ferma() {&lt;br /&gt;
   digitalWrite(m1fd,LOW);&lt;br /&gt;
   digitalWrite(m2fd,LOW);&lt;br /&gt;
   digitalWrite(m1bk,LOW);&lt;br /&gt;
   digitalWrite(m2bk,LOW);&lt;br /&gt;
   delay(50);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  long echo() {&lt;br /&gt;
   pinMode(pinping, OUTPUT);&lt;br /&gt;
   digitalWrite(pinping, LOW);&lt;br /&gt;
   delayMicroseconds(2);&lt;br /&gt;
   digitalWrite(pinping, HIGH);&lt;br /&gt;
   delayMicroseconds(5);&lt;br /&gt;
   digitalWrite(pinping, LOW);&lt;br /&gt;
   pinMode(pinping, INPUT);&lt;br /&gt;
   duration = pulseIn(pinping,HIGH);&lt;br /&gt;
   return duration;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
= Terza Versione =&lt;br /&gt;
Dopo l'ennesimo disastroso trasporto di Ardubottino, nel quale si è smontato tutto, ho deciso di dargli una sistemata definitiva. Saldature migliori, componenti fissati e meno fili volanti. Inoltre sono state fatte le seguenti modifiche.&lt;br /&gt;
&lt;br /&gt;
[[File:ardubottino_3ver.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Passaggio dal Micro al Pro Mini ==&lt;br /&gt;
Per ragioni di spazio sono passato dall'Arduino Micro al Pro Mini della Deek Robots.&lt;br /&gt;
&lt;br /&gt;
[[File:Newardbot2.JPG]]&lt;br /&gt;
&lt;br /&gt;
C'è poco da dire su questa board. È sotto tutti gli aspetti un Arduino Pro Mini. Per essere programmato ha bisogno dell'adattatore USB. Purtroppo, come si può vedere nell'immagine, l'ho montato alla rovescia sulla breadboard e così non è possibile capire il numero dei pin. Capirci qualcosa è stato particolarmente ostico.&lt;br /&gt;
&lt;br /&gt;
== Abbastanza batterie ==&lt;br /&gt;
Avere l'alimentazione separata motori/logica è una soluzione che non mi soddisfa per niente. Come fare però per fare in modo che gli spikes dei motori non facciano riavviare l'Arduino? La questione è stata risolta in questa maniera.&lt;br /&gt;
&lt;br /&gt;
=== Condensatori ===&lt;br /&gt;
Sono stati aggiunti dei condensatori ai motori. In questo modo lo spike dovrebbe essere assorbito in parte.&lt;br /&gt;
&lt;br /&gt;
=== L'Arduino e i motori hanno una sorgente comune ===&lt;br /&gt;
Le batterie dei motori, 4 stilo da 2100mAh l'una, hanno amperaggio più che sufficiente per tenere acceso Arduino e motori. Dal + delle batterie partono due fili, uno va all'Arduino e l'altro al ponte ad H. Nei tentativi precedenti, davo al ponte ad H l'uscita a 5v dell'Arduino. Evidentemente la richiesta dei motori era eccessiva per il regolatore a 5v.&lt;br /&gt;
&lt;br /&gt;
== Turbo! ==&lt;br /&gt;
Aggiunta la modalità turbo, che fa andare il ns. robot più veloce!&lt;br /&gt;
&lt;br /&gt;
== Altri problemi ==&lt;br /&gt;
Avrei voluto mettere il sensore a ultrasuoni su un servo ma un bug della libreria Servo blocca il PWM in alcuni pin[http://forum.arduino.cc/index.php?topic=243264.0] per cui ho lasciato perdere.&lt;br /&gt;
&lt;br /&gt;
== Nuovo codice! ==&lt;br /&gt;
Inutile incollarlo qui. Ho aperto uno spazio su GitHub:&lt;br /&gt;
&lt;br /&gt;
[https://github.com/raspibo/ardubottino Link]&lt;br /&gt;
&lt;br /&gt;
= Quarta versione =&lt;br /&gt;
Era giunto il momento di sfruttare un po' di roba che rimaneva inutilizzata.&lt;br /&gt;
Le modifiche sono state:&lt;br /&gt;
&lt;br /&gt;
* Encoder, stavolta funzionanti&lt;br /&gt;
* Calibrazione automatica&lt;br /&gt;
* Modalità programmazione&lt;br /&gt;
* Blocco quando una ruota non gira&lt;br /&gt;
* Sensore di caduta&lt;br /&gt;
&lt;br /&gt;
== Encoders ==&lt;br /&gt;
Nonostante abbia rotto le rondelle originali (che comunque erano fatte malissimo) sono riuscito a trovare alcuni modelli funzionanti. Il PLA azzurro, a differenza di quello bianco e di quello nero, sembra riflettere l'infrarosso dell'encoder. Tutto stava nel capire quale forma funzionasse meglio.&lt;br /&gt;
&lt;br /&gt;
[[File:Arduencoder.JPG]]&lt;br /&gt;
&lt;br /&gt;
La forma che funziona meglio (per ora) è quella a destra. Potete trovare l'STL nel [https://github.com/raspibo/ardubottino repository ardubottino su GitHub].&lt;br /&gt;
&lt;br /&gt;
Il problema principale, nel creare questo tipo di oggetto in 3D, è stato il foro a forma di prisma esagonale. In Blender occorre creare un cilindro, ridurre i vertici a 6 e poi modificarne la dimensione solo con lo strumento proporzionale, in modo da non deformarlo.&lt;br /&gt;
&lt;br /&gt;
[[File:Newardbot3.JPG]]&lt;br /&gt;
&lt;br /&gt;
Gli encoder permettono di fare diverse cose interessanti. Ora Ardubottino sente quando una ruota non sta girando, ad esempio, inoltre sono state aggiunte due nuove modalità: la modalità &amp;quot;programmazione&amp;quot; (vai avanti di 10, poi gira a destra di 5, ecc.) e la modalità &amp;quot;calibrazione&amp;quot; (modifica la velocità di un motore fino a che le ruote non girano più o meno uguali).&lt;br /&gt;
&lt;br /&gt;
Purtroppo gli encoder non sono tanto precisi, ogni tanto leggono male e segnano un passo in più o in meno. Questo però era così anche con le rotelle originali.&lt;br /&gt;
&lt;br /&gt;
== Il sensore di caduta ==&lt;br /&gt;
Posto sul davanti, sente quando ad Ardubottino manca la terra sotto i cingoli. Quando sente il vuoto ferma tutto.&lt;br /&gt;
&lt;br /&gt;
[[File:Newardbot1.JPG]]&lt;br /&gt;
&lt;br /&gt;
== Il codice ==&lt;br /&gt;
Il codice sta diventando veramente troppo lungo per essere incollato qui, su questa pagina, per cui ne commenterò solo alcune parti. Lo sketch completo lo trovate su [https://github.com/raspibo/ardubottino GitHub].&lt;br /&gt;
&lt;br /&gt;
 #include &amp;quot;ardubottino.h&amp;quot;&lt;br /&gt;
Sì, era ora che creassi un header con tutti i codici del telecomando. Per adattare Ardubottino a un altro telecomando basterà cambiare header.&lt;br /&gt;
&lt;br /&gt;
 volatile long right_interval = 0;&lt;br /&gt;
 volatile long left_interval = 0;&lt;br /&gt;
 volatile int right_count = 0;&lt;br /&gt;
 volatile int left_count = 0;&lt;br /&gt;
&lt;br /&gt;
Le variabili che sono modificate dagli encoder devono essere di tipo &amp;quot;volatile&amp;quot;. Le variabili volatile possono essere cambiate da un evento esterno, nel nostro caso da un evento scatenato da un interrupt.&lt;br /&gt;
  &lt;br /&gt;
 void right_encoder() {&lt;br /&gt;
  static unsigned long last_interrupt = 0;&lt;br /&gt;
  unsigned long time_interrupt = millis();&lt;br /&gt;
  if(time_interrupt - last_interrupt &amp;gt;70){&lt;br /&gt;
    right_interval = time_interrupt - last_interrupt;&lt;br /&gt;
    next_check_right = millis()+right_interval*2;&lt;br /&gt;
    right_count +=1;&lt;br /&gt;
    last_interrupt = time_interrupt;&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void left_encoder() {&lt;br /&gt;
  static unsigned long last_interrupt = 0;&lt;br /&gt;
  unsigned long time_interrupt = millis();&lt;br /&gt;
  if(time_interrupt - last_interrupt &amp;gt;70) {&lt;br /&gt;
    left_interval = millis() - last_interrupt;&lt;br /&gt;
    next_check_left = millis()+left_interval*2;&lt;br /&gt;
    left_count +=1;&lt;br /&gt;
    last_interrupt = millis();&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Ecco le brevi funzioni chiamate da &lt;br /&gt;
  attachInterrupt(0, right_encoder,RISING);&lt;br /&gt;
  attachInterrupt(1, left_encoder,RISING);&lt;br /&gt;
gli interrupt.&lt;br /&gt;
La variabile x_count conta quanti giri (quanti quarti di giro) ha fatto la ruota; x_interval l'intervallo, in millisecondi, fra un passaggio e l'altro; next_check_x è una stima massima di quando dovrebbe essere il prossimo passaggio, serve per capire se una ruota s'è inceppata.&lt;br /&gt;
&lt;br /&gt;
  if (irrecv.decode(&amp;amp;results)) {&lt;br /&gt;
   curr_result = results.value;&lt;br /&gt;
   if (curr_result == prev_result) {&lt;br /&gt;
     curr_result = 0;&lt;br /&gt;
   } else {&lt;br /&gt;
     prev_result = curr_result;&lt;br /&gt;
   }&lt;br /&gt;
 (...)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Ricordate quando vi dissi che il telecomando per ogni tasto ha due codici? Serve per distinguere se state tenendo premuto il tasto o se lo state premendo più volte contemporaneamente. Con questo piccolo brandello di codice faccio in modo di ignorare i codici ripetuti, visto che ad Ardubottino non servono. Non tutti i telecomandi funzionano così.&lt;br /&gt;
 if (program) {&lt;br /&gt;
      if (curr_result == OKA || curr_result == OKB) {&lt;br /&gt;
        blinkOK();&lt;br /&gt;
        executeProgram();&lt;br /&gt;
        clearMoves();&lt;br /&gt;
        noMotion();&lt;br /&gt;
      } else if (curr_result == NUM1A || curr_result == NUM1B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +1;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM2A || curr_result == NUM2A) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +2;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM3A || curr_result == NUM3B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +3;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM4A || curr_result == NUM4B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +4;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM5A || curr_result == NUM5B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +5;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM6A || curr_result == NUM6B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +6;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM7A || curr_result == NUM7B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +7;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM8A || curr_result == NUM8B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +8;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM9A || curr_result == NUM9B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +9;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM0A || curr_result == NUM0B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10);   &lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == FORWARDA || curr_result == FORWARDB) {&lt;br /&gt;
        moves[pointer][1] = 1;&lt;br /&gt;
        pointer ++;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == BACKA || curr_result == BACKB) {&lt;br /&gt;
        moves[pointer][1] = 2;&lt;br /&gt;
        pointer ++;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == LEFTA || curr_result == LEFTB) {&lt;br /&gt;
        moves[pointer][1] = 3;&lt;br /&gt;
        pointer ++;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == RIGHTA || curr_result == RIGHTB) {&lt;br /&gt;
        moves[pointer][1] = 4;&lt;br /&gt;
        pointer ++;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == WINA || curr_result == WINB) {&lt;br /&gt;
        clearMoves();&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else {&lt;br /&gt;
        blinkNO();&lt;br /&gt;
      }&lt;br /&gt;
      if(moves[pointer][0] &amp;gt; 99) {&lt;br /&gt;
       moves[pointer][0] = moves[pointer][0]-((moves[pointer][0]/100)*100);&lt;br /&gt;
      }&lt;br /&gt;
      if (pointer &amp;gt;49) {&lt;br /&gt;
        executeProgram();&lt;br /&gt;
      }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Et voilà: 50 mosse programmabili per il nostro robottino. Si scrive un numero di massimo 2 cifre e una direzione per massimo 50 istruzioni. Premendo OK si dà inizio al programma.&lt;br /&gt;
Ho anche aggiunto un lampeggiamento del LED di bordo in modo da dare un feedback visivo. Come ben saprete, i telecomandi a volte non trasmettono bene.&lt;br /&gt;
&lt;br /&gt;
 void executeProgram() {&lt;br /&gt;
  int right_count_program = right_count;&lt;br /&gt;
  &lt;br /&gt;
  for (int x=0;x&amp;lt;=49;x++){&lt;br /&gt;
    if (moves[x][1] == 0) {&lt;br /&gt;
      break;&lt;br /&gt;
    } else if (moves[x][1] == 1){&lt;br /&gt;
      forward();&lt;br /&gt;
    } else if (moves[x][1] == 2){&lt;br /&gt;
      backward();&lt;br /&gt;
    } else if (moves[x][1] == 3){&lt;br /&gt;
      left();&lt;br /&gt;
    } else if (moves[x][1] == 4){&lt;br /&gt;
      right();&lt;br /&gt;
    }&lt;br /&gt;
    while(moves[x][0] &amp;gt; 0) {&lt;br /&gt;
      if (right_count_program != right_count ) {&lt;br /&gt;
        moves[x][0] --;&lt;br /&gt;
        right_count_program = right_count;&lt;br /&gt;
        &lt;br /&gt;
      }&lt;br /&gt;
      if (digitalRead(fall)) {      &lt;br /&gt;
        noMotion();&lt;br /&gt;
        program = false;&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    moves[x][1] = 0;&lt;br /&gt;
  }&lt;br /&gt;
  program = false;&lt;br /&gt;
  noMotion();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Come potete vedere a metà c'è anche un check (c'è anche per le modalità automatica e manuale) sul sensore di caduta.&lt;br /&gt;
&lt;br /&gt;
 if (curr_result == BLUEA|| curr_result == BLUEB) { //calibration&lt;br /&gt;
      blinkOK();&lt;br /&gt;
      program = false;&lt;br /&gt;
      automat = false;&lt;br /&gt;
      noMotion();&lt;br /&gt;
      delay(500);&lt;br /&gt;
      forward();&lt;br /&gt;
      int loops = 0;&lt;br /&gt;
      int last_left = left_count;&lt;br /&gt;
      int last_right = right_count;&lt;br /&gt;
      bool left_pass = false;&lt;br /&gt;
      bool right_pass = false;&lt;br /&gt;
      while (loops &amp;lt; 12) {&lt;br /&gt;
        if (last_left != left_count) {&lt;br /&gt;
          left_pass = true;&lt;br /&gt;
        }&lt;br /&gt;
        if (last_right != right_count) {&lt;br /&gt;
          right_pass = true;&lt;br /&gt;
        }&lt;br /&gt;
        if (left_pass &amp;amp;&amp;amp; right_pass) {&lt;br /&gt;
          left_pass = false;&lt;br /&gt;
          right_pass = false;&lt;br /&gt;
          last_left = left_count;&lt;br /&gt;
          last_right = right_count;&lt;br /&gt;
          if (abs(right_interval - left_interval) &amp;lt; 80) {&lt;br /&gt;
            loops +=1;&lt;br /&gt;
          } else if (right_interval &amp;gt; left_interval) {&lt;br /&gt;
            motor1PWM += 1;&lt;br /&gt;
            analogWrite(en1,motor1PWM);&lt;br /&gt;
            loops = 0;&lt;br /&gt;
          } else {&lt;br /&gt;
            motor1PWM -= 1;&lt;br /&gt;
            analogWrite(en1,motor1PWM);&lt;br /&gt;
            loops = 0;&lt;br /&gt;
          }&lt;br /&gt;
          if(debug) {&lt;br /&gt;
            Serial.print(motor1PWM);&lt;br /&gt;
            Serial.print(&amp;quot; &amp;quot;);&lt;br /&gt;
            Serial.println(motor2PWM);&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      noMotion();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
La calibrazione: modifica la potenza di uno dei due motori fino a che gli intervalli degli encoder delle due ruote non sono quasi uguali. Occorre staccare i cingoli o mettere Ardubottino in un posto sopraelevato perché per funzionare ha bisogno di andare forward() per qualche minuto.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Progetti]]&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6821</id>
		<title>Installare MicroPython su NUCLEO-F401RE</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6821"/>
		<updated>2019-03-02T15:45:21Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* Caricare uno script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questa guida è basata quasi tutta su quella di Carmine Noviello https://www.carminenoviello.com/2015/06/03/running-micropyton-stm32nucleo-f4/ che peraltro trovate anche in italiano https://www.carminenoviello.com/it/2015/08/11/compilare-micropython-una-scheda-stm32nucleo-f4/ per cui scriverò solo le differenze.&lt;br /&gt;
&lt;br /&gt;
La versione di Carmine di micropython, che si trova sul suo [https://github.com/cnoviello/micropython github], risolve il problema relativo alla mancanza di memoria SD della scheda Nucleo. Il file con il programma .py sarà caricato direttamente sulla flash.&lt;br /&gt;
&lt;br /&gt;
= La scheda =&lt;br /&gt;
&lt;br /&gt;
NUCLEO-F401RE della STMicroelectronics è una scheda basata su ARM Cortex M4 e fa parte della famiglia STM32 Nucleo Boards. Ha 512KB di Flash, 96 KB di SRAM, un clock di 84MHz, 50 GPIO, RTC, supporto I²C, SPI, USART e molto altro ([https://os.mbed.com/platforms/ST-Nucleo-F401RE/ maggiori info]). La sua forma le permette di alloggiare sia gli shield per Arduino che le estensioni Morpho di STMicroelectronics.&lt;br /&gt;
Il prezzo è abbastanza contenuto (attorno ai 12€ su Mouser) il che ne fa una scheda piuttosto interessante.&lt;br /&gt;
&lt;br /&gt;
Normalmente si programmerebbe tramite l'[https://ide.mbed.com/compiler editor online di Mbed]. Il compilatore genererà dal nostro codice un file con estensione bin. Collegando la scheda verrà montato un volume, chiamato &amp;quot;NUCLEO&amp;quot; sul quale caricare il file bin. Quando la scheda verrà resettata, il codice verrà eseguito. È possibile anche usare editor offline con toolchain di compilazione come Eclipse. Non credo sia possibile usare la IDE di Arduino.&lt;br /&gt;
&lt;br /&gt;
= Installazione MicroPython =&lt;br /&gt;
&lt;br /&gt;
== Primo tentativo ==&lt;br /&gt;
&lt;br /&gt;
=== Toolchain e OpenOCD ===&lt;br /&gt;
&lt;br /&gt;
Per compilare vi servirà la toolchain gcc-arm-embedded. Non è nei repo ufficiali quindi la dovete installare a mano oppure aggiungere un PPA. https://launchpad.net/gcc-arm-embedded&lt;br /&gt;
Il programma per comunicare col debugger della scheda, openocd, invece è nei repo di Debian.&lt;br /&gt;
 &lt;br /&gt;
=== Come installare MicroPython ===&lt;br /&gt;
&lt;br /&gt;
Potete seguire la guida di Carmine per la compilazione. Ovviamente se avete installato la toolchain con apt non è necessario aggiungere il path a tutti i comandi, perché sono già dentro a /usr/bin.&lt;br /&gt;
&lt;br /&gt;
OpenOCD ci permette di caricare il firmware che abbiamo crosscompilato. Basterà lanciare il comando:&lt;br /&gt;
 $ openocd  -f board/st_nucleo_f4.cfg&lt;br /&gt;
Un LED della scheda dovrebbe lampeggiare rosso/verde. Il debugger è attivo. Per collegarcisi:&lt;br /&gt;
 $ telnet localhost 4444&lt;br /&gt;
e poi scrivete:&lt;br /&gt;
 &amp;gt; reset halt&lt;br /&gt;
e infine:&lt;br /&gt;
 &amp;gt; flash write_image erase &amp;lt;file .elf da flashare&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inizialmente non sembrava funzionare. Il tentativo finale che ha sbloccato la situazione è stato dare il comando shutdown. Non sono sicuro però che sia stato proprio quel comando e bisognerebbe indagare meglio.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dall'interprete ===&lt;br /&gt;
&lt;br /&gt;
Aprendo la porta della nostra scheda (la trovate su dmesg non appena la attaccate, è /dev/ttyACMx dove x è un numero che parte da 0) con un emulatore di terminale (come console) alla velocità di 115200 baud, dovreste vedere l'interprete dei comandi di MicroPython. Provate a dare il comando:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pyb.LED(1).on()&lt;br /&gt;
per vedere se si accende il LED onboard.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dal PC ===&lt;br /&gt;
&lt;br /&gt;
Fra i tool di MicroPython, che trovate nella cartella di git micropython/tools, c'è pyboard.py, un programma che vi permette di eseguire uno script in MicroPython. Se la vostra porta non è accessibile dall'utente dovrete usare sudo.&lt;br /&gt;
 # ./pyboard.py &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Carmine ha fatto una modifica a pyboard in modo che possa caricare un file sulla board.&lt;br /&gt;
 # ./pyboard.py --device=/dev/ttyACMx --send &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
MicroPython ha due file di default quando viene installato: boot.py e main.py. Il primo è un file di sistema che serve allo stesso MicroPython di partire. Non occorre di solito modificarlo. Il secondo, main.py, è uno script che viene eseguito all'avvio. Se carichiamo un file main.py questo verrà eseguito all'accensione.&lt;br /&gt;
&lt;br /&gt;
=== Considerazioni finali ===&lt;br /&gt;
&lt;br /&gt;
Molto bene, ma la versione di micropython non è aggiornata. Forse è per questo che non riesco a far funzionare la porta I²C?&lt;br /&gt;
&lt;br /&gt;
== Secondo tentativo ==&lt;br /&gt;
&lt;br /&gt;
Boochow fornisce dei firmware già compilati su https://blog.boochow.com/micropython-firmware-for-mbed-boards basta scegliere la board giusta e caricare il file .bin nel volume &amp;quot;NUCLEO&amp;quot; che si monta quando si collega la USB.&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Un modo piuttosto comodo di inviare e ricevere file sulla flash della Nucleo è usare uPyLoader:&lt;br /&gt;
https://github.com/BetaRavener/uPyLoader/&lt;br /&gt;
ma quasi sempre dà un errore di timeout.&lt;br /&gt;
&lt;br /&gt;
Il programma fornito da Adafruit sembra funzionare decisamente meglio&lt;br /&gt;
https://learn.adafruit.com/micropython-basics-load-files-and-run-code/install-ampy&lt;br /&gt;
&lt;br /&gt;
Per installarlo usare pip (o pip3):&lt;br /&gt;
 pip install adafruit-ampy&lt;br /&gt;
&lt;br /&gt;
Per usarlo:&lt;br /&gt;
 ampy -p &amp;lt;porta seriale&amp;gt; put &amp;lt;nome file&amp;gt;&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6820</id>
		<title>Installare MicroPython su NUCLEO-F401RE</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6820"/>
		<updated>2019-03-02T15:43:10Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questa guida è basata quasi tutta su quella di Carmine Noviello https://www.carminenoviello.com/2015/06/03/running-micropyton-stm32nucleo-f4/ che peraltro trovate anche in italiano https://www.carminenoviello.com/it/2015/08/11/compilare-micropython-una-scheda-stm32nucleo-f4/ per cui scriverò solo le differenze.&lt;br /&gt;
&lt;br /&gt;
La versione di Carmine di micropython, che si trova sul suo [https://github.com/cnoviello/micropython github], risolve il problema relativo alla mancanza di memoria SD della scheda Nucleo. Il file con il programma .py sarà caricato direttamente sulla flash.&lt;br /&gt;
&lt;br /&gt;
= La scheda =&lt;br /&gt;
&lt;br /&gt;
NUCLEO-F401RE della STMicroelectronics è una scheda basata su ARM Cortex M4 e fa parte della famiglia STM32 Nucleo Boards. Ha 512KB di Flash, 96 KB di SRAM, un clock di 84MHz, 50 GPIO, RTC, supporto I²C, SPI, USART e molto altro ([https://os.mbed.com/platforms/ST-Nucleo-F401RE/ maggiori info]). La sua forma le permette di alloggiare sia gli shield per Arduino che le estensioni Morpho di STMicroelectronics.&lt;br /&gt;
Il prezzo è abbastanza contenuto (attorno ai 12€ su Mouser) il che ne fa una scheda piuttosto interessante.&lt;br /&gt;
&lt;br /&gt;
Normalmente si programmerebbe tramite l'[https://ide.mbed.com/compiler editor online di Mbed]. Il compilatore genererà dal nostro codice un file con estensione bin. Collegando la scheda verrà montato un volume, chiamato &amp;quot;NUCLEO&amp;quot; sul quale caricare il file bin. Quando la scheda verrà resettata, il codice verrà eseguito. È possibile anche usare editor offline con toolchain di compilazione come Eclipse. Non credo sia possibile usare la IDE di Arduino.&lt;br /&gt;
&lt;br /&gt;
= Installazione MicroPython =&lt;br /&gt;
&lt;br /&gt;
== Primo tentativo ==&lt;br /&gt;
&lt;br /&gt;
=== Toolchain e OpenOCD ===&lt;br /&gt;
&lt;br /&gt;
Per compilare vi servirà la toolchain gcc-arm-embedded. Non è nei repo ufficiali quindi la dovete installare a mano oppure aggiungere un PPA. https://launchpad.net/gcc-arm-embedded&lt;br /&gt;
Il programma per comunicare col debugger della scheda, openocd, invece è nei repo di Debian.&lt;br /&gt;
 &lt;br /&gt;
=== Come installare MicroPython ===&lt;br /&gt;
&lt;br /&gt;
Potete seguire la guida di Carmine per la compilazione. Ovviamente se avete installato la toolchain con apt non è necessario aggiungere il path a tutti i comandi, perché sono già dentro a /usr/bin.&lt;br /&gt;
&lt;br /&gt;
OpenOCD ci permette di caricare il firmware che abbiamo crosscompilato. Basterà lanciare il comando:&lt;br /&gt;
 $ openocd  -f board/st_nucleo_f4.cfg&lt;br /&gt;
Un LED della scheda dovrebbe lampeggiare rosso/verde. Il debugger è attivo. Per collegarcisi:&lt;br /&gt;
 $ telnet localhost 4444&lt;br /&gt;
e poi scrivete:&lt;br /&gt;
 &amp;gt; reset halt&lt;br /&gt;
e infine:&lt;br /&gt;
 &amp;gt; flash write_image erase &amp;lt;file .elf da flashare&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inizialmente non sembrava funzionare. Il tentativo finale che ha sbloccato la situazione è stato dare il comando shutdown. Non sono sicuro però che sia stato proprio quel comando e bisognerebbe indagare meglio.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dall'interprete ===&lt;br /&gt;
&lt;br /&gt;
Aprendo la porta della nostra scheda (la trovate su dmesg non appena la attaccate, è /dev/ttyACMx dove x è un numero che parte da 0) con un emulatore di terminale (come console) alla velocità di 115200 baud, dovreste vedere l'interprete dei comandi di MicroPython. Provate a dare il comando:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pyb.LED(1).on()&lt;br /&gt;
per vedere se si accende il LED onboard.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dal PC ===&lt;br /&gt;
&lt;br /&gt;
Fra i tool di MicroPython, che trovate nella cartella di git micropython/tools, c'è pyboard.py, un programma che vi permette di eseguire uno script in MicroPython. Se la vostra porta non è accessibile dall'utente dovrete usare sudo.&lt;br /&gt;
 # ./pyboard.py &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Carmine ha fatto una modifica a pyboard in modo che possa caricare un file sulla board.&lt;br /&gt;
 # ./pyboard.py --device=/dev/ttyACMx --send &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
MicroPython ha due file di default quando viene installato: boot.py e main.py. Il primo è un file di sistema che serve allo stesso MicroPython di partire. Non occorre di solito modificarlo. Il secondo, main.py, è uno script che viene eseguito all'avvio. Se carichiamo un file main.py questo verrà eseguito all'accensione.&lt;br /&gt;
&lt;br /&gt;
=== Considerazioni finali ===&lt;br /&gt;
&lt;br /&gt;
Molto bene, ma la versione di micropython non è aggiornata. Forse è per questo che non riesco a far funzionare la porta I²C?&lt;br /&gt;
&lt;br /&gt;
== Secondo tentativo ==&lt;br /&gt;
&lt;br /&gt;
Boochow fornisce dei firmware già compilati su https://blog.boochow.com/micropython-firmware-for-mbed-boards basta scegliere la board giusta e caricare il file .bin nel volume &amp;quot;NUCLEO&amp;quot; che si monta quando si collega la USB.&lt;br /&gt;
&lt;br /&gt;
== Caricare uno script ==&lt;br /&gt;
&lt;br /&gt;
Un modo piuttosto comodo di inviare e ricevere file sulla flash della Nucleo è usare uPyLoader:&lt;br /&gt;
https://github.com/BetaRavener/uPyLoader/&lt;br /&gt;
ma quasi sempre dà un errore di timeout.&lt;br /&gt;
&lt;br /&gt;
Il programma fornito da Adafruit sembra funzionare decisamente meglio&lt;br /&gt;
https://learn.adafruit.com/micropython-basics-load-files-and-run-code/install-ampy&lt;br /&gt;
&lt;br /&gt;
Per installarlo usare pip (o pip3):&lt;br /&gt;
 pip install adafruit-ampy&lt;br /&gt;
&lt;br /&gt;
Per usarlo:&lt;br /&gt;
 ampy -p &amp;lt;porta seriale&amp;gt; put &amp;lt;nome file&amp;gt;&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6819</id>
		<title>Installare MicroPython su NUCLEO-F401RE</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6819"/>
		<updated>2019-03-02T15:36:09Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* Secondo tentativo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questa guida è basata quasi tutta su quella di Carmine Noviello https://www.carminenoviello.com/2015/06/03/running-micropyton-stm32nucleo-f4/ che peraltro trovate anche in italiano https://www.carminenoviello.com/it/2015/08/11/compilare-micropython-una-scheda-stm32nucleo-f4/ per cui scriverò solo le differenze.&lt;br /&gt;
&lt;br /&gt;
La versione di Carmine di micropython, che si trova sul suo [https://github.com/cnoviello/micropython github], risolve il problema relativo alla mancanza di memoria SD della scheda Nucleo. Il file con il programma .py sarà caricato direttamente sulla flash.&lt;br /&gt;
&lt;br /&gt;
= La scheda =&lt;br /&gt;
&lt;br /&gt;
NUCLEO-F401RE della STMicroelectronics è una scheda basata su ARM Cortex M4 e fa parte della famiglia STM32 Nucleo Boards. Ha 512KB di Flash, 96 KB di SRAM, un clock di 84MHz, 50 GPIO, RTC, supporto I²C, SPI, USART e molto altro ([https://os.mbed.com/platforms/ST-Nucleo-F401RE/ maggiori info]). La sua forma le permette di alloggiare sia gli shield per Arduino che le estensioni Morpho di STMicroelectronics.&lt;br /&gt;
Il prezzo è abbastanza contenuto (attorno ai 12€ su Mouser) il che ne fa una scheda piuttosto interessante.&lt;br /&gt;
&lt;br /&gt;
Normalmente si programmerebbe tramite l'[https://ide.mbed.com/compiler editor online di Mbed]. Il compilatore genererà dal nostro codice un file con estensione bin. Collegando la scheda verrà montato un volume, chiamato &amp;quot;NUCLEO&amp;quot; sul quale caricare il file bin. Quando la scheda verrà resettata, il codice verrà eseguito. È possibile anche usare editor offline con toolchain di compilazione come Eclipse. Non credo sia possibile usare la IDE di Arduino.&lt;br /&gt;
&lt;br /&gt;
= Installazione MicroPython =&lt;br /&gt;
&lt;br /&gt;
== Primo tentativo ==&lt;br /&gt;
&lt;br /&gt;
=== Toolchain e OpenOCD ===&lt;br /&gt;
&lt;br /&gt;
Per compilare vi servirà la toolchain gcc-arm-embedded. Non è nei repo ufficiali quindi la dovete installare a mano oppure aggiungere un PPA. https://launchpad.net/gcc-arm-embedded&lt;br /&gt;
Il programma per comunicare col debugger della scheda, openocd, invece è nei repo di Debian.&lt;br /&gt;
 &lt;br /&gt;
=== Come installare MicroPython ===&lt;br /&gt;
&lt;br /&gt;
Potete seguire la guida di Carmine per la compilazione. Ovviamente se avete installato la toolchain con apt non è necessario aggiungere il path a tutti i comandi, perché sono già dentro a /usr/bin.&lt;br /&gt;
&lt;br /&gt;
OpenOCD ci permette di caricare il firmware che abbiamo crosscompilato. Basterà lanciare il comando:&lt;br /&gt;
 $ openocd  -f board/st_nucleo_f4.cfg&lt;br /&gt;
Un LED della scheda dovrebbe lampeggiare rosso/verde. Il debugger è attivo. Per collegarcisi:&lt;br /&gt;
 $ telnet localhost 4444&lt;br /&gt;
e poi scrivete:&lt;br /&gt;
 &amp;gt; reset halt&lt;br /&gt;
e infine:&lt;br /&gt;
 &amp;gt; flash write_image erase &amp;lt;file .elf da flashare&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inizialmente non sembrava funzionare. Il tentativo finale che ha sbloccato la situazione è stato dare il comando shutdown. Non sono sicuro però che sia stato proprio quel comando e bisognerebbe indagare meglio.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dall'interprete ===&lt;br /&gt;
&lt;br /&gt;
Aprendo la porta della nostra scheda (la trovate su dmesg non appena la attaccate, è /dev/ttyACMx dove x è un numero che parte da 0) con un emulatore di terminale (come console) alla velocità di 115200 baud, dovreste vedere l'interprete dei comandi di MicroPython. Provate a dare il comando:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pyb.LED(1).on()&lt;br /&gt;
per vedere se si accende il LED onboard.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dal PC ===&lt;br /&gt;
&lt;br /&gt;
Fra i tool di MicroPython, che trovate nella cartella di git micropython/tools, c'è pyboard.py, un programma che vi permette di eseguire uno script in MicroPython. Se la vostra porta non è accessibile dall'utente dovrete usare sudo.&lt;br /&gt;
 # ./pyboard.py &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Carmine ha fatto una modifica a pyboard in modo che possa caricare un file sulla board.&lt;br /&gt;
 # ./pyboard.py --device=/dev/ttyACMx --send &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
MicroPython ha due file di default quando viene installato: boot.py e main.py. Il primo è un file di sistema che serve allo stesso MicroPython di partire. Non occorre di solito modificarlo. Il secondo, main.py, è uno script che viene eseguito all'avvio. Se carichiamo un file main.py questo verrà eseguito all'accensione.&lt;br /&gt;
&lt;br /&gt;
=== Considerazioni finali ===&lt;br /&gt;
&lt;br /&gt;
Molto bene, ma la versione di micropython non è aggiornata. Forse è per questo che non riesco a far funzionare la porta I²C?&lt;br /&gt;
&lt;br /&gt;
== Secondo tentativo ==&lt;br /&gt;
&lt;br /&gt;
Boochow fornisce dei firmware già compilati su https://blog.boochow.com/micropython-firmware-for-mbed-boards basta scegliere la board giusta e caricare il file .bin nel volume &amp;quot;NUCLEO&amp;quot; che si monta quando si collega la USB.&lt;br /&gt;
È l'ultima versione ed è quella più completa.&lt;br /&gt;
&lt;br /&gt;
== Terzo tentativo ==&lt;br /&gt;
&lt;br /&gt;
Sul forum di MicroPython, l'utente dhylands ha messo il link a una versione di MicroPython precedente. Caricata con OpenOCD funziona. Anche in questo caso però il caricamento di un file sulla scheda ha dato problemi di timeout.&lt;br /&gt;
https://forum.micropython.org/viewtopic.php?t=3709&lt;br /&gt;
&lt;br /&gt;
== Caricare uno script ==&lt;br /&gt;
&lt;br /&gt;
Un modo piuttosto comodo di inviare e ricevere file sulla flash della Nucleo è usare uPyLoader.&lt;br /&gt;
https://github.com/BetaRavener/uPyLoader/&lt;br /&gt;
&lt;br /&gt;
È una versione alfa ma in qualche modo sono riuscito a caricare il file della libreria di un display OLED che vorrei usare come test per la porta I²C.&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6818</id>
		<title>Installare MicroPython su NUCLEO-F401RE</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6818"/>
		<updated>2019-03-02T15:35:15Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* Terzo tentativo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questa guida è basata quasi tutta su quella di Carmine Noviello https://www.carminenoviello.com/2015/06/03/running-micropyton-stm32nucleo-f4/ che peraltro trovate anche in italiano https://www.carminenoviello.com/it/2015/08/11/compilare-micropython-una-scheda-stm32nucleo-f4/ per cui scriverò solo le differenze.&lt;br /&gt;
&lt;br /&gt;
La versione di Carmine di micropython, che si trova sul suo [https://github.com/cnoviello/micropython github], risolve il problema relativo alla mancanza di memoria SD della scheda Nucleo. Il file con il programma .py sarà caricato direttamente sulla flash.&lt;br /&gt;
&lt;br /&gt;
= La scheda =&lt;br /&gt;
&lt;br /&gt;
NUCLEO-F401RE della STMicroelectronics è una scheda basata su ARM Cortex M4 e fa parte della famiglia STM32 Nucleo Boards. Ha 512KB di Flash, 96 KB di SRAM, un clock di 84MHz, 50 GPIO, RTC, supporto I²C, SPI, USART e molto altro ([https://os.mbed.com/platforms/ST-Nucleo-F401RE/ maggiori info]). La sua forma le permette di alloggiare sia gli shield per Arduino che le estensioni Morpho di STMicroelectronics.&lt;br /&gt;
Il prezzo è abbastanza contenuto (attorno ai 12€ su Mouser) il che ne fa una scheda piuttosto interessante.&lt;br /&gt;
&lt;br /&gt;
Normalmente si programmerebbe tramite l'[https://ide.mbed.com/compiler editor online di Mbed]. Il compilatore genererà dal nostro codice un file con estensione bin. Collegando la scheda verrà montato un volume, chiamato &amp;quot;NUCLEO&amp;quot; sul quale caricare il file bin. Quando la scheda verrà resettata, il codice verrà eseguito. È possibile anche usare editor offline con toolchain di compilazione come Eclipse. Non credo sia possibile usare la IDE di Arduino.&lt;br /&gt;
&lt;br /&gt;
= Installazione MicroPython =&lt;br /&gt;
&lt;br /&gt;
== Primo tentativo ==&lt;br /&gt;
&lt;br /&gt;
=== Toolchain e OpenOCD ===&lt;br /&gt;
&lt;br /&gt;
Per compilare vi servirà la toolchain gcc-arm-embedded. Non è nei repo ufficiali quindi la dovete installare a mano oppure aggiungere un PPA. https://launchpad.net/gcc-arm-embedded&lt;br /&gt;
Il programma per comunicare col debugger della scheda, openocd, invece è nei repo di Debian.&lt;br /&gt;
 &lt;br /&gt;
=== Come installare MicroPython ===&lt;br /&gt;
&lt;br /&gt;
Potete seguire la guida di Carmine per la compilazione. Ovviamente se avete installato la toolchain con apt non è necessario aggiungere il path a tutti i comandi, perché sono già dentro a /usr/bin.&lt;br /&gt;
&lt;br /&gt;
OpenOCD ci permette di caricare il firmware che abbiamo crosscompilato. Basterà lanciare il comando:&lt;br /&gt;
 $ openocd  -f board/st_nucleo_f4.cfg&lt;br /&gt;
Un LED della scheda dovrebbe lampeggiare rosso/verde. Il debugger è attivo. Per collegarcisi:&lt;br /&gt;
 $ telnet localhost 4444&lt;br /&gt;
e poi scrivete:&lt;br /&gt;
 &amp;gt; reset halt&lt;br /&gt;
e infine:&lt;br /&gt;
 &amp;gt; flash write_image erase &amp;lt;file .elf da flashare&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inizialmente non sembrava funzionare. Il tentativo finale che ha sbloccato la situazione è stato dare il comando shutdown. Non sono sicuro però che sia stato proprio quel comando e bisognerebbe indagare meglio.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dall'interprete ===&lt;br /&gt;
&lt;br /&gt;
Aprendo la porta della nostra scheda (la trovate su dmesg non appena la attaccate, è /dev/ttyACMx dove x è un numero che parte da 0) con un emulatore di terminale (come console) alla velocità di 115200 baud, dovreste vedere l'interprete dei comandi di MicroPython. Provate a dare il comando:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pyb.LED(1).on()&lt;br /&gt;
per vedere se si accende il LED onboard.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dal PC ===&lt;br /&gt;
&lt;br /&gt;
Fra i tool di MicroPython, che trovate nella cartella di git micropython/tools, c'è pyboard.py, un programma che vi permette di eseguire uno script in MicroPython. Se la vostra porta non è accessibile dall'utente dovrete usare sudo.&lt;br /&gt;
 # ./pyboard.py &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Carmine ha fatto una modifica a pyboard in modo che possa caricare un file sulla board.&lt;br /&gt;
 # ./pyboard.py --device=/dev/ttyACMx --send &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
MicroPython ha due file di default quando viene installato: boot.py e main.py. Il primo è un file di sistema che serve allo stesso MicroPython di partire. Non occorre di solito modificarlo. Il secondo, main.py, è uno script che viene eseguito all'avvio. Se carichiamo un file main.py questo verrà eseguito all'accensione.&lt;br /&gt;
&lt;br /&gt;
=== Considerazioni finali ===&lt;br /&gt;
&lt;br /&gt;
Molto bene, ma la versione di micropython non è aggiornata. Forse è per questo che non riesco a far funzionare la porta I²C?&lt;br /&gt;
&lt;br /&gt;
== Secondo tentativo ==&lt;br /&gt;
&lt;br /&gt;
Boochow fornisce dei firmware già compilati su https://blog.boochow.com/micropython-firmware-for-mbed-boards basta scegliere la board giusta e caricare il file .bin nel volume &amp;quot;NUCLEO&amp;quot; che si monta quando si collega la USB.&lt;br /&gt;
L'ultima versione però non è molto stabile, soprattutto quando si è trattato di inviare dei file alla flash della Nucleo, per cui ho dovuto ripiegare a una versione successiva.&lt;br /&gt;
&lt;br /&gt;
== Terzo tentativo ==&lt;br /&gt;
&lt;br /&gt;
Sul forum di MicroPython, l'utente dhylands ha messo il link a una versione di MicroPython precedente. Caricata con OpenOCD funziona. Anche in questo caso però il caricamento di un file sulla scheda ha dato problemi di timeout.&lt;br /&gt;
https://forum.micropython.org/viewtopic.php?t=3709&lt;br /&gt;
&lt;br /&gt;
== Caricare uno script ==&lt;br /&gt;
&lt;br /&gt;
Un modo piuttosto comodo di inviare e ricevere file sulla flash della Nucleo è usare uPyLoader.&lt;br /&gt;
https://github.com/BetaRavener/uPyLoader/&lt;br /&gt;
&lt;br /&gt;
È una versione alfa ma in qualche modo sono riuscito a caricare il file della libreria di un display OLED che vorrei usare come test per la porta I²C.&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6800</id>
		<title>Installare MicroPython su NUCLEO-F401RE</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6800"/>
		<updated>2019-02-21T19:56:02Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questa guida è basata quasi tutta su quella di Carmine Noviello https://www.carminenoviello.com/2015/06/03/running-micropyton-stm32nucleo-f4/ che peraltro trovate anche in italiano https://www.carminenoviello.com/it/2015/08/11/compilare-micropython-una-scheda-stm32nucleo-f4/ per cui scriverò solo le differenze.&lt;br /&gt;
&lt;br /&gt;
La versione di Carmine di micropython, che si trova sul suo [https://github.com/cnoviello/micropython github], risolve il problema relativo alla mancanza di memoria SD della scheda Nucleo. Il file con il programma .py sarà caricato direttamente sulla flash.&lt;br /&gt;
&lt;br /&gt;
= La scheda =&lt;br /&gt;
&lt;br /&gt;
NUCLEO-F401RE della STMicroelectronics è una scheda basata su ARM Cortex M4 e fa parte della famiglia STM32 Nucleo Boards. Ha 512KB di Flash, 96 KB di SRAM, un clock di 84MHz, 50 GPIO, RTC, supporto I²C, SPI, USART e molto altro ([https://os.mbed.com/platforms/ST-Nucleo-F401RE/ maggiori info]). La sua forma le permette di alloggiare sia gli shield per Arduino che le estensioni Morpho di STMicroelectronics.&lt;br /&gt;
Il prezzo è abbastanza contenuto (attorno ai 12€ su Mouser) il che ne fa una scheda piuttosto interessante.&lt;br /&gt;
&lt;br /&gt;
Normalmente si programmerebbe tramite l'[https://ide.mbed.com/compiler editor online di Mbed]. Il compilatore genererà dal nostro codice un file con estensione bin. Collegando la scheda verrà montato un volume, chiamato &amp;quot;NUCLEO&amp;quot; sul quale caricare il file bin. Quando la scheda verrà resettata, il codice verrà eseguito. È possibile anche usare editor offline con toolchain di compilazione come Eclipse. Non credo sia possibile usare la IDE di Arduino.&lt;br /&gt;
&lt;br /&gt;
= Installazione MicroPython =&lt;br /&gt;
&lt;br /&gt;
== Primo tentativo ==&lt;br /&gt;
&lt;br /&gt;
=== Toolchain e OpenOCD ===&lt;br /&gt;
&lt;br /&gt;
Per compilare vi servirà la toolchain gcc-arm-embedded. Non è nei repo ufficiali quindi la dovete installare a mano oppure aggiungere un PPA. https://launchpad.net/gcc-arm-embedded&lt;br /&gt;
Il programma per comunicare col debugger della scheda, openocd, invece è nei repo di Debian.&lt;br /&gt;
 &lt;br /&gt;
=== Come installare MicroPython ===&lt;br /&gt;
&lt;br /&gt;
Potete seguire la guida di Carmine per la compilazione. Ovviamente se avete installato la toolchain con apt non è necessario aggiungere il path a tutti i comandi, perché sono già dentro a /usr/bin.&lt;br /&gt;
&lt;br /&gt;
OpenOCD ci permette di caricare il firmware che abbiamo crosscompilato. Basterà lanciare il comando:&lt;br /&gt;
 $ openocd  -f board/st_nucleo_f4.cfg&lt;br /&gt;
Un LED della scheda dovrebbe lampeggiare rosso/verde. Il debugger è attivo. Per collegarcisi:&lt;br /&gt;
 $ telnet localhost 4444&lt;br /&gt;
e poi scrivete:&lt;br /&gt;
 &amp;gt; reset halt&lt;br /&gt;
e infine:&lt;br /&gt;
 &amp;gt; flash write_image erase &amp;lt;file .elf da flashare&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inizialmente non sembrava funzionare. Il tentativo finale che ha sbloccato la situazione è stato dare il comando shutdown. Non sono sicuro però che sia stato proprio quel comando e bisognerebbe indagare meglio.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dall'interprete ===&lt;br /&gt;
&lt;br /&gt;
Aprendo la porta della nostra scheda (la trovate su dmesg non appena la attaccate, è /dev/ttyACMx dove x è un numero che parte da 0) con un emulatore di terminale (come console) alla velocità di 115200 baud, dovreste vedere l'interprete dei comandi di MicroPython. Provate a dare il comando:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pyb.LED(1).on()&lt;br /&gt;
per vedere se si accende il LED onboard.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dal PC ===&lt;br /&gt;
&lt;br /&gt;
Fra i tool di MicroPython, che trovate nella cartella di git micropython/tools, c'è pyboard.py, un programma che vi permette di eseguire uno script in MicroPython. Se la vostra porta non è accessibile dall'utente dovrete usare sudo.&lt;br /&gt;
 # ./pyboard.py &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Carmine ha fatto una modifica a pyboard in modo che possa caricare un file sulla board.&lt;br /&gt;
 # ./pyboard.py --device=/dev/ttyACMx --send &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
MicroPython ha due file di default quando viene installato: boot.py e main.py. Il primo è un file di sistema che serve allo stesso MicroPython di partire. Non occorre di solito modificarlo. Il secondo, main.py, è uno script che viene eseguito all'avvio. Se carichiamo un file main.py questo verrà eseguito all'accensione.&lt;br /&gt;
&lt;br /&gt;
=== Considerazioni finali ===&lt;br /&gt;
&lt;br /&gt;
Molto bene, ma la versione di micropython non è aggiornata. Forse è per questo che non riesco a far funzionare la porta I²C?&lt;br /&gt;
&lt;br /&gt;
== Secondo tentativo ==&lt;br /&gt;
&lt;br /&gt;
Boochow fornisce dei firmware già compilati su https://blog.boochow.com/micropython-firmware-for-mbed-boards basta scegliere la board giusta e caricare il file .bin nel volume &amp;quot;NUCLEO&amp;quot; che si monta quando si collega la USB.&lt;br /&gt;
L'ultima versione però non è molto stabile, soprattutto quando si è trattato di inviare dei file alla flash della Nucleo, per cui ho dovuto ripiegare a una versione successiva.&lt;br /&gt;
&lt;br /&gt;
== Terzo tentativo ==&lt;br /&gt;
&lt;br /&gt;
Sul forum di MicroPython, l'utente dhylands ha messo il link a una versione di MicroPython precedente. Caricata con OpenOCD funziona.&lt;br /&gt;
https://forum.micropython.org/viewtopic.php?t=3709&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Un modo piuttosto comodo di inviare e ricevere file sulla flash della Nucleo è usare uPyLoader.&lt;br /&gt;
https://github.com/BetaRavener/uPyLoader/&lt;br /&gt;
&lt;br /&gt;
È una versione alfa ma in qualche modo sono riuscito a caricare il file della libreria di un display OLED che vorrei usare come test per la porta I²C.&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6799</id>
		<title>Installare MicroPython su NUCLEO-F401RE</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6799"/>
		<updated>2019-02-21T19:31:03Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questa guida è basata quasi tutta su quella di Carmine Noviello https://www.carminenoviello.com/2015/06/03/running-micropyton-stm32nucleo-f4/ che peraltro trovate anche in italiano https://www.carminenoviello.com/it/2015/08/11/compilare-micropython-una-scheda-stm32nucleo-f4/ per cui scriverò solo le differenze.&lt;br /&gt;
&lt;br /&gt;
La versione di Carmine di micropython, che si trova sul suo [https://github.com/cnoviello/micropython github], risolve il problema relativo alla mancanza di memoria SD della scheda Nucleo. Il file con il programma .py sarà caricato direttamente sulla flash.&lt;br /&gt;
&lt;br /&gt;
= La scheda =&lt;br /&gt;
&lt;br /&gt;
NUCLEO-F401RE della STMicroelectronics è una scheda basata su ARM Cortex M4 e fa parte della famiglia STM32 Nucleo Boards. Ha 512KB di Flash, 96 KB di SRAM, un clock di 84MHz, 50 GPIO, RTC, supporto I²C, SPI, USART e molto altro ([https://os.mbed.com/platforms/ST-Nucleo-F401RE/ maggiori info]). La sua forma le permette di alloggiare sia gli shield per Arduino che le estensioni Morpho di STMicroelectronics.&lt;br /&gt;
Il prezzo è abbastanza contenuto (attorno ai 12€ su Mouser) il che ne fa una scheda piuttosto interessante.&lt;br /&gt;
&lt;br /&gt;
Normalmente si programmerebbe tramite l'[https://ide.mbed.com/compiler editor online di Mbed]. Il compilatore genererà dal nostro codice un file con estensione bin. Collegando la scheda verrà montato un volume, chiamato &amp;quot;NUCLEO&amp;quot; sul quale caricare il file bin. Quando la scheda verrà resettata, il codice verrà eseguito. È possibile anche usare editor offline con toolchain di compilazione come Eclipse. Non credo sia possibile usare la IDE di Arduino.&lt;br /&gt;
&lt;br /&gt;
= Installazione MicroPython =&lt;br /&gt;
&lt;br /&gt;
== Primo tentativo ==&lt;br /&gt;
&lt;br /&gt;
=== Toolchain e OpenOCD ===&lt;br /&gt;
&lt;br /&gt;
Per compilare vi servirà la toolchain gcc-arm-embedded. Non è nei repo ufficiali quindi la dovete installare a mano oppure aggiungere un PPA. https://launchpad.net/gcc-arm-embedded&lt;br /&gt;
Il programma per comunicare col debugger della scheda, openocd, invece è nei repo di Debian.&lt;br /&gt;
 &lt;br /&gt;
=== Come installare MicroPython ===&lt;br /&gt;
&lt;br /&gt;
Potete seguire la guida di Carmine per la compilazione. Ovviamente se avete installato la toolchain con apt non è necessario aggiungere il path a tutti i comandi, perché sono già dentro a /usr/bin.&lt;br /&gt;
&lt;br /&gt;
OpenOCD ci permette di caricare il firmware che abbiamo crosscompilato. Basterà lanciare il comando:&lt;br /&gt;
 $ openocd  -f board/st_nucleo_f4.cfg&lt;br /&gt;
Un LED della scheda dovrebbe lampeggiare rosso/verde. Il debugger è attivo. Per collegarcisi:&lt;br /&gt;
 $ telnet localhost 4444&lt;br /&gt;
e poi scrivete:&lt;br /&gt;
 &amp;gt; reset halt&lt;br /&gt;
e infine:&lt;br /&gt;
 &amp;gt; flash write_image erase &amp;lt;file .elf da flashare&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inizialmente non sembrava funzionare. Il tentativo finale che ha sbloccato la situazione è stato dare il comando shutdown. Non sono sicuro però che sia stato proprio quel comando e bisognerebbe indagare meglio.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dall'interprete ===&lt;br /&gt;
&lt;br /&gt;
Aprendo la porta della nostra scheda (la trovate su dmesg non appena la attaccate, è /dev/ttyACMx dove x è un numero che parte da 0) con un emulatore di terminale (come console) alla velocità di 115200 baud, dovreste vedere l'interprete dei comandi di MicroPython. Provate a dare il comando:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pyb.LED(1).on()&lt;br /&gt;
per vedere se si accende il LED onboard.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dal PC ===&lt;br /&gt;
&lt;br /&gt;
Fra i tool di MicroPython, che trovate nella cartella di git micropython/tools, c'è pyboard.py, un programma che vi permette di eseguire uno script in MicroPython. Se la vostra porta non è accessibile dall'utente dovrete usare sudo.&lt;br /&gt;
 # ./pyboard.py &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Carmine ha fatto una modifica a pyboard in modo che possa caricare un file sulla board.&lt;br /&gt;
 # ./pyboard.py --device=/dev/ttyACMx --send &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
MicroPython ha due file di default quando viene installato: boot.py e main.py. Il primo è un file di sistema che serve allo stesso MicroPython di partire. Non occorre di solito modificarlo. Il secondo, main.py, è uno script che viene eseguito all'avvio. Se carichiamo un file main.py questo verrà eseguito all'accensione.&lt;br /&gt;
&lt;br /&gt;
=== Considerazioni finali ===&lt;br /&gt;
&lt;br /&gt;
Molto bene, ma la versione di micropython non è aggiornata. Forse è per questo che non riesco a far funzionare la porta I²C?&lt;br /&gt;
&lt;br /&gt;
== Secondo tentativo ==&lt;br /&gt;
&lt;br /&gt;
Boochow fornisce dei firmware già compilati su https://blog.boochow.com/micropython-firmware-for-mbed-boards basta scegliere la board giusta e caricare il file .bin nel volume &amp;quot;NUCLEO&amp;quot; che si monta quando si collega la USB.&lt;br /&gt;
L'ultima versione però non è molto stabile, soprattutto quando si è trattato di inviare dei file alla flash della Nucleo, per cui ho dovuto ripiegare a una versione successiva.&lt;br /&gt;
&lt;br /&gt;
== Terzo tentativo ==&lt;br /&gt;
&lt;br /&gt;
Sul forum di MicroPython, l'utente dhylands ha messo il link a una versione di MicroPython precedente. Caricata con OpenOCD funziona e sembra più stabile delle altre.&lt;br /&gt;
https://forum.micropython.org/viewtopic.php?t=3709&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Un modo piuttosto comodo di inviare e ricevere file sulla flash della Nucleo è usare uPyLoader.&lt;br /&gt;
https://github.com/BetaRavener/uPyLoader/&lt;br /&gt;
&lt;br /&gt;
È una versione alfa ma in qualche modo sono riuscito a caricare il file della libreria di un display OLED che vorrei usare come test per la porta I²C.&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6798</id>
		<title>Installare MicroPython su NUCLEO-F401RE</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6798"/>
		<updated>2019-02-21T19:30:23Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questa guida è basata quasi tutta su quella di Carmine Noviello https://www.carminenoviello.com/2015/06/03/running-micropyton-stm32nucleo-f4/ che peraltro trovate anche in italiano https://www.carminenoviello.com/it/2015/08/11/compilare-micropython-una-scheda-stm32nucleo-f4/ per cui scriverò solo le differenze.&lt;br /&gt;
&lt;br /&gt;
La versione di Carmine di micropython, che si trova sul suo [https://github.com/cnoviello/micropython github], risolve il problema relativo alla mancanza di memoria SD della scheda Nucleo. Il file con il programma .py sarà caricato direttamente sulla flash.&lt;br /&gt;
&lt;br /&gt;
= La scheda =&lt;br /&gt;
&lt;br /&gt;
NUCLEO-F401RE della STMicroelectronics è una scheda basata su ARM Cortex M4 e fa parte della famiglia STM32 Nucleo Boards. Ha 512KB di Flash, 96 KB di SRAM, un clock di 84MHz, 50 GPIO, RTC, supporto I²C, SPI, USART e molto altro ([https://os.mbed.com/platforms/ST-Nucleo-F401RE/ maggiori info]). La sua forma le permette di alloggiare sia gli shield per Arduino che le estensioni Morpho di STMicroelectronics.&lt;br /&gt;
Il prezzo è abbastanza contenuto (attorno ai 12€ su Mouser) il che ne fa una scheda piuttosto interessante.&lt;br /&gt;
&lt;br /&gt;
Normalmente si programmerebbe tramite l'[https://ide.mbed.com/compiler editor online di Mbed]. Il compilatore genererà dal nostro codice un file con estensione bin. Collegando la scheda verrà montato un volume, chiamato &amp;quot;NUCLEO&amp;quot; sul quale caricare il file bin. Quando la scheda verrà resettata, il codice verrà eseguito. È possibile anche usare editor offline con toolchain di compilazione come Eclipse. Non credo sia possibile usare la IDE di Arduino.&lt;br /&gt;
&lt;br /&gt;
== Primo tentativo ==&lt;br /&gt;
&lt;br /&gt;
=== Toolchain e OpenOCD ===&lt;br /&gt;
&lt;br /&gt;
Per compilare vi servirà la toolchain gcc-arm-embedded. Non è nei repo ufficiali quindi la dovete installare a mano oppure aggiungere un PPA. https://launchpad.net/gcc-arm-embedded&lt;br /&gt;
Il programma per comunicare col debugger della scheda, openocd, invece è nei repo di Debian.&lt;br /&gt;
 &lt;br /&gt;
=== Come installare MicroPython ===&lt;br /&gt;
&lt;br /&gt;
Potete seguire la guida di Carmine per la compilazione. Ovviamente se avete installato la toolchain con apt non è necessario aggiungere il path a tutti i comandi, perché sono già dentro a /usr/bin.&lt;br /&gt;
&lt;br /&gt;
OpenOCD ci permette di caricare il firmware che abbiamo crosscompilato. Basterà lanciare il comando:&lt;br /&gt;
 $ openocd  -f board/st_nucleo_f4.cfg&lt;br /&gt;
Un LED della scheda dovrebbe lampeggiare rosso/verde. Il debugger è attivo. Per collegarcisi:&lt;br /&gt;
 $ telnet localhost 4444&lt;br /&gt;
e poi scrivete:&lt;br /&gt;
 &amp;gt; reset halt&lt;br /&gt;
e infine:&lt;br /&gt;
 &amp;gt; flash write_image erase &amp;lt;file .elf da flashare&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inizialmente non sembrava funzionare. Il tentativo finale che ha sbloccato la situazione è stato dare il comando shutdown. Non sono sicuro però che sia stato proprio quel comando e bisognerebbe indagare meglio.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dall'interprete ===&lt;br /&gt;
&lt;br /&gt;
Aprendo la porta della nostra scheda (la trovate su dmesg non appena la attaccate, è /dev/ttyACMx dove x è un numero che parte da 0) con un emulatore di terminale (come console) alla velocità di 115200 baud, dovreste vedere l'interprete dei comandi di MicroPython. Provate a dare il comando:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pyb.LED(1).on()&lt;br /&gt;
per vedere se si accende il LED onboard.&lt;br /&gt;
&lt;br /&gt;
=== Usare MicroPython dal PC ===&lt;br /&gt;
&lt;br /&gt;
Fra i tool di MicroPython, che trovate nella cartella di git micropython/tools, c'è pyboard.py, un programma che vi permette di eseguire uno script in MicroPython. Se la vostra porta non è accessibile dall'utente dovrete usare sudo.&lt;br /&gt;
 # ./pyboard.py &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Carmine ha fatto una modifica a pyboard in modo che possa caricare un file sulla board.&lt;br /&gt;
 # ./pyboard.py --device=/dev/ttyACMx --send &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
MicroPython ha due file di default quando viene installato: boot.py e main.py. Il primo è un file di sistema che serve allo stesso MicroPython di partire. Non occorre di solito modificarlo. Il secondo, main.py, è uno script che viene eseguito all'avvio. Se carichiamo un file main.py questo verrà eseguito all'accensione.&lt;br /&gt;
&lt;br /&gt;
=== Considerazioni finali ===&lt;br /&gt;
&lt;br /&gt;
Molto bene, ma la versione di micropython non è aggiornata. Forse è per questo che non riesco a far funzionare la porta I²C?&lt;br /&gt;
&lt;br /&gt;
== Secondo tentativo ==&lt;br /&gt;
&lt;br /&gt;
Boochow fornisce dei firmware già compilati su https://blog.boochow.com/micropython-firmware-for-mbed-boards basta scegliere la board giusta e caricare il file .bin nel volume &amp;quot;NUCLEO&amp;quot; che si monta quando si collega la USB.&lt;br /&gt;
L'ultima versione però non è molto stabile, soprattutto quando si è trattato di inviare dei file alla flash della Nucleo, per cui ho dovuto ripiegare a una versione successiva.&lt;br /&gt;
&lt;br /&gt;
== Terzo tentativo ==&lt;br /&gt;
&lt;br /&gt;
Sul forum di MicroPython, l'utente dhylands ha messo il link a una versione di MicroPython precedente. Caricata con OpenOCD funziona e sembra più stabile delle altre.&lt;br /&gt;
https://forum.micropython.org/viewtopic.php?t=3709&lt;br /&gt;
&lt;br /&gt;
=== Caricare uno script ===&lt;br /&gt;
&lt;br /&gt;
Un modo piuttosto comodo di inviare e ricevere file sulla flash della Nucleo è usare uPyLoader.&lt;br /&gt;
https://github.com/BetaRavener/uPyLoader/&lt;br /&gt;
&lt;br /&gt;
È una versione alfa ma in qualche modo sono riuscito a caricare il file della libreria di un display OLED che vorrei usare come test per la porta I²C.&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6797</id>
		<title>Installare MicroPython su NUCLEO-F401RE</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6797"/>
		<updated>2019-02-20T18:34:07Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questa guida è basata quasi tutta su quella di Carmine Noviello https://www.carminenoviello.com/2015/06/03/running-micropyton-stm32nucleo-f4/ che peraltro trovate anche in italiano https://www.carminenoviello.com/it/2015/08/11/compilare-micropython-una-scheda-stm32nucleo-f4/ per cui scriverò solo le differenze.&lt;br /&gt;
&lt;br /&gt;
La versione di Carmine di micropython, che si trova sul suo [https://github.com/cnoviello/micropython github], risolve il problema relativo alla mancanza di memoria SD della scheda Nucleo. Il file con il programma .py sarà caricato direttamente sulla flash.&lt;br /&gt;
&lt;br /&gt;
= La scheda =&lt;br /&gt;
&lt;br /&gt;
NUCLEO-F401RE della STMicroelectronics è una scheda basata su ARM Cortex M4 e fa parte della famiglia STM32 Nucleo Boards. Ha 512KB di Flash, 96 KB di SRAM, un clock di 84MHz, 50 GPIO, RTC, supporto I²C, SPI, USART e molto altro ([https://os.mbed.com/platforms/ST-Nucleo-F401RE/ maggiori info]). La sua forma le permette di alloggiare sia gli shield per Arduino che le estensioni Morpho di STMicroelectronics.&lt;br /&gt;
Il prezzo è abbastanza contenuto (attorno ai 12€ su Mouser) il che ne fa una scheda piuttosto interessante.&lt;br /&gt;
&lt;br /&gt;
Normalmente si programmerebbe tramite l'[https://ide.mbed.com/compiler editor online di Mbed]. Il compilatore genererà dal nostro codice un file con estensione bin. Collegando la scheda verrà montato un volume, chiamato &amp;quot;NUCLEO&amp;quot; sul quale caricare il file bin. Quando la scheda verrà resettata, il codice verrà eseguito. È possibile anche usare editor offline con toolchain di compilazione come Eclipse. Non credo sia possibile usare la IDE di Arduino.&lt;br /&gt;
&lt;br /&gt;
= Primo tentativo =&lt;br /&gt;
&lt;br /&gt;
== Toolchain e OpenOCD ==&lt;br /&gt;
&lt;br /&gt;
Per compilare vi servirà la toolchain gcc-arm-embedded. Non è nei repo ufficiali quindi la dovete installare a mano oppure aggiungere un PPA. https://launchpad.net/gcc-arm-embedded&lt;br /&gt;
Il programma per comunicare col debugger della scheda, openocd, invece è nei repo di Debian.&lt;br /&gt;
 &lt;br /&gt;
== Come installare MicroPython ==&lt;br /&gt;
&lt;br /&gt;
Potete seguire la guida di Carmine per la compilazione. Ovviamente se avete installato la toolchain con apt non è necessario aggiungere il path a tutti i comandi, perché sono già dentro a /usr/bin.&lt;br /&gt;
&lt;br /&gt;
OpenOCD ci permette di caricare il firmware che abbiamo crosscompilato. Basterà lanciare il comando:&lt;br /&gt;
 $ openocd  -f board/st_nucleo_f4.cfg&lt;br /&gt;
Un LED della scheda dovrebbe lampeggiare rosso/verde. Il debugger è attivo. Per collegarcisi:&lt;br /&gt;
 $ telnet localhost 4444&lt;br /&gt;
e poi scrivete:&lt;br /&gt;
 &amp;gt; reset halt&lt;br /&gt;
e infine:&lt;br /&gt;
 &amp;gt; flash write_image erase &amp;lt;file .elf da flashare&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inizialmente non sembrava funzionare. Il tentativo finale che ha sbloccato la situazione è stato dare il comando shutdown. Non sono sicuro però che sia stato proprio quel comando e bisognerebbe indagare meglio.&lt;br /&gt;
&lt;br /&gt;
== Usare MicroPython dall'interprete ==&lt;br /&gt;
&lt;br /&gt;
Aprendo la porta della nostra scheda (la trovate su dmesg non appena la attaccate, è /dev/ttyACMx dove x è un numero che parte da 0) con un emulatore di terminale (come console) alla velocità di 115200 baud, dovreste vedere l'interprete dei comandi di MicroPython. Provate a dare il comando:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pyb.LED(1).on()&lt;br /&gt;
per vedere se si accende il LED onboard.&lt;br /&gt;
&lt;br /&gt;
== Usare MicroPython dal PC ==&lt;br /&gt;
&lt;br /&gt;
Fra i tool di MicroPython, che trovate nella cartella di git micropython/tools, c'è pyboard.py, un programma che vi permette di eseguire uno script in MicroPython. Se la vostra porta non è accessibile dall'utente dovrete usare sudo.&lt;br /&gt;
 # ./pyboard.py &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
== Caricare uno script ==&lt;br /&gt;
&lt;br /&gt;
Carmine ha fatto una modifica a pyboard in modo che possa caricare un file sulla board.&lt;br /&gt;
 # ./pyboard.py --device=/dev/ttyACMx --send &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
MicroPython ha due file di default quando viene installato: boot.py e main.py. Il primo è un file di sistema che serve allo stesso MicroPython di partire. Non occorre di solito modificarlo. Il secondo, main.py, è uno script che viene eseguito all'avvio. Se carichiamo un file main.py questo verrà eseguito all'accensione.&lt;br /&gt;
&lt;br /&gt;
== Considerazioni finali ==&lt;br /&gt;
&lt;br /&gt;
Molto bene, ma la versione di micropython non è aggiornata. Forse è per questo che non riesco a far funzionare la porta I²C?&lt;br /&gt;
&lt;br /&gt;
= Secondo tentativo = &lt;br /&gt;
&lt;br /&gt;
Boochow fornisce dei firmware già compilati su https://blog.boochow.com/micropython-firmware-for-mbed-boards basta scegliere la board giusta e caricare il file .bin nel volume &amp;quot;NUCLEO&amp;quot; che si monta quando si collega la USB.&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6796</id>
		<title>Installare MicroPython su NUCLEO-F401RE</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6796"/>
		<updated>2019-02-20T18:26:03Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* La scheda */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questa guida è basata quasi tutta su quella di Carmine Noviello https://www.carminenoviello.com/2015/06/03/running-micropyton-stm32nucleo-f4/ che peraltro trovate anche in italiano https://www.carminenoviello.com/it/2015/08/11/compilare-micropython-una-scheda-stm32nucleo-f4/ per cui scriverò solo le differenze.&lt;br /&gt;
&lt;br /&gt;
La versione di Carmine di micropython, che si trova sul suo [https://github.com/cnoviello/micropython github], risolve il problema relativo alla mancanza di memoria SD della scheda Nucleo. Il file con il programma .py sarà caricato direttamente sulla flash.&lt;br /&gt;
&lt;br /&gt;
= La scheda =&lt;br /&gt;
&lt;br /&gt;
NUCLEO-F401RE della STMicroelectronics è una scheda basata su ARM Cortex M4 e fa parte della famiglia STM32 Nucleo Boards. Ha 512KB di Flash, 96 KB di SRAM, un clock di 84MHz, 50 GPIO, RTC, supporto I²C, SPI, USART e molto altro ([https://os.mbed.com/platforms/ST-Nucleo-F401RE/ maggiori info]). La sua forma le permette di alloggiare sia gli shield per Arduino che le estensioni Morpho di STMicroelectronics.&lt;br /&gt;
Il prezzo è abbastanza contenuto (attorno ai 12€ su Mouser) il che ne fa una scheda piuttosto interessante.&lt;br /&gt;
&lt;br /&gt;
Normalmente si programmerebbe tramite l'[https://ide.mbed.com/compiler editor online di Mbed]. Il compilatore genererà dal nostro codice un file con estensione bin. Collegando la scheda verrà montato un volume, chiamato &amp;quot;NUCLEO&amp;quot; sul quale caricare il file bin. Quando la scheda verrà resettata, il codice verrà eseguito. È possibile anche usare editor offline con toolchain di compilazione come Eclipse. Non credo sia possibile usare la IDE di Arduino.&lt;br /&gt;
&lt;br /&gt;
== Toolchain e OpenOCD ==&lt;br /&gt;
&lt;br /&gt;
Per compilare vi servirà la toolchain gcc-arm-embedded. Non è nei repo ufficiali quindi la dovete installare a mano oppure aggiungere un PPA. https://launchpad.net/gcc-arm-embedded&lt;br /&gt;
Il programma per comunicare col debugger della scheda, openocd, invece è nei repo di Debian.&lt;br /&gt;
 &lt;br /&gt;
== Come installare MicroPython ==&lt;br /&gt;
&lt;br /&gt;
Potete seguire la guida di Carmine per la compilazione. Ovviamente se avete installato la toolchain con apt non è necessario aggiungere il path a tutti i comandi, perché sono già dentro a /usr/bin.&lt;br /&gt;
&lt;br /&gt;
OpenOCD ci permette di caricare il firmware che abbiamo crosscompilato. Basterà lanciare il comando:&lt;br /&gt;
 $ openocd  -f board/st_nucleo_f4.cfg&lt;br /&gt;
Un LED della scheda dovrebbe lampeggiare rosso/verde. Il debugger è attivo. Per collegarcisi:&lt;br /&gt;
 $ telnet localhost 4444&lt;br /&gt;
e poi scrivete:&lt;br /&gt;
 &amp;gt; reset halt&lt;br /&gt;
e infine:&lt;br /&gt;
 &amp;gt; flash write_image erase &amp;lt;file .elf da flashare&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inizialmente non sembrava funzionare. Il tentativo finale che ha sbloccato la situazione è stato dare il comando shutdown. Non sono sicuro però che sia stato proprio quel comando e bisognerebbe indagare meglio.&lt;br /&gt;
&lt;br /&gt;
== Usare MicroPython dall'interprete ==&lt;br /&gt;
&lt;br /&gt;
Aprendo la porta della nostra scheda (la trovate su dmesg non appena la attaccate, è /dev/ttyACMx dove x è un numero che parte da 0) con un emulatore di terminale (come console) alla velocità di 115200 baud, dovreste vedere l'interprete dei comandi di MicroPython. Provate a dare il comando:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pyb.LED(1).on()&lt;br /&gt;
per vedere se si accende il LED onboard.&lt;br /&gt;
&lt;br /&gt;
== Usare MicroPython dal PC ==&lt;br /&gt;
&lt;br /&gt;
Fra i tool di MicroPython, che trovate nella cartella di git micropython/tools, c'è pyboard.py, un programma che vi permette di eseguire uno script in MicroPython. Se la vostra porta non è accessibile dall'utente dovrete usare sudo.&lt;br /&gt;
 # ./pyboard.py &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
== Caricare uno script ==&lt;br /&gt;
&lt;br /&gt;
Carmine ha fatto una modifica a pyboard in modo che possa caricare un file sulla board.&lt;br /&gt;
 # ./pyboard.py --device=/dev/ttyACMx --send &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
MicroPython ha due file di default quando viene installato: boot.py e main.py. Il primo è un file di sistema che serve allo stesso MicroPython di partire. Non occorre di solito modificarlo. Il secondo, main.py, è uno script che viene eseguito all'avvio. Se carichiamo un file main.py questo verrà eseguito all'accensione.&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6795</id>
		<title>Installare MicroPython su NUCLEO-F401RE</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6795"/>
		<updated>2019-02-19T20:38:45Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questa guida è basata quasi tutta su quella di Carmine Noviello https://www.carminenoviello.com/2015/06/03/running-micropyton-stm32nucleo-f4/ che peraltro trovate anche in italiano https://www.carminenoviello.com/it/2015/08/11/compilare-micropython-una-scheda-stm32nucleo-f4/ per cui scriverò solo le differenze.&lt;br /&gt;
&lt;br /&gt;
La versione di Carmine di micropython, che si trova sul suo [https://github.com/cnoviello/micropython github], risolve il problema relativo alla mancanza di memoria SD della scheda Nucleo. Il file con il programma .py sarà caricato direttamente sulla flash.&lt;br /&gt;
&lt;br /&gt;
== La scheda ==&lt;br /&gt;
&lt;br /&gt;
NUCLEO-F401RE della STMicroelectronics è una scheda basata su ARM Cortex M4 e fa parte della famiglia STM32 Nucleo Boards. Ha 512KB di Flash, 96 KB di SRAM, un clock di 84MHz, 50 GPIO, RTC, supporto I²C, SPI, USART e molto altro ([https://os.mbed.com/platforms/ST-Nucleo-F401RE/ maggiori info]). La sua forma le permette di alloggiare sia gli shield per Arduino che le estensioni Morpho di STMicroelectronics.&lt;br /&gt;
Il prezzo è abbastanza contenuto (attorno ai 12€ su Mouser) il che ne fa una scheda piuttosto interessante.&lt;br /&gt;
&lt;br /&gt;
Normalmente si programmerebbe tramite l'[https://ide.mbed.com/compiler editor online di Mbed]. Il compilatore genererà dal nostro codice un file con estensione bin. Collegando la scheda verrà montato un volume, chiamato &amp;quot;NUCLEO&amp;quot; sul quale caricare il file bin. Quando la scheda verrà resettata, il codice verrà eseguito. È possibile anche usare editor offline con toolchain di compilazione come Eclipse. Non credo sia possibile usare la IDE di Arduino.&lt;br /&gt;
&lt;br /&gt;
== Toolchain e OpenOCD ==&lt;br /&gt;
&lt;br /&gt;
Per compilare vi servirà la toolchain gcc-arm-embedded. Non è nei repo ufficiali quindi la dovete installare a mano oppure aggiungere un PPA. https://launchpad.net/gcc-arm-embedded&lt;br /&gt;
Il programma per comunicare col debugger della scheda, openocd, invece è nei repo di Debian.&lt;br /&gt;
 &lt;br /&gt;
== Come installare MicroPython ==&lt;br /&gt;
&lt;br /&gt;
Potete seguire la guida di Carmine per la compilazione. Ovviamente se avete installato la toolchain con apt non è necessario aggiungere il path a tutti i comandi, perché sono già dentro a /usr/bin.&lt;br /&gt;
&lt;br /&gt;
OpenOCD ci permette di caricare il firmware che abbiamo crosscompilato. Basterà lanciare il comando:&lt;br /&gt;
 $ openocd  -f board/st_nucleo_f4.cfg&lt;br /&gt;
Un LED della scheda dovrebbe lampeggiare rosso/verde. Il debugger è attivo. Per collegarcisi:&lt;br /&gt;
 $ telnet localhost 4444&lt;br /&gt;
e poi scrivete:&lt;br /&gt;
 &amp;gt; reset halt&lt;br /&gt;
e infine:&lt;br /&gt;
 &amp;gt; flash write_image erase &amp;lt;file .elf da flashare&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inizialmente non sembrava funzionare. Il tentativo finale che ha sbloccato la situazione è stato dare il comando shutdown. Non sono sicuro però che sia stato proprio quel comando e bisognerebbe indagare meglio.&lt;br /&gt;
&lt;br /&gt;
== Usare MicroPython dall'interprete ==&lt;br /&gt;
&lt;br /&gt;
Aprendo la porta della nostra scheda (la trovate su dmesg non appena la attaccate, è /dev/ttyACMx dove x è un numero che parte da 0) con un emulatore di terminale (come console) alla velocità di 115200 baud, dovreste vedere l'interprete dei comandi di MicroPython. Provate a dare il comando:&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pyb.LED(1).on()&lt;br /&gt;
per vedere se si accende il LED onboard.&lt;br /&gt;
&lt;br /&gt;
== Usare MicroPython dal PC ==&lt;br /&gt;
&lt;br /&gt;
Fra i tool di MicroPython, che trovate nella cartella di git micropython/tools, c'è pyboard.py, un programma che vi permette di eseguire uno script in MicroPython. Se la vostra porta non è accessibile dall'utente dovrete usare sudo.&lt;br /&gt;
 # ./pyboard.py &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
== Caricare uno script ==&lt;br /&gt;
&lt;br /&gt;
Carmine ha fatto una modifica a pyboard in modo che possa caricare un file sulla board.&lt;br /&gt;
 # ./pyboard.py --device=/dev/ttyACMx --send &amp;lt;nome file&amp;gt;.py&lt;br /&gt;
&lt;br /&gt;
MicroPython ha due file di default quando viene installato: boot.py e main.py. Il primo è un file di sistema che serve allo stesso MicroPython di partire. Non occorre di solito modificarlo. Il secondo, main.py, è uno script che viene eseguito all'avvio. Se carichiamo un file main.py questo verrà eseguito all'accensione.&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6794</id>
		<title>Installare MicroPython su NUCLEO-F401RE</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Installare_MicroPython_su_NUCLEO-F401RE&amp;diff=6794"/>
		<updated>2019-02-19T19:48:06Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: Creata pagina con 'Questa guida è basata quasi tutta su quella di Carmine Noviello https://www.carminenoviello.com/2015/06/03/running-micropyton-stm32nucleo-f4/ che peraltro trovate anche in it...'&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questa guida è basata quasi tutta su quella di Carmine Noviello https://www.carminenoviello.com/2015/06/03/running-micropyton-stm32nucleo-f4/ che peraltro trovate anche in italiano https://www.carminenoviello.com/it/2015/08/11/compilare-micropython-una-scheda-stm32nucleo-f4/ per cui scriverò solo le differenze sostanziali, per il resto vi rimando alla sua guida che comunque riassumerò.&lt;br /&gt;
&lt;br /&gt;
La versione di Carmine di micropython, che si trova sul suo [https://github.com/cnoviello/micropython github], risolve il problema relativo alla mancanza di memoria SD della scheda Nucleo. Il file con il programma .py sarà caricato direttamente sulla flash.&lt;br /&gt;
&lt;br /&gt;
== La scheda ==&lt;br /&gt;
&lt;br /&gt;
NUCLEO-F401RE della STMicroelectronics è una scheda basata su ARM Cortex M4 e fa parte della famiglia STM32 Nucleo Boards. Ha 512KB di Flash, 96 KB di SRAM, un clock di 84MHz, 50 GPIO, RTC, supporto I²C, SPI, USART e molto altro ([https://os.mbed.com/platforms/ST-Nucleo-F401RE/ maggiori info]). La sua forma le permette di alloggiare sia gli shield per Arduino che le estensioni Morpho di STMicroelectronics.&lt;br /&gt;
Il prezzo è abbastanza contenuto (attorno ai 12€ su Mouser) il che ne fa una scheda piuttosto interessante.&lt;br /&gt;
&lt;br /&gt;
Normalmente si programmerebbe tramite l'[https://ide.mbed.com/compiler editor online di Mbed]. Il compilatore genererà dal nostro codice un file con estensione bin. Collegando la scheda verrà montato un volume, chiamato &amp;quot;NUCLEO&amp;quot; sul quale caricare il file bin. Quando la scheda verrà resettata, il codice verrà eseguito. È possibile anche usare editor offline con toolchain di compilazione come Eclipse. Non credo sia possibile usare la IDE di Arduino.&lt;br /&gt;
&lt;br /&gt;
== Toolchain ==&lt;br /&gt;
&lt;br /&gt;
Potete installare, dai repo di Debian,&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Gruppo_%C2%B5Python&amp;diff=6793</id>
		<title>Gruppo µPython</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Gruppo_%C2%B5Python&amp;diff=6793"/>
		<updated>2019-02-19T19:08:17Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* NUCLEO-F401RE */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Gruppo&lt;br /&gt;
|nome=MicroPython&lt;br /&gt;
|descrizione=Proviamo il MicroPython https://micropython.org/&lt;br /&gt;
|iscritti=Oloturia&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Il linguaggio più bello del mondo approda anche ai microcontrollori. Ecco qui le nostre esperienze.&lt;br /&gt;
&lt;br /&gt;
=== Micro:Bit ===&lt;br /&gt;
&lt;br /&gt;
Il Micro:Bit è una piattaforma educational che si può programmare anche in MicroPython. https://microbit.org/guide/python/&lt;br /&gt;
&lt;br /&gt;
=== NUCLEO-F401RE ===&lt;br /&gt;
&lt;br /&gt;
Sulla scheda NUCLEO-F401RE della STMicroelectronics è possibile installare MicroPython, con alcuni accorgimenti. Leggi la [[Installare MicroPython su NUCLEO-F401RE|guida]] qui.&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Gruppo_%C2%B5Python&amp;diff=6792</id>
		<title>Gruppo µPython</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Gruppo_%C2%B5Python&amp;diff=6792"/>
		<updated>2019-02-19T19:06:34Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Gruppo&lt;br /&gt;
|nome=MicroPython&lt;br /&gt;
|descrizione=Proviamo il MicroPython https://micropython.org/&lt;br /&gt;
|iscritti=Oloturia&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Il linguaggio più bello del mondo approda anche ai microcontrollori. Ecco qui le nostre esperienze.&lt;br /&gt;
&lt;br /&gt;
=== Micro:Bit ===&lt;br /&gt;
&lt;br /&gt;
Il Micro:Bit è una piattaforma educational che si può programmare anche in MicroPython. https://microbit.org/guide/python/&lt;br /&gt;
&lt;br /&gt;
=== NUCLEO-F401RE ===&lt;br /&gt;
&lt;br /&gt;
Sulla scheda NUCLEO-F401RE della STMicroelectronics è possibile installare MicroPython, con alcuni accorgimenti. Leggi la [[guida|Installare MicroPython su NUCLEO-F401RE]] qui.&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Gruppo_%C2%B5Python&amp;diff=6791</id>
		<title>Gruppo µPython</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Gruppo_%C2%B5Python&amp;diff=6791"/>
		<updated>2019-02-19T18:57:49Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: Creata pagina con '{{Gruppo |nome=MicroPython |descrizione=Proviamo il micro python |iscritti=Oloturia }}  Il linguaggio più bello del mondo approda anche ai microcontrollori. Ecco qui le nostr...'&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Gruppo&lt;br /&gt;
|nome=MicroPython&lt;br /&gt;
|descrizione=Proviamo il micro python&lt;br /&gt;
|iscritti=Oloturia&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Il linguaggio più bello del mondo approda anche ai microcontrollori. Ecco qui le nostre esperienze.&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Gruppi&amp;diff=6790</id>
		<title>Gruppi</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Gruppi&amp;diff=6790"/>
		<updated>2019-02-19T18:52:03Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;column-count:2;-moz-column-count:2;-webkit-column-count:2&amp;quot;&amp;gt;&lt;br /&gt;
* [[Tavolo zero (renzo)|Tavolo zero (renzo)]]&lt;br /&gt;
* [[Gruppo CNC|CNC/Stampa 3D]]&lt;br /&gt;
* [[Gruppo Domotica|Domotica]]&lt;br /&gt;
* [[Gruppo Didattica|Didattica]]&lt;br /&gt;
* [[GruppoLampone|Gruppo Lampone]]&lt;br /&gt;
* [[Gruppo Meteo|Meteo/Ambiente]]&lt;br /&gt;
* [[Gruppo Robottini|Robottini]]&lt;br /&gt;
* [[Gruppo Auto|Auto/Mobilità]]&lt;br /&gt;
* [[Gruppo Volo|Volo]]&lt;br /&gt;
* [[Gruppo Ham|Ham/Radio]]&lt;br /&gt;
* [[Gruppo Chaser man|Chaser man]]&lt;br /&gt;
* [[Gruppo Cycloscope|Cycloscope]]&lt;br /&gt;
* [[Gruppo WBEN|WBEN]]&lt;br /&gt;
* [[Gruppo Event Man(anger)|Event Man(anager)]]&lt;br /&gt;
* [[Gruppo Metal Detector DIY]]&lt;br /&gt;
* [[Gruppo µPython]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Gruppo_Meteo/Software/Devel/StimaVersione2&amp;diff=6728</id>
		<title>Gruppo Meteo/Software/Devel/StimaVersione2</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Gruppo_Meteo/Software/Devel/StimaVersione2&amp;diff=6728"/>
		<updated>2018-11-13T22:14:27Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* C++ */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Guide per developers =&lt;br /&gt;
== Software rmap ==&lt;br /&gt;
=== Libreria di &amp;quot;driver&amp;quot; per sensori ===&lt;br /&gt;
Esistono attualmente due versioni, una in C++ e una in python&lt;br /&gt;
&lt;br /&gt;
==== C++ ====&lt;br /&gt;
&lt;br /&gt;
https://github.com/r-map/rmap/tree/master/arduino/sketchbook/libraries/SensorDriver&lt;br /&gt;
&lt;br /&gt;
Porta le gestione della sensoristica ad un livello di astrazione più&lt;br /&gt;
alto. Praticamente si tratterebbe di estendere una classe&lt;br /&gt;
con quattro metodi per effettuare la lettura di uno specifico sensore:&lt;br /&gt;
&lt;br /&gt;
    virtual int setup(const char* driver, const int address, const int node=0, const char* type=NULL, char* mainbuf=0, size_t lenbuf=0, RF24Network* network=NULL);&lt;br /&gt;
effettua eventuali settaggi necessari al funzionamento del sensore;&lt;br /&gt;
esempio per temperatura: numero di bit di risoluzione, operazione di&lt;br /&gt;
misura one-shot; i paramteri const int node=0, const char* type=NULL, char* mainbuf=0, size_t lenbuf=0, RF24Network* network=NULL servono per la gestione di un sensore remoto eseguendo una jsonrpc su trasporto NRF24Network&lt;br /&gt;
&lt;br /&gt;
    virtual int prepare(unsigned long* waittime) = 0;&lt;br /&gt;
impartisce al sensore il comando per effettuare una singola misurazione&lt;br /&gt;
torna il tempo in millisecondi di attesa necessario&lt;br /&gt;
&lt;br /&gt;
    virtual int get(int values[],size_t lenvalues) = 0;&lt;br /&gt;
torna i valori della misurazione&lt;br /&gt;
&lt;br /&gt;
    virtual aJsonObject* getJson() = 0;&lt;br /&gt;
torna i valori in formato json, formato preferito ed utilizzato in r-map&lt;br /&gt;
Vedi RFC-rmap&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Questa piccola libreria è nata per sensori I2C, ma non per forza&lt;br /&gt;
limitata a quelli e infatti prevede già una json-rpc con trasporto via radio.&lt;br /&gt;
Sarà estesa per umidità, pressione, direzione e intensità del vento e&lt;br /&gt;
precipitazione.&lt;br /&gt;
&lt;br /&gt;
il file SensorDriver_config.h definisce quali driver includere nella libreria e altri parametri di configurazione a compile time&lt;br /&gt;
&lt;br /&gt;
==== python ====&lt;br /&gt;
&lt;br /&gt;
https://github.com/r-map/rmap/blob/master/python/rmap/sensordriver.py&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=OttoBot&amp;diff=6688</id>
		<title>OttoBot</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=OttoBot&amp;diff=6688"/>
		<updated>2018-06-04T15:26:24Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* Lo chassis */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;OttoBot è il risultato di un tentativo di usare un [http://www.atmel.com/devices/atmega8.aspx ATmega8] al posto di una board Arduino.&lt;br /&gt;
&lt;br /&gt;
= Le specifiche tecniche =&lt;br /&gt;
L'ATmega8, prodotto da Atmel, è piuttosto modesto.&lt;br /&gt;
&lt;br /&gt;
* Ha 8KB di memoria flash. Se usate il bootloader di Arduino allora ve ne rimarranno solo 7.&lt;br /&gt;
* Il clock è massimo 16Mhz usando un risuonatore esterno. Quello interno va a 8Mhz (ma vi risparmiate un bel po' di circuiteria). Per usare il risuonatore interno occorre cambiare un fuse.&lt;br /&gt;
* 23 pin programmabili.&lt;br /&gt;
* 2 interrupt.&lt;br /&gt;
* Porte SPI, I²C e seriale (ma non è possibile usare seriali software, presenti nella libreria di Arduino).&lt;br /&gt;
* Costa una bazzecola. &lt;br /&gt;
&lt;br /&gt;
Per essere acceso ha bisogno da 2,7 a 5,5 Volt.&lt;br /&gt;
Il prezzo oscilla attorno all'euro.&lt;br /&gt;
[[Category:Progetti]]&lt;br /&gt;
&lt;br /&gt;
= Prime versioni =&lt;br /&gt;
&lt;br /&gt;
[[File:8bot.jpg]]&lt;br /&gt;
&lt;br /&gt;
Come potete vedere, la dimensione è proprio mini. Si comanda tramite bluetooth. Ruote e chassis sono stampate 3d.&lt;br /&gt;
&lt;br /&gt;
[[File:8bots.JPG]]&lt;br /&gt;
&lt;br /&gt;
Da sinistra a destra, l'evoluzione di 8bot!&lt;br /&gt;
&lt;br /&gt;
= Modificare l'ATmega8 affinché sembri un Arduino =&lt;br /&gt;
&lt;br /&gt;
Per approfondire questo argomento leggete anche  [[Programmazione dei microcontrollori]].&lt;br /&gt;
&lt;br /&gt;
Per ottenere questo occorre fare tre cose:&lt;br /&gt;
* Trovare un programmatore (potete usare la [http://www.instructables.com/id/Simplest-AVR-Parallel-port-programmer/ porta parallela] oppure acquistarne uno, ma anche un normalissimo Arduino può essere usato come programmatore)&lt;br /&gt;
* Settare i fuses&lt;br /&gt;
* Caricare il bootloader&lt;br /&gt;
* Aggiungere l'ATmega8 nel file boards.txt di Arduino&lt;br /&gt;
&lt;br /&gt;
Una volta fatti questi passi, potrete usare l'IDE come per qualsiasi altra board.&lt;br /&gt;
&lt;br /&gt;
Di guide su come usare i programmatori ne trovate a bizzeffe su internet, noi ci concentreremo sull'utilizzo di Arduino come ISP, che è la procedura che ho usato io.&lt;br /&gt;
&lt;br /&gt;
== Arduino as ISP ==&lt;br /&gt;
&lt;br /&gt;
Negli sketch di esempio nella IDE di Arduino c'è &amp;quot;Arduino as ISP&amp;quot; (In-System Programmer). Caricatelo su un Arduino di vostra scelta con l'accortezza di controllare i pin da usare: sui Mega sono diversi. Dovrete usare la porta SPI e in genere avete: 10 reset, 11 MOSI, 12 MISO e 13 clock (SCK). Sui Mega le porte sono rispettivamente 53, 51, 50 e 52. Trovate tutto nei commenti dello sketch.&lt;br /&gt;
Altri pin, opzionali, sono il 9 (heartbeat, mostra se il programma sta girando), 8 (error, si accende se c'è un problema), 7 (programming, si accende durante le comunicazioni).&lt;br /&gt;
&lt;br /&gt;
La porta SPI va così collegata, MISO con MISO, MOSI con MOSI, SCK con SCK e reset con reset. Il datasheet lo trovate qui [http://www.atmel.com/Images/Atmel-2486-8-bit-AVR-microcontroller-ATmega8_L_datasheet.pdf]&lt;br /&gt;
&lt;br /&gt;
[[File:Atmega8 arduinopinout.png]]&lt;br /&gt;
&lt;br /&gt;
I pin che vedete sono quelli come da IDE di Arduino. Se lo programmate con altri sistemi (come Eclipse) i riferimenti possono essere diversi.&lt;br /&gt;
Se il vostro ATmega8 è settato per avere un risuonatore esterno, dovrete collegarlo con un pin XTAL1 e l'altro su XTAL2. Entrambi i pin XTAL1 e XTAL2 vanno poi collegati a terra con un condensatore da 22 picofarad. Ne avrete bisogno se volete raggiungere frequenze superiori agli 8 Mhz o se avete bisogno di maggiore stabilità (il risuonatore interno non è molto preciso). Per contro, il risuonatore interno non ha bisogno di collegare nulla. Per approfondire guardate questa guida [http://kskpages.weebly.com/clock-settings.html]&lt;br /&gt;
&lt;br /&gt;
== avrdude ==&lt;br /&gt;
&lt;br /&gt;
Per interagire con l'ATmega8 dovrete usare avrdude, questa è una riga di esempio:&lt;br /&gt;
 avrdude -p m8 -c arduino -P /dev/ttyACM1 -U flash:w:{bootloader}.hex -U hfuse:w:0xd9:m -U lfuse:w:0xe3:m -b 19200&lt;br /&gt;
&lt;br /&gt;
Per saperne di più [http://www.nongnu.org/avrdude/user-manual/avrdude_4.html]&lt;br /&gt;
&lt;br /&gt;
 -p m8 &lt;br /&gt;
dice che abbiamo a che fare con un ATmega8&lt;br /&gt;
&lt;br /&gt;
 -c arduino&lt;br /&gt;
segnala che stiamo usando un Arduino come programmatore, nelle nuove versioni della IDE, con il nuovo sketch ArduinoISP probabilmente il protocollo da usare è stk500v1&lt;br /&gt;
&lt;br /&gt;
 -P /dev/(porta)&lt;br /&gt;
è la porta dove avete collegato il programmatore, di solito per gli Arduino è ttyACMx o ttyUSBx; per conoscerla ci sono due modi: guardare nella IDE di Arduino le porte disponibili o collegare l'Arduino e guardare gli ultimi messaggi in dmesg&lt;br /&gt;
&lt;br /&gt;
 -U flash:w:{bootloader}.hex&lt;br /&gt;
scrive il bootloader, vedi sotto&lt;br /&gt;
 &lt;br /&gt;
 -U hfuse:w:0xd9:m -U lfuse:w:0xe3:m &lt;br /&gt;
modifica i fuse, vedi sotto&lt;br /&gt;
&lt;br /&gt;
 -b 19200&lt;br /&gt;
la velocità di comunicazione in baud&lt;br /&gt;
&lt;br /&gt;
== Caricare il bootloader ==&lt;br /&gt;
&lt;br /&gt;
Se volete usarlo come Arduino dovreste caricare il bootloader. Potete farne anche a meno e risparmiare 1Kb (su 8, non è poco). In teoria potreste farne a meno e continuare a caricare gli sketch sull'ATmega8 l'Arduino come programmatore. Fatto sta che l'ho caricato una volta e non ho mai provato a toglierlo (del resto: if ain't broke, don't fix it). I bootloader li trovate in {cartella di Arduino}/hardware/arduino/avr/bootloaders. Se non li avete li trovate qua [https://github.com/arduino/Arduino/tree/master/hardware/arduino/avr/bootloaders]&lt;br /&gt;
&lt;br /&gt;
== Settare i fuse ==&lt;br /&gt;
&lt;br /&gt;
Molte opzioni dell'ATmega8 sono settabili tramite dei fuse. I fuse sono dei bit su una memoria EEPROM che dicono al microcontrollore come deve comportarsi. Tramite i fuses è possibile settare il clock, se usare un oscillatore esterno o interno, quanto deve aspettare durante il boot per una nuova programmazione, etc. &lt;br /&gt;
Qui trovate due calcolatori di fuse, questo è più semplice da usare [https://elektronik-kompendium.de/public/arnerossius/programme/web/avrfuse/ avrfuse] questo è più completo [http://www.engbedded.com/fusecalc/ Engbedded AVR Fuse Calculator].&lt;br /&gt;
&lt;br /&gt;
== Aggiungere le opzioni alla IDE di Arduino ==&lt;br /&gt;
&lt;br /&gt;
Se siete affezionati alla IDE dovrete aggiungere al menu delle board l'ATmega8.&lt;br /&gt;
&lt;br /&gt;
In teoria, nel menu Tools/boards, c'è già &amp;quot;Arduino NG or older&amp;quot; che ha, fra le varie opzioni, anche la possibilità di usare l'ATmega8, ma io ho avuto una serie di problemi a usarla e alla fine non ho provato a capire perché non funzionasse.&lt;br /&gt;
&lt;br /&gt;
Andate in {cartella di Arduino}/hardware/arduino/avr e aprite il file boards.txt (se avete paura di fare dei danni, fate una copia di questo file prima, per precauzione).&lt;br /&gt;
&lt;br /&gt;
Per aggiungere l'ATmega8 basta aggiungere queste opzioni alla fine [https://github.com/chuckb/atmega/blob/master/atmega/avr/boards.txt].&lt;br /&gt;
&lt;br /&gt;
''In alternativa''&lt;br /&gt;
&lt;br /&gt;
Copiate i files dal repository https://github.com/chuckb/atmega, cartellle incluse, nella directory hardware degli sketches arduino, per esempio (nel mio caso):&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:blue;overflow:auto&amp;quot;&amp;gt;&lt;br /&gt;
ls ~/arduino-sketches/hardware/atmega/avr/&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:green;overflow:auto&amp;quot;&amp;gt;&lt;br /&gt;
boards.txt  platform.txt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se caricate uno sketch sul microcontrollore con un clock sbagliato accadranno risultati imprevedibili, ad es. caricate dalla IDE usando ATmega8 a 4Mhz con i fuses settati in modo che vada a 8Mhz scoprirete che tutto andrà al doppio della velocità.&lt;br /&gt;
I secondi diventano mezzi secondi, 9600 baud diventano 19200 e così via. Non una gran cosa se state cercando di programmare, però può sfuggirvi perché non segnala nessun errore.&lt;br /&gt;
&lt;br /&gt;
Una volta editato boards.txt riavviate la IDE se l'avevate aperta e vedrete comparire nel menu Tools/board una nuova voce, quella dell'ATmega8.&lt;br /&gt;
&lt;br /&gt;
== Caricare uno sketch ==&lt;br /&gt;
&lt;br /&gt;
Collegate il programmatore (nei nostri esempi, l'Arduino) all'ATmega8 alla seriale (se avete caricato il bootloader) o alla SPI, collegate il reset (di default su Arduino as ISP è il pin 10), il +5v e la terra, andate sotto Sketch e usate &amp;quot;Upload Using Programmer&amp;quot;. Alternativamente potete cliccare shift+pulsante del caricamento dello sketch. Se tutto è andato come dovrebbe vedrete lampeggiare i LED della seriale dell'Arduino per qualche secondo fino a che l'IDE non ci comunicherà &amp;quot;done&amp;quot;.&lt;br /&gt;
Se invece non volete usare la IDE, potete compilare il vostro sketch con avr-gcc e uploadarlo direttamente con avrdude (ma di questo non tratteremo qui).&lt;br /&gt;
&lt;br /&gt;
Problemi più frequenti: cavetti non collegati bene, cavetti invertiti, alimentazione non sufficiente, oscillatore esterno previsto ma mancante.&lt;br /&gt;
&lt;br /&gt;
== Altri metodi ==&lt;br /&gt;
&lt;br /&gt;
Potete usare, ad esempio, la SPI del Raspberry Pi, guardate la pagina [[Programmazione_dei_microcontrollori]].&lt;br /&gt;
&lt;br /&gt;
= Lo schema elettrico =&lt;br /&gt;
&lt;br /&gt;
È estremamente banale. Collegate le batterie a modulo Bluetooth, integrato e motori, in parallelo, collegate i fili del segnale dei servo a un pin libero dell'ATmega8, collegate RX dell'integrato a TX del modulo Bluetooth. Se volete un feedback dall'integrato allora collegate anche il TX dell'integrato al RX del modulo Bluetooth.&lt;br /&gt;
&lt;br /&gt;
[[File:8botschema.png]]&lt;br /&gt;
&lt;br /&gt;
In sintesi:&lt;br /&gt;
* il + delle batterie va collegato a: vcc del modulo Bluetooth, vcc dell'ATmega8, + del servo 1 e 2&lt;br /&gt;
* il - delle batterie va collegato a: gnd del modulo Bluetooth, due gnd dell'ATmega8, - del servo 1 e 2&lt;br /&gt;
* TX del modulo Bluetooth va collegato a RX dell'ATmega8&lt;br /&gt;
* RX del modulo Bluetooth va collegato a TX dell'ATmega8&lt;br /&gt;
* i segnali dei servi vanno collegati a due pin liberi (nel nostro caso 14 e 15 ma potete benissimo sceglierne degli altri)&lt;br /&gt;
&lt;br /&gt;
= Lo sketch =&lt;br /&gt;
&lt;br /&gt;
Lo trovate sul repository:&lt;br /&gt;
[https://gitlab.com/oloturia/8bot]&lt;br /&gt;
&lt;br /&gt;
Vediamo un po' i punti più strani.&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Servo.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 Servo dx_servo;&lt;br /&gt;
 Servo sx_servo;&lt;br /&gt;
 &lt;br /&gt;
 const int dx_pin = 8;&lt;br /&gt;
 const int sx_pin = 9;&lt;br /&gt;
 int fd_spd_dx = 180; //initial values&lt;br /&gt;
 int bk_spd_dx = 0;   //180 is full forward, 0 full backward&lt;br /&gt;
 int fd_spd_sx = 0;   //stop is somewhere in the middle &lt;br /&gt;
 int bk_spd_sx = 180; //but the motors keep running&lt;br /&gt;
&lt;br /&gt;
Per far funzionare il nostro robottino servirà la libreria Servo. La EEPROM ci servirà per mantenere la calibrazione da spento. Ci sono due costanti, i pin a cui sono collegati il segnale dei servi, e i valori che passeremo al metodo write degli oggetti dx_servo e sx_servo. Nei servo continui 0 è antiorario e 180 orario, lo stato fermo è più o meno 90. In questo caso però li staccheremo con detach così da non mantenerli in tensione. Se il vostro progetto non ha bisogno che il servo faccia resistenza (ad es. deve tenere un peso) allora è meglio staccarlo. Non è solo una questione di risparmio energetico: i piccoli servo e quelli di scarsa qualità quando sono in tensione tendono a scaldare.&lt;br /&gt;
Le quattro variabili sono rispettivamente il valore avanti e indietro del motore a destra e il valore avanti e indietro del motore a sinistra.&lt;br /&gt;
&lt;br /&gt;
 void setup() {&lt;br /&gt;
   Serial.begin(9600);&lt;br /&gt;
   Serial.println(&amp;quot;READY&amp;quot;);&lt;br /&gt;
   if (EEPROM.read(4) == 1) {&lt;br /&gt;
     fd_spd_dx = EEPROM.read(0);//reserve 4 bytes &lt;br /&gt;
     bk_spd_dx = EEPROM.read(1);//for saved calibration&lt;br /&gt;
     fd_spd_sx = EEPROM.read(2);&lt;br /&gt;
     bk_spd_sx = EEPROM.read(3);&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Accende la seriale e si legge la EEPROM. La memoria non scritta ha come valore 255 quindi serve un quinto elemento che comunichi se la calibrazione è stata fatta o meno. Scrivere e aggiornare la EEPROM è facilissimo. Vi consiglio di leggere la guida ufficiale [https://www.arduino.cc/en/Reference/EEPROM]. Ricordate che l'ATmega8 ha 512 bytes a disposizione nella EEPROM.&lt;br /&gt;
&lt;br /&gt;
 void loop() {&lt;br /&gt;
   if(Serial.available()){&lt;br /&gt;
     char command = Serial.read(); //every command is a char&lt;br /&gt;
     if (command == 's') {         //it is possible to write to  the bot&lt;br /&gt;
       turnOnServo();              //using a keyboard&lt;br /&gt;
       dx_servo.write(fd_spd_dx);&lt;br /&gt;
       sx_servo.write(fd_spd_sx);&lt;br /&gt;
  } else if (command == 'd') {&lt;br /&gt;
  [...]&lt;br /&gt;
&lt;br /&gt;
Ogni comando ricevuto dalla seriale è un char. Si potrebbe eventualmente mandare un byte, ma così è più comodo soprattutto quando ancora non avevo pronta la app e dovevo pilotare il piccolo bot con la tastiera. Si può ancora fare: i tasti sono wasd. Sulla funzione turnOnServo() torneremo dopo.&lt;br /&gt;
&lt;br /&gt;
  [...]&lt;br /&gt;
  } else if (command == 'h') {&lt;br /&gt;
       if (fd_spd_dx &amp;gt; 90) {&lt;br /&gt;
         fd_spd_dx --;        &lt;br /&gt;
  }&lt;br /&gt;
  [...]&lt;br /&gt;
&lt;br /&gt;
Altri comandi servono per la calibrazione. Purtroppo nella app la calibrazione è ancora molto confusionaria. Ogni variabile può diventare da 0 a 90 e da 91 a 180.&lt;br /&gt;
&lt;br /&gt;
    [...]&lt;br /&gt;
    } else if (command == 'z') { //save calibration into eeprom&lt;br /&gt;
      EEPROM.update(0,fd_spd_dx);&lt;br /&gt;
      EEPROM.update(1,bk_spd_dx); &lt;br /&gt;
      EEPROM.update(2,fd_spd_sx);&lt;br /&gt;
      EEPROM.update(3,bk_spd_sx);&lt;br /&gt;
      EEPROM.update(4,1);&lt;br /&gt;
      Serial.println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      stopServo(); //if the serial is empty, stop the motors&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Infine, ecco dove la EEPROM viene scritta, incluso l'indirizzo 4 che diventa 1 e segnala al prossimo riavvio di leggersi i valori che avevamo salvato. Se non arriva nessun comando i servo vengono staccati.&lt;br /&gt;
&lt;br /&gt;
 void turnOnServo() {&lt;br /&gt;
   dx_servo.attach(dx_pin);&lt;br /&gt;
   sx_servo.attach(sx_pin);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 void stopServo() {&lt;br /&gt;
   dx_servo.detach();&lt;br /&gt;
   sx_servo.detach();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Ogni volta che arriva un comando vengono riattaccati. In questo modo non rimarranno sotto tensione.&lt;br /&gt;
&lt;br /&gt;
= Il bluetooth = &lt;br /&gt;
&lt;br /&gt;
Il collegamento fra l'Ottobot e il vostro smartphone o il vostro computer avverrà tramite il modulo HC-05 o HC-06. Il modulo è molto semplice da usare: ha una porta seriale fisica dove legge e scrive tutto ciò che arriva via il servizio di porta seriale via Bluetooth. Nel nostro caso sarà attaccato direttamente ai pin RX e TX del nostro ATmega8 e farà come da ponte fra il nostro dispositivo e il microcontrollore. Potete leggere più informazioni su come giocare con questo tipo di moduli nella pagina [[HC-05 e HC-06]].&lt;br /&gt;
&lt;br /&gt;
= L'app =&lt;br /&gt;
&lt;br /&gt;
Potete scaricarla, guardarla e modificarla all'indirizzo di App Inventor (serve account Google) [http://ai2.appinventor.mit.edu/?locale=en&amp;amp;galleryId=5162309564235776 qua].&lt;br /&gt;
&lt;br /&gt;
L'app è stata scritta con il MIT App Inventor 2. È un tool molto potente utile per chi, come me, è ancora fermo a cercare di fare un &amp;quot;Hello World&amp;quot; decente su Android. Non è la soluzione più efficace, ma nell'attesa di imparare qualcosa di migliore, è la più semplice.&lt;br /&gt;
&lt;br /&gt;
L'App Inventor è basato sul popolare linguaggio educativo Scratch. Permette di inserire pulsanti, grafica e di interagire con i sensori e, nel nostro caso, con dispositivi Bluetooth. Permette di collegarsi a un dispositivo Android (anche emulato) per fare dei test in real-time e fare correzioni al volo. Quando avrete finito potrete creare un .apk da installare così non avrete più bisogno dell'App Inventor per usarla.&lt;br /&gt;
&lt;br /&gt;
Tutte le informazioni su come utilizzarlo le trovate nel sito ufficiale [http://appinventor.mit.edu/explore/ai2/setup.html].&lt;br /&gt;
&lt;br /&gt;
Nel repository c'è il sorgente in formato .aia, che potete caricare sull'App Inventor con Import.&lt;br /&gt;
&lt;br /&gt;
Per prima cosa ho creato, nello Screen 1, una lista che si carica con la lista dei dispositivi Bluetooth che sono nel range del nostro tablet o telefono. Nella schermata c'è solo una lista e un componente &amp;quot;Bluetooth Client&amp;quot; chiamato BluetoothClient1.&lt;br /&gt;
&lt;br /&gt;
[[File:Initbt.png]]&lt;br /&gt;
&lt;br /&gt;
AfterPicking, ovvero dopo aver scelto un dispositivo, andrà nello screen &amp;quot;Controls&amp;quot; portandosi dietro il nome del dispositivo a cui ci vogliamo connettere. &lt;br /&gt;
&lt;br /&gt;
Andiamo ora nella schermata &amp;quot;Controls&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Controls_8bot.png]]&lt;br /&gt;
&lt;br /&gt;
Ci sono i pulsanti per le direzioni, un pulsante per connettersi a un altro dispositivo (che non fa altro che tornare a Screen1), e i pulsanti per la taratura (ancora in beta). Anche qui c'è BluetoothClient1. Appena arriva in questa schermata l'app si fermerà per permettere di fare l'accoppiamento tramite Bluetooth. Il pin è di solito 1234.&lt;br /&gt;
&lt;br /&gt;
[[File:Initcontr.png]]&lt;br /&gt;
&lt;br /&gt;
Se non riesce a connettersi o se clicchiamo &amp;quot;Connect&amp;quot; tornerà nella schermata di selezione precedente.&lt;br /&gt;
&lt;br /&gt;
[[File:Controlscomm.png]]&lt;br /&gt;
&lt;br /&gt;
I controlli sono molto semplici: ogni tasto invia un carattere. Quando viene rilasciato manda un carattere che spegne i servo. Non è ancora perfetto perché se perde la connessione i motori rimangono accesi, in futuro questo problema sarà corretto.&lt;br /&gt;
&lt;br /&gt;
[[File:Trim8bot.png]]&lt;br /&gt;
&lt;br /&gt;
Infine il codice per la calibrazione. A seconda se il robot sta andando avanti oppure indietro saranno calibrati i valori che vengono usati per muovere i motori. Purtroppo questa parte non è ancora scritta in modo efficace (ad es. il motore che va avanti in senso antiorario va più veloce con un valore INFERIORE, quindi per farlo andare più veloce occorre premere il tasto MENO). Quando la calibrazione è soddisfacente, con il tasto &amp;quot;Write&amp;quot; la si memorizza nella EEPROM dell'ATmega8.&lt;br /&gt;
&lt;br /&gt;
= I motori =&lt;br /&gt;
&lt;br /&gt;
L'8bot ha bisogno di due servo motori 9g continui, detti anche servo a 360°. Se volete risparmiare ulteriormente potete acquistare dei normalissimi servo a 180° e fare qualche modifica per trasformarli in 360°.&lt;br /&gt;
Per effettuare la modifica seguite [[Modifica_servo_rc_per_rotazione_continua|questa guida]].&lt;br /&gt;
&lt;br /&gt;
= Lo chassis =&lt;br /&gt;
Tutti gli .stl di 8bot li trovate su git [https://gitlab.com/oloturia/8bot]&lt;br /&gt;
&lt;br /&gt;
== Le ruote ==&lt;br /&gt;
Per le ruote ci sono due modelli, uno è della dimensione delle gomme delle mini4wd Tamiya[https://gitlab.com/oloturia/8bot/blob/master/wheel-mini4wd.stl]:&lt;br /&gt;
&lt;br /&gt;
[[File:8bot4wd.png]]&lt;br /&gt;
&lt;br /&gt;
mentre l'altro è della dimensione di un o-ring[https://gitlab.com/oloturia/8bot/blob/master/wheel0ring.stl]:&lt;br /&gt;
&lt;br /&gt;
[[File:8botoring.png]]&lt;br /&gt;
&lt;br /&gt;
entrambe si incastrano sul pignone del servo senza bisogno di viti o altro (ma se volete metterne una, male non fa).&lt;br /&gt;
&lt;br /&gt;
== Il telaio ==&lt;br /&gt;
Il telaio è una piccola piattaforma con due fessure per inserire un'aletta del servi e un foro per la casterball. Recentemente ho aggiunto altre due alette per tenere fermo il portabatterie[https://gitlab.com/oloturia/8bot/blob/master/body.stl].&lt;br /&gt;
&lt;br /&gt;
[[File:Chass.png]]&lt;br /&gt;
&lt;br /&gt;
= Corso di costruzione Ottobot =&lt;br /&gt;
Nell'autunno 2016 a Raspibo un gruppo di makers si e' riunito specificamente per costruire Ottobot e programmarli sotto la guida paziente di Oloturia, creatore del progetto.&lt;br /&gt;
&lt;br /&gt;
== Materiale ==&lt;br /&gt;
Il materiale e' stato procurato dallo stesso Oloturia da vari fornitori durante l'estate con un occhio particolare ai costi per permettera tutti di realizzare un piccolo robot didattico.&lt;br /&gt;
&lt;br /&gt;
Alcune parti progettate appositamente, sono state stampate in 3D.&lt;br /&gt;
&lt;br /&gt;
Ad ogni partecipante del corso e' stato fornito un kit, oltre a questo ogni partecipante ha portato un po' di attrezzi ed un pc.&lt;br /&gt;
&lt;br /&gt;
[[File:Ottobot kit.jpg|600px|thumb|center|Il kit completo del corso ottobot]]&lt;br /&gt;
&lt;br /&gt;
== Preparazione dei motori ==&lt;br /&gt;
Nel kit i due servo possono essere sia a rotazione continua quindi gia' pronti oppure standard.&lt;br /&gt;
&lt;br /&gt;
Per i motori standard e' neccessario procedere ad una modifica vedi [[Modifica_servo_rc_per_rotazione_continua]]&lt;br /&gt;
&lt;br /&gt;
== Assemblaggio del robot ==&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;margin-top:2px; background:none;align:center;width:100%;border:1px solid red;-moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius:10px;&amp;quot;&lt;br /&gt;
|[[File:Ottobot assemblaggio 10.jpg|400px|thumb|left|Montare le ruote sul microservo modificato per rotazione continua]] &lt;br /&gt;
|Le ruote vanno montate sull'asse con una vite che si trova nel sacchetto degli accessori del servo. Il tutto va poi incastrato sulla base. Se la stampa e' perfetta i motori si incastrano perfettamete sulla base altrimenti ci si puo' aiutare con colla, viti o nastro biadesivo.&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;margin-top:2px; background:none;align:center;width:100%;border:1px solid red;-moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius:10px;&amp;quot;&lt;br /&gt;
|[[File:Ottobot assemblaggio 20.jpg|400px|thumb|left|Fissare la ball caster]] &lt;br /&gt;
|Come terzo appoggio utilizziamo una ballcaster che consente liberta' di movimento e di sterzata. Inserire il pezzo nel foro centrale e fissarlo con tre viti, oppure colla.&lt;br /&gt;
|&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=OttoBot&amp;diff=6687</id>
		<title>OttoBot</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=OttoBot&amp;diff=6687"/>
		<updated>2018-06-04T15:24:51Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* Lo sketch */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;OttoBot è il risultato di un tentativo di usare un [http://www.atmel.com/devices/atmega8.aspx ATmega8] al posto di una board Arduino.&lt;br /&gt;
&lt;br /&gt;
= Le specifiche tecniche =&lt;br /&gt;
L'ATmega8, prodotto da Atmel, è piuttosto modesto.&lt;br /&gt;
&lt;br /&gt;
* Ha 8KB di memoria flash. Se usate il bootloader di Arduino allora ve ne rimarranno solo 7.&lt;br /&gt;
* Il clock è massimo 16Mhz usando un risuonatore esterno. Quello interno va a 8Mhz (ma vi risparmiate un bel po' di circuiteria). Per usare il risuonatore interno occorre cambiare un fuse.&lt;br /&gt;
* 23 pin programmabili.&lt;br /&gt;
* 2 interrupt.&lt;br /&gt;
* Porte SPI, I²C e seriale (ma non è possibile usare seriali software, presenti nella libreria di Arduino).&lt;br /&gt;
* Costa una bazzecola. &lt;br /&gt;
&lt;br /&gt;
Per essere acceso ha bisogno da 2,7 a 5,5 Volt.&lt;br /&gt;
Il prezzo oscilla attorno all'euro.&lt;br /&gt;
[[Category:Progetti]]&lt;br /&gt;
&lt;br /&gt;
= Prime versioni =&lt;br /&gt;
&lt;br /&gt;
[[File:8bot.jpg]]&lt;br /&gt;
&lt;br /&gt;
Come potete vedere, la dimensione è proprio mini. Si comanda tramite bluetooth. Ruote e chassis sono stampate 3d.&lt;br /&gt;
&lt;br /&gt;
[[File:8bots.JPG]]&lt;br /&gt;
&lt;br /&gt;
Da sinistra a destra, l'evoluzione di 8bot!&lt;br /&gt;
&lt;br /&gt;
= Modificare l'ATmega8 affinché sembri un Arduino =&lt;br /&gt;
&lt;br /&gt;
Per approfondire questo argomento leggete anche  [[Programmazione dei microcontrollori]].&lt;br /&gt;
&lt;br /&gt;
Per ottenere questo occorre fare tre cose:&lt;br /&gt;
* Trovare un programmatore (potete usare la [http://www.instructables.com/id/Simplest-AVR-Parallel-port-programmer/ porta parallela] oppure acquistarne uno, ma anche un normalissimo Arduino può essere usato come programmatore)&lt;br /&gt;
* Settare i fuses&lt;br /&gt;
* Caricare il bootloader&lt;br /&gt;
* Aggiungere l'ATmega8 nel file boards.txt di Arduino&lt;br /&gt;
&lt;br /&gt;
Una volta fatti questi passi, potrete usare l'IDE come per qualsiasi altra board.&lt;br /&gt;
&lt;br /&gt;
Di guide su come usare i programmatori ne trovate a bizzeffe su internet, noi ci concentreremo sull'utilizzo di Arduino come ISP, che è la procedura che ho usato io.&lt;br /&gt;
&lt;br /&gt;
== Arduino as ISP ==&lt;br /&gt;
&lt;br /&gt;
Negli sketch di esempio nella IDE di Arduino c'è &amp;quot;Arduino as ISP&amp;quot; (In-System Programmer). Caricatelo su un Arduino di vostra scelta con l'accortezza di controllare i pin da usare: sui Mega sono diversi. Dovrete usare la porta SPI e in genere avete: 10 reset, 11 MOSI, 12 MISO e 13 clock (SCK). Sui Mega le porte sono rispettivamente 53, 51, 50 e 52. Trovate tutto nei commenti dello sketch.&lt;br /&gt;
Altri pin, opzionali, sono il 9 (heartbeat, mostra se il programma sta girando), 8 (error, si accende se c'è un problema), 7 (programming, si accende durante le comunicazioni).&lt;br /&gt;
&lt;br /&gt;
La porta SPI va così collegata, MISO con MISO, MOSI con MOSI, SCK con SCK e reset con reset. Il datasheet lo trovate qui [http://www.atmel.com/Images/Atmel-2486-8-bit-AVR-microcontroller-ATmega8_L_datasheet.pdf]&lt;br /&gt;
&lt;br /&gt;
[[File:Atmega8 arduinopinout.png]]&lt;br /&gt;
&lt;br /&gt;
I pin che vedete sono quelli come da IDE di Arduino. Se lo programmate con altri sistemi (come Eclipse) i riferimenti possono essere diversi.&lt;br /&gt;
Se il vostro ATmega8 è settato per avere un risuonatore esterno, dovrete collegarlo con un pin XTAL1 e l'altro su XTAL2. Entrambi i pin XTAL1 e XTAL2 vanno poi collegati a terra con un condensatore da 22 picofarad. Ne avrete bisogno se volete raggiungere frequenze superiori agli 8 Mhz o se avete bisogno di maggiore stabilità (il risuonatore interno non è molto preciso). Per contro, il risuonatore interno non ha bisogno di collegare nulla. Per approfondire guardate questa guida [http://kskpages.weebly.com/clock-settings.html]&lt;br /&gt;
&lt;br /&gt;
== avrdude ==&lt;br /&gt;
&lt;br /&gt;
Per interagire con l'ATmega8 dovrete usare avrdude, questa è una riga di esempio:&lt;br /&gt;
 avrdude -p m8 -c arduino -P /dev/ttyACM1 -U flash:w:{bootloader}.hex -U hfuse:w:0xd9:m -U lfuse:w:0xe3:m -b 19200&lt;br /&gt;
&lt;br /&gt;
Per saperne di più [http://www.nongnu.org/avrdude/user-manual/avrdude_4.html]&lt;br /&gt;
&lt;br /&gt;
 -p m8 &lt;br /&gt;
dice che abbiamo a che fare con un ATmega8&lt;br /&gt;
&lt;br /&gt;
 -c arduino&lt;br /&gt;
segnala che stiamo usando un Arduino come programmatore, nelle nuove versioni della IDE, con il nuovo sketch ArduinoISP probabilmente il protocollo da usare è stk500v1&lt;br /&gt;
&lt;br /&gt;
 -P /dev/(porta)&lt;br /&gt;
è la porta dove avete collegato il programmatore, di solito per gli Arduino è ttyACMx o ttyUSBx; per conoscerla ci sono due modi: guardare nella IDE di Arduino le porte disponibili o collegare l'Arduino e guardare gli ultimi messaggi in dmesg&lt;br /&gt;
&lt;br /&gt;
 -U flash:w:{bootloader}.hex&lt;br /&gt;
scrive il bootloader, vedi sotto&lt;br /&gt;
 &lt;br /&gt;
 -U hfuse:w:0xd9:m -U lfuse:w:0xe3:m &lt;br /&gt;
modifica i fuse, vedi sotto&lt;br /&gt;
&lt;br /&gt;
 -b 19200&lt;br /&gt;
la velocità di comunicazione in baud&lt;br /&gt;
&lt;br /&gt;
== Caricare il bootloader ==&lt;br /&gt;
&lt;br /&gt;
Se volete usarlo come Arduino dovreste caricare il bootloader. Potete farne anche a meno e risparmiare 1Kb (su 8, non è poco). In teoria potreste farne a meno e continuare a caricare gli sketch sull'ATmega8 l'Arduino come programmatore. Fatto sta che l'ho caricato una volta e non ho mai provato a toglierlo (del resto: if ain't broke, don't fix it). I bootloader li trovate in {cartella di Arduino}/hardware/arduino/avr/bootloaders. Se non li avete li trovate qua [https://github.com/arduino/Arduino/tree/master/hardware/arduino/avr/bootloaders]&lt;br /&gt;
&lt;br /&gt;
== Settare i fuse ==&lt;br /&gt;
&lt;br /&gt;
Molte opzioni dell'ATmega8 sono settabili tramite dei fuse. I fuse sono dei bit su una memoria EEPROM che dicono al microcontrollore come deve comportarsi. Tramite i fuses è possibile settare il clock, se usare un oscillatore esterno o interno, quanto deve aspettare durante il boot per una nuova programmazione, etc. &lt;br /&gt;
Qui trovate due calcolatori di fuse, questo è più semplice da usare [https://elektronik-kompendium.de/public/arnerossius/programme/web/avrfuse/ avrfuse] questo è più completo [http://www.engbedded.com/fusecalc/ Engbedded AVR Fuse Calculator].&lt;br /&gt;
&lt;br /&gt;
== Aggiungere le opzioni alla IDE di Arduino ==&lt;br /&gt;
&lt;br /&gt;
Se siete affezionati alla IDE dovrete aggiungere al menu delle board l'ATmega8.&lt;br /&gt;
&lt;br /&gt;
In teoria, nel menu Tools/boards, c'è già &amp;quot;Arduino NG or older&amp;quot; che ha, fra le varie opzioni, anche la possibilità di usare l'ATmega8, ma io ho avuto una serie di problemi a usarla e alla fine non ho provato a capire perché non funzionasse.&lt;br /&gt;
&lt;br /&gt;
Andate in {cartella di Arduino}/hardware/arduino/avr e aprite il file boards.txt (se avete paura di fare dei danni, fate una copia di questo file prima, per precauzione).&lt;br /&gt;
&lt;br /&gt;
Per aggiungere l'ATmega8 basta aggiungere queste opzioni alla fine [https://github.com/chuckb/atmega/blob/master/atmega/avr/boards.txt].&lt;br /&gt;
&lt;br /&gt;
''In alternativa''&lt;br /&gt;
&lt;br /&gt;
Copiate i files dal repository https://github.com/chuckb/atmega, cartellle incluse, nella directory hardware degli sketches arduino, per esempio (nel mio caso):&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:blue;overflow:auto&amp;quot;&amp;gt;&lt;br /&gt;
ls ~/arduino-sketches/hardware/atmega/avr/&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:green;overflow:auto&amp;quot;&amp;gt;&lt;br /&gt;
boards.txt  platform.txt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se caricate uno sketch sul microcontrollore con un clock sbagliato accadranno risultati imprevedibili, ad es. caricate dalla IDE usando ATmega8 a 4Mhz con i fuses settati in modo che vada a 8Mhz scoprirete che tutto andrà al doppio della velocità.&lt;br /&gt;
I secondi diventano mezzi secondi, 9600 baud diventano 19200 e così via. Non una gran cosa se state cercando di programmare, però può sfuggirvi perché non segnala nessun errore.&lt;br /&gt;
&lt;br /&gt;
Una volta editato boards.txt riavviate la IDE se l'avevate aperta e vedrete comparire nel menu Tools/board una nuova voce, quella dell'ATmega8.&lt;br /&gt;
&lt;br /&gt;
== Caricare uno sketch ==&lt;br /&gt;
&lt;br /&gt;
Collegate il programmatore (nei nostri esempi, l'Arduino) all'ATmega8 alla seriale (se avete caricato il bootloader) o alla SPI, collegate il reset (di default su Arduino as ISP è il pin 10), il +5v e la terra, andate sotto Sketch e usate &amp;quot;Upload Using Programmer&amp;quot;. Alternativamente potete cliccare shift+pulsante del caricamento dello sketch. Se tutto è andato come dovrebbe vedrete lampeggiare i LED della seriale dell'Arduino per qualche secondo fino a che l'IDE non ci comunicherà &amp;quot;done&amp;quot;.&lt;br /&gt;
Se invece non volete usare la IDE, potete compilare il vostro sketch con avr-gcc e uploadarlo direttamente con avrdude (ma di questo non tratteremo qui).&lt;br /&gt;
&lt;br /&gt;
Problemi più frequenti: cavetti non collegati bene, cavetti invertiti, alimentazione non sufficiente, oscillatore esterno previsto ma mancante.&lt;br /&gt;
&lt;br /&gt;
== Altri metodi ==&lt;br /&gt;
&lt;br /&gt;
Potete usare, ad esempio, la SPI del Raspberry Pi, guardate la pagina [[Programmazione_dei_microcontrollori]].&lt;br /&gt;
&lt;br /&gt;
= Lo schema elettrico =&lt;br /&gt;
&lt;br /&gt;
È estremamente banale. Collegate le batterie a modulo Bluetooth, integrato e motori, in parallelo, collegate i fili del segnale dei servo a un pin libero dell'ATmega8, collegate RX dell'integrato a TX del modulo Bluetooth. Se volete un feedback dall'integrato allora collegate anche il TX dell'integrato al RX del modulo Bluetooth.&lt;br /&gt;
&lt;br /&gt;
[[File:8botschema.png]]&lt;br /&gt;
&lt;br /&gt;
In sintesi:&lt;br /&gt;
* il + delle batterie va collegato a: vcc del modulo Bluetooth, vcc dell'ATmega8, + del servo 1 e 2&lt;br /&gt;
* il - delle batterie va collegato a: gnd del modulo Bluetooth, due gnd dell'ATmega8, - del servo 1 e 2&lt;br /&gt;
* TX del modulo Bluetooth va collegato a RX dell'ATmega8&lt;br /&gt;
* RX del modulo Bluetooth va collegato a TX dell'ATmega8&lt;br /&gt;
* i segnali dei servi vanno collegati a due pin liberi (nel nostro caso 14 e 15 ma potete benissimo sceglierne degli altri)&lt;br /&gt;
&lt;br /&gt;
= Lo sketch =&lt;br /&gt;
&lt;br /&gt;
Lo trovate sul repository:&lt;br /&gt;
[https://gitlab.com/oloturia/8bot]&lt;br /&gt;
&lt;br /&gt;
Vediamo un po' i punti più strani.&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Servo.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;EEPROM.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 Servo dx_servo;&lt;br /&gt;
 Servo sx_servo;&lt;br /&gt;
 &lt;br /&gt;
 const int dx_pin = 8;&lt;br /&gt;
 const int sx_pin = 9;&lt;br /&gt;
 int fd_spd_dx = 180; //initial values&lt;br /&gt;
 int bk_spd_dx = 0;   //180 is full forward, 0 full backward&lt;br /&gt;
 int fd_spd_sx = 0;   //stop is somewhere in the middle &lt;br /&gt;
 int bk_spd_sx = 180; //but the motors keep running&lt;br /&gt;
&lt;br /&gt;
Per far funzionare il nostro robottino servirà la libreria Servo. La EEPROM ci servirà per mantenere la calibrazione da spento. Ci sono due costanti, i pin a cui sono collegati il segnale dei servi, e i valori che passeremo al metodo write degli oggetti dx_servo e sx_servo. Nei servo continui 0 è antiorario e 180 orario, lo stato fermo è più o meno 90. In questo caso però li staccheremo con detach così da non mantenerli in tensione. Se il vostro progetto non ha bisogno che il servo faccia resistenza (ad es. deve tenere un peso) allora è meglio staccarlo. Non è solo una questione di risparmio energetico: i piccoli servo e quelli di scarsa qualità quando sono in tensione tendono a scaldare.&lt;br /&gt;
Le quattro variabili sono rispettivamente il valore avanti e indietro del motore a destra e il valore avanti e indietro del motore a sinistra.&lt;br /&gt;
&lt;br /&gt;
 void setup() {&lt;br /&gt;
   Serial.begin(9600);&lt;br /&gt;
   Serial.println(&amp;quot;READY&amp;quot;);&lt;br /&gt;
   if (EEPROM.read(4) == 1) {&lt;br /&gt;
     fd_spd_dx = EEPROM.read(0);//reserve 4 bytes &lt;br /&gt;
     bk_spd_dx = EEPROM.read(1);//for saved calibration&lt;br /&gt;
     fd_spd_sx = EEPROM.read(2);&lt;br /&gt;
     bk_spd_sx = EEPROM.read(3);&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Accende la seriale e si legge la EEPROM. La memoria non scritta ha come valore 255 quindi serve un quinto elemento che comunichi se la calibrazione è stata fatta o meno. Scrivere e aggiornare la EEPROM è facilissimo. Vi consiglio di leggere la guida ufficiale [https://www.arduino.cc/en/Reference/EEPROM]. Ricordate che l'ATmega8 ha 512 bytes a disposizione nella EEPROM.&lt;br /&gt;
&lt;br /&gt;
 void loop() {&lt;br /&gt;
   if(Serial.available()){&lt;br /&gt;
     char command = Serial.read(); //every command is a char&lt;br /&gt;
     if (command == 's') {         //it is possible to write to  the bot&lt;br /&gt;
       turnOnServo();              //using a keyboard&lt;br /&gt;
       dx_servo.write(fd_spd_dx);&lt;br /&gt;
       sx_servo.write(fd_spd_sx);&lt;br /&gt;
  } else if (command == 'd') {&lt;br /&gt;
  [...]&lt;br /&gt;
&lt;br /&gt;
Ogni comando ricevuto dalla seriale è un char. Si potrebbe eventualmente mandare un byte, ma così è più comodo soprattutto quando ancora non avevo pronta la app e dovevo pilotare il piccolo bot con la tastiera. Si può ancora fare: i tasti sono wasd. Sulla funzione turnOnServo() torneremo dopo.&lt;br /&gt;
&lt;br /&gt;
  [...]&lt;br /&gt;
  } else if (command == 'h') {&lt;br /&gt;
       if (fd_spd_dx &amp;gt; 90) {&lt;br /&gt;
         fd_spd_dx --;        &lt;br /&gt;
  }&lt;br /&gt;
  [...]&lt;br /&gt;
&lt;br /&gt;
Altri comandi servono per la calibrazione. Purtroppo nella app la calibrazione è ancora molto confusionaria. Ogni variabile può diventare da 0 a 90 e da 91 a 180.&lt;br /&gt;
&lt;br /&gt;
    [...]&lt;br /&gt;
    } else if (command == 'z') { //save calibration into eeprom&lt;br /&gt;
      EEPROM.update(0,fd_spd_dx);&lt;br /&gt;
      EEPROM.update(1,bk_spd_dx); &lt;br /&gt;
      EEPROM.update(2,fd_spd_sx);&lt;br /&gt;
      EEPROM.update(3,bk_spd_sx);&lt;br /&gt;
      EEPROM.update(4,1);&lt;br /&gt;
      Serial.println(&amp;quot;OK&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      stopServo(); //if the serial is empty, stop the motors&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Infine, ecco dove la EEPROM viene scritta, incluso l'indirizzo 4 che diventa 1 e segnala al prossimo riavvio di leggersi i valori che avevamo salvato. Se non arriva nessun comando i servo vengono staccati.&lt;br /&gt;
&lt;br /&gt;
 void turnOnServo() {&lt;br /&gt;
   dx_servo.attach(dx_pin);&lt;br /&gt;
   sx_servo.attach(sx_pin);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 void stopServo() {&lt;br /&gt;
   dx_servo.detach();&lt;br /&gt;
   sx_servo.detach();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Ogni volta che arriva un comando vengono riattaccati. In questo modo non rimarranno sotto tensione.&lt;br /&gt;
&lt;br /&gt;
= Il bluetooth = &lt;br /&gt;
&lt;br /&gt;
Il collegamento fra l'Ottobot e il vostro smartphone o il vostro computer avverrà tramite il modulo HC-05 o HC-06. Il modulo è molto semplice da usare: ha una porta seriale fisica dove legge e scrive tutto ciò che arriva via il servizio di porta seriale via Bluetooth. Nel nostro caso sarà attaccato direttamente ai pin RX e TX del nostro ATmega8 e farà come da ponte fra il nostro dispositivo e il microcontrollore. Potete leggere più informazioni su come giocare con questo tipo di moduli nella pagina [[HC-05 e HC-06]].&lt;br /&gt;
&lt;br /&gt;
= L'app =&lt;br /&gt;
&lt;br /&gt;
Potete scaricarla, guardarla e modificarla all'indirizzo di App Inventor (serve account Google) [http://ai2.appinventor.mit.edu/?locale=en&amp;amp;galleryId=5162309564235776 qua].&lt;br /&gt;
&lt;br /&gt;
L'app è stata scritta con il MIT App Inventor 2. È un tool molto potente utile per chi, come me, è ancora fermo a cercare di fare un &amp;quot;Hello World&amp;quot; decente su Android. Non è la soluzione più efficace, ma nell'attesa di imparare qualcosa di migliore, è la più semplice.&lt;br /&gt;
&lt;br /&gt;
L'App Inventor è basato sul popolare linguaggio educativo Scratch. Permette di inserire pulsanti, grafica e di interagire con i sensori e, nel nostro caso, con dispositivi Bluetooth. Permette di collegarsi a un dispositivo Android (anche emulato) per fare dei test in real-time e fare correzioni al volo. Quando avrete finito potrete creare un .apk da installare così non avrete più bisogno dell'App Inventor per usarla.&lt;br /&gt;
&lt;br /&gt;
Tutte le informazioni su come utilizzarlo le trovate nel sito ufficiale [http://appinventor.mit.edu/explore/ai2/setup.html].&lt;br /&gt;
&lt;br /&gt;
Nel repository c'è il sorgente in formato .aia, che potete caricare sull'App Inventor con Import.&lt;br /&gt;
&lt;br /&gt;
Per prima cosa ho creato, nello Screen 1, una lista che si carica con la lista dei dispositivi Bluetooth che sono nel range del nostro tablet o telefono. Nella schermata c'è solo una lista e un componente &amp;quot;Bluetooth Client&amp;quot; chiamato BluetoothClient1.&lt;br /&gt;
&lt;br /&gt;
[[File:Initbt.png]]&lt;br /&gt;
&lt;br /&gt;
AfterPicking, ovvero dopo aver scelto un dispositivo, andrà nello screen &amp;quot;Controls&amp;quot; portandosi dietro il nome del dispositivo a cui ci vogliamo connettere. &lt;br /&gt;
&lt;br /&gt;
Andiamo ora nella schermata &amp;quot;Controls&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Controls_8bot.png]]&lt;br /&gt;
&lt;br /&gt;
Ci sono i pulsanti per le direzioni, un pulsante per connettersi a un altro dispositivo (che non fa altro che tornare a Screen1), e i pulsanti per la taratura (ancora in beta). Anche qui c'è BluetoothClient1. Appena arriva in questa schermata l'app si fermerà per permettere di fare l'accoppiamento tramite Bluetooth. Il pin è di solito 1234.&lt;br /&gt;
&lt;br /&gt;
[[File:Initcontr.png]]&lt;br /&gt;
&lt;br /&gt;
Se non riesce a connettersi o se clicchiamo &amp;quot;Connect&amp;quot; tornerà nella schermata di selezione precedente.&lt;br /&gt;
&lt;br /&gt;
[[File:Controlscomm.png]]&lt;br /&gt;
&lt;br /&gt;
I controlli sono molto semplici: ogni tasto invia un carattere. Quando viene rilasciato manda un carattere che spegne i servo. Non è ancora perfetto perché se perde la connessione i motori rimangono accesi, in futuro questo problema sarà corretto.&lt;br /&gt;
&lt;br /&gt;
[[File:Trim8bot.png]]&lt;br /&gt;
&lt;br /&gt;
Infine il codice per la calibrazione. A seconda se il robot sta andando avanti oppure indietro saranno calibrati i valori che vengono usati per muovere i motori. Purtroppo questa parte non è ancora scritta in modo efficace (ad es. il motore che va avanti in senso antiorario va più veloce con un valore INFERIORE, quindi per farlo andare più veloce occorre premere il tasto MENO). Quando la calibrazione è soddisfacente, con il tasto &amp;quot;Write&amp;quot; la si memorizza nella EEPROM dell'ATmega8.&lt;br /&gt;
&lt;br /&gt;
= I motori =&lt;br /&gt;
&lt;br /&gt;
L'8bot ha bisogno di due servo motori 9g continui, detti anche servo a 360°. Se volete risparmiare ulteriormente potete acquistare dei normalissimi servo a 180° e fare qualche modifica per trasformarli in 360°.&lt;br /&gt;
Per effettuare la modifica seguite [[Modifica_servo_rc_per_rotazione_continua|questa guida]].&lt;br /&gt;
&lt;br /&gt;
= Lo chassis =&lt;br /&gt;
Tutti gli .stl di 8bot li trovate su git [https://github.com/raspibo/8bot]&lt;br /&gt;
&lt;br /&gt;
== Le ruote ==&lt;br /&gt;
Per le ruote ci sono due modelli, uno è della dimensione delle gomme delle mini4wd Tamiya[https://github.com/raspibo/8bot/blob/master/wheel-mini4wd.stl]:&lt;br /&gt;
&lt;br /&gt;
[[File:8bot4wd.png]]&lt;br /&gt;
&lt;br /&gt;
mentre l'altro è della dimensione di un o-ring[https://github.com/raspibo/8bot/blob/master/wheel0ring.stl]:&lt;br /&gt;
&lt;br /&gt;
[[File:8botoring.png]]&lt;br /&gt;
&lt;br /&gt;
entrambe si incastrano sul pignone del servo senza bisogno di viti o altro (ma se volete metterne una, male non fa).&lt;br /&gt;
&lt;br /&gt;
== Il telaio ==&lt;br /&gt;
Il telaio è una piccola piattaforma con due fessure per inserire un'aletta del servi e un foro per la casterball. Recentemente ho aggiunto altre due alette per tenere fermo il portabatterie[https://github.com/raspibo/8bot/blob/master/body.stl].&lt;br /&gt;
&lt;br /&gt;
[[File:Chass.png]]&lt;br /&gt;
&lt;br /&gt;
= Corso di costruzione Ottobot =&lt;br /&gt;
Nell'autunno 2016 a Raspibo un gruppo di makers si e' riunito specificamente per costruire Ottobot e programmarli sotto la guida paziente di Oloturia, creatore del progetto.&lt;br /&gt;
&lt;br /&gt;
== Materiale ==&lt;br /&gt;
Il materiale e' stato procurato dallo stesso Oloturia da vari fornitori durante l'estate con un occhio particolare ai costi per permettera tutti di realizzare un piccolo robot didattico.&lt;br /&gt;
&lt;br /&gt;
Alcune parti progettate appositamente, sono state stampate in 3D.&lt;br /&gt;
&lt;br /&gt;
Ad ogni partecipante del corso e' stato fornito un kit, oltre a questo ogni partecipante ha portato un po' di attrezzi ed un pc.&lt;br /&gt;
&lt;br /&gt;
[[File:Ottobot kit.jpg|600px|thumb|center|Il kit completo del corso ottobot]]&lt;br /&gt;
&lt;br /&gt;
== Preparazione dei motori ==&lt;br /&gt;
Nel kit i due servo possono essere sia a rotazione continua quindi gia' pronti oppure standard.&lt;br /&gt;
&lt;br /&gt;
Per i motori standard e' neccessario procedere ad una modifica vedi [[Modifica_servo_rc_per_rotazione_continua]]&lt;br /&gt;
&lt;br /&gt;
== Assemblaggio del robot ==&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;margin-top:2px; background:none;align:center;width:100%;border:1px solid red;-moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius:10px;&amp;quot;&lt;br /&gt;
|[[File:Ottobot assemblaggio 10.jpg|400px|thumb|left|Montare le ruote sul microservo modificato per rotazione continua]] &lt;br /&gt;
|Le ruote vanno montate sull'asse con una vite che si trova nel sacchetto degli accessori del servo. Il tutto va poi incastrato sulla base. Se la stampa e' perfetta i motori si incastrano perfettamete sulla base altrimenti ci si puo' aiutare con colla, viti o nastro biadesivo.&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;margin-top:2px; background:none;align:center;width:100%;border:1px solid red;-moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius:10px;&amp;quot;&lt;br /&gt;
|[[File:Ottobot assemblaggio 20.jpg|400px|thumb|left|Fissare la ball caster]] &lt;br /&gt;
|Come terzo appoggio utilizziamo una ballcaster che consente liberta' di movimento e di sterzata. Inserire il pezzo nel foro centrale e fissarlo con tre viti, oppure colla.&lt;br /&gt;
|&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=HC-05_e_HC-06&amp;diff=6686</id>
		<title>HC-05 e HC-06</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=HC-05_e_HC-06&amp;diff=6686"/>
		<updated>2018-06-04T15:20:20Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;HC-05 e HC-06 sono due tipi di moduli Bluetooth che ci permettono di trasmettere e ricevere dati tramite l'interfaccia seriale (ma non solo). Sono molto semplici da usare e hanno molteplici utilizzi.&lt;br /&gt;
&lt;br /&gt;
[[File:Hc-05.jpg]]&lt;br /&gt;
&lt;br /&gt;
Nella foto potete vedere a sinistra il modulo senza lo zoccolo, i cui pin sono i contatti intorno, a destra la versione più comune, saldata su uno zoccolo con i pin di alimentazione e la seriale libera. Gli zoccoli hanno diverse forme e alcuni (come questo) hanno anche alcuni pin in più con funzioni diverse.&lt;br /&gt;
&lt;br /&gt;
= Pinout =&lt;br /&gt;
&lt;br /&gt;
Le board hanno il seguente pinout ([http://www.14core.com/working-with-hc05-hc06-to-configure-and-implementations/ immagine tratta da 14core.com])&lt;br /&gt;
[[File:Bluetooth-HC06-Versus-HC05-Bluetooth-Module-Comparison-001.jpg]]&lt;br /&gt;
&lt;br /&gt;
Essendo la board spesso saldata su uno zoccolo ed essendo quest'ultimo non standard, non è possibile dare un pinout preciso. I pin che troverete sempre sono:&lt;br /&gt;
&lt;br /&gt;
* '''Vcc''' e '''GND'''&lt;br /&gt;
* '''TXD''' e '''RXD''' (sono TX e RX seriali)&lt;br /&gt;
&lt;br /&gt;
Quelli opzionali:&lt;br /&gt;
&lt;br /&gt;
* '''Key''' questo pin è collegato al pin della board che deve essere collegato alla 3,3V per entrare in modalità AT, normalmente lo zoccolo ha anche un pulsante che fa la stessa cosa, in mancanza dell'uno e dell'altro dovrete fare ponte con qualcosa di conduttivo fra una sorgente a 3,3V e il pin Key sulla board&lt;br /&gt;
* '''State''' questo pin dovrebbe essere alto quando il device è connesso a qualcosa e basso quando non è collegato a niente&lt;br /&gt;
* '''EN''' dovrebbe essere l'enable, ma non è chiaro come funzioni&lt;br /&gt;
&lt;br /&gt;
Le board hanno anche il collegamento per un LED di stato. Lo zoccolo di solito ne possiede uno. Il LED ha tre stati:&lt;br /&gt;
&lt;br /&gt;
* Lampeggia velocemente: la board è accesa e non è collegata a niente&lt;br /&gt;
* Lampeggia piano (circa 1s): la board è collegata a qualcosa&lt;br /&gt;
* Lampeggia molto piano (circa 2s): la board è in modalità AT&lt;br /&gt;
&lt;br /&gt;
= Differenze HC-05 e HC-06 =&lt;br /&gt;
&lt;br /&gt;
I due device sono molto simili. Nella maggior parte dei casi potete prendere l'uno o l'altro indifferentemente. Le uniche differenze degne di nota sono:&lt;br /&gt;
&lt;br /&gt;
* L'HC-05 può essere impostato come master, mentre l''''HC-06 è solo slave'''. Questo comporta che entrambi possono ricevere connessioni ma '''solo l'HC-05 può iniziarne una'''.&lt;br /&gt;
&lt;br /&gt;
* L'HC-06 è sempre in modalità AT quando non è collegato a un altro dispositivo, mentre l'HC-05 occorre accenderlo mandando 3,3 volt allo speciale pin &amp;quot;key&amp;quot; (gli zoccoli di solito hanno un pin &amp;quot;Key&amp;quot; oppure un pulsante da premere).&lt;br /&gt;
&lt;br /&gt;
* Il pinout è diverso (ovviamente s'intende il pinout della board, non quello dello zoccolo).&lt;br /&gt;
&lt;br /&gt;
= Alimentazione =&lt;br /&gt;
I moduli vanno alimentati a 3,3V. Gli zoccoli più comuni permettono anche alimentazioni diverse tramite un regolatore di voltaggio, ma i livelli logici sono sempre a 3,3V.&lt;br /&gt;
&lt;br /&gt;
= Collegamento all'Arduino =&lt;br /&gt;
Potete collegare direttamente la seriale UART dell'Arduino al modulo HC-0X. RX (ricevitore seriale) e TX (trasmittente seriale) di Arduino (pin 0 e 1) vanno collegati rispettivamente al TX e all'RX del modulo Bluetooth (in pratica: dovete incrociarli: RX con TX e TX con RX). Se vi serve solo come ricevente, potete collegare solo il TX dell'HC-0X all'RX dell'Arduino, al contrario se vi serve solo una trasmittente collegate solo l'RX dell'HC-0X al TX dell'Arduino. RX e TX a volte sono scritti RXD e TXD. Non cambia assolutamente nulla.&lt;br /&gt;
&lt;br /&gt;
Se la seriale fisica dovesse essere occupata, è possibile averne una software su due pin diversi con la libreria [https://www.arduino.cc/en/Reference/SoftwareSerial SoftwareSerial].&lt;br /&gt;
&lt;br /&gt;
= Collegamento Bluetooth al PC =&lt;br /&gt;
&lt;br /&gt;
Sotto Linux ci sono diversi modi per attivare una comunicazione seriale fra il SO e un dispositivo che permette questo tipo di servizio. La seriale comparirà come file di device nella posizione /dev/rfcommX dove X è un numero che parte da 0. Se abbiamo una sola comunicazione seriale avremo quindi /dev/rfcomm0. A questo file ci si può collegare ad esempio con il comando screen.&lt;br /&gt;
&lt;br /&gt;
 # screen /dev/rfcommX &amp;lt;velocità baud&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Occorre essere root o dare il comando con sudo, perché l'utente normale non dovrebbe essere in grado di scrivere su rfcommX.&lt;br /&gt;
&lt;br /&gt;
== Prerequisiti ==&lt;br /&gt;
&lt;br /&gt;
L'utente deve essere nel gruppo &amp;quot;bluetooth&amp;quot;. Per aggiungersi al gruppo bisogna editare il file /etc/group e aggiungere il vostro nome al gruppo, troverete qualcosa come&lt;br /&gt;
&lt;br /&gt;
 bluetooth:x:&amp;lt;ID&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
dovete aggiungere l'utente dopo i due punti&lt;br /&gt;
&lt;br /&gt;
 bluetooth:x:&amp;lt;ID&amp;gt;:utente&lt;br /&gt;
&lt;br /&gt;
per attivare la modifica fate log out e log in&lt;br /&gt;
&lt;br /&gt;
== Bluetooth Manager ==&lt;br /&gt;
&lt;br /&gt;
Bluetooth Manager è il programma che viene aperto di default quando un adattatore Bluetooth USB è collegato al PC. Purtroppo è anche pieno di bug e abbastanza prono a crashare. Nelle ultime versioni pare che vada molto meglio. Nel caso abbiate problemi vi consiglio di chiudere il programma (dovete cliccare col tasto destro sull'icona del Bluetooth sulla barra delle applet oppure killate blueman-manager) e lanciare da un terminale blueman-manager. Vediamo passo passo come fare a creare un collegamento seriale.&lt;br /&gt;
&lt;br /&gt;
Cliccate su &amp;quot;Search&amp;quot; e cercate il dispositivo a cui dovete collegarvi. Se non l'avete rinominato, gli HC si chiameranno HC-05 o HC-06. Nel caso ce ne sia più di uno, cercate di ricordare l'indirizzo fisico, il MAC Address.&lt;br /&gt;
&lt;br /&gt;
[[File:Hc0506 1.png]]&lt;br /&gt;
&lt;br /&gt;
Cliccate col tasto destro e selezionate &amp;quot;Pair&amp;quot;. Uscirà un pop up in cui vi verrà chiesto il pin. Se non l'avete modificato normalmente è 1234.&lt;br /&gt;
&lt;br /&gt;
[[File:Hc0506 2.png]]&lt;br /&gt;
&lt;br /&gt;
Una volta avvenuto il pairing, comparirà il simbolo di una chiave vicino all'icona del vostro device Bluetooth. Cliccate di nuovo il tasto destro e selezionate Serial Port.&lt;br /&gt;
&lt;br /&gt;
[[File:Hc0506 4.png]]&lt;br /&gt;
&lt;br /&gt;
Se tutto è andato come doveva, vedrete l'indicazione di quale file di device è la vostra comunicazione seriale. Ora potete aprirlo con screen o altri programmi.&lt;br /&gt;
&lt;br /&gt;
[[File:Hc0506 5.png]]&lt;br /&gt;
&lt;br /&gt;
= Cambiare configurazione =&lt;br /&gt;
&lt;br /&gt;
Gran parte di questo capitolo è preso da [http://www.instructables.com/id/AT-command-mode-of-HC-05-Bluetooth-module/ questa guida su Instructables].&lt;br /&gt;
Per cambiare configurazione al vostro modulo (ad es. cambiare velocità di trasmissione, nome, pin, ecc.) dovete entrare in modalità AT. L'HC-06 dovrebbe essere sempre in questa modalità, mentre l'HC-05 dev'essere acceso tenendo premuto il tasto &amp;quot;KEY&amp;quot; oppure mettendo a +3.3v il pin key sulla board. Quando è in modalità AT, l'HC-05 lampeggerà a intervalli di 2 secondi circa e potrete mandare i comandi AT alla seriale fisica sulla board. Se non avete un convertitore USB TTL, potete riciclare un Arduino per fare da ponte. Poiché l'Arduino Uno e simili (non il Mega, ad es.) ha una sola porta seriale, dovrete usare una porta seriale emulata via software. Lo sketch sarà più o meno così:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;SoftwareSerial.h&amp;gt;&lt;br /&gt;
 SoftwareSerial mySerial(10, 11); // RX, TX&lt;br /&gt;
 void setup() {&lt;br /&gt;
     Serial.begin(9600);&lt;br /&gt;
     pinMode(9,OUTPUT); digitalWrite(9,HIGH);&lt;br /&gt;
     Serial.println(&amp;quot;Enter AT commands:&amp;quot;);&lt;br /&gt;
     mySerial.begin(38400);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void loop() {&lt;br /&gt;
     if (mySerial.available()) Serial.write(mySerial.read());&lt;br /&gt;
     if (Serial.available()) mySerial.write(Serial.read());&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Notate alcune cose di questo codice: mySerial è la software seriale dove andrà collegato il vostro HC, nei pin 10 e 11 (10 è RX e 11 TX, quindi il 10 andrà collegato al TX dell'HC e l'11 al RX). '''In modalità AT il modulo HC comunica a 38400 baud'''.&lt;br /&gt;
&lt;br /&gt;
Ora aprite una seriale (va bene anche quella dell'IDE di Arduino, ricordatevi di mettere come CR e NL come fine linea) a 38400 baud e scrivete:&lt;br /&gt;
&lt;br /&gt;
 AT&lt;br /&gt;
&lt;br /&gt;
L'HC dovrebbe rispondervi&lt;br /&gt;
&lt;br /&gt;
 OK&lt;br /&gt;
&lt;br /&gt;
Se non lo fa forse avete sbagliato uno dei passi precedenti.&lt;br /&gt;
&lt;br /&gt;
I comandi più utili sono:&lt;br /&gt;
* AT+NAME=&amp;lt;nome&amp;gt; cambia nome all'ID Bluetooth&lt;br /&gt;
* AT+UART=&amp;lt;baudrate&amp;gt; cambia la velocità della trasmissione Bluetooth (la modalità AT rimane a 38400)&lt;br /&gt;
* AT+ROLE=&amp;lt;1:master 0:slave&amp;gt; permette l'HC-05 di essere master o di essere solo slave in una comunicazione&lt;br /&gt;
* AT+ORGL ripristina le configurazioni di fabbrica&lt;br /&gt;
* AT+PSWD cambia la password&lt;br /&gt;
&lt;br /&gt;
I comandi, se seguiti da ?, dovrebbero dire quale è il valore al momento memorizzato, ad esempio:&lt;br /&gt;
&lt;br /&gt;
 AT+UART?&lt;br /&gt;
&lt;br /&gt;
dovrebbe restituire&lt;br /&gt;
&lt;br /&gt;
 9600&lt;br /&gt;
&lt;br /&gt;
In [http://cdn.instructables.com/ORIG/FKY/Z0UT/HX7OYY7I/FKYZ0UTHX7OYY7I.pdf questa guida] potete trovare dettagli più approfonditi.&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=RaspiTank&amp;diff=6685</id>
		<title>RaspiTank</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=RaspiTank&amp;diff=6685"/>
		<updated>2018-06-04T15:14:29Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* Il codice! Sempre più mal scritto! Sempre più mal commentato! */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Il RaspiTank è un tentativo di integrare il Raspberry Pi con un vecchio giocattolo a motore elettrico con i cingoli. Il controllo del motore è analogo a quello della [[RaspiCar]] mentre lo sterzo è affidato a un differenziale mosso tramite un servo.&lt;br /&gt;
&lt;br /&gt;
= Prima versione =&lt;br /&gt;
&lt;br /&gt;
[[File:Raspitank finale.jpg]]&lt;br /&gt;
&lt;br /&gt;
Il RaspiTank aveva le seguenti caratteristiche:&lt;br /&gt;
* Motore alimentato da due batterie tipo D, alloggiate nel vano originale del giocattolo&lt;br /&gt;
* Raspberry Pi modello A, con Wi-Fi dongle, alimentato da 4 pile AA; garantisce qualche ora di autonomia, a seconda dell'uso&lt;br /&gt;
* Marcia avanti e indietro&lt;br /&gt;
* Sterzo ottenuto facendo girare un cingolo solo alla volta, usando il differenziale originale del giocattolo mosso da un servocomando&lt;br /&gt;
* Streaming dalla camera frontale&lt;br /&gt;
* Luci a LED accendibili e spegnibili&lt;br /&gt;
* Si può comandare da remoto tramite ssh con le frecce&lt;br /&gt;
&lt;br /&gt;
[[File:RaspiTank_inlavorazione.jpeg]]&lt;br /&gt;
&lt;br /&gt;
== Il nostro amico servocomando ==&lt;br /&gt;
I servi si muovono grazie a un impulso PWM come descritto in questa pagina: [[Servo (radio control)]]. A cicli di 20ms, a seconda dell'ampiezza dell'impulso, il servo si metterà in una posizione. Per il RaspiTank abbiamo usato la libreria ServoBlaster[https://github.com/richardghirst/PiBits/tree/master/ServoBlaster]. Poiché useremo (per ora) solo un servo abbiamo disabilitato tutti gli altri pin utilizzati dal demone di Servoblaster che altrimenti sarebbero stati inutilizzabili per altri scopi.&lt;br /&gt;
&lt;br /&gt;
== Il groviglio di fili, ovvero la parte elettronica ==&lt;br /&gt;
&lt;br /&gt;
[[File:Raspitank interior.jpg]]&lt;br /&gt;
&lt;br /&gt;
Per l'azionamento del motore abbiamo riciclato i circuiti già fatti per la [[RaspiCar]] ovvero questi.&lt;br /&gt;
&lt;br /&gt;
[[File:RaspiCar Schema Motor.png]]&lt;br /&gt;
&lt;br /&gt;
La tensione data al motore circola in un senso o nell'altro a seconda di come scattano i due relè. Se il primo è acceso e il secondo è spento il motore girerà in un senso, vice versa se il primo è spento e il secondo è acceso il motore girerà nell'altro senso. Il motore resta spento se i due relè sono entrambi accesi o spenti.&lt;br /&gt;
Questo è il circuito per far scattare il singolo relè.&lt;br /&gt;
&lt;br /&gt;
[[File:RaspiCar Schema Relay.png]]&lt;br /&gt;
&lt;br /&gt;
Per via di una interferenza che portava il servo a muoversi da solo durante la marcia, abbiamo usato un ulteriore relè che alimenta il servo solo quando si deve muovere. Il circuito per l'alimentazione del servo è lo stesso degli altri due relè.&lt;br /&gt;
Per l'illuminazione abbiamo usato una luce alimentata da USB a due LED. Abbiamo collegato la terra alla terra della USB e il +5V al pin 15 wiringpi (pin 8 fisico). Nonostante siano solo 3,3V l'illuminazione è sufficiente per vedere diversi centimetri nell'oscurità ed evitare gli ostacoli.&lt;br /&gt;
&lt;br /&gt;
== La camera ==&lt;br /&gt;
Inizialmente il RaspiTank usava una webcam recuperata da un EeePC della ASUS collegata alla porta USB. Con il passaggio dal Raspberry Pi modello B al modello A è venuta meno una porta USB e aggiungere un HUB sarebbe stato scomodo. Abbiamo così deciso di non usare MjpegStreamer[http://sourceforge.net/projects/mjpg-streamer/] e di usare la camera da attaccare direttamente alla porta CSI del Raspberry Pi. Questo ci ha costretti a disabilitare un pin di ServoBlaster (vedete la issue qui[https://github.com/richardghirst/PiBits/issues/11])&lt;br /&gt;
&lt;br /&gt;
== Il codice, mal scritto e mal commentato ==&lt;br /&gt;
&lt;br /&gt;
La libreria usata per la gestione della GPIO è wiringpi [https://projects.drogon.net/raspberry-pi/wiringpi/]. Per l'interfaccia testuale abbiamo usato curses.&lt;br /&gt;
Il codice accetta un argomento, il nome del file xml su cui scrivere le azioni registrate. Se non è specificato non verrà registrato nulla. Al momento esiste uno script per riprodurre le azioni salvate o scritte a mano. Purtroppo il motore del RaspiTank non è molto preciso e quindi la registrazione, al momento, non è molto affidabile.&lt;br /&gt;
&lt;br /&gt;
Le frecce su e giù controllano il motore. Per fermare il RaspiTank occorre dare il controllo contrario (i.e. se sta avanzando occorre premere giù). Le frecce destra e sinistra fanno spostare l'ingranaggio del differenziale. Non è possibile cambiare la direzione mentre il RaspiTank sta muovendosi.&lt;br /&gt;
Il tasto spazio accende e spegne le luci.&lt;br /&gt;
Il tasto home accende la camera e fa partire lo streaming.&lt;br /&gt;
 #!/usr/bin/python&lt;br /&gt;
 import os&lt;br /&gt;
 import wiringpi&lt;br /&gt;
 import curses&lt;br /&gt;
 import time&lt;br /&gt;
 import sys&lt;br /&gt;
 import threading&lt;br /&gt;
 &lt;br /&gt;
 #PIN da usare&lt;br /&gt;
 #11 controllo relay avanti&lt;br /&gt;
 #10 controllo relay indietro&lt;br /&gt;
 #14 controllo relay servo&lt;br /&gt;
 #7 PWM servo (servo n.0 ServoBlaster)&lt;br /&gt;
 #I relay devono essere alimentati da +5V&lt;br /&gt;
 #Il servo puo' essere alimentato da +3,3V&lt;br /&gt;
 &lt;br /&gt;
 class getkey(threading.Thread):&lt;br /&gt;
 	key = ''&lt;br /&gt;
 	light = False&lt;br /&gt;
 	motion = 'stop'&lt;br /&gt;
 	direction = 'straight'&lt;br /&gt;
 	def run(self):&lt;br /&gt;
 		while self.key != ord('q'):&lt;br /&gt;
 			self.key = stdscr.getch()&lt;br /&gt;
 			if self.key == ord(' '): #spazio accende e spegne le luci&lt;br /&gt;
 				if self.light:&lt;br /&gt;
 					motor.digitalWrite(15,motor.LOW)&lt;br /&gt;
 					time.sleep(0.5)&lt;br /&gt;
 					self.light = False&lt;br /&gt;
 					stdscr.addstr(6,5,&amp;quot;Lights:off&amp;quot;)&lt;br /&gt;
 				else:&lt;br /&gt;
 					motor.digitalWrite(15,motor.HIGH)&lt;br /&gt;
 					time.sleep(0.5)&lt;br /&gt;
 					self.light = True&lt;br /&gt;
 					stdscr.addstr(6,5,&amp;quot;Lights:on &amp;quot;)&lt;br /&gt;
 			elif self.key == curses.KEY_HOME or self.key == curses.KEY_SHOME:&lt;br /&gt;
 				self.videostart = os.system(&amp;quot;ps -ae|grep raspivid &amp;gt; /dev/null&amp;quot;)&lt;br /&gt;
 				if self.videostart !=0:&lt;br /&gt;
 					stdscr.addstr(7,5,&amp;quot;Stream:on USE nc raspitank.local 9999 |mplayer -fps 150 -demuxer h264es -&amp;quot;)&lt;br /&gt;
 					if self.key == curses.KEY_HOME:&lt;br /&gt;
 						os.system('raspivid -t 0 -fps 15 -w 640 -h 480 -rot 180 -o - |nc -l 9999 &amp;amp;')&lt;br /&gt;
 					else:&lt;br /&gt;
 						os.system('raspivid -t 0 -fps 15 -w 640 -h 480 -rot 180 -ex night -o - |nc -l 9999 &amp;amp;')&lt;br /&gt;
 				else:&lt;br /&gt;
 					stdscr.addstr(7,5,&amp;quot;Stream:off                                                                 &amp;quot;)&lt;br /&gt;
 					os.system('killall raspivid &amp;gt;/dev/null')&lt;br /&gt;
 					os.system('killall nc &amp;gt;/dev/null')&lt;br /&gt;
 			elif self.key == curses.KEY_UP:&lt;br /&gt;
 				if self.motion == 'down':&lt;br /&gt;
 					stop()&lt;br /&gt;
 					self.motion = 'stop'&lt;br /&gt;
 					time.sleep(0.2)&lt;br /&gt;
 				elif self.motion == 'stop':&lt;br /&gt;
 					avanti()&lt;br /&gt;
 					self.motion = 'up'&lt;br /&gt;
 				stdscr.addstr(2,5,&amp;quot;Motion:&amp;quot;+self.motion+&amp;quot;    &amp;quot;)&lt;br /&gt;
 				stdscr.refresh()&lt;br /&gt;
 			elif self.key == curses.KEY_DOWN:&lt;br /&gt;
 				if self.motion == 'up':&lt;br /&gt;
 					stop()&lt;br /&gt;
 					self.motion = 'stop'&lt;br /&gt;
 					time.sleep(0.2)&lt;br /&gt;
 				elif self.motion == 'stop':&lt;br /&gt;
 					indietro()&lt;br /&gt;
 					self.motion = 'down'&lt;br /&gt;
 				stdscr.addstr(2,5,&amp;quot;Motion:&amp;quot;+self.motion+&amp;quot;    &amp;quot;)&lt;br /&gt;
 				stdscr.refresh()&lt;br /&gt;
 			elif self.key == curses.KEY_LEFT:&lt;br /&gt;
 				stop()&lt;br /&gt;
 				self.motion = 'stop'&lt;br /&gt;
 				if self.direction == 'right':&lt;br /&gt;
 					dritto()&lt;br /&gt;
 					self.direction = 'straight'&lt;br /&gt;
 					time.sleep(0.2)&lt;br /&gt;
 				elif self.direction == 'straight':&lt;br /&gt;
 					self.direction = 'left'&lt;br /&gt;
 					orario()&lt;br /&gt;
 				else:&lt;br /&gt;
 					self.direction = 'left'&lt;br /&gt;
 					time.sleep(0.2)&lt;br /&gt;
 				stdscr.addstr(2,5,&amp;quot;Motion:&amp;quot;+self.motion+&amp;quot;    &amp;quot;)&lt;br /&gt;
 				stdscr.addstr(3,5,&amp;quot;Direct:&amp;quot;+self.direction+&amp;quot;         &amp;quot;)&lt;br /&gt;
 				stdscr.refresh()&lt;br /&gt;
 			elif self.key == curses.KEY_RIGHT:&lt;br /&gt;
 				stop()&lt;br /&gt;
 				self.motion = 'stop'&lt;br /&gt;
 				if self.direction == 'left':&lt;br /&gt;
 					dritto()&lt;br /&gt;
 					self.direction ='straight'&lt;br /&gt;
 					time.sleep(0.2)&lt;br /&gt;
 				elif self.direction == 'straight':&lt;br /&gt;
 					self.direction = 'right'&lt;br /&gt;
 					antiorario()&lt;br /&gt;
 				else:&lt;br /&gt;
 					self.direction = 'right'&lt;br /&gt;
 					time.sleep(0.2)&lt;br /&gt;
 				stdscr.addstr(2,5,&amp;quot;Motion:&amp;quot;+self.motion+&amp;quot;    &amp;quot;)&lt;br /&gt;
 				stdscr.addstr(3,5,&amp;quot;Direct:&amp;quot;+self.direction+&amp;quot;         &amp;quot;)&lt;br /&gt;
 				stdscr.refresh()&lt;br /&gt;
 &lt;br /&gt;
 		exit()&lt;br /&gt;
 &lt;br /&gt;
 def antiorario():&lt;br /&gt;
 	motor.digitalWrite(14,motor.HIGH)&lt;br /&gt;
 	os.system(&amp;quot;echo 0=60 &amp;gt; /dev/servoblaster&amp;quot;)&lt;br /&gt;
 	time.sleep(0.5)&lt;br /&gt;
 	motor.digitalWrite(14,motor.LOW)	&lt;br /&gt;
 &lt;br /&gt;
 def indietro():&lt;br /&gt;
 	motor.digitalWrite(10,motor.HIGH)&lt;br /&gt;
 &lt;br /&gt;
 def avanti():&lt;br /&gt;
 	motor.digitalWrite(11,motor.HIGH)&lt;br /&gt;
 &lt;br /&gt;
 def stop():&lt;br /&gt;
 	motor.digitalWrite(10,motor.LOW)&lt;br /&gt;
 	motor.digitalWrite(11,motor.LOW)&lt;br /&gt;
 	&lt;br /&gt;
 def orario():&lt;br /&gt;
 	motor.digitalWrite(14,motor.HIGH)&lt;br /&gt;
 	os.system(&amp;quot;echo 0=240 &amp;gt; /dev/servoblaster&amp;quot;)&lt;br /&gt;
 	time.sleep(0.5)&lt;br /&gt;
 	motor.digitalWrite(14,motor.LOW)&lt;br /&gt;
 &lt;br /&gt;
 def dritto():&lt;br /&gt;
 	motor.digitalWrite(14,motor.HIGH)&lt;br /&gt;
 	os.system(&amp;quot;echo 0=145 &amp;gt; /dev/servoblaster&amp;quot;)&lt;br /&gt;
 	time.sleep(0.5)&lt;br /&gt;
 	motor.digitalWrite(14,motor.LOW)&lt;br /&gt;
 &lt;br /&gt;
 if os.system(&amp;quot;ps -ae |grep servod &amp;gt; /dev/null&amp;quot;) !=0:&lt;br /&gt;
 	os.system(&amp;quot;sudo servod &amp;gt; /dev/null&amp;quot;)&lt;br /&gt;
 motor = wiringpi.GPIO(wiringpi.GPIO.WPI_MODE_PINS)&lt;br /&gt;
 motor.pinMode(10,motor.OUTPUT) #motore direzione 1&lt;br /&gt;
 motor.pinMode(11,motor.OUTPUT) #motore direzione -1&lt;br /&gt;
 motor.pinMode(14,motor.OUTPUT) #accensione servo&lt;br /&gt;
 motor.pinMode(15,motor.OUTPUT) #luci&lt;br /&gt;
 motor.digitalWrite(12,motor.LOW)&lt;br /&gt;
 stop()&lt;br /&gt;
 dritto()&lt;br /&gt;
 if __name__==&amp;quot;__main__&amp;quot;:&lt;br /&gt;
 	stdscr = curses.initscr()&lt;br /&gt;
 	curses.cbreak()&lt;br /&gt;
 	curses.noecho()&lt;br /&gt;
 	stdscr.keypad(1)&lt;br /&gt;
 	stdscr.addstr(0,5,&amp;quot;Press 'q' to quit, up/down = Motion, left/right = Direct, space = Lights&amp;quot;)&lt;br /&gt;
 	stdscr.addstr(1,5,&amp;quot;home = Stream, shift+home = Night stream&amp;quot;)&lt;br /&gt;
 	stdscr.addstr(2,5,&amp;quot;Motion:&amp;quot;)&lt;br /&gt;
 	stdscr.addstr(3,5,&amp;quot;Direct:straight&amp;quot;)&lt;br /&gt;
 	stdscr.addstr(6,5,&amp;quot;Lights:off&amp;quot;)&lt;br /&gt;
 	stdscr.addstr(7,5,&amp;quot;Stream:off&amp;quot;)&lt;br /&gt;
 	curses.curs_set(0)&lt;br /&gt;
 	stdscr.refresh()&lt;br /&gt;
 	getkey = getkey()&lt;br /&gt;
 	getkey.start()&lt;br /&gt;
 	key=' '&lt;br /&gt;
 	secondpass = time.time()&lt;br /&gt;
 	while getkey.key != ord('q'):&lt;br /&gt;
 		if time.time() - secondpass &amp;gt; 1:&lt;br /&gt;
 			link = os.popen('iwconfig wlan0 |grep &amp;quot;Link Quality&amp;quot;') #deprecated&lt;br /&gt;
 			stdscr.addstr(15,5,link.read().strip())&lt;br /&gt;
 			stdscr.refresh()&lt;br /&gt;
 			secondpass = time.time()&lt;br /&gt;
 	os.system('killall raspivid &amp;gt;/dev/null')&lt;br /&gt;
 	os.system('killall nc &amp;gt; /dev/null')&lt;br /&gt;
 	stop()&lt;br /&gt;
 	curses.endwin()&lt;br /&gt;
 	motor.digitalWrite(15,motor.LOW)&lt;br /&gt;
&lt;br /&gt;
= RaspiTank con RaspiArm =&lt;br /&gt;
&lt;br /&gt;
Tutto è iniziato quando ho trovato un braccio meccanico in scatola di montaggio[http://www.owirobots.com/store/index.php?l=product_detail&amp;amp;p=110]. Originariamente era filoguidato da un sistema di interruttori a levette, ma il fatto che avesse i contatti esterni con i pin perfettamente compatibili con quelli dei cavetti per la breadboard lo rendeva particolarmente irresistibile.&lt;br /&gt;
Inizialmente il gioco è stato eliminare il controller e usare la GPIO del Raspberry Pi per comandarlo. Essendo composto da cinque motori e dovendo comunque muovere il motore della base, ci sarebbero dovuti essere sette relè: due per determinare il senso della corrente e cinque per attivare ognuno dei motori. L'ultimo relè avrebbe mosso alternativamente il motore n.5 del braccio o il motore dei cingoli.&lt;br /&gt;
&lt;br /&gt;
==Il nostro nuovo amico ULN2803==&lt;br /&gt;
&lt;br /&gt;
ULN2803 è un driver che permette di dirigere i 5V del Raspberry Pi in 7 uscite diverse comandate dai pin della GPIO. In pratica sostituisce tutto quel circuito composto dal diodo e il transistor. Lo potete intravedere in questa foto, al centro della breadboard.&lt;br /&gt;
&lt;br /&gt;
[[File:RaspiArm.jpeg]]&lt;br /&gt;
&lt;br /&gt;
Non sto a scendere nel dettaglio del circuito: in pratica è il circuito già usato prima con più motori.&lt;br /&gt;
&lt;br /&gt;
==L'unione dei due==&lt;br /&gt;
&lt;br /&gt;
[[File:Raspitank_arm.jpeg]]&lt;br /&gt;
&lt;br /&gt;
Una volta riportato il circuito della breadboard su una millefori è bastato fissare il braccio sulla base. Le luci sono state sostituite da un led già integrato sulla pinza. L'alimentazione del motore non è più dato da due pile torcia nella sede originale del carro ma sono le quattro che stanno dentro al braccio. Essendo raddoppiato il voltaggio adesso va molto più veloce.&lt;br /&gt;
&lt;br /&gt;
==Il codice! Sempre più mal scritto! Sempre più mal commentato!==&lt;br /&gt;
&lt;br /&gt;
Lo trovate su GitLab [https://gitlab.com/oloturia/raspitank https://gitlab.com/oloturia/raspitank]&lt;br /&gt;
&lt;br /&gt;
Contiene:&lt;br /&gt;
* audio.sh 	Piccolo script per lo streaming audio (serve una scheda sonora USB con microfono)&lt;br /&gt;
* raspitank.ino Nella nuova versione un ATmega8 si occupa dei relay tramite seriale.&lt;br /&gt;
* roboy.py 	Il codice sul Raspberry&lt;br /&gt;
* videoday.sh 	Due script in bash per far partire lo streaming video normale...&lt;br /&gt;
* videonig.sh 	...e con filtro notturno&lt;br /&gt;
&lt;br /&gt;
= I video e altre foto =&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=H2Sz7JgYbbQ Il RaspiTank con il RaspiArm]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=QB28DayPIVk Il video della prima scampagnata del RaspiTank]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=3hHXWNNRBxU Il video della prima escursione notturna]&lt;br /&gt;
&lt;br /&gt;
[[File:Raspitank_insegue_Ardubottino.png]]&lt;br /&gt;
&lt;br /&gt;
Scappa, [[Ardubottino]], scappa!! (questa foto è quel che si vede dalla camera del RaspiTank)&lt;br /&gt;
&lt;br /&gt;
[[Category:Progetti]]&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
	<entry>
		<id>https://www.raspibo.org/wiki/index.php?title=Ardubottino&amp;diff=6684</id>
		<title>Ardubottino</title>
		<link rel="alternate" type="text/html" href="https://www.raspibo.org/wiki/index.php?title=Ardubottino&amp;diff=6684"/>
		<updated>2018-06-04T15:13:30Z</updated>

		<summary type="html">&lt;p&gt;Oloturia: /* Il codice */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ardubottino è stato creato soprattutto per testare tre componenti: l'Arduino, il sensore della distanza a ultrasuoni e il ponte ad H. Lo chassis e i motori sono Tamiya.&lt;br /&gt;
&lt;br /&gt;
[[File:Ardubottino.jpg]]&lt;br /&gt;
&lt;br /&gt;
= Prima Versione =&lt;br /&gt;
&lt;br /&gt;
== Componenti ==&lt;br /&gt;
Ardubottino ha questi componenti:&lt;br /&gt;
* Arduino UNO [http://arduino.cc/en/Main/arduinoBoardUno]&lt;br /&gt;
* Sensore di distanza a ultrasuoni SRF05 [http://www.robot-electronics.co.uk/htm/srf05tech.htm]&lt;br /&gt;
* Il board con montato il ponte ad H L298 [http://www.vetco.net/catalog/product_info.php?products_id=14337]&lt;br /&gt;
* Kit Tamiya per lo chassis e i motori&lt;br /&gt;
* Batteria da 9v&lt;br /&gt;
* Ulteriori batterie per il motore (inizialmente 4,5v, poi 4,8v)&lt;br /&gt;
&lt;br /&gt;
Il sensore di distanza è sprovvisto di pin, occorre quindi saldarne una strip prima di procedere.&lt;br /&gt;
&lt;br /&gt;
== Il sensore di distanza a ultrasuoni SRF05 ==&lt;br /&gt;
[[File:102_1298.JPG]]&lt;br /&gt;
&lt;br /&gt;
È piuttosto semplice da usare. Seguendo le istruzioni [ http://www.robot-electronics.co.uk/htm/srf05tech.htm trovate qui] si può notare che ha due modalità di comunicazioni, date dal pin Mode. Se questo pin è collegato alla 0v il sensore userà un solo pin per la comunicazione dei dati dell'eco (Echo) e la ricezione dei comandi (Trigger), se, al contrario, non è connesso a niente allora saranno usati due pin diversi. Nel caso dell'Ardubottino ho preferito usare la prima modalità, quella con un pin solo (soprattutto per pigrizia: perché è già così lo sketch di esempio &amp;quot;ping&amp;quot; nella libreria di Arduino!). Oltre al pin Mode e al pin Trigger/Echo occorre collegare il primo e l'ultimo pin rispettivamente a +5v e a terra.&lt;br /&gt;
Nella foto si può vedere, da sinistra: +5v, non usato, Trigger/Echo (collegato al pin 13 di Arduino), Mode (terra), Terra (terra).&lt;br /&gt;
&lt;br /&gt;
== Il board ponte ad H L298 ==&lt;br /&gt;
[[File:Ardubottino_dettagliol298.jpg]]&lt;br /&gt;
&lt;br /&gt;
Il ponte ad H L298 è utilissimo per manovrare due motori indipendenti. Può essere usato anche per muovere un motore passo-passo.&lt;br /&gt;
Ha due ingressi per la corrente: tramite un ponticello può essere separata fra corrente per la logica e corrente per i motori. La logica dev'essere alimentata da +5v; se l'alimentazione è separata, i motori possono ricevere fino a +12v. Per comodità (e anche dopo diversi goffi tentativi per capire come funzionava) ho preferito alimentare i motori solo con i 5v.&lt;br /&gt;
&lt;br /&gt;
Sui lati ci sono le connessioni per i motori mentre, a fianco dell'alimentazione, ci sono i pin che servono per comandarli. I pin sono sei, due sono gli enable per i motori e quattro servono per dare la direzione, due per motore. I pin dell'enable si possono chiudere con dei ponticelli, comandarli da Arduino/Raspberry Pi oppure gli si può mandare un impulso PWM per regolare la velocità.&lt;br /&gt;
&lt;br /&gt;
== Motori ad encoder, gioie (poche) e dolorer (tanto) ==&lt;br /&gt;
Il problema di Ardubottino è che non va dritto. Il motivo? Forse il ponte ad H non dà gli stessi voltaggi ai motori, forse i motori sono un po' diversi, forse si stanno usurando in modo diverso, forse i cingoli hanno qualche imperfezione, forse le ruote sono storte, forse è sbilanciato. Ad ogni modo ognuno di questi problemi (tranne le ruote storte e le imperfezioni dei cingoli) si sarebbero risolti scoprendo a che velocità vanno i motori. Per scoprire questo dato sono necessari gli encoder. Un encoder è una rotellina con dei fori e un sensore o due, composti da un LED e da un ricevitore a infrarossi, che sentono quando un foro è passato. Encoder di questo tipo si trovano ad esempio nelle rotelline dei mouse o in quelli che hanno ancora la pallina.&lt;br /&gt;
&lt;br /&gt;
[[File:EncoderArdubottino.JPG]]&lt;br /&gt;
&lt;br /&gt;
Ora: questi sarebbero degli encoder &amp;quot;fatti apposta&amp;quot; per il kit Tamiya. Uso il condizionale perché, se non sono stato io ad averli montati in modo approssimativo, il loro utilizzo è alquanto scomodo. Anzitutto la rotella non sta fissa sull'albero. Il foro esagonale è troppo grande e ha un notevole gioco. Il range del sensore è minimo e non tiene conto della struttura del kit Tamiya (la rotella va quasi a sfregare contro le viti che lo fissano allo chassis). Inoltre sono estremamente fragili: una delle rotelle si è spaccata subito in due. I sensori stessi, poi, non si incastrano nella sede e occorre incollarli.&lt;br /&gt;
La lettura degli encoder andrebbe fatta sfruttando gli interrupt di Arduino. Gli interrupt sono dei pin che restano in ascolto e fanno scattare degli eventi quando cambiano valore[http://arduino.cc/en/Reference/AttachInterrupt]. Purtroppo uno dei due pin (sull'Arduino Uno sono il pin 2 e il pin 3) dava dei risultati estremamente inaffidabili. Dopo varie prove, il risultato migliore l'ho ottenuto usando la libreria Encoder [http://www.pjrc.com/teensy/td_libs_Encoder.html] su due pin non di interrupt. Il risultato di tutta questa fatica è un robottino che grosso modo va dritto. Un risultato mediocre di molto inferiore alla calibrazione a occhio. Alla fine, infatti, ho preferito quest'ultima.&lt;br /&gt;
&lt;br /&gt;
== Lo sketch ==&lt;br /&gt;
&lt;br /&gt;
Lo sketch deriva per una parte dall'esempio ''Ping'' già presente nella libreria di Arduino. In pratica fa avanzare Ardubottino fino a che non incontra un ostacolo. Se lo incontra sterza in un senso e poi nell'altro e alla fine prosegue per la direzione dove ha trovato più campo libero.&lt;br /&gt;
4 7 6 5 sono i  pin a cui ho collegato il ponte ad H. Sterzo è il tempo che deve impiegare per sterzare. pinping è il pin a cui è attaccato il trigger/echo del sensore a ultrasuoni.&lt;br /&gt;
 long duration;&lt;br /&gt;
 long dursx;&lt;br /&gt;
 long durdx; &lt;br /&gt;
 const int en1 = 11; //pin enable&lt;br /&gt;
 const int en2 = 9;&lt;br /&gt;
 const int m1fd = 4; //controlli motore&lt;br /&gt;
 const int m2fd = 7;&lt;br /&gt;
 const int m1bk = 5;&lt;br /&gt;
 const int m2bk = 6;&lt;br /&gt;
 const int pinping = 13; //pin sensore distanza&lt;br /&gt;
 const int sterzo = 600; //durata dello sterzo&lt;br /&gt;
 const int distanza = 500; //distanza minima ostacoli&lt;br /&gt;
 int motore1 = 67;//pwm motore dx&lt;br /&gt;
 int motore2 = 74;//pwm motore sx&lt;br /&gt;
 &lt;br /&gt;
 void setup() {&lt;br /&gt;
  pinMode(m1fd, OUTPUT);&lt;br /&gt;
  pinMode(m1bk, OUTPUT);&lt;br /&gt;
  pinMode(m2fd, OUTPUT);&lt;br /&gt;
  pinMode(m2bk, OUTPUT);&lt;br /&gt;
  pinMode(en1, OUTPUT);&lt;br /&gt;
  pinMode(en2, OUTPUT);&lt;br /&gt;
  analogWrite(en1,motore1);&lt;br /&gt;
  analogWrite(en2,motore2);&lt;br /&gt;
  dritto();&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void loop() {&lt;br /&gt;
  if (echo() &amp;lt; distanza){ //trovato un ostacolo&lt;br /&gt;
   analogWrite(en1,170);&lt;br /&gt;
   analogWrite(en2,170);&lt;br /&gt;
   ferma();&lt;br /&gt;
   sinistra();&lt;br /&gt;
   delay(sterzo);&lt;br /&gt;
   ferma();&lt;br /&gt;
   dursx = echo(); //guarda a sinistra&lt;br /&gt;
   destra();&lt;br /&gt;
   delay(sterzo*2);&lt;br /&gt;
   ferma();&lt;br /&gt;
   durdx = echo(); //guarda a destra&lt;br /&gt;
   if (dursx &amp;lt; distanza &amp;amp;&amp;amp; durdx &amp;lt; distanza){&lt;br /&gt;
     destra();&lt;br /&gt;
     delay(sterzo);&lt;br /&gt;
   } else if (dursx &amp;gt; durdx) {&lt;br /&gt;
     sinistra();&lt;br /&gt;
     delay(sterzo*2);&lt;br /&gt;
   } //sceglie dove c'è più spazio&lt;br /&gt;
   dritto();&lt;br /&gt;
   analogWrite(en1,motore1);&lt;br /&gt;
   analogWrite(en2,motore2);&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void dritto() {&lt;br /&gt;
  digitalWrite(m1bk,LOW);&lt;br /&gt;
  digitalWrite(m2bk,LOW);&lt;br /&gt;
  digitalWrite(m2fd,HIGH);&lt;br /&gt;
  digitalWrite(m1fd,HIGH);   &lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void rovescia() {&lt;br /&gt;
  digitalWrite(m1fd,LOW);&lt;br /&gt;
  digitalWrite(m2fd,LOW);&lt;br /&gt;
  digitalWrite(m1bk,HIGH);&lt;br /&gt;
  digitalWrite(m2bk,HIGH);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void destra() {&lt;br /&gt;
  digitalWrite(m1fd,LOW);&lt;br /&gt;
  digitalWrite(m2fd,HIGH);&lt;br /&gt;
  digitalWrite(m1bk,HIGH);&lt;br /&gt;
  digitalWrite(m2bk,LOW);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sinistra() {&lt;br /&gt;
  digitalWrite(m1fd,HIGH);&lt;br /&gt;
  digitalWrite(m2fd,LOW);&lt;br /&gt;
  digitalWrite(m1bk,LOW);&lt;br /&gt;
  digitalWrite(m2bk,HIGH);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void ferma() {&lt;br /&gt;
  digitalWrite(m1fd,LOW);&lt;br /&gt;
  digitalWrite(m2fd,LOW);&lt;br /&gt;
  digitalWrite(m1bk,LOW);&lt;br /&gt;
  digitalWrite(m2bk,LOW);&lt;br /&gt;
  delay(50);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 long echo() {&lt;br /&gt;
  pinMode(pinping, OUTPUT);&lt;br /&gt;
  digitalWrite(pinping, LOW);&lt;br /&gt;
  delayMicroseconds(2);&lt;br /&gt;
  digitalWrite(pinping, HIGH);&lt;br /&gt;
  delayMicroseconds(5);&lt;br /&gt;
  digitalWrite(pinping, LOW);&lt;br /&gt;
  pinMode(pinping, INPUT);&lt;br /&gt;
  duration = pulseIn(pinping,HIGH);&lt;br /&gt;
  return duration;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
= Seconda Versione =&lt;br /&gt;
Ok, la modifica è un po' minima per essere una vera e propria seconda versione, ma dopo il fallimento degli encoder ero un po' giù di morale.&lt;br /&gt;
Il progetto era di rendere Ardubottino telecomandabile con qualche mezzo estremamente low cost e nella maniera più semplice possibile. La mia scelta è caduta sull'infrarosso.&lt;br /&gt;
&lt;br /&gt;
== Il sensore a infrarossi ==&lt;br /&gt;
[[File:Arduir.jpg]]&lt;br /&gt;
&lt;br /&gt;
Quello che potete vedere nella foto è un sensore a infrarossi come quelli che potreste recuperare in qualsivoglia elettrodomestico. I sensori IR hanno tre pin: +5v, terra e dati. Questo in particolare aveva le stesse specifiche di quest'altro[http://learn.adafruit.com/ir-sensor/testing-an-ir-sensor] usato nel tutorial di Adafruit per leggere gli impulsi infrarossi con Arduino. Potrebbero non essere tutti uguali, quindi cautela.&lt;br /&gt;
&lt;br /&gt;
== La libreria IRremote ==&lt;br /&gt;
Gran parte del lavoro lo fa la libreria IRremote (che trovate qui [https://github.com/shirriff/Arduino-IRremote]). Con questo sketch [http://www.mediafire.com/view/6qnsndqp9a838xe/Decode_IR.ino] si possono leggere, sotto forma di cifre, i codici del telecomando che volete usare. Tramite il monitor seriale noterete dapprincipio che ogni tasto ha assegnato due codici, questo per fare in modo che ci sia una differenza fra tenere premuto il tasto (dà lo stesso codice in uscita, in modo continuo) e dei clic ripetuti (ogni clic diverso il codice cambia). Con questo sketch sono riuscito a capire che il codice del tasto SU del telecomando era legato ai codici 2742014623 e 31889539.&lt;br /&gt;
La libreria IRremote permette anche di trasmettere, ma per ora non sfrutteremo questa sua proprietà. Potete trovare più informazioni qui [http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html]&lt;br /&gt;
&lt;br /&gt;
== Lo sketch finale ==&lt;br /&gt;
Non ho voluto togliere all'Ardubottino la possibilità di andarsene in giro da solo, quindi ho assegnato al tasto OK del telecomando la capacità di passare dallo stato manuale a quello automatico.&lt;br /&gt;
La libreria IRremote ci permette di creare la classe IRrecv che, tramite i suoi metodi, prepara (enableIrIN) , legge (decode), e aspetta il prossimo segnale (resume). I valori sono memorizzati nella struttura decode_results, il cui valore value è il codice del segnale del telecomando. La variabile booleana automat determina se Ardubottino è in modalità automatica o meno.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#FF0000&amp;quot;&amp;gt;ATTENZIONE: La libreria IRremote.h non è compatibile con la libreria RobotIRRemote fornita con l'ultima versione della IDE di Arduino. Per compilare questo sketch occorre prima disabilitare RobotIRRemote. Per disabilitare una libreria occorre andare in arduino/libraries e spostare la cartella della libreria in un altro posto.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  #include &amp;lt;IRremote.h&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  int IRpin =2; //pin del sensore IR&lt;br /&gt;
  IRrecv irrecv(IRpin);&lt;br /&gt;
  long duration;&lt;br /&gt;
  long dursx;&lt;br /&gt;
  long durdx;&lt;br /&gt;
  &lt;br /&gt;
  const int en1 = 10; //pin enable&lt;br /&gt;
  const int en2 = 9;&lt;br /&gt;
  const int m1fd = 4; //controlli motore&lt;br /&gt;
  const int m2fd = 7;&lt;br /&gt;
  const int m1bk = 5;&lt;br /&gt;
  const int m2bk = 6;&lt;br /&gt;
  const int pinping = 13; //pin sensore distanza&lt;br /&gt;
  const int sterzo = 600; //durata dello sterzo&lt;br /&gt;
  const int distanza = 500; //distanza minima ostacoli&lt;br /&gt;
  int motore1 = 66;//pwm motore dx&lt;br /&gt;
  int motore2 = 72;//pwm motore sx&lt;br /&gt;
  boolean automat = false;&lt;br /&gt;
  &lt;br /&gt;
  decode_results results;&lt;br /&gt;
  &lt;br /&gt;
  void setup() {&lt;br /&gt;
   pinMode(m1fd, OUTPUT);&lt;br /&gt;
   pinMode(m1bk, OUTPUT);&lt;br /&gt;
   pinMode(m2fd, OUTPUT);&lt;br /&gt;
   pinMode(m2bk, OUTPUT);&lt;br /&gt;
   pinMode(en1, OUTPUT);&lt;br /&gt;
   pinMode(en2, OUTPUT);&lt;br /&gt;
   analogWrite(en1,motore1);&lt;br /&gt;
   analogWrite(en2,motore2);&lt;br /&gt;
   irrecv.enableIRIn();&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  void loop() {&lt;br /&gt;
    if(irrecv.decode(&amp;amp;results)){&lt;br /&gt;
      if (!automat) {&lt;br /&gt;
        if(results.value == 2742014623 || results.value == 31889539){&lt;br /&gt;
          dritto();&lt;br /&gt;
        } else if (results.value == 2383694249 || results.value == 2039764837 ) {&lt;br /&gt;
          sinistra();&lt;br /&gt;
        } else if (results.value == 15111918 || results.value == 2725237002) {&lt;br /&gt;
          rovescia();&lt;br /&gt;
        } else if (results.value == 1665824360 || results.value == 3250666572 ) {&lt;br /&gt;
          destra();&lt;br /&gt;
        } else  {&lt;br /&gt;
          ferma();&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      if (results.value == 3969632309 || results.value == 18594425) {&lt;br /&gt;
        if (automat) {&lt;br /&gt;
          automat = false;&lt;br /&gt;
          ferma();&lt;br /&gt;
          delayMicroseconds(300000);  &lt;br /&gt;
        }else{&lt;br /&gt;
          automat = true;&lt;br /&gt;
          dritto();&lt;br /&gt;
          delayMicroseconds(300000);&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      irrecv.resume();&lt;br /&gt;
    }&lt;br /&gt;
    if (automat &amp;amp;&amp;amp; echo() &amp;lt; distanza){ //trovato un ostacolo&lt;br /&gt;
     analogWrite(en1,170);&lt;br /&gt;
     analogWrite(en2,170);&lt;br /&gt;
     ferma();&lt;br /&gt;
     sinistra();&lt;br /&gt;
     delay(sterzo);&lt;br /&gt;
     ferma();&lt;br /&gt;
     dursx = echo(); //guarda a sinistra&lt;br /&gt;
     destra();&lt;br /&gt;
     delay(sterzo*2);&lt;br /&gt;
     ferma();&lt;br /&gt;
     durdx = echo(); //guarda a destra&lt;br /&gt;
     if (dursx &amp;lt; distanza &amp;amp;&amp;amp; durdx &amp;lt; distanza){&lt;br /&gt;
       destra();&lt;br /&gt;
       delay(sterzo);&lt;br /&gt;
     } else if (dursx &amp;gt; durdx) {&lt;br /&gt;
       sinistra();&lt;br /&gt;
       delay(sterzo*2);&lt;br /&gt;
     } //sceglie dove c'è più spazio&lt;br /&gt;
     dritto();&lt;br /&gt;
     analogWrite(en1,motore1);&lt;br /&gt;
     analogWrite(en2,motore2);&lt;br /&gt;
   }&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  void dritto() {&lt;br /&gt;
   digitalWrite(m1bk,LOW);&lt;br /&gt;
   digitalWrite(m2bk,LOW);&lt;br /&gt;
   digitalWrite(m2fd,HIGH);&lt;br /&gt;
   digitalWrite(m1fd,HIGH);   &lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  void rovescia() {&lt;br /&gt;
   digitalWrite(m1fd,LOW);&lt;br /&gt;
   digitalWrite(m2fd,LOW);&lt;br /&gt;
   digitalWrite(m1bk,HIGH);&lt;br /&gt;
   digitalWrite(m2bk,HIGH);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  void destra() {&lt;br /&gt;
   digitalWrite(m1fd,LOW);&lt;br /&gt;
   digitalWrite(m2fd,HIGH);&lt;br /&gt;
   digitalWrite(m1bk,HIGH);&lt;br /&gt;
   digitalWrite(m2bk,LOW);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  void sinistra() {&lt;br /&gt;
   digitalWrite(m1fd,HIGH);&lt;br /&gt;
   digitalWrite(m2fd,LOW);&lt;br /&gt;
   digitalWrite(m1bk,LOW);&lt;br /&gt;
   digitalWrite(m2bk,HIGH);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  void ferma() {&lt;br /&gt;
   digitalWrite(m1fd,LOW);&lt;br /&gt;
   digitalWrite(m2fd,LOW);&lt;br /&gt;
   digitalWrite(m1bk,LOW);&lt;br /&gt;
   digitalWrite(m2bk,LOW);&lt;br /&gt;
   delay(50);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  long echo() {&lt;br /&gt;
   pinMode(pinping, OUTPUT);&lt;br /&gt;
   digitalWrite(pinping, LOW);&lt;br /&gt;
   delayMicroseconds(2);&lt;br /&gt;
   digitalWrite(pinping, HIGH);&lt;br /&gt;
   delayMicroseconds(5);&lt;br /&gt;
   digitalWrite(pinping, LOW);&lt;br /&gt;
   pinMode(pinping, INPUT);&lt;br /&gt;
   duration = pulseIn(pinping,HIGH);&lt;br /&gt;
   return duration;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
= Terza Versione =&lt;br /&gt;
Dopo l'ennesimo disastroso trasporto di Ardubottino, nel quale si è smontato tutto, ho deciso di dargli una sistemata definitiva. Saldature migliori, componenti fissati e meno fili volanti. Inoltre sono state fatte le seguenti modifiche.&lt;br /&gt;
&lt;br /&gt;
[[File:ardubottino_3ver.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Passaggio dal Micro al Pro Mini ==&lt;br /&gt;
Per ragioni di spazio sono passato dall'Arduino Micro al Pro Mini della Deek Robots.&lt;br /&gt;
&lt;br /&gt;
[[File:Newardbot2.JPG]]&lt;br /&gt;
&lt;br /&gt;
C'è poco da dire su questa board. È sotto tutti gli aspetti un Arduino Pro Mini. Per essere programmato ha bisogno dell'adattatore USB. Purtroppo, come si può vedere nell'immagine, l'ho montato alla rovescia sulla breadboard e così non è possibile capire il numero dei pin. Capirci qualcosa è stato particolarmente ostico.&lt;br /&gt;
&lt;br /&gt;
== Abbastanza batterie ==&lt;br /&gt;
Avere l'alimentazione separata motori/logica è una soluzione che non mi soddisfa per niente. Come fare però per fare in modo che gli spikes dei motori non facciano riavviare l'Arduino? La questione è stata risolta in questa maniera.&lt;br /&gt;
&lt;br /&gt;
=== Condensatori ===&lt;br /&gt;
Sono stati aggiunti dei condensatori ai motori. In questo modo lo spike dovrebbe essere assorbito in parte.&lt;br /&gt;
&lt;br /&gt;
=== L'Arduino e i motori hanno una sorgente comune ===&lt;br /&gt;
Le batterie dei motori, 4 stilo da 2100mAh l'una, hanno amperaggio più che sufficiente per tenere acceso Arduino e motori. Dal + delle batterie partono due fili, uno va all'Arduino e l'altro al ponte ad H. Nei tentativi precedenti, davo al ponte ad H l'uscita a 5v dell'Arduino. Evidentemente la richiesta dei motori era eccessiva per il regolatore a 5v.&lt;br /&gt;
&lt;br /&gt;
== Turbo! ==&lt;br /&gt;
Aggiunta la modalità turbo, che fa andare il ns. robot più veloce!&lt;br /&gt;
&lt;br /&gt;
== Altri problemi ==&lt;br /&gt;
Avrei voluto mettere il sensore a ultrasuoni su un servo ma un bug della libreria Servo blocca il PWM in alcuni pin[http://forum.arduino.cc/index.php?topic=243264.0] per cui ho lasciato perdere.&lt;br /&gt;
&lt;br /&gt;
== Nuovo codice! ==&lt;br /&gt;
Inutile incollarlo qui. Ho aperto uno spazio su GitLab:&lt;br /&gt;
&lt;br /&gt;
[https://gitlab.com/oloturia/ardubottino Link]&lt;br /&gt;
&lt;br /&gt;
= Quarta versione =&lt;br /&gt;
Era giunto il momento di sfruttare un po' di roba che rimaneva inutilizzata.&lt;br /&gt;
Le modifiche sono state:&lt;br /&gt;
&lt;br /&gt;
* Encoder, stavolta funzionanti&lt;br /&gt;
* Calibrazione automatica&lt;br /&gt;
* Modalità programmazione&lt;br /&gt;
* Blocco quando una ruota non gira&lt;br /&gt;
* Sensore di caduta&lt;br /&gt;
&lt;br /&gt;
== Encoders ==&lt;br /&gt;
Nonostante abbia rotto le rondelle originali (che comunque erano fatte malissimo) sono riuscito a trovare alcuni modelli funzionanti. Il PLA azzurro, a differenza di quello bianco e di quello nero, sembra riflettere l'infrarosso dell'encoder. Tutto stava nel capire quale forma funzionasse meglio.&lt;br /&gt;
&lt;br /&gt;
[[File:Arduencoder.JPG]]&lt;br /&gt;
&lt;br /&gt;
La forma che funziona meglio (per ora) è quella a destra. Potete trovare l'STL nel [https://gitlab.com/oloturia/ardubottino repository ardubottino su GitLab].&lt;br /&gt;
&lt;br /&gt;
Il problema principale, nel creare questo tipo di oggetto in 3D, è stato il foro a forma di prisma esagonale. In Blender occorre creare un cilindro, ridurre i vertici a 6 e poi modificarne la dimensione solo con lo strumento proporzionale, in modo da non deformarlo.&lt;br /&gt;
&lt;br /&gt;
[[File:Newardbot3.JPG]]&lt;br /&gt;
&lt;br /&gt;
Gli encoder permettono di fare diverse cose interessanti. Ora Ardubottino sente quando una ruota non sta girando, ad esempio, inoltre sono state aggiunte due nuove modalità: la modalità &amp;quot;programmazione&amp;quot; (vai avanti di 10, poi gira a destra di 5, ecc.) e la modalità &amp;quot;calibrazione&amp;quot; (modifica la velocità di un motore fino a che le ruote non girano più o meno uguali).&lt;br /&gt;
&lt;br /&gt;
Purtroppo gli encoder non sono tanto precisi, ogni tanto leggono male e segnano un passo in più o in meno. Questo però era così anche con le rotelle originali.&lt;br /&gt;
&lt;br /&gt;
== Il sensore di caduta ==&lt;br /&gt;
Posto sul davanti, sente quando ad Ardubottino manca la terra sotto i cingoli. Quando sente il vuoto ferma tutto.&lt;br /&gt;
&lt;br /&gt;
[[File:Newardbot1.JPG]]&lt;br /&gt;
&lt;br /&gt;
== Il codice ==&lt;br /&gt;
Il codice sta diventando veramente troppo lungo per essere incollato qui, su questa pagina, per cui ne commenterò solo alcune parti. Lo sketch completo lo trovate su [https://gitlab.com/oloturia/ardubottino GitLab].&lt;br /&gt;
&lt;br /&gt;
 #include &amp;quot;ardubottino.h&amp;quot;&lt;br /&gt;
Sì, era ora che creassi un header con tutti i codici del telecomando. Per adattare Ardubottino a un altro telecomando basterà cambiare header.&lt;br /&gt;
&lt;br /&gt;
 volatile long right_interval = 0;&lt;br /&gt;
 volatile long left_interval = 0;&lt;br /&gt;
 volatile int right_count = 0;&lt;br /&gt;
 volatile int left_count = 0;&lt;br /&gt;
&lt;br /&gt;
Le variabili che sono modificate dagli encoder devono essere di tipo &amp;quot;volatile&amp;quot;. Le variabili volatile possono essere cambiate da un evento esterno, nel nostro caso da un evento scatenato da un interrupt.&lt;br /&gt;
  &lt;br /&gt;
 void right_encoder() {&lt;br /&gt;
  static unsigned long last_interrupt = 0;&lt;br /&gt;
  unsigned long time_interrupt = millis();&lt;br /&gt;
  if(time_interrupt - last_interrupt &amp;gt;70){&lt;br /&gt;
    right_interval = time_interrupt - last_interrupt;&lt;br /&gt;
    next_check_right = millis()+right_interval*2;&lt;br /&gt;
    right_count +=1;&lt;br /&gt;
    last_interrupt = time_interrupt;&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void left_encoder() {&lt;br /&gt;
  static unsigned long last_interrupt = 0;&lt;br /&gt;
  unsigned long time_interrupt = millis();&lt;br /&gt;
  if(time_interrupt - last_interrupt &amp;gt;70) {&lt;br /&gt;
    left_interval = millis() - last_interrupt;&lt;br /&gt;
    next_check_left = millis()+left_interval*2;&lt;br /&gt;
    left_count +=1;&lt;br /&gt;
    last_interrupt = millis();&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Ecco le brevi funzioni chiamate da &lt;br /&gt;
  attachInterrupt(0, right_encoder,RISING);&lt;br /&gt;
  attachInterrupt(1, left_encoder,RISING);&lt;br /&gt;
gli interrupt.&lt;br /&gt;
La variabile x_count conta quanti giri (quanti quarti di giro) ha fatto la ruota; x_interval l'intervallo, in millisecondi, fra un passaggio e l'altro; next_check_x è una stima massima di quando dovrebbe essere il prossimo passaggio, serve per capire se una ruota s'è inceppata.&lt;br /&gt;
&lt;br /&gt;
  if (irrecv.decode(&amp;amp;results)) {&lt;br /&gt;
   curr_result = results.value;&lt;br /&gt;
   if (curr_result == prev_result) {&lt;br /&gt;
     curr_result = 0;&lt;br /&gt;
   } else {&lt;br /&gt;
     prev_result = curr_result;&lt;br /&gt;
   }&lt;br /&gt;
 (...)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Ricordate quando vi dissi che il telecomando per ogni tasto ha due codici? Serve per distinguere se state tenendo premuto il tasto o se lo state premendo più volte contemporaneamente. Con questo piccolo brandello di codice faccio in modo di ignorare i codici ripetuti, visto che ad Ardubottino non servono. Non tutti i telecomandi funzionano così.&lt;br /&gt;
 if (program) {&lt;br /&gt;
      if (curr_result == OKA || curr_result == OKB) {&lt;br /&gt;
        blinkOK();&lt;br /&gt;
        executeProgram();&lt;br /&gt;
        clearMoves();&lt;br /&gt;
        noMotion();&lt;br /&gt;
      } else if (curr_result == NUM1A || curr_result == NUM1B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +1;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM2A || curr_result == NUM2A) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +2;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM3A || curr_result == NUM3B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +3;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM4A || curr_result == NUM4B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +4;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM5A || curr_result == NUM5B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +5;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM6A || curr_result == NUM6B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +6;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM7A || curr_result == NUM7B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +7;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM8A || curr_result == NUM8B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +8;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM9A || curr_result == NUM9B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10) +9;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == NUM0A || curr_result == NUM0B) {&lt;br /&gt;
        moves[pointer][0] = (moves[pointer][0]*10);   &lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == FORWARDA || curr_result == FORWARDB) {&lt;br /&gt;
        moves[pointer][1] = 1;&lt;br /&gt;
        pointer ++;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == BACKA || curr_result == BACKB) {&lt;br /&gt;
        moves[pointer][1] = 2;&lt;br /&gt;
        pointer ++;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == LEFTA || curr_result == LEFTB) {&lt;br /&gt;
        moves[pointer][1] = 3;&lt;br /&gt;
        pointer ++;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == RIGHTA || curr_result == RIGHTB) {&lt;br /&gt;
        moves[pointer][1] = 4;&lt;br /&gt;
        pointer ++;&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else if (curr_result == WINA || curr_result == WINB) {&lt;br /&gt;
        clearMoves();&lt;br /&gt;
        blinkOK();&lt;br /&gt;
      } else {&lt;br /&gt;
        blinkNO();&lt;br /&gt;
      }&lt;br /&gt;
      if(moves[pointer][0] &amp;gt; 99) {&lt;br /&gt;
       moves[pointer][0] = moves[pointer][0]-((moves[pointer][0]/100)*100);&lt;br /&gt;
      }&lt;br /&gt;
      if (pointer &amp;gt;49) {&lt;br /&gt;
        executeProgram();&lt;br /&gt;
      }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Et voilà: 50 mosse programmabili per il nostro robottino. Si scrive un numero di massimo 2 cifre e una direzione per massimo 50 istruzioni. Premendo OK si dà inizio al programma.&lt;br /&gt;
Ho anche aggiunto un lampeggiamento del LED di bordo in modo da dare un feedback visivo. Come ben saprete, i telecomandi a volte non trasmettono bene.&lt;br /&gt;
&lt;br /&gt;
 void executeProgram() {&lt;br /&gt;
  int right_count_program = right_count;&lt;br /&gt;
  &lt;br /&gt;
  for (int x=0;x&amp;lt;=49;x++){&lt;br /&gt;
    if (moves[x][1] == 0) {&lt;br /&gt;
      break;&lt;br /&gt;
    } else if (moves[x][1] == 1){&lt;br /&gt;
      forward();&lt;br /&gt;
    } else if (moves[x][1] == 2){&lt;br /&gt;
      backward();&lt;br /&gt;
    } else if (moves[x][1] == 3){&lt;br /&gt;
      left();&lt;br /&gt;
    } else if (moves[x][1] == 4){&lt;br /&gt;
      right();&lt;br /&gt;
    }&lt;br /&gt;
    while(moves[x][0] &amp;gt; 0) {&lt;br /&gt;
      if (right_count_program != right_count ) {&lt;br /&gt;
        moves[x][0] --;&lt;br /&gt;
        right_count_program = right_count;&lt;br /&gt;
        &lt;br /&gt;
      }&lt;br /&gt;
      if (digitalRead(fall)) {      &lt;br /&gt;
        noMotion();&lt;br /&gt;
        program = false;&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    moves[x][1] = 0;&lt;br /&gt;
  }&lt;br /&gt;
  program = false;&lt;br /&gt;
  noMotion();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Come potete vedere a metà c'è anche un check (c'è anche per le modalità automatica e manuale) sul sensore di caduta.&lt;br /&gt;
&lt;br /&gt;
 if (curr_result == BLUEA|| curr_result == BLUEB) { //calibration&lt;br /&gt;
      blinkOK();&lt;br /&gt;
      program = false;&lt;br /&gt;
      automat = false;&lt;br /&gt;
      noMotion();&lt;br /&gt;
      delay(500);&lt;br /&gt;
      forward();&lt;br /&gt;
      int loops = 0;&lt;br /&gt;
      int last_left = left_count;&lt;br /&gt;
      int last_right = right_count;&lt;br /&gt;
      bool left_pass = false;&lt;br /&gt;
      bool right_pass = false;&lt;br /&gt;
      while (loops &amp;lt; 12) {&lt;br /&gt;
        if (last_left != left_count) {&lt;br /&gt;
          left_pass = true;&lt;br /&gt;
        }&lt;br /&gt;
        if (last_right != right_count) {&lt;br /&gt;
          right_pass = true;&lt;br /&gt;
        }&lt;br /&gt;
        if (left_pass &amp;amp;&amp;amp; right_pass) {&lt;br /&gt;
          left_pass = false;&lt;br /&gt;
          right_pass = false;&lt;br /&gt;
          last_left = left_count;&lt;br /&gt;
          last_right = right_count;&lt;br /&gt;
          if (abs(right_interval - left_interval) &amp;lt; 80) {&lt;br /&gt;
            loops +=1;&lt;br /&gt;
          } else if (right_interval &amp;gt; left_interval) {&lt;br /&gt;
            motor1PWM += 1;&lt;br /&gt;
            analogWrite(en1,motor1PWM);&lt;br /&gt;
            loops = 0;&lt;br /&gt;
          } else {&lt;br /&gt;
            motor1PWM -= 1;&lt;br /&gt;
            analogWrite(en1,motor1PWM);&lt;br /&gt;
            loops = 0;&lt;br /&gt;
          }&lt;br /&gt;
          if(debug) {&lt;br /&gt;
            Serial.print(motor1PWM);&lt;br /&gt;
            Serial.print(&amp;quot; &amp;quot;);&lt;br /&gt;
            Serial.println(motor2PWM);&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      noMotion();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
La calibrazione: modifica la potenza di uno dei due motori fino a che gli intervalli degli encoder delle due ruote non sono quasi uguali. Occorre staccare i cingoli o mettere Ardubottino in un posto sopraelevato perché per funzionare ha bisogno di andare forward() per qualche minuto.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Progetti]]&lt;/div&gt;</summary>
		<author><name>Oloturia</name></author>
	</entry>
</feed>