<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Elettronica Archives</title>
	<atom:link href="https://logicaprogrammabile.it/category/tutorial-elettronica-analogica-digitale/feed/" rel="self" type="application/rss+xml" />
	<link>https://logicaprogrammabile.it/category/tutorial-elettronica-analogica-digitale/</link>
	<description>Tutorial in italiano per imparare a programmare usando Arduino, Raspberry PI, Netduino</description>
	<lastBuildDate>Fri, 07 Feb 2020 19:09:24 +0000</lastBuildDate>
	<language>it-IT</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.2</generator>

<image>
	<url>https://logicaprogrammabile.it/wp-content/uploads/2017/11/cropped-logicaprogrammabile-logo-02-32x32.png</url>
	<title>Elettronica Archives</title>
	<link>https://logicaprogrammabile.it/category/tutorial-elettronica-analogica-digitale/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Alimentare a batteria una MKR ZERO</title>
		<link>https://logicaprogrammabile.it/alimentare-batteria-arduino-mkr-zero/</link>
					<comments>https://logicaprogrammabile.it/alimentare-batteria-arduino-mkr-zero/#comments</comments>
		
		<dc:creator><![CDATA[Marco Lai]]></dc:creator>
		<pubDate>Tue, 14 Jan 2020 20:02:27 +0000</pubDate>
				<category><![CDATA[Elettronica]]></category>
		<category><![CDATA[mkrZero]]></category>
		<guid isPermaLink="false">https://logicaprogrammabile.it/?p=6164</guid>

					<description><![CDATA[<p>MKRZERO e problemi di alimentazione a batteria E&#8217; da diverso tempo che provo schede della serie MKR. Mi piace molto il form factor e quindi la possibilità di inserirle in maniera molto semplice in pcb custom. Nonostante ciò ho riscontrato alcune anomalie sulla scheda MKR...</p>
<p>The post <a href="https://logicaprogrammabile.it/alimentare-batteria-arduino-mkr-zero/">Alimentare a batteria una MKR ZERO</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1>MKRZERO e problemi di alimentazione a batteria</h1>
<p>E&#8217; da diverso tempo che provo schede della serie MKR. Mi piace molto il form factor e quindi la possibilità di inserirle in maniera molto semplice in pcb custom. Nonostante ciò ho riscontrato alcune <strong>anomalie</strong> sulla scheda <a href="https://store.arduino.cc/arduino-mkr-zero-i2s-bus-sd-for-sound-music-digital-audio-data">MKR Zero</a>. Questa scheda è predisposta per essere alimentata tramite una batteria<strong> LiPo</strong> da 3.7V. Sulla documentazione viene specificato che il led ON, normalmente acceso con alimentazione da porta usb, dovrebbe essere spento se la scheda è alimentata a batteria.</p>
<p>Ho notato che nelle mie schede <strong>MKR ZERO</strong>, tutte nuove e acquistare dallo store ufficiale, presentano delle anomalie; infatti alimentando la scheda da <strong>LiPo</strong>, il led ON risulta parzialmente acceso.</p>
<p>Ho eseguito diversi controlli sullo schema elettrico e cercato sul web se altri utenti riscontrano gli stessi fenomeni ma senza trovare soluzioni.</p>
<p><span id="more-6164"></span></p>
<p>Nella <strong>MKR ZERO</strong> la gestione della batteria è affidata al chip <strong>MCP738312</strong>. Seguendo lo schema riportato di seguito proverò a fare un ragionamento su come dovrebbe funzionare il circuito:</p>
<figure id="attachment_6175" aria-describedby="caption-attachment-6175" style="width: 819px" class="wp-caption aligncenter"><img fetchpriority="high" decoding="async" class="size-full wp-image-6175" src="https://logicaprogrammabile.it/wp-content/uploads/2020/01/MKRZero_Power.png" alt="Alimentatore MKR ZERO" width="819" height="303" srcset="https://logicaprogrammabile.it/wp-content/uploads/2020/01/MKRZero_Power.png 819w, https://logicaprogrammabile.it/wp-content/uploads/2020/01/MKRZero_Power-300x111.png 300w, https://logicaprogrammabile.it/wp-content/uploads/2020/01/MKRZero_Power-150x55.png 150w, https://logicaprogrammabile.it/wp-content/uploads/2020/01/MKRZero_Power-768x284.png 768w, https://logicaprogrammabile.it/wp-content/uploads/2020/01/MKRZero_Power-585x216.png 585w" sizes="(max-width: 819px) 100vw, 819px" /><figcaption id="caption-attachment-6175" class="wp-caption-text">Sezione alimentazione MKR ZERO</figcaption></figure>
<p>Nel caso in cui non sia presente la batteria, la tensione potrà arrivare al pin <strong>VDD</strong> dell&#8217;integrato <strong>MCP738312</strong> in tre modi, dalla USB, Dal pin Vin e dal pin 5V. Inoltre questa tensione raggiungerà anche il pin VIN del regolatore <strong>U2</strong>, tramite il diodo <strong>Q3B</strong>, fornendo alimentazione alla scheda.</p>
<p>In questa situazione il mosfet <strong>Q3A</strong>, di tipo P-channel, risulta spento perché al suo gate è presente una tensione positiva. In questo modo, se fosse presente una batteria (e ammettendo che essa sia completamente carica e che quindi il regolatore sia in sleep mode) la tensione non raggiungerebbe la batteria stessa.</p>
<p>[the_ad id=&#8221;6199&#8243;]</p>
<p>Se invece la batteria fosse scarica e l&#8217;integrato <strong>MCP738312</strong> Inizierà a ricaricarla. Nel mio caso la <strong>VBat</strong> misurata sul connettore <strong>J2</strong> è di circa 3.82Vdc e quindi non raggiungerà l&#8217;integrato <strong>U2</strong> perché il diodo del mosfet <strong>Q3A</strong> è interdetto (potenziale sull&#8217;anodo minore del catodo).</p>
<p>La mia domanda è questa, il mosfet <strong>Q3A</strong> sarebbe stato possibile sostituirlo con un semplice diodo?</p>
<p><img decoding="async" class="aligncenter size-full wp-image-6180" src="https://logicaprogrammabile.it/wp-content/uploads/2020/01/MKRZERO.jpg" alt="MKR ZERO" width="570" height="331" srcset="https://logicaprogrammabile.it/wp-content/uploads/2020/01/MKRZERO.jpg 570w, https://logicaprogrammabile.it/wp-content/uploads/2020/01/MKRZERO-300x174.jpg 300w, https://logicaprogrammabile.it/wp-content/uploads/2020/01/MKRZERO-150x87.jpg 150w" sizes="(max-width: 570px) 100vw, 570px" /></p>
<p>Ora ammettiamo di alimentare la scheda solo con la batteria <strong>LiPo</strong>.<br />
Il ragionamento è il seguente: Il diodo del mosfet <strong>Q3A</strong> porterà la tensione della batteria all&#8217;integrato <strong>U2</strong> alimentando la scheda. In questa situazione ho però una tensione di circa 1.8V sulla linea dei 5V che teoricamente non dovrebbe esserci. Questa tensione va ad alimentare il diodo DL1 che viene leggermente acceso e ovviamente incide sui consumi della batteria in modo significativo.</p>
<p>Questa alimentazione da dove proviene? E&#8217; un difetto dell&#8217;integrato <strong>MCP738312</strong> che riporta parte della tensione della batteria sul pin VDD?</p>
<p>Qualcuno può verificare quanto scritto e se in possesso di una scheda <strong>MKR ZERO</strong> verificare la mia tesi?</p>
<p style="text-align: center;"><iframe style="width: 120px; height: 240px;" src="//rcm-eu.amazon-adsystem.com/e/cm?lt1=_blank&amp;bc1=000000&amp;IS2=1&amp;bg1=FFFFFF&amp;fc1=000000&amp;lc1=0000FF&amp;t=logicaprogram-21&amp;language=it_IT&amp;o=29&amp;p=8&amp;l=as4&amp;m=amazon&amp;f=ifr&amp;ref=as_ss_li_til&amp;asins=B077NBB23L&amp;linkId=6b6c680fd9a977037c080c499fde91d6" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe></p>
<p>The post <a href="https://logicaprogrammabile.it/alimentare-batteria-arduino-mkr-zero/">Alimentare a batteria una MKR ZERO</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://logicaprogrammabile.it/alimentare-batteria-arduino-mkr-zero/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>MCP1703 regolatore di tensione a basso consumo</title>
		<link>https://logicaprogrammabile.it/mcp1703-regolatore-tensione-basso-consumo/</link>
					<comments>https://logicaprogrammabile.it/mcp1703-regolatore-tensione-basso-consumo/#respond</comments>
		
		<dc:creator><![CDATA[Marco Lai]]></dc:creator>
		<pubDate>Mon, 12 Aug 2019 06:00:14 +0000</pubDate>
				<category><![CDATA[Elettronica]]></category>
		<guid isPermaLink="false">https://logicaprogrammabile.it/?p=6116</guid>

					<description><![CDATA[<p>MCP1703 Low Quiescent Current LDO Regulator I dispositivi alimentati a batteria hanno circuiti integrati capaci di avere un assorbimento di corrente nell&#8217;ordine dei uA. Per poter avere la certezza che possa funzionare per diversi mesi, due sono le soluzioni più immediate, quella di utilizzare una...</p>
<p>The post <a href="https://logicaprogrammabile.it/mcp1703-regolatore-tensione-basso-consumo/">MCP1703 regolatore di tensione a basso consumo</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1>MCP1703 Low Quiescent Current LDO Regulator</h1>
<p>I dispositivi alimentati a batteria hanno circuiti integrati capaci di avere un assorbimento di corrente nell&#8217;ordine dei uA.</p>
<p><img decoding="async" class="aligncenter size-full wp-image-6125" src="https://logicaprogrammabile.it/wp-content/uploads/2019/07/MCP1307.png" alt="MCP1307 LDO Regulator" width="470" height="405" srcset="https://logicaprogrammabile.it/wp-content/uploads/2019/07/MCP1307.png 470w, https://logicaprogrammabile.it/wp-content/uploads/2019/07/MCP1307-300x259.png 300w" sizes="(max-width: 470px) 100vw, 470px" /></p>
<p>Per poter avere la certezza che possa funzionare per diversi mesi, due sono le soluzioni più immediate, quella di utilizzare una fonte di energia capace di fornire tutta la corrente per sostenere il circuito elettronico (come una batteria capiente o un sistema basato su pannello solare), oppure quella di progettare il circuito elettronico affinché possa assorbire una corrente irrisoria.</p>
<p>Usare una batteria capiente o un pannello solare permette di non preoccuparci tanto degli assorbimenti dei componenti elettronici ma in questo caso dobbiamo fare i conti con installazioni con ingombri maggiori e costi maggiori, mentre utilizzare batterie a basso costo con ingombri ridotti otteniamo semplicità di installazione e costi decisamente inferiori.</p>
<p><span id="more-6116"></span></p>
<p>Un componente che generalmente troviamo in ogni circuito elettronico è il regolatore di tensione. Questo componente è fondamentale per avere un assorbimento estremamente basso. Infatti se alcuni componenti possiamo disabilitarli o mandarli in modalità basso consumo, il circuito di regolazione deve avere un consumo intrinseco di corrente molto basso in modo da non incidere sul consumo totale di corrente.</p>
<h3>Come scegliere il regolatore di tensione.</h3>
<p>La prima cosa da sapere è la quantità di corrente massima assorbita dal circuito. Questa può essere calcolata in funzione dei componenti scelti oppure più precisamente misurata utilizzando un comune tester.</p>
<p>Il regolatore di tensione deve avere come parametro principale la capacità di fornire tutta la corrente richiesta dal circuito. Ora verifichiamo il parametro solitamente indicato con la voce quiescent current, che indica la corrente minima necessaria per far funzionare il regolatore.<br />
Più è basso questo valore più andiamo a risparmiare corrente durante le fasi di sleep mode del circuito.</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-6128" src="https://logicaprogrammabile.it/wp-content/uploads/2019/07/MCP1307_datasheet.png" alt="MCP1307 Datasheet quiescent current" width="636" height="401" srcset="https://logicaprogrammabile.it/wp-content/uploads/2019/07/MCP1307_datasheet.png 636w, https://logicaprogrammabile.it/wp-content/uploads/2019/07/MCP1307_datasheet-150x95.png 150w, https://logicaprogrammabile.it/wp-content/uploads/2019/07/MCP1307_datasheet-300x189.png 300w, https://logicaprogrammabile.it/wp-content/uploads/2019/07/MCP1307_datasheet-420x265.png 420w, https://logicaprogrammabile.it/wp-content/uploads/2019/07/MCP1307_datasheet-585x369.png 585w" sizes="auto, (max-width: 636px) 100vw, 636px" /></p>
<p>Nel caso del componente MCP1307 il valore di quiescent current è di soli 2uA.</p>
<p>In definitiva per chi è alle prese nel realizzare circuiti a basso assorbimento troverà nel regolatore MCP1703 un valido componente capace di fornire sufficiente corrente al circuito e bassissimi consumi.</p>
<p>&nbsp;</p>
<p>The post <a href="https://logicaprogrammabile.it/mcp1703-regolatore-tensione-basso-consumo/">MCP1703 regolatore di tensione a basso consumo</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://logicaprogrammabile.it/mcp1703-regolatore-tensione-basso-consumo/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Flyport Ethernet leggere dai pin analogici</title>
		<link>https://logicaprogrammabile.it/flyport-ethernet-leggere-dai-pin-analogici/</link>
		
		<dc:creator><![CDATA[Marco Lai]]></dc:creator>
		<pubDate>Mon, 18 Nov 2013 09:45:15 +0000</pubDate>
				<category><![CDATA[Elettronica]]></category>
		<category><![CDATA[OpenPicus]]></category>
		<category><![CDATA[Flyport]]></category>
		<category><![CDATA[Ingresso analogico]]></category>
		<guid isPermaLink="false">https://logicaprogrammabile.it/?p=3760</guid>

					<description><![CDATA[<p>Come acquisire un segnale analogico tramite modulo Flyport L&#8217;acquisizione di segnali analogici permette l&#8217;interfacciamento del Flyport Ethernet con svariate tipologie di sensori e trasduttori che forniscono una tensione analogica in funzione della grandezza fisica misurata. Il modulo dispone di 4 ingressi analogici (p18, p20, p23,...</p>
<p>The post <a href="https://logicaprogrammabile.it/flyport-ethernet-leggere-dai-pin-analogici/">Flyport Ethernet leggere dai pin analogici</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h3>Come acquisire un segnale analogico tramite modulo Flyport</h3>
<p>L&#8217;acquisizione di segnali analogici permette l&#8217;interfacciamento del <strong>Flyport Ethernet</strong> con svariate tipologie di sensori e trasduttori che forniscono una tensione analogica in funzione della grandezza fisica misurata.<br /> Il modulo dispone di <strong>4 ingressi analogici (p18, p20, p23, p25)</strong> con una risoluzione di <strong>10bit</strong> (valori restituiti da 0 a 1023) ed una tensione di riferimento molto precisa fissata a 2.048V.<br /> I pin analogici non supportano tensioni superiori a 3.3V quindi dobbiamo stare attenti al valore di tensione che sarà applicato sul pin analogico.</p>
<p>Dato che la tensione di riferimento è di 2.048V, il convertitore analogico digitale fornirà il valore intero zero(0) quando in ingresso sarà presente una tensione di 0V, fornirà invece il valore 1023 quando sul pin analogico sarà presente una tensione pari a 2.048V. Superata questa soglia, fino al valore consentito di 3.3V il convertitore restituirà sempre 1023.</p>
<p><span id="more-3760"></span></p>
<p>La relazione tra valore di conversione e tensione è la seguente</p>
<p style="text-align: center;"><strong>tensione di riferimento / risoluzione =&gt; 2.048/1024 = 0.002V</strong></p>
<p>quindi se il convertitore restituirà il valore di 560, potremmo facilmente constatare che sul pin analogico sarà presente la tensione di 1.12V</p>
<p style="text-align: center;"><strong>valore conversione * valore minimo di conversione =&gt; 560 * 0.002 = 1.12V</strong></p>
<p>Ho realizzato il seguente circuito per provare le istruzioni che acquisiscono il segnale analogico presente sul pin <strong>p18</strong>.</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/09/FlyportAnalogRead1.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3824" alt="Analog Read Flyport Ethernet" src="https://logicaprogrammabile.it/wp-content/uploads/2013/09/FlyportAnalogRead1.png" width="414" height="299" srcset="https://logicaprogrammabile.it/wp-content/uploads/2013/09/FlyportAnalogRead1.png 414w, https://logicaprogrammabile.it/wp-content/uploads/2013/09/FlyportAnalogRead1-300x216.png 300w" sizes="auto, (max-width: 414px) 100vw, 414px" /></a></p>
<p>il pin p24 è quello che fornisce la 3.3Vdc, il pin p22 è la massa ed il pi p18 è l&#8217;ingresso analogico 4 del modulo <strong>Flyport Ethernet</strong>.<br /> Il potenziometro <strong>PT</strong> è da 5Kohm mentre la resistenza <strong>R</strong> è da 47Ohm e serve per evitare il cortocircuito nel caso in cui ci sia un malfunzionamento della meccanica del potenziometro che porta il collegamento della 3.3Vdc direttamente al gnd.</p>
<p>Le istruzioni per acquisire il segnale analogico sono molto semplici, i commenti nel codice illustrano questo procedimento:</p>
<pre>[c]&lt;br /&gt;#include &quot;taskFlyport.h&quot;&lt;br /&gt;&lt;br /&gt;void FlyportTask()&lt;br /&gt;{&lt;br /&gt;&lt;%%KEEPWHITESPACE%%&gt;  int Valore_ADC = 0;&lt;br /&gt;&lt;%%KEEPWHITESPACE%%&gt;  char Dato_ADC[5];&lt;br /&gt;&lt;br /&gt;&lt;%%KEEPWHITESPACE%%&gt;  while(1)&lt;br /&gt;&lt;%%KEEPWHITESPACE%%&gt;  {&lt;br /&gt;&lt;%%KEEPWHITESPACE%%&gt;    //acquisisco ildato presente sul pin p18&lt;br /&gt;&lt;%%KEEPWHITESPACE%%&gt;    Valore_ADC = ADCVal(4);&lt;br /&gt;&lt;%%KEEPWHITESPACE%%&gt;    //converto il valore intero in un array di char&lt;br /&gt;&lt;%%KEEPWHITESPACE%%&gt;    sprintf(Dato_ADC, &quot;%d\n&quot;, Valore_ADC);&lt;br /&gt;&lt;%%KEEPWHITESPACE%%&gt;    //invio il dato al serial monitor&lt;br /&gt;&lt;%%KEEPWHITESPACE%%&gt;    UARTWrite(1, Dato_ADC);&lt;br /&gt;&lt;%%KEEPWHITESPACE%%&gt;    //attesa di 1 secondo&lt;br /&gt;&lt;%%KEEPWHITESPACE%%&gt;    vTaskDelay(100);&lt;br /&gt;&lt;%%KEEPWHITESPACE%%&gt;  }&lt;br /&gt;}&lt;br /&gt;[/c]</pre>
<p>L&#8217;unica raccomandazione nell&#8217;uso dei pin analogici è quella di non superare mai la tensione massima in ingressi di 3.3Vdc. Nel caso in cui la tensione da acquisire fosse maggiore si potrebbe adottare un semplice partitore di tensione.</p>
<p>The post <a href="https://logicaprogrammabile.it/flyport-ethernet-leggere-dai-pin-analogici/">Flyport Ethernet leggere dai pin analogici</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>L298N pilotare motore passo passo bipolare</title>
		<link>https://logicaprogrammabile.it/pilotare-motore-passo-passo-bipolare-driver-l298n/</link>
					<comments>https://logicaprogrammabile.it/pilotare-motore-passo-passo-bipolare-driver-l298n/#comments</comments>
		
		<dc:creator><![CDATA[Marco Lai]]></dc:creator>
		<pubDate>Tue, 28 May 2013 09:32:02 +0000</pubDate>
				<category><![CDATA[Elettronica]]></category>
		<category><![CDATA[Tutorial Arduino]]></category>
		<category><![CDATA[Motore DC]]></category>
		<category><![CDATA[Stepper]]></category>
		<guid isPermaLink="false">https://logicaprogrammabile.it/?p=3634</guid>

					<description><![CDATA[<p>Come pilotare un motore passo passo usando l&#8217;integrato L298N Quando osservo i robot industriali assemblare, saldare, fresare o posizionare oggetti con una precisione sconcertante rimango affascinato dalla capacità umana di poter costruire queste macchine. Anche nelle nostre abitazioni sono presenti oggetti dotati di parti meccaniche,...</p>
<p>The post <a href="https://logicaprogrammabile.it/pilotare-motore-passo-passo-bipolare-driver-l298n/">L298N pilotare motore passo passo bipolare</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1>Come pilotare un motore passo passo usando l&#8217;integrato L298N</h1>
<p>Quando osservo i robot industriali assemblare, saldare, fresare o posizionare oggetti con una precisione sconcertante rimango affascinato dalla capacità umana di poter costruire queste macchine.<br />
Anche nelle nostre abitazioni sono presenti oggetti dotati di parti meccaniche, che compiono movimenti molto precisi, come ad esempio le stampanti, i plotter e gli scanner.<br />
Questi dispositivi hanno in comune tra loro un particolare dispositivo chiamato motore passo passo (<strong>stepper motor</strong>).<br />
E&#8217; un <strong>trasduttore elettromeccanico</strong> che converte degli impulsi elettrici in un movimento fisico. Ad ogni <strong>impulso elettrico</strong> corrisponde un <strong>movimento del rotore</strong>; questo spostamento viene chiamato <strong>step</strong>.<br />
A differenza del motore in corrente continua i motori passo passo possono mantenere la propria velocità di <strong>rotazione costante</strong>, anche con carico applicato, senza usare sistemi di controreazione (tachimetriche o encoder).<br />
Il motore eroga una <strong>coppia elevata</strong>, anche con bassi numeri di giri, possiede <strong>accelerazioni e frenate repentine</strong> ed è capace di mantenere il carico applicato fermo in posizione, senza vibrazioni.</p>
<p>Naturalmente esistono anche degli <strong>svantaggi</strong>, tra cui la necessità di utilizzare un <strong>circuito elettrico di pilotaggio</strong>, un <strong>rendimento energetico basso</strong>, una <strong>velocità di rotazione ridotta</strong> ed un <strong>costo di acquisto elevato</strong>.</p>
<p><span id="more-3634"></span></p>
<p>La figura seguente mostra, in maniera semplificata, il principio di costruzione di un motore passo passo.</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/05/Motore_PassoPasso.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3640" src="https://logicaprogrammabile.it/wp-content/uploads/2013/05/Motore_PassoPasso.png" alt="Motore Passo Passo" width="484" height="373" srcset="https://logicaprogrammabile.it/wp-content/uploads/2013/05/Motore_PassoPasso.png 484w, https://logicaprogrammabile.it/wp-content/uploads/2013/05/Motore_PassoPasso-300x231.png 300w" sizes="auto, (max-width: 484px) 100vw, 484px" /></a></p>
<p>Il movimento del rotore avviene alimentando le bobine in modo consecutivo. Eccitando solo la<strong> bobina A1</strong> il rotore si posiziona verso <strong>NORD</strong>, eccitando solo la<strong> bobina B1</strong> il rotore si posiziona in direzione <strong>EST</strong>, eccitando solo la<strong> bobina A2</strong> il rotore si posiziona in direzione <strong>SUD</strong> ed infine eccitando solo la <strong>bobina B2</strong> il rotore si posiziona in direzione <strong>OVEST</strong>.<br />
La tabella seguente riassumere la sequenza.</p>
<div align="center">
<table>
<tbody>
<tr>
<td style="text-align: center;" colspan="5"><span style="font-size: large;">Fasi di Alimentazione</span></td>
</tr>
<tr>
<td style="text-align: center;"></td>
<td style="text-align: center;"><span style="font-size: large;">A1</span></td>
<td style="text-align: center;"><span style="font-size: large;">A2</span></td>
<td style="text-align: center;"><span style="font-size: large;">B1 </span></td>
<td style="text-align: center;"><span style="font-size: large;">B2 </span></td>
</tr>
<tr>
<td style="text-align: center;"><span style="font-size: large;">Fase 1</span></td>
<td style="text-align: center;" bgcolor="#FF0000"><span style="font-size: large;">+</span></td>
<td style="text-align: center; background-color: #04c4fa;"><span style="font-size: large;">&#8211;</span></td>
<td style="text-align: center; background-color: #04c4fa;"><span style="font-size: large;">&#8211;</span></td>
<td style="text-align: center; background-color: #04c4fa;"><span style="font-size: large;">&#8211;</span></td>
</tr>
<tr>
<td style="text-align: center;"><span style="font-size: large;">Fase 2</span></td>
<td style="text-align: center; background-color: #04c4fa;"><span style="font-size: large;">&#8211;</span></td>
<td style="text-align: center; background-color: #04c4fa;"><span style="font-size: large;">&#8211;</span></td>
<td style="text-align: center;" bgcolor="#FF0000"><span style="font-size: large;">+</span></td>
<td style="text-align: center; background-color: #04c4fa;"><span style="font-size: large;">&#8211;</span></td>
</tr>
<tr>
<td style="text-align: center;"><span style="font-size: large;">Fase 3</span></td>
<td style="text-align: center; background-color: #04c4fa;"><span style="font-size: large;">&#8211;</span></td>
<td style="text-align: center;" bgcolor="#FF0000"><span style="font-size: large;">+</span></td>
<td style="text-align: center; background-color: #04c4fa;"><span style="font-size: large;">&#8211;</span></td>
<td style="text-align: center; background-color: #04c4fa;"><span style="font-size: large;">&#8211;</span></td>
</tr>
<tr>
<td style="text-align: center;"><span style="font-size: large;">Fase 4</span></td>
<td style="text-align: center; background-color: #04c4fa;"><span style="font-size: large;">&#8211;</span></td>
<td style="text-align: center; background-color: #04c4fa;"><span style="font-size: large;">&#8211;</span></td>
<td style="text-align: center; background-color: #04c4fa;"><span style="font-size: large;">&#8211;</span></td>
<td style="text-align: center;" bgcolor="#FF0000"><span style="font-size: large;">+</span></td>
</tr>
</tbody>
</table>
</div>
<p>Seguendo le <strong>fasi di alimentazioni A1-B1-A2-B2</strong> il rotore si sposterà in senso <strong>orario</strong>, invertendo la sequenza <strong>B2-A2-B1-A1</strong> il rotore si sposterà in senso <strong>antiorario</strong>. E&#8217; importante alimentare le bobine in modo sequenziale perché il rotore deve seguire in maniera lineare il campo elettromagnetico generato dalle bobine.</p>
<p>Naturalmente nei <strong>motori passo passo</strong> reali la sequenza delle 4 fasi fa girare l&#8217;albero di un solo passo (step). Il numero dei passi è una caratteristica costruttiva del motore, solitamente ha un valore di <strong>200 step/giro</strong>, ma ne esistono anche da <strong>20, 24, 48 e 400 step/giro</strong>. Il numero di step può essere espresso in gradi sessagesimali, ad esempio un motore da 7.5° equivale ad uno con 48 step/giro (360°/7.5°=48).<br />
Le 4 fasi di alimentazione delle bobine (considerando un ipotetico motore da <strong>1 step/giro</strong>), viene rappresentata dalla figura seguente:</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/05/FasiAlimentazione.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3652" src="https://logicaprogrammabile.it/wp-content/uploads/2013/05/FasiAlimentazione.png" alt="Fasi di alimentazione motore passo passo" width="710" height="231" srcset="https://logicaprogrammabile.it/wp-content/uploads/2013/05/FasiAlimentazione.png 710w, https://logicaprogrammabile.it/wp-content/uploads/2013/05/FasiAlimentazione-300x97.png 300w" sizes="auto, (max-width: 710px) 100vw, 710px" /></a></p>
<p>La sequenza di alimentazione è solitamente gestita da un integrato a logica programmabile mentre il compito di fornire l&#8217;energia è demandato ad un <strong>ponte ad H</strong>. Abbiamo affrontato l&#8217;utilizzo del ponte H in questo <a href="https://logicaprogrammabile.it/pilotare-motore-dc-tramite-ponte-h/">precedente articolo</a>. Per essere più precisi, avendo 4 fili, dobbiamo usare <strong>due ponti H</strong> uno che alimenta le <strong>bobine A1 e A2</strong> e l&#8217;altro che alimenta le <strong>bobine B1 e B2</strong>.</p>
<p>In questo tutorial ho usato come microcontrollore la <strong>Arduino Leonardo</strong> e come doppio ponte H il driver L298N prodotto da <a href="http://www.st.com/web/catalog/sense_power/FM142/CL851/SC1790/SS1555/PF63147" target="_blank">ST Microelectronics</a>. Il motore è un 48 passi/giro operante a 12Vdc, smontato da una vecchia stampante non più funzionante.</p>
<h4>Collegamento dei componenti</h4>
<p>Il <strong>circuito elettrico</strong> che permette di pilotare il motore è rappresentato nella figura seguente:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-5496" src="https://logicaprogrammabile.it/wp-content/uploads/2013/05/Schema_Motore_l298.png" alt="Motore passo passo l298" width="599" height="406" srcset="https://logicaprogrammabile.it/wp-content/uploads/2013/05/Schema_Motore_l298.png 599w, https://logicaprogrammabile.it/wp-content/uploads/2013/05/Schema_Motore_l298-300x203.png 300w" sizes="auto, (max-width: 599px) 100vw, 599px" /></p>
<p>riassumo i collegamenti tramite la tabella seguente</p>
<table style="width: 57px; height: 23px;">
<tbody>
<tr>
<td style="text-align: center;" nowrap="nowrap"><span style="font-size: small;"><strong>Motore Passo Passo</strong></span></td>
<td style="text-align: center;" nowrap="nowrap"><span style="font-size: small;"><strong>Integrato L298N</strong></span></td>
<td style="text-align: center;" nowrap="nowrap"><span style="font-size: small;"><strong>Arduino Leonardo</strong></span></td>
</tr>
<tr>
<td style="text-align: center;"><span style="font-size: small;"> </span></td>
<td style="text-align: center;"><span style="font-size: small;">1-8-15</span></td>
<td style="text-align: center;"><span style="font-size: small;">GND</span></td>
</tr>
<tr>
<td style="text-align: center;"><span style="font-size: small;"> </span></td>
<td style="text-align: center;"><span style="font-size: small;">6-9-11</span></td>
<td style="text-align: center;"><span style="font-size: small;">VCC 5Vdc</span></td>
</tr>
<tr>
<td style="text-align: center;"><span style="font-size: small;"> </span></td>
<td style="text-align: center;"><span style="font-size: small;">5</span></td>
<td style="text-align: center;"><span style="font-size: small;">5<br />
</span></td>
</tr>
<tr>
<td style="text-align: center;"><span style="font-size: small;"> </span></td>
<td style="text-align: center;"><span style="font-size: small;">7</span></td>
<td style="text-align: center;"><span style="font-size: small;">4<br />
</span></td>
</tr>
<tr>
<td style="text-align: center;"><span style="font-size: small;"> </span></td>
<td style="text-align: center;"><span style="font-size: small;">10</span></td>
<td style="text-align: center;"><span style="font-size: small;">3<br />
</span></td>
</tr>
<tr>
<td style="text-align: center;"><span style="font-size: small;"> </span></td>
<td style="text-align: center;"><span style="font-size: small;">12</span></td>
<td style="text-align: center;"><span style="font-size: small;">2<br />
</span></td>
</tr>
<tr>
<td style="text-align: center;"><span style="font-size: small;"> A1</span></td>
<td style="text-align: center;"><span style="font-size: small;">14</span></td>
<td style="text-align: center;"><span style="font-size: small;"> </span></td>
</tr>
<tr>
<td style="text-align: center;"><span style="font-size: small;"> A2</span></td>
<td style="text-align: center;"><span style="font-size: small;">13</span></td>
<td style="text-align: center;"><span style="font-size: small;"> </span></td>
</tr>
<tr>
<td style="text-align: center;"><span style="font-size: small;"> B1</span></td>
<td style="text-align: center;"><span style="font-size: small;">3</span></td>
<td style="text-align: center;"><span style="font-size: small;"> </span></td>
</tr>
<tr>
<td style="text-align: center;"><span style="font-size: small;"> B2</span></td>
<td style="text-align: center;"><span style="font-size: small;">2</span></td>
<td style="text-align: center;"><span style="font-size: small;"> </span></td>
</tr>
<tr>
<td style="text-align: center;"><span style="font-size: small;">Alimentazione Motore 12Vdc</span></td>
<td style="text-align: center;"><span style="font-size: small;">4</span></td>
<td style="text-align: center;"><span style="font-size: small;"> </span></td>
</tr>
</tbody>
</table>
<p>i <strong>diodi in contro fase</strong> servono per <strong>proteggere</strong> le uscite dell&#8217;integrato <strong>L298N</strong> da eventuali <strong>sovratensioni</strong> generate durante l&#8217;alimentazione delle bobine.</p>
<p>Il codice necessario per pilotare il motore rispecchia quanto detto precedentemente. In pratica è necessario alimentare in modo consecutivo le bobine rispettando le quatto fasi.</p>
<pre class="">void setup()
{
  //i pin 2-3-4-5 sono
  //configurati come uscite
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);

  //forzo le uscite a livello logico basso
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
}

void loop()
{
  //FASE 1
  //Alimento solo la prima bobina
  digitalWrite(2, HIGH);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  delay(10);

  //FASE 2
  //Alimento solo la seconda bobina
  digitalWrite(2, LOW);
  digitalWrite(3, HIGH);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  delay(10);

  //FASE 3
  //Alimento solo la terza bobina
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  digitalWrite(4, HIGH);
  digitalWrite(5, LOW);
  delay(10);

  //fase 4
  //Alimento solo la quarta bobina
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  digitalWrite(5, HIGH);
  delay(10);

}
</pre>
<p>Una volta caricato lo sketch, l&#8217;albero del motore inizierà a girare in senso orario. Per invertire la rotazione è sufficiente alimentare le bobine dalla fase 4 alla fase 1.</p>
<p>Cambiando il valore del<strong> delay()</strong> otterremmo una variazione di <strong>velocità nella rotazione</strong> del rotore.</p>
<p>Se avete delle stampanti vecchie potete subito passare alla pratica realizzando piccoli meccanismi e semplici robot. Volendo si possono collegare alla Leonardo 2 driver <strong>L298N</strong> per pilotare altrettanti motori passo passo, questo vi permette di poter controllare i due motori simultaneamente creando sistemi meccanici più complessi.</p>
<p>The post <a href="https://logicaprogrammabile.it/pilotare-motore-passo-passo-bipolare-driver-l298n/">L298N pilotare motore passo passo bipolare</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://logicaprogrammabile.it/pilotare-motore-passo-passo-bipolare-driver-l298n/feed/</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
			</item>
		<item>
		<title>Usare il potenziometro digitale MCP4131-103</title>
		<link>https://logicaprogrammabile.it/usare-potenziometro-digitale-mcp4131/</link>
					<comments>https://logicaprogrammabile.it/usare-potenziometro-digitale-mcp4131/#comments</comments>
		
		<dc:creator><![CDATA[Marco Lai]]></dc:creator>
		<pubDate>Mon, 18 Feb 2013 14:04:27 +0000</pubDate>
				<category><![CDATA[Elettronica]]></category>
		<category><![CDATA[Tutorial Arduino]]></category>
		<category><![CDATA[SPI]]></category>
		<guid isPermaLink="false">https://logicaprogrammabile.it/?p=3346</guid>

					<description><![CDATA[<p>Come usare Arduino per pilotare un potenziometro digitale Molte applicazioni richiedono la variazione continua di alcuni parametri, come ad esempio un alimentatore, un amplificatore audio, un termostato o un varilight che solitamente impiegano un potenziometro analogico e l&#8217;intervento manuale di una persona per effettuare queste...</p>
<p>The post <a href="https://logicaprogrammabile.it/usare-potenziometro-digitale-mcp4131/">Usare il potenziometro digitale MCP4131-103</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h3>Come usare Arduino per pilotare un potenziometro digitale</h3>
<p>Molte applicazioni richiedono la variazione continua di alcuni parametri, come ad esempio un alimentatore, un amplificatore audio, un termostato o un varilight che solitamente impiegano un potenziometro analogico e l&#8217;intervento manuale di una persona per effettuare queste variazioni.<br />
Possiamo digitalizzare questi sistemi impiegando lo stesso principio di regolazione basato su potenziometro ma invece di agire fisicamente sulla manopola di regolazione possiamo utilizzare dei comandi software per incrementare decrementare il valore resistivo del potenziometro.</p>
<p>Il componente che andremmo ad usare è l&#8217;integrato <a href="http://ww1.microchip.com/downloads/en/DeviceDoc/22060b.pdf" target="_blank">MCP4131-103 prodotto dalla Microchip</a>. E&#8217; un integrato a 8 pin che possiamo comandare tramite il protocollo seriale SPI.<br />
Al suo interno troviamo un potenziometro da 10Kohm.</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_BlockDiagram.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3349" alt="Diagramma interno MCP4131 103" src="https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_BlockDiagram.png" width="229" height="177" /></a></p>
<p><span id="more-3346"></span></p>
<p>Il potenziometro è composto da una rete resistiva composta da 128 elementi  il cui valore totale è, nel nostro modello, di 10Kohm. Tramite software possiamo spostare la posizione dello <strong>Wiper</strong>, che corrisponde al contatto strisciante di un potenziometro meccanico. Gli spostamenti dello <strong>Wiper</strong> vengono definiti <strong>steps</strong> e vanno dalla posizione <strong>00H (Wiper collegato al pin P0A)</strong> alla posizione <strong>80H(Wiper collegato al pin P0B)</strong>.<br />
Il potenziometro digitale <strong>MCP4131</strong> permette un massimo di <strong>129 steps</strong>.</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_InternalPot.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3372" alt="MCP4131 Internal potentiometer diagram" src="https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_InternalPot.png" width="286" height="456" srcset="https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_InternalPot.png 286w, https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_InternalPot-188x300.png 188w" sizes="auto, (max-width: 286px) 100vw, 286px" /></a></p>
<p>Il datasheet è comune a diversi potenziometri digitali quindi per poter capire quale siano i comandi corretti per pilotare il nostro modello dobbiamo esaminare le parti che ci interessano. La prima sezione riguarda le <strong>Caratteristiche del dispositivo</strong> (Device Features)</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_DeviceFeatures.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3351" alt="Caratteristiche del dispositivo MCP4131-103" src="https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_DeviceFeatures.png" width="732" height="259" srcset="https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_DeviceFeatures.png 732w, https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_DeviceFeatures-300x106.png 300w" sizes="auto, (max-width: 732px) 100vw, 732px" /></a></p>
<p>Da questa tabella deduciamo che il dispositivo ha un <span style="text-decoration: underline;">singolo potenziometro</span>, che i valori della posizione dello Wiper sono <strong>memorizzati in RAM</strong> (piuttosto che sulla EEPROM). L&#8217;interfaccia di comunicazione è <strong>SPI</strong>, i numeri di<strong> Steps sono 129</strong> e il range con cui possiamo alimentare l&#8217;integrato va da 1.8Vdc a 5.5Vdc.</p>
<p>L&#8217;<strong>MCP4131</strong> supporta comandi a<strong> 8 bit e a 16 bit</strong>. Il comando a 8 bit permette di incrementare o decrementare il valore dello Wiper di uno steps per volta mentre il comando a 16 bit permette di scrivere direttamente sulla RAM il valore della posizione dello Wiper.</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_CommandType.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3353" alt="MCP4131command format" src="https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_CommandType.png" width="569" height="236" srcset="https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_CommandType.png 569w, https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_CommandType-300x124.png 300w" sizes="auto, (max-width: 569px) 100vw, 569px" /></a></p>
<p>Nella figura il comando a 8 bit è composto da 2 bit di dati (che non vengono utilizzati), 2 bit di comando (incremento &#8211; decremento)  e 4 bit che definiscono l&#8217;indirizzo di memoria che vogliamo usare (indirizzo dello Wiper 00h).<br />
Nella figura del comando a 16 bit la prima parte è identica a quella a 8 bit con la differenza che nei 2 bit di comando possiamo specificare se scrivere o leggere dall&#8217;area di memoria del dispositivo, i restanti 8 bit compongono il Data Byte che ci permette di indicare direttamente il valore dello <strong>Wiper</strong>.</p>
<p>Gli indirizzi di memoria disponibili sono i seguenti:</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_MemoryMAP.gif"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3359" alt="MCP4131 Memory Map" src="https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_MemoryMAP.gif" width="364" height="204" /></a>nel nostro caso <strong>utilizzeremmo l&#8217;indirizzo 00h</strong>, che corrisponde all&#8217;unico Wiper disponibile all&#8217;interno del nostro chip.</p>
<p>I bit di commando invece sono i seguenti:</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_Command_Bit.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3360" alt="MCP4131 Command Bits" src="https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_Command_Bit.png" width="364" height="187" srcset="https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_Command_Bit.png 364w, https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_Command_Bit-300x154.png 300w" sizes="auto, (max-width: 364px) 100vw, 364px" /></a></p>
<p>Passando alla pratica, se volessi inviare un comando di incremento al Wiper dell&#8217;MCP4131, usando la modalità a 8bit, invierei tramite SPI il valore decimale 4</p>
<p style="text-align: center;"><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/02/Comando_4dec.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3367" alt="Arduino Leonardo MCP4131" src="https://logicaprogrammabile.it/wp-content/uploads/2013/02/Comando_4dec.png" width="461" height="234" srcset="https://logicaprogrammabile.it/wp-content/uploads/2013/02/Comando_4dec.png 461w, https://logicaprogrammabile.it/wp-content/uploads/2013/02/Comando_4dec-300x152.png 300w" sizes="auto, (max-width: 461px) 100vw, 461px" /></a></p>
<p style="text-align: left;">Per decrementare il valore corrente dello Wiper bisogna spedire via SPI il valore decimale 8:</p>
<p style="text-align: center;"><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/02/Comando_8dec.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3368" alt="Arduino Leonardo MCP4131" src="https://logicaprogrammabile.it/wp-content/uploads/2013/02/Comando_8dec.png" width="461" height="234" srcset="https://logicaprogrammabile.it/wp-content/uploads/2013/02/Comando_8dec.png 461w, https://logicaprogrammabile.it/wp-content/uploads/2013/02/Comando_8dec-300x152.png 300w" sizes="auto, (max-width: 461px) 100vw, 461px" /></a></p>
<p style="text-align: left;">Se volessi spostare il Wiper al centro della sua corsa, utilizzerei la modalità a 16 bit, inviando per primo il dato contenente l&#8217;indirizzo di memoria che vogliamo usare e il comando di scrittura</p>
<p style="text-align: center;"><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/02/Comando_0dec.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3369" alt="Leonardo mcp4131-103" src="https://logicaprogrammabile.it/wp-content/uploads/2013/02/Comando_0dec.png" width="461" height="234" srcset="https://logicaprogrammabile.it/wp-content/uploads/2013/02/Comando_0dec.png 461w, https://logicaprogrammabile.it/wp-content/uploads/2013/02/Comando_0dec-300x152.png 300w" sizes="auto, (max-width: 461px) 100vw, 461px" /></a></p>
<p style="text-align: left;">Seguito dal valore della posizione dove vogliamo spostare lo Wiper, in questo esempio il valore 64 decimale (128/2) corrisponde a metà corsa.</p>
<p style="text-align: center;"><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/02/Dati.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3370" alt="Leonardo" src="https://logicaprogrammabile.it/wp-content/uploads/2013/02/Dati.png" width="461" height="178" srcset="https://logicaprogrammabile.it/wp-content/uploads/2013/02/Dati.png 461w, https://logicaprogrammabile.it/wp-content/uploads/2013/02/Dati-300x115.png 300w" sizes="auto, (max-width: 461px) 100vw, 461px" /></a></p>
<p>Ora che conosciamo come utilizzare il chip possiamo passare alla pratica collegando la porta SPI dell&#8217;Arduino all&#8217;MCP4131. Nel mio caso ho utilizzato un <strong>Arduino Leonardo</strong> (<span style="text-decoration: underline;">la porta SPI è disponibile sui pin dell&#8217;header ICSP</span>). Lo schema è il seguente:</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/02/Arduino_Leonardo_MCP4131.gif"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3374" alt="Arduino Leonardo collegamento MCP4131-103" src="https://logicaprogrammabile.it/wp-content/uploads/2013/02/Arduino_Leonardo_MCP4131.gif" width="299" height="260" /></a></p>
<p>L&#8217;uscita <strong>W</strong> è collegata all&#8217;ingresso analogico<strong> A0</strong> della Leonardo, in questo modo posso misurare il valore di tensione disponibile su tale piedino.<br />
Il <strong>Pin B</strong> dell&#8217;MCP4131, corrispondente alla posizione 00H <strong>è collegato a massa</strong> mentre il<strong> pin A</strong> corrispondente alla posizione 80H è <strong>collegato alla 5Vdc</strong>.<br />
Il codice seguente posiziona lo Wiper nella posizione 00H, ottenendo cosi una tensione pressochè nulla sul <strong>pin W</strong> (poiche internamente il pin W è collegato con il pin B).</p>
<p>[c]<br />
#include &lt;SPI.h&gt;</p>
<p>void setup()<br />
{<br />
  //Definisco il pin come uscita<br />
  //il pin 2 viene usato per selezionare il<br />
  //chip all&#8217;interno di un collegamento SPI<br />
  pinMode (2, OUTPUT);</p>
<p>  //Inizializzo la libreria SPI<br />
  SPI.begin();</p>
<p>  //Inizializzo la porta seriale<br />
  Serial.begin(9600);</p>
<p>  //metto alta la linea CS per<br />
  //deselezionare il chip MCP4131<br />
  digitalWrite(2, HIGH);</p>
<p>}</p>
<p>void loop()<br />
{<br />
  //Inizializzo la posizione dello Wiper<br />
  byte Posizione = 0;</p>
<p>  //Per selezionare l&#8217;MCP4131<br />
  //metto basso la linea CS del<br />
  //potenziometro digitale<br />
  digitalWrite(2, LOW);</p>
<p>  //Invio il primo byte per eseguire una scrittura<br />
  //sul registro Wiper<br />
  SPI.transfer(0);<br />
  //Invio il valore della posizione dello Wiper<br />
  //valori da 00H a 80H (0-128 in decimale)<br />
  SPI.transfer(Posizione);</p>
<p>  //metto alta la linea CS per<br />
  //deselezionare il chip MCP4131<br />
  digitalWrite(2, HIGH);</p>
<p>  //eseguo la lettura sul pin analogico A0<br />
  //in questo pin è collegato il pin Wiper<br />
  //del potenziometro digitale<br />
  int Data = analogRead(0);</p>
<p>  //spedisco il dato letto al serial Monitor<br />
  //Valori da 0 a 1023<br />
  Serial.println(Data);</p>
<p>  //ritardo di mezzo secondo<br />
  delay(500);<br />
}<br />
[/c]</p>
<p>Aprendo il serial monitor otterremmo dei valori prossimi allo zero poichè la tensione in ingresso del pin A0 sarà nulla. Questo è ciò che avviene all&#8217;interno dell&#8217;MCP4131:</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_Wip_Gnd.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3381" alt="Wiper to GND" src="https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_Wip_Gnd.png" width="286" height="456" srcset="https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_Wip_Gnd.png 286w, https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_Wip_Gnd-188x300.png 188w" sizes="auto, (max-width: 286px) 100vw, 286px" /></a></p>
<p>Per posizionare lo Wiper verso il<strong> pin A</strong>, collegato alla 5Vdc, dobbiamo scrivere sull&#8217;indirizzo 00H il valore 80H, come descritto nel codice seguente:</p>
<p>[c]<br />
#include &lt;SPI.h&gt;</p>
<p>void setup()<br />
{<br />
  //Definisco il pin come uscita<br />
  //il pin 2 viene usato per selezionare il<br />
  //chip all&#8217;interno di un collegamento SPI<br />
  pinMode (2, OUTPUT);</p>
<p>  //Inizializzo la libreria SPI<br />
  SPI.begin();</p>
<p>  //Inizializzo la porta seriale<br />
  Serial.begin(9600);</p>
<p>  //metto alta la linea CS per<br />
  //deselezionare il chip MCP4131<br />
  digitalWrite(2, HIGH);</p>
<p>}</p>
<p>void loop()<br />
{<br />
  //Inizializzo la posizione dello Wiper<br />
  byte Posizione = 128;</p>
<p>  //Per selezionare l&#8217;MCP4131<br />
  //metto basso la linea CS del<br />
  //potenziometro digitale<br />
  digitalWrite(2, LOW);</p>
<p>  //Invio il primo byte per eseguire una scrittura<br />
  //sul registro Wiper<br />
  SPI.transfer(0);<br />
  //Invio il valore della posizione dello Wiper<br />
  //valori da 00H a 80H (0-128 in decimale)<br />
  SPI.transfer(Posizione);</p>
<p>  //metto alta la linea CS per<br />
  //deselezionare il chip MCP4131<br />
  digitalWrite(2, HIGH);</p>
<p>  //eseguo la lettura sul pin analogico A0<br />
  //in questo pin è collegato il pin Wiper<br />
  //del potenziometro digitale<br />
  int Data = analogRead(0);</p>
<p>  //spedisco il dato letto al serial Monitor<br />
  //Valori da 0 a 1023<br />
  Serial.println(Data);</p>
<p>  //ritardo di mezzo secondo<br />
  delay(500);<br />
}<br />
[/c]</p>
<p>In questo caso aprendo il <strong>serial monitor</strong> leggeremmo dei valori prossimi a 1023 in quanto sul pin analogico A0 sarà presente la tensione di 5Vdc.<br />
Internamente otterremo questo risultato:</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_Wip_Vcc.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3383" alt="wiper to vcc" src="https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_Wip_Vcc.png" width="286" height="456" srcset="https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_Wip_Vcc.png 286w, https://logicaprogrammabile.it/wp-content/uploads/2013/02/MCP4131_Wip_Vcc-188x300.png 188w" sizes="auto, (max-width: 286px) 100vw, 286px" /></a></p>
<p>Di conseguenza per avere tutti gli altri valori intermedi potremmo cambiare il valore della variabile Posizione assegnandole <strong>valori tra 0 e 128</strong>.</p>
<p>The post <a href="https://logicaprogrammabile.it/usare-potenziometro-digitale-mcp4131/">Usare il potenziometro digitale MCP4131-103</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://logicaprogrammabile.it/usare-potenziometro-digitale-mcp4131/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Promemoria alternativo con Arduino e RTC</title>
		<link>https://logicaprogrammabile.it/promemoria-arduino-rtc/</link>
					<comments>https://logicaprogrammabile.it/promemoria-arduino-rtc/#respond</comments>
		
		<dc:creator><![CDATA[Marco Lai]]></dc:creator>
		<pubDate>Tue, 03 Apr 2012 08:48:33 +0000</pubDate>
				<category><![CDATA[Elettronica]]></category>
		<category><![CDATA[Programmazione]]></category>
		<category><![CDATA[Tutorial Arduino]]></category>
		<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Gadget]]></category>
		<category><![CDATA[Promemoria]]></category>
		<category><![CDATA[RTC]]></category>
		<guid isPermaLink="false">https://logicaprogrammabile.it/?p=2650</guid>

					<description><![CDATA[<p>Come realizzare un simpatico gadget per ricordarci delle date importanti Se anche tu hai difficoltà a ricordare le date degli appuntamenti e sei un tipo creativo e non ti accontenti dei classici promemoria via cellulare, tablet o computer, ma vuoi realizzare qualcosa di insolito, puoi...</p>
<p>The post <a href="https://logicaprogrammabile.it/promemoria-arduino-rtc/">Promemoria alternativo con Arduino e RTC</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h3>Come realizzare un simpatico gadget per ricordarci delle date importanti</h3>
<p>Se anche tu hai difficoltà a ricordare le date degli appuntamenti e sei un tipo creativo e non ti accontenti dei classici promemoria via cellulare, tablet o computer, ma vuoi realizzare qualcosa di insolito, puoi sfruttare la tua passione per l&#8217;elettronica e la tua voglia di costruire per realizzare questo progetto di promemoria con Arduino.</p>
<p>Avendo già le basi per poter<a title="Usare il modulo RTC DS1307 con Arduino" href="https://logicaprogrammabile.it/usare-modulo-rtc-ds1307-arduino/"> lavorare con l&#8217;integrato RTC DS1307</a> puoi sfruttare la ram non volatile di questo chip per memorizzare circa 18 date e permettere, ad Arduino, di avvisarti tramite display, led rgb, twitter o quello che ti viene in mente!!</p>
<p>L&#8217;idea è quella di utilizzare l&#8217;RTC per memorizzare il dato di tempo e sfruttare i 56 byte di flash ram aggiuntive per memorizzare le date degli avvenimenti. Arduino ha il compito di comparare le date e di agire di conseguenza pilotando le uscite digitali.</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-2681" title="PromemDate" src="https://logicaprogrammabile.it/wp-content/uploads/2012/04/PromemDate.gif" alt="" width="617" height="245" srcset="https://logicaprogrammabile.it/wp-content/uploads/2012/04/PromemDate.gif 617w, https://logicaprogrammabile.it/wp-content/uploads/2012/04/PromemDate-300x119.gif 300w" sizes="auto, (max-width: 617px) 100vw, 617px" /></p>
<p>Parto dal presupposto che la data e l&#8217;ora del RTC sia già stata impostata come spiegato nel precedente tutorial.<span id="more-2650"></span><br />
Per memorizzare le date degli avvenimenti possiamo usare un array di 3 byte (Giorno Mese ed Anno), il codice è il seguente:</p>
<p>[c]<br />
//inserisco la libreria per il bus I2C<br />
#include &lt;Wire.h&gt;</p>
<p>//Variabile per memorizzare l&#8217;indirizzo della ram del DS1307<br />
byte IndRam = 0x00;<br />
//array per la data (G M A)<br />
byte Data[3];</p>
<p>void setup()<br />
{<br />
  //init bus I2C<br />
  Wire.begin();<br />
  //init seriale<br />
  Serial.begin(9600);</p>
<p>  //imposto l&#8217;indirizzo iniziale della user ram<br />
  IndRam = 0x08;</p>
<p>  //avvio la comunicazione con il DS1307<br />
  //indirizzo 0x68<br />
  Wire.beginTransmission(0x68);<br />
  //specifico l&#8217;indirizzo a cui voglio accedere<br />
  Wire.write(IndRam);</p>
<p>  //imposto la data 25/04/12 in esadecimale<br />
  Data[0] = 0x19;  //giorno 25<br />
  Data[1] = 0x04;  //mese   04<br />
  Data[2] = 0x0C;  //anno   12</p>
<p>  //scrivo i 3 byte negli indirizzi 0x08 0x09 0x0A<br />
  Wire.write(Data,3);</p>
<p>  //chiudo la comunicazione<br />
  Wire.endTransmission();</p>
<p>}</p>
<p>void loop()<br />
{}</p>
<p>[/c]</p>
<p>Nel datasheet del <strong>DS1307</strong> la ram aggiuntiva inizia all&#8217;indirizzo <strong>0x08</strong> e finisce all&#8217;indirizzo <strong>0x3F</strong> e, sapendo che per memorizzare una data servono 3 byte (G M A), devi sommare alla variabile <strong>IndRam</strong> valori multipli di 3.<br />
Ad esempio per memorizzare la seconda data <strong>IndRam</strong> varrà <strong>0x08 + 3</strong> per la terza data<strong> 0x08+6</strong> e cosi via fino a <strong>0x08+51</strong>, ottenendo così 18 date memorizzabili.</p>
<table style="width: 300px;" border="0" cellspacing="3" cellpadding="3" align="center">
<tbody>
<tr>
<td>Locazione</td>
<td>Valore variabile IndRam</td>
</tr>
<tr>
<td>1</td>
<td>0x08 (8)</td>
</tr>
<tr>
<td>2</td>
<td>0x0B (11)</td>
</tr>
<tr>
<td>3</td>
<td>0x0E (14)</td>
</tr>
<tr>
<td>4</td>
<td>0x11 (17)</td>
</tr>
<tr>
<td>5</td>
<td>0x14 (20)</td>
</tr>
<tr>
<td>6</td>
<td>0x17 (23)</td>
</tr>
<tr>
<td>7</td>
<td>0x1A (26)</td>
</tr>
<tr>
<td>8</td>
<td>0x1D (29)</td>
</tr>
<tr>
<td>9</td>
<td>0x20 (32)</td>
</tr>
<tr>
<td>10</td>
<td>0x23 (35)</td>
</tr>
<tr>
<td>11</td>
<td>0x26 (38)</td>
</tr>
<tr>
<td>12</td>
<td>0x29 (41)</td>
</tr>
<tr>
<td>13</td>
<td>0x2C (44)</td>
</tr>
<tr>
<td>14</td>
<td>0x2F (47)</td>
</tr>
<tr>
<td>15</td>
<td>0x32 (50)</td>
</tr>
<tr>
<td>16</td>
<td>0x35 (53)</td>
</tr>
<tr>
<td>17</td>
<td>0x38 (56)</td>
</tr>
<tr>
<td>18</td>
<td>0x3B (59)</td>
</tr>
</tbody>
</table>
<p>Una volta memorizzate le date che ci interessano, è necessario scrivere del codice che confronti questi valori con quelli dell&#8217;RTC e di conseguenza eseguire delle operazioni di output.</p>
<p>Per primo recupero il giorno, mese e anno dell&#8217;RTC a partire dall&#8217;indirizzo  0x04</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-2689" title="RamDS1307" src="https://logicaprogrammabile.it/wp-content/uploads/2012/04/RamDS1307.gif" alt="RAM ds1307" width="263" height="269" /></p>
<p>e poi recupero i dati della user ram per eseguire il confronto quindi:</p>
<p>[c]</p>
<p>void loop()<br />
{<br />
  IndRam = 0x04;</p>
<p>  //setto l&#8217;indirizzo da ddove iniziare<br />
  //a leggere<br />
  Wire.beginTransmission(0x68);<br />
  Wire.write(IndRam);<br />
  Wire.endTransmission();</p>
<p>  //recupero 3 byte G M A<br />
  Wire.requestFrom(0x68, 3);<br />
  byte Giorno = Wire.read();<br />
  byte Mese = Wire.read();<br />
  byte Anno = Wire.read();</p>
<p>  Serial.print(Giorno, DEC);<br />
  Serial.print(&quot;/&quot;);<br />
  Serial.print(Mese,DEC);<br />
  Serial.print(&quot;/&quot;);<br />
  Serial.println(Anno, DEC);</p>
<p>  //recupero tutte le date memorizzate nella user ram<br />
  //e le confronto con quella attuale dell&#8217;RTC</p>
<p>  for( byte Ciclo = 0; Ciclo &lt; 54; Ciclo += 3)<br />
  {<br />
    IndRam = 0x08 + Ciclo;<br />
    //Serial.println(IndRam, HEX);</p>
<p>    Wire.beginTransmission(0x68);<br />
    Wire.write(IndRam);<br />
    Wire.endTransmission();</p>
<p>    Wire.requestFrom(0x68, 3);<br />
    byte memGiorno = Wire.read();<br />
    byte memMese = Wire.read();<br />
    byte memAnno = Wire.read();</p>
<p>    //confronta i dati</p>
<p>    if(Giorno == memGiorno &amp;&amp; Mese == memMese &amp;&amp; Anno == memAnno)<br />
    {<br />
      //trovata data<br />
      //fai qualcosa<br />
      Serial.println(&quot;Data OK&quot;);<br />
    }</p>
<p>    delay(10);<br />
  }</p>
<p>  delay(1000);<br />
}<br />
[/c]</p>
<p>Il codice controlla ciclicamente se la data impostata nell&#8217;RTC è presente nella user ram in caso affermativo viene printata la stringa <strong>Data OK</strong>.<br />
Il codice ha un problema, non tiene conto dell&#8217;andamento temporale, infatti viene fatto un controllo di valori che non permette di verificare se una data è precedente o successiva a quella impostata.<br />
Il compito del codice dovrebbe essere quello di avvisarci degli avvenimenti futuri mentre dovrebbe escludere quelli passati.</p>
<p>Per poter confrontare le date tra di loro mi sono avvalso della libreria <strong>Time</strong> che tra le varie funzioni permette di restituire il numero di secondi trascorsi tra il 1 gennaio 1970 e una data definita.<br />
Ottenendo un numero progressivo posso confrontare due date e capirne l&#8217;ordine temporale.</p>
<h4>Installare e utilizzare la libreria Time</h4>
<p>Sul sito ufficiale di Arduino, seguendo <a href="http://www.arduino.cc/playground/Code/Time" target="_blank">questo link</a> possiamo scaricare la libreria. Scompattiamo il file zip nella cartella Arduino 1.0-&gt;libraries. Questa operazione produrrà tre cartelle una con nome <strong>Time</strong>, <strong>DS1307RTC</strong> e <strong>TimeAlarms</strong>. <span style="text-decoration: underline;">Riavviamo l&#8217;IDE per aggiornare le lista delle librerie e degli esempi</span>.</p>
<p>Per utilizzare la libreria nello sketch del progetto che stiamo sviluppando, possiamo inserire a mano la clausola</p>
<p>[c]#include &lt;Time.h&gt;[/c]</p>
<p>oppure dal menu dell&#8217;ide eseguiamo <strong>Sketch-&gt;Import Library-&gt;Time</strong></p>
<p>Per ottenere i secondi trascorsi dal 1 gennaio 1970 è disponibile la funzione<strong> now()</strong>, ma prima, giustamente bisogna settare la data di riferimento, per farlo si utilizza la funzione <strong>setTime(ora, minuti, secondi, giorno, mese, anno)</strong> quindi il codice precedente viene modificato così:</p>
<p>[c]<br />
#include &lt;Wire.h&gt;<br />
//includo la libreria Time<br />
#include &lt;Time.h&gt;</p>
<p>byte IndRam = 0x00;<br />
byte Data[3];</p>
<p>byte val = 0x00;</p>
<p>//queste variabili servono per memorizzare<br />
//la data in secondi trascorsi dal 1 gen 1970<br />
unsigned long UnixData = 0;<br />
unsigned long memUnixData = 0;</p>
<p>void setup()<br />
{<br />
  Wire.begin();<br />
  Serial.begin(9600);</p>
<p>  //imposto l&#8217;indirizzo iniziale della user ram<br />
  IndRam = 0x08;</p>
<p>  //carico una data da ricordare nei primi<br />
  //3 byte della user ram<br />
  Wire.beginTransmission(0x68);<br />
  Wire.write(IndRam);<br />
  Data[0] = 0x05; //giorno  05<br />
  Data[1] = 0x04; //mese    04<br />
  Data[2] = 0x0C;  //anno   12<br />
  Wire.write(Data,3);<br />
  Wire.endTransmission();</p>
<p>  delay(100);</p>
<p>  //verifico la data appena impostata<br />
  //nella user ram<br />
  Wire.beginTransmission(0x68);<br />
  Wire.write(IndRam);<br />
  Wire.endTransmission();</p>
<p>  Wire.requestFrom(0x68, 3);<br />
  byte data = Wire.read();<br />
  Serial.print(data);<br />
  Serial.print(&quot;/&quot;);<br />
  data = Wire.read();<br />
  Serial.print(data);<br />
  Serial.print(&quot;/&quot;);<br />
  data = Wire.read();<br />
  Serial.print(data);<br />
  Serial.println(&quot;/&quot;);</p>
<p>  delay(100);<br />
}</p>
<p>void loop()<br />
{<br />
  //setto l&#8217;indirizzo per accedere alla data<br />
  //impostata nell&#8217;RTC<br />
  IndRam = 0x04;<br />
  //setto l&#8217;indirizzo da dove iniziare<br />
  //a leggere<br />
  Wire.beginTransmission(0x68);<br />
  Wire.write(IndRam);<br />
  Wire.endTransmission();</p>
<p>  //recupero 3 byte G M A<br />
  Wire.requestFrom(0x68, 3);<br />
  byte Giorno = Wire.read();<br />
  byte Mese = Wire.read();<br />
  byte Anno = Wire.read();</p>
<p>  //visualizzo la data dell&#8217;RTC<br />
  Serial.print(Giorno, DEC);<br />
  Serial.print(&quot;/&quot;);<br />
  Serial.print(Mese,DEC);<br />
  Serial.print(&quot;/&quot;);<br />
  Serial.println(Anno, DEC);</p>
<p>  //setto la libreria Time con la data dell&#8217;RTC<br />
  setTime(0,0,0, Giorno, Mese, (Anno + 2000));<br />
  //Recupero i secondi trascorsi tra la data 1 Gen 1970<br />
  //e la data dell&#8217;RTC<br />
  UnixData = now();<br />
  //Visualizzo i secondi trascorsi sul Serial Monitor<br />
  Serial.println(now());</p>
<p>  //recupero tutte le date memorizzate nella ram<br />
  //e le confronto con quella attuale dell&#8217;RTC<br />
  //trasformandole in secondi in modo da poter confrontare<br />
  //le date</p>
<p>  for( byte Ciclo = 0; Ciclo &lt; 54; Ciclo += 3)<br />
  {<br />
    //imposto il primo indirizzo della user ram<br />
    //e poi proseguo ciclicamente incrementando di<br />
    //3 posizioni<br />
    IndRam = 0x08 + Ciclo;<br />
    //Serial.println(IndRam, HEX);</p>
<p>    //setto l&#8217;indirizzo<br />
    Wire.beginTransmission(0x68);<br />
    Wire.write(IndRam);<br />
    Wire.endTransmission();</p>
<p>    //recupero i tre byte G M A<br />
    //dalla user RAM<br />
    Wire.requestFrom(0x68, 3);<br />
    byte memGiorno = Wire.read();<br />
    byte memMese = Wire.read();<br />
    byte memAnno = Wire.read();</p>
<p>    //imposto la libreria Time con la data dela user RAM<br />
    // per convertirla in secondi<br />
    setTime(0,0,0, memGiorno, memMese, (memAnno + 2000));<br />
    memUnixData = now();<br />
    //Serial.println(now());</p>
<p>    //confronto la data in secondi dell&#8217;RTC con la data<br />
    //appena recuperata dalla user ram</p>
<p>    if(UnixData == memUnixData)<br />
    {<br />
      //trovata data<br />
      //fai qualcosa<br />
      Serial.println(&quot;TROVATA!!!&quot;);<br />
    }</p>
<p>    delay(10);<br />
  }</p>
<p>  delay(1000);<br />
}<br />
[/c]</p>
<p>Il codice ha lo stesso comportamento di quello iniziale ma adesso c&#8217;è la possibilità di eseguire il confronto numerico grazie alla conversione in secondi. Ad esempio per escludere tutte le date passate possiamo fare questa semplice modifica</p>
<p>[c]</p>
<p>   //escludi le date passate</p>
<p>   if(UnixData &gt;= memUnixData)<br />
   {<br />
     //trovata data<br />
     //fai qualcosa<br />
     Serial.println(&quot;TROVATA!!!&quot;);<br />
   }</p>
<p>[/c]</p>
<p>oppure eseguire del codice per avvisarci una settimana in anticipo:</p>
<p>[c]  //avvisami una settimana prima<br />
  //settimana in secondi 60*60*24*7 = 604800</p>
<p>  if((memUnixData &#8211; UnixData) &lt;= 604800)<br />
  {<br />
    //trovata data<br />
    //fai qualcosa<br />
    Serial.println(&quot;TROVATA!!!&quot;);<br />
  }<br />
[/c]</p>
<p>Avendo il modo di eseguire un confronto numerico tra le date ci offre la possibilità di realizzare ulteriori funzioni, come ad esempio sketch che gestiscono l&#8217;Arduino a seconda delle date impostate nella user ram.</p>
<p>Per le operazioni da eseguire quando viene trovata una data possiamo eseguire tutte le tipiche funzioni di output che può gestire Arduino.</p>
<p>&nbsp;</p>
<p>[c]<br />
   //escludi le date passate<br />
   if(UnixData &gt;= memUnixData)<br />
   {<br />
     //trovata data<br />
     //fai qualcosa<br />
     Serial.println(&quot;TROVATA!!!&quot;);<br />
   }<br />
[/c]</p>
<p>The post <a href="https://logicaprogrammabile.it/promemoria-arduino-rtc/">Promemoria alternativo con Arduino e RTC</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://logicaprogrammabile.it/promemoria-arduino-rtc/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Netduino e irrigazione automatica fai da te (Teoria)</title>
		<link>https://logicaprogrammabile.it/irrigazione-automatica-netduino/</link>
					<comments>https://logicaprogrammabile.it/irrigazione-automatica-netduino/#comments</comments>
		
		<dc:creator><![CDATA[Marco Lai]]></dc:creator>
		<pubDate>Fri, 13 May 2011 06:33:56 +0000</pubDate>
				<category><![CDATA[Elettronica]]></category>
		<category><![CDATA[Notizie]]></category>
		<category><![CDATA[.Net micro framework]]></category>
		<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Autocostruzione]]></category>
		<category><![CDATA[Automatismo]]></category>
		<category><![CDATA[Elettrovalvola]]></category>
		<category><![CDATA[Fai da te]]></category>
		<category><![CDATA[Irrrigazione]]></category>
		<category><![CDATA[Netduino]]></category>
		<guid isPermaLink="false">https://logicaprogrammabile.it/?p=1135</guid>

					<description><![CDATA[<p>Come realizzare centralina di micro irrigazione Mi è sempre piaciuta l&#8217;idea di un orto/giardino automatizzato, magari con Netduino, capace di sfruttare l&#8217;irrigazione in modo coscienzioso e senza sprechi d&#8217;acqua. Penso sia uno di quei progetti molto ricercati per la sua evidente utilità pratica, e anche...</p>
<p>The post <a href="https://logicaprogrammabile.it/irrigazione-automatica-netduino/">Netduino e irrigazione automatica fai da te (Teoria)</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1>Come realizzare centralina di micro irrigazione</h1>
<p>Mi è sempre piaciuta l&#8217;idea di un orto/giardino automatizzato, magari con <strong>Netduino</strong>, capace di sfruttare l&#8217;irrigazione in modo coscienzioso e senza sprechi d&#8217;acqua.<br />
Penso sia uno di quei progetti molto ricercati per la sua evidente utilità pratica, e anche perché la coltivazione e la cura di piante è un istinto innato che ci avvicina alla natura e ci fa sentire bene!</p>
<p>Abito in un piccolo paese dove ogni famiglia possiede un piccolo orto per la coltivazione di verdure e frutti. La tecnica di irrigazione principale è quella a solco (scorrimento), decisamente svantaggiosa e poco efficace per l&#8217;eccessivo spreco d&#8217;acqua.<br />
Fortunatamente oggi ci sono molte tecnologie efficienti che permettono l&#8217;impiego di sistemi programmabili per la gestione delle attività di irrigazione.</p>
<p>Anche io ho voluto sviluppare il mio sistema a microcontrollore per gestire le fasi di irrigazione di un piccolo orto.<br />
Per la realizzazione di questo sistema bisogna avere un minimo di esperienza nella coltivazione di piante ed essere consapevoli che ci dovremmo sporcare le mani!!</p>
<p>La tecnica di irrigazione migliore per questo progetto si basa sulla microirrigazione a goccia. E&#8217; necessario quindi procurarci tutto il materiale per l&#8217;impianto. Le mie informazioni progettuali sono da considerare di carattere generale, dato che il sistema è influenzato da vari parametri come, la tipologia del terreno (inclinazione, consistenza, composizione, esposizione agli agenti atmosferici) il tipo e la quantità di piantine da coltivare.<span id="more-1135"></span>La figura seguente rappresenta un tipico impianto a goccia automatizzato:</p>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="aligncenter wp-image-1144 size-full" title="OrtoAutomatizzato" src="https://logicaprogrammabile.it/wp-content/uploads/2011/05/OrtoAutomatizzato1.gif" alt="Schema di principio orto automatizzato" width="621" height="427" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/05/OrtoAutomatizzato1.gif 621w, https://logicaprogrammabile.it/wp-content/uploads/2011/05/OrtoAutomatizzato1-300x206.gif 300w" sizes="auto, (max-width: 621px) 100vw, 621px" /></p>
<p>La cisterna contiene l&#8217;acqua necessaria ad irrigare le piante, le sue dimensioni variano a seconda della dimensione dell&#8217;orto, un valore sufficiente per una autonomia di 2-3 settimane potrebbe essere di 1000 litri.<br />
Subito dopo troviamo il filtro, questo elemento è essenziale per un impianto di <strong>microirrigazione </strong>in quanto blocca le impurità dell&#8217;acqua che col tempo potrebbero otturare i gocciolatori.<br />
L&#8217;elettrovalvola è un rubinetto elettronico che permette, tramite la centralina elettronica, di gestire tutte le fasi d&#8217;irrigazione. La centralina riceve input dai sensori di umidità, temperatura e luminosità, in questo modo possiamo sviluppare algoritmi che gestiscono l&#8217;irrigazione in funzione dei parametri ambientali.</p>
<p>Il tubo di mandata principale permette di alimentare i vari rami dell&#8217;impianto, ogni ramo (ala gocciolante) è sezionabile tramite un minirubinetto, questo permette di effettuare operazioni di manutenzione anche durante l&#8217;irrigazione.<br />
L&#8217;ala gocciolante è composta da un tubo, solitamente da 16mm, dove sono collocati i gocciolatori. Ogni gocciolatore irriga una singola pianta.</p>
<p>La realizzazione dell&#8217;impianto dipende dalla dimensione del terreno a disposizione e dal numero e tipo di piante da coltivare. Secondo la mia esperienza vi posso dire che per il fabbisogno di una famiglia di 5-6 persone potete coltivare i seguenti prodotti</p>
<ul>
<li>20 piante Pomodoro</li>
<li>10 piante Melanzane</li>
<li>10 piante Peperoni</li>
<li>20 piante Fagiolini</li>
<li>10 piante Cetrioli</li>
<li>5 piante Zucchine</li>
<li>20 piante Lattuga</li>
</ul>
<p>naturalmente ognuno può aumentare o diminuire queste quantità a seconda delle preferenze e dei gusti personali.<br />
Per quanto riguarda la distanza tra gocciolatori possiamo dimensionare in questo modo</p>
<ul>
<li>40-50 cm per Pomodori, Melanzane, Peperoni, Fagiolini e Cetrioli</li>
<li>60-70 cm per le Zucchine</li>
<li>15-20 cm per le Lattughe</li>
</ul>
<p>Mentre la distanza tra un <strong>ala gocciolante</strong> e la successiva può variare da 40-50 cm a  80-100cm a seconda dello spazio a disposizione, e della comodità che vogliamo avere per passare tra i filari.</p>
<p>Dopo l&#8217;assemblaggio dell&#8217;impianto è necessario verificare che tutti i gocciolatori funzionino a dovere e che non ci siano perdite d&#8217;acqua dai raccordi di connessione.</p>
<p>La parte che ora bisogna studiare, riguarda la centralina elettronica. Certamente sul mercato esistono vari modelli con prezzi anche di poche decine di euro, che potrebbero farci abbandonare l&#8217;idea dell&#8217;autocostruzione, ma il nostro scopo è quello di sperimentare e imparare nuovi concetti per poi applicarli in altri ambiti o per accrescere il nostro bagaglio culturale.</p>
<p>Apro una piccola parentesi sull&#8217;elettrovalvola: a parte le varie dimensioni e capacità idriche, esistono modelli a 24Vac e a 9Vcc. Volendo creare un impianto autonomo è meglio utilizzare il modello a 9Vcc in modo da eliminare qualsiasi trasformatore. Il costo delle elettrovalvole in continua è purtroppo superiore a quelle in ca (circa 30€).</p>
<p>Il circuito elettronico deve acquisire come input i dati dai sensori e pilotare l&#8217;elettrovalvola per un tempo che può essere fisso o variabile a seconda del software che andremmo a sviluppare.<br />
Come microcontrollore possiamo optare per diverse soluzioni come <strong>Netduino </strong>piuttosto che <strong>Arduino</strong> o <strong>Picmicro</strong>. Certamente un fattore importante è il costo, che si aggira intono ai 30€ per Netduino/Arduino mentre per i Picmicro siamo intorno ai 3-8€.<br />
In una prima fase possiamo usare Netduino per creare un prototipo, per poi eseguire un porting del progetto su Picmicro in modo da abbattere i costi di realizzazione della centralina.</p>
<p>I sensori del mio prototipo sono tre, un sensore di temperatura analogico tipo <strong>MCP9700a</strong>, un sensore di luminosità basato su <strong>fotoresistenza</strong> e un sensore di umidità realizzato con due puntali da inserire nel terreno.<br />
Il Netduino acquisisce tramite gli ingressi analogici questi segnali e in base al suo software gestisce un piccolo relè che va a pilotare l&#8217;elettrovalvola.<br />
Nella figura seguente è rappresentato lo schema a blocchi:</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-1165 size-full" title="SchemaBlocchiAutoIrrigazione" src="https://logicaprogrammabile.it/wp-content/uploads/2011/05/SchemaBlocchiAutoIrrigazione.gif" alt="Schema Sistema Irrigazione Fai da Te" width="513" height="408" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/05/SchemaBlocchiAutoIrrigazione.gif 513w, https://logicaprogrammabile.it/wp-content/uploads/2011/05/SchemaBlocchiAutoIrrigazione-300x238.gif 300w" sizes="auto, (max-width: 513px) 100vw, 513px" /></p>
<p>Credo che le informazioni di questo articolo siano sufficienti per iniziare a costruire il proprio orto automatizzato. Certamente le nozioni per la realizzazione dell&#8217;impianto di microirrigazione sono da approfondire ma con un po di manualità si può apprendere da soli come impostare e realizzare il proprio sistema idrico.<br />
Per quanto riguarda la parte della realizzazione della centralina elettronica vi rimando al prossimo articolo.</p>
<p>The post <a href="https://logicaprogrammabile.it/irrigazione-automatica-netduino/">Netduino e irrigazione automatica fai da te (Teoria)</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://logicaprogrammabile.it/irrigazione-automatica-netduino/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Accedere ai registri dell&#8217;MCP9803 (2° parte)</title>
		<link>https://logicaprogrammabile.it/mcp9803-cambiare-risoluzione-campionamento/</link>
					<comments>https://logicaprogrammabile.it/mcp9803-cambiare-risoluzione-campionamento/#respond</comments>
		
		<dc:creator><![CDATA[Marco Lai]]></dc:creator>
		<pubDate>Tue, 05 Apr 2011 17:08:49 +0000</pubDate>
				<category><![CDATA[Elettronica]]></category>
		<category><![CDATA[MCP9803]]></category>
		<category><![CDATA[Termometro]]></category>
		<guid isPermaLink="false">https://logicaprogrammabile.it/?p=747</guid>

					<description><![CDATA[<p>Gestire i registri dell&#8217;MCP9803 Nella prima parte abbiamo visto come comunicare con il sensore di temperatura MCP9803 utilizzando il bus I2C per leggere il valore di temperatura contenuto nel Temperature Register. Proveremmo ora a fare qualcosa di più interessante variando alcuni parametri del sensore. Il...</p>
<p>The post <a href="https://logicaprogrammabile.it/mcp9803-cambiare-risoluzione-campionamento/">Accedere ai registri dell&#8217;MCP9803 (2° parte)</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1>Gestire i registri dell&#8217;MCP9803</h1>
<p>Nella <a title="Protocollo I2C e sensore di temperatura MCP9803 (1°parte)" href="https://logicaprogrammabile.it/protocollo-i2c-e-sensore-di-temperatura-mcp9803-1%c2%b0parte/">prima parte</a> abbiamo visto come comunicare con il sensore di temperatura <strong>MCP9803</strong> utilizzando il bus I2C per leggere il valore di temperatura contenuto nel Temperature Register.<br />
Proveremmo ora a fare qualcosa di più interessante variando alcuni parametri del sensore. Il circuito elettrico è sempre quello impiegato nella <a title="Protocollo I2C e sensore di temperatura MCP9803 (1°parte)" href="https://logicaprogrammabile.it/protocollo-i2c-e-sensore-di-temperatura-mcp9803-1%c2%b0parte/">prima parte</a> dell&#8217;articolo.</p>
<p>Il <strong>register pointer</strong> permette di selezionare 4 registri differenti a seconda di come vengono impostati i bit <strong>P0</strong> e <strong>P1</strong>.</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-750 size-full" title="Conf_register" src="https://logicaprogrammabile.it/wp-content/uploads/2011/04/Conf_register.gif" width="646" height="238" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/04/Conf_register.gif 646w, https://logicaprogrammabile.it/wp-content/uploads/2011/04/Conf_register-300x110.gif 300w" sizes="auto, (max-width: 646px) 100vw, 646px" /></p>
<p>Per cambiare la risoluzione del convertitore dobbiamo accedere al registro di configurazione. Come mostra la tabella della figura precedente bisogna impostare il bit P1 a 0 ed il bit P0 a 1.<span id="more-747"></span></p>
<p>La figura seguente Riporto in figura il registro <strong>Configuration register</strong>  come illustrato nel datasheet:</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-751 size-full" title="Conf_register1" src="https://logicaprogrammabile.it/wp-content/uploads/2011/04/Conf_register1.gif" alt="Registro di configurazione del pic" width="583" height="644" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/04/Conf_register1.gif 583w, https://logicaprogrammabile.it/wp-content/uploads/2011/04/Conf_register1-271x300.gif 271w" sizes="auto, (max-width: 583px) 100vw, 583px" /></p>
<p>Come è possibile osservare questo registro permette di eseguire diverse operazioni. Quella che a noi ci interessa è relativa alla sezione Resolution (Bit5 e Bit6). Quando il sensore di temperatura viene alimentato i bit di questo registro sono impostati tutti a 0 (Power-up default).</p>
<p>Le operazioni che dobbiamo eseguire per impostare la risoluzione del convertitore a 12bit sono le seguenti:</p>
<ol>
<li>Selezionare il sensore tramite l&#8217;indirizzo</li>
<li>Selezionare il registro di configurazione</li>
<li>Impostare i bit5 e il bit6 a 1</li>
<li>Selezionare il registro della temperatura</li>
<li>Leggere dal registro della temperatura</li>
</ol>
<p>Queste sono le illustrazioni presenti nel datasheet:</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-752 size-full" title="Conf_register_write_data" src="https://logicaprogrammabile.it/wp-content/uploads/2011/04/Conf_register_write_data.gif" alt="Scrivere un byte sul registro di configurazione" width="652" height="212" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/04/Conf_register_write_data.gif 652w, https://logicaprogrammabile.it/wp-content/uploads/2011/04/Conf_register_write_data-300x97.gif 300w" sizes="auto, (max-width: 652px) 100vw, 652px" /></p>
<p>Il master invia un comando di Start, invia un byte contenente l&#8217;indirizzo del sensore (7bit) e il flag di lettura/scrittura, nel nostro esempio 1001000 (0x90 in esadecimale). Il sensore risponde con un acknowledges (ACK), il master invia il secondo un byte che sarà scritto sul <strong>Pointer Register</strong>. Questo valore è 00000001 (0x01 in esadecimale) che seleziona il Configuration Register. Il sensore risponde con un acknowledges. Il master invia un terzo byte 01100000 (0x60 in esadecimale) che sarà scritto nel configuration register. Il sensore risponde con un acknowledges. Il master termina la comunicazione con un comando di Stop.</p>
<p>Ora possiamo eseguire la procedura di lettura come abbiamo visto nella prima parte:</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-758 size-full" title="Read_Data2byte" src="https://logicaprogrammabile.it/wp-content/uploads/2011/04/Read_Data2byte1.gif" alt="Diagramma di lettura di due Byte dal registro" width="643" height="208" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/04/Read_Data2byte1.gif 643w, https://logicaprogrammabile.it/wp-content/uploads/2011/04/Read_Data2byte1-300x97.gif 300w" sizes="auto, (max-width: 643px) 100vw, 643px" /></p>
<p>Riassumiamo la procedura:</p>
<ul>
<li>Il master invia un comando di Start</li>
<li>Il master invia un byte contenente l&#8217;indirizzo dello slave e il flag di lettura/scrittura impostato su lettura (1).</li>
<li>Il sensore risponde con un acknowledges.</li>
<li>Il master legge il primo byte dallo slave e  invia un acknowledges.</li>
<li>Il master legge il secondo Byte e invia un not acknowledges(NAK) per indicare allo slave la fine della lettura.</li>
<li>Il master invia il comando di stop.</li>
</ul>
<p>Utilizzando la tabella di esempio possiamo apprendere come i dati verranno scritti nel <strong>Temperature Register</strong>:</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-753 size-full" title="TA_register12bit" src="https://logicaprogrammabile.it/wp-content/uploads/2011/04/TA_register12bit.gif" alt="Registro di temperatura a 12 bit" width="675" height="354" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/04/TA_register12bit.gif 675w, https://logicaprogrammabile.it/wp-content/uploads/2011/04/TA_register12bit-300x157.gif 300w" sizes="auto, (max-width: 675px) 100vw, 675px" /></p>
<p>Prendiamo per esempio la colonna 12bit ed una temperatura ambiente di 25.4375°C, il valore binario presente nel Temperature Register è 000110010111. Il primo byte letto dal pic è 00011001 mentre il secondo byte letto è 01110000.<br />
Il primo byte letto dal pic è quello più significativo mentre il secondo è quello meno significativo. Per ottenere il valore della temperatura ambiente, campionata dal sensore, dobbiamo prendere il valore binario del secondo byte e unirlo al valore binario del primo byte in questo modo</p>
<p style="text-align: center;">00011001 + 0111 =&gt; 000110010111</p>
<p>il valore ottenuto è 000110010111 che convertito in decimale diviene 407. La temperatura viene calcolata utilizzando la formula seguente:</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-771 size-full" title="Equazione" src="https://logicaprogrammabile.it/wp-content/uploads/2011/04/Equazione1.gif" width="355" height="185" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/04/Equazione1.gif 355w, https://logicaprogrammabile.it/wp-content/uploads/2011/04/Equazione1-300x156.gif 300w" sizes="auto, (max-width: 355px) 100vw, 355px" /></p>
<p><strong>n</strong> nel nostro caso vale -4 perché la risoluzione del convertitore è settata a 12bit, di conseguenza la nostra formula per calcolare la temperatura diventa:</p>
<p style="text-align: center;"><strong>407 * 2^-4 =&gt; 407 * 0.0625 =&gt; 25.4375°C</strong></p>
<p>Il codice di esempio seguente è compilato e caricato sul pic16f876, sono presenti numerosi commenti che illustrano il funzionamento del programma:</p>
<pre class="lang:c# decode:true ">unsigned short Primo_Byte = 0;
unsigned short Secondo_Byte = 0;

void main()
{
//inizializzo la porta UART
//a 9600bps
UART1_Init(9600);
//Inizializzo la porta I2C
//con una velocità di 400Khz
I2C1_Init(400000);

//Attendo 100 millisecondi
Delay_ms(100);

//procedura per variare la risoluzione
//del convertitore digitale
//invio uno Start sul bus I2C
I2C1_Start();
//Invio l'indirizzo 1001000
//setto il bit per la scrittura
I2C1_Wr(0x90); //10010000
//Seleziono il registro di configurazione
I2C1_Wr(0x01); //00000001
//scrivo sul Configuration Register il valore 96
//per impostare 12bit di risoluzione
I2C1_Wr(0x60);
//termino la comunicazione
I2C1_Stop();

//invio uno Start sul bus I2C
I2C1_Start();
//Invio l'indirizzo 1001000
//setto il bit per la scrittura
I2C1_Wr(0x90); //10010000
//scrivo sul Register point il valore 0
//per accedere al Temperature Register
I2C1_Wr(0x00);

//ciclo infinito per leggere
//continuamente la temperatura
while (1)
{
//invio uno Start sul bus I2C
I2C1_Start();

//Invio l'indirizzo 1001000
//setto il bit per la scrittura
I2C1_Wr(0x91); //10010001
//leggo il primo Byte ed invio un acknowledge
Primo_Byte = I2C1_Rd(1);
//leggo il primo Byte ed invio un NOT acknowledge
Secondo_Byte = I2C1_Rd(0);
//Invio uno stop sul bus I2C
I2C1_Stop();

//Invio sulla seriale i dati letti dal sensore
UART1_Write(Primo_Byte);
UART1_Write(Secondo_Byte);

//attendo 2 secondi tra una lettura e la
//sucessiva
Delay_ms(2000);

}
}</pre>
<p>&nbsp;</p>
<p>Quello che adesso rimane da fare è il software lato pc che acquisisce i dati dalla seriale. Ho utilizzato <strong>Visual C#</strong> per creare un&#8217;applicazione windows form.<br />
Anche in questo caso il codice seguente è ricco di commenti che permettono di capire meglio il programma:</p>
<pre class="lang:c# decode:true ">using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Collections;
using System.IO.Ports;

namespace SensoreTemperaturaMCP9803
{
public partial class frmMain : Form
{
//variabili per la lettura dalla seriale
Double temperaturaRX = 0;
Int16 Temperatura = 0;
Byte[] bytesRicevuti = new Byte[2];

//creo un delegate per accedere dal thread secondario a quello principale
public delegate void AggiornaTXT(string _str);

/// &lt;summary&gt;
/// questa funzione permette di accedere alla textbox da un thread secondario
/// &lt;/summary&gt;
/// &lt;param name="str"&gt;Testo da inserire nella textbox&lt;/param&gt;
public void FormTxtUpdate(string str)
{
if (this.txtTemperatura.InvokeRequired)
{
AggiornaTXT updaterdelegate = new AggiornaTXT(FormTxtUpdate);
this.Invoke(updaterdelegate, new object[] { str });
}
else
{
txtTemperatura.Text = str;
}
}

/// &lt;summary&gt;
/// Questa funzione converte un valore binario in un valore a 16 bit
/// &lt;/summary&gt;
/// &lt;param name="ValoreBinario"&gt;Valore in bit&lt;/param&gt;
/// &lt;param name="Start"&gt;Indice di partenza del BitArray&lt;/param&gt;
/// &lt;param name="NumBit"&gt;Numero di bit da convertire&lt;/param&gt;
/// &lt;returns&gt;&lt;/returns&gt;
private Int16 ConverToDecimal(BitArray ValoreBinario, Int32 Start, Int32 NumBit)
{
Int32 Ciclo = 0;
Int16 Valore = 0;

for (Ciclo = 0; Ciclo &lt; NumBit; Ciclo++)
{
if (ValoreBinario[Ciclo + Start])
Valore |= (Int16)(1 &lt;&lt; Ciclo);
}

return (Valore);
}

public frmMain()
{
InitializeComponent();
}

/// &lt;summary&gt;
/// Questo evento viene generato ala ricezione di un byte sulla seriale
/// &lt;/summary&gt;
/// &lt;param name="sender"&gt;&lt;/param&gt;
/// &lt;param name="e"&gt;&lt;/param&gt;
private void RS232_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
//questa funzione viene eseguita in un thread secondario

//quando sono disponibili almeno 2 byte inizia
//l'elaborazione
if (RS232.BytesToRead &gt;= 2)
{
//leggi 2 byte e memorizzali nell'array bytesRicevuti
RS232.Read(bytesRicevuti, 0, 2);

//inverto l'array
Array.Reverse(bytesRicevuti);
//converto l'array di 2 byte in un array di bit
BitArray ba = new BitArray(bytesRicevuti);

//ottengo il valore della temperatura utilizzando solo i bit validi
//versione con risoluzione a 9bit
//Temperatura = ConverToDecimal(ba, 7, 8);
//calcolo il valore della temperatura
//se il valore del convertiore è a 9 bit devo moltiplicare per 0.5
//temperaturaRX = Temperatura * 0.5;

//ottengo il valore della temperatura utilizzando solo i bit validi
//versione con risoluzione a 12bit
Temperatura = ConverToDecimal(ba, 4, 12);
//calcolo il valore della temperatura
//se il valore del convertiore è a 12 bit devo moltiplicare per 0.0625
temperaturaRX = Temperatura * 0.0625;

//rappresento il valore della temperatura nella textbox
FormTxtUpdate(Convert.ToString(temperaturaRX) + " °C");
}
}

private void frmMain_Load(object sender, EventArgs e)
{
//apro la seriale per iniziare a leggere i dati
RS232.Open();
}

private void frmMain_FormClosed(object sender, FormClosedEventArgs e)
{
//alla chiusura del form chiudo la comunicazione seriale
RS232.Close();
}

private void btnChiudi_Click(object sender, EventArgs e)
{
//chiudi
Close();
}
}
}</pre>
<p>&nbsp;</p>
<p>Le operazioni che esegue il programma sono riassunte in questo modo:</p>
<ul>
<li>La porta seriale viene aperta per poter acquisire i dati</li>
<li>Un gestore di evento viene scatenato quando sulla seriale arrivano dei dati</li>
<li>Il gestore di evento leggere due byte alla volta.</li>
<li>Il gestore di evento elabora i due byte in modo da ottenere il valore decimale del dato della temperatura</li>
<li>Il valore della temperatura è visualizzato su un controllo textbox</li>
</ul>
<p>Adesso potete divertirvi con il codice per creare un <strong>datalogger</strong> della temperatura e magari creare un sistema con più sensori di temperatura.</p>
<p>Come sempre suggerimenti e critiche sono sempre ben accette.</p>
<p>Buon divertimento!</p>
<p>The post <a href="https://logicaprogrammabile.it/mcp9803-cambiare-risoluzione-campionamento/">Accedere ai registri dell&#8217;MCP9803 (2° parte)</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://logicaprogrammabile.it/mcp9803-cambiare-risoluzione-campionamento/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Protocollo I2C e sensore di temperatura MCP9803 (1°parte)</title>
		<link>https://logicaprogrammabile.it/protocollo-i2c-e-sensore-di-temperatura-mcp9803-1%c2%b0parte/</link>
					<comments>https://logicaprogrammabile.it/protocollo-i2c-e-sensore-di-temperatura-mcp9803-1%c2%b0parte/#respond</comments>
		
		<dc:creator><![CDATA[Marco Lai]]></dc:creator>
		<pubDate>Mon, 04 Apr 2011 12:38:50 +0000</pubDate>
				<category><![CDATA[Elettronica]]></category>
		<category><![CDATA[bus]]></category>
		<category><![CDATA[I2C]]></category>
		<guid isPermaLink="false">https://logicaprogrammabile.it/?p=639</guid>

					<description><![CDATA[<p>Protocollo I2C ed uso dell&#8217;integrato MCP8903 Il mondo dell&#8217;elettronica, come sapiamo, è composto da migliaia di componenti che svolgono funzioni dedicate, come un sensore di temperatura, oppure sono capaci di gestire diverse operazioni come nel caso dei microcontrollori. La tecnologia analogica ha pian piano lasciato...</p>
<p>The post <a href="https://logicaprogrammabile.it/protocollo-i2c-e-sensore-di-temperatura-mcp9803-1%c2%b0parte/">Protocollo I2C e sensore di temperatura MCP9803 (1°parte)</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1>Protocollo I2C ed uso dell&#8217;integrato MCP8903</h1>
<p>Il mondo dell&#8217;elettronica, come sapiamo, è composto da migliaia di componenti che svolgono funzioni dedicate, come un sensore di temperatura, oppure sono capaci di gestire diverse operazioni come nel caso dei microcontrollori.<br />
La tecnologia analogica ha pian piano lasciato il posto a quella digitale e i componenti hanno iniziato a colloquiare tra loro utilizzando vari protocolli di comunicazione (insieme di regole che determinano il funzionamento della comunicazione).<br />
Oggi, la maggior parte dei circuiti utilizza un microcontrollore, il cui compito è quello di gestire il circuito ed i componenti ad esso collegato.<br />
Nel caso di sistemi complessi i componenti che creano il circuito sono diversi e possono saturare la capacità fisica di collegamento del microcontrollore, come nel caso proposto in figura.</p>
<p><a href="https://logicaprogrammabile.it/protocollo-i2c-e-sensore-di-temperatura-mcp9803-1%c2%b0parte/componenti/" rel="attachment wp-att-653"><img loading="lazy" decoding="async" class="aligncenter wp-image-653 size-full" title="Componenti" src="https://logicaprogrammabile.it/wp-content/uploads/2011/03/Componenti.gif" width="434" height="424" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/03/Componenti.gif 434w, https://logicaprogrammabile.it/wp-content/uploads/2011/03/Componenti-300x293.gif 300w" sizes="auto, (max-width: 434px) 100vw, 434px" /> </a></p>
<p>Ben presto si è capito che per snellire questo tipo di circuiti era necessario creare un meccanismo capace di ottimizzare l&#8217;interconnessione tra componenti e microcontrollore. Il sistema più efficace è certamente quello di adottare un bus di collegamento, che permette lo scambio di dati, tra componenti e microcontrollore, utilizzando pochi fili comuni.<br />
La figura seguente mostra un esempio di bus dove diversi componenti sono interconnessi utilizzando solo 2 fili. Il microcontrollore in questo caso deve gestire la comunicazione utilizzando un protocollo comune a tutti i componenti.<br />
<span id="more-639"></span><a href="https://logicaprogrammabile.it/protocollo-i2c-e-sensore-di-temperatura-mcp9803-1%c2%b0parte/componentibus/" rel="attachment wp-att-650"><img loading="lazy" decoding="async" class="aligncenter wp-image-650 size-full" title="ComponentiBus" src="https://logicaprogrammabile.it/wp-content/uploads/2011/03/ComponentiBus.gif" width="490" height="341" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/03/ComponentiBus.gif 490w, https://logicaprogrammabile.it/wp-content/uploads/2011/03/ComponentiBus-300x208.gif 300w" sizes="auto, (max-width: 490px) 100vw, 490px" /> </a>Diverse aziende svilupparono dei protocolli che col tempo sono divenuti degli standard, in questo modo componenti e microcontrollori hanno iniziato a scambiarsi dati in modo semplice ed efficiente.</p>
<p>La Philips negli anni &#8217;80 sviluppò il Bus <strong>I2C</strong> (<strong>I</strong>nter <strong>I</strong>ntegrated <strong>C</strong>ircuit pronunciato <em>i-quadro</em>-ci o <em>i-due-ci</em>), un protocollo seriale che usa due fili per instaurare la comunicazione con i componenti.</p>
<p>Tipicamente questo protocollo richiede un master (il microcontrollore che gestisce la comunicazione), e uno o più componenti slave (sensori, ADC, DAC, memorie ecc&#8230; che inviano i dati al microcontrollore).<br />
Gli slave vengono identificati nel bus tramite un <span style="text-decoration: underline;">indirizzo univoco</span>. Il master invia sulla linea l&#8217;indirizzo dello slave con cui vuole instaurare la comunicazione.<br />
E&#8217; possibile un sistema con più master (multimaster) ma la comunicazione deve sempre essere gestita da un master alla volta.</p>
<p>Il bus I2C permette di collegare agli stessi due fili ben 112 dispositivi. La velocità di comunicazione non è elevatissima e puoi variare, tipicamente, da un minimo di 10Kbits/s fino a 400Kbits/s (sviluppi successivi del bus I2c hanno permesso velocità fino a 3.4Mbits/S e interconnessioni di 1024 componenti).</p>
<p>I segnali presenti sui fili sono chiamati SDA (<strong>S</strong>ignal <strong>DA</strong>ta) per il trasferimento dei dati e SCL (<strong>S</strong>erial <strong>C</strong>lock <strong>L</strong>ine) per la sincronizzazione della linea. In figura è rappresentato il diagramma dei segnali:</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-665 size-full" title="I2C_Protocollo" src="https://logicaprogrammabile.it/wp-content/uploads/2011/04/I2C_Protocollo.gif" width="670" height="150" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/04/I2C_Protocollo.gif 670w, https://logicaprogrammabile.it/wp-content/uploads/2011/04/I2C_Protocollo-300x67.gif 300w" sizes="auto, (max-width: 670px) 100vw, 670px" /></p>
<p>Il master deve eseguire, per avviare la comunicazione, una commutazione della linea SDA dallo stato alto allo stato basso, quando il segnale SCL è alto (vedi riquadro Start).<br />
Successivamente il master può inviare dati sulla linea SDA.<br />
Quando il segnale SCL è basso il master inizia a scrivere il valore del bit (1 o 0); quando il segnale SCL è alto, il bit è stabile e può essere letto dallo slave (riquadro BIT1).Questo procedimento si ripete per tutti i bit (Riquadro BIT2 e BIT N).<br />
Quando tutti i bit sono stati inviati, la comunicazione termina quando il master riporta la linea SDA a livello alto in concomitanza del livello alto della linea SCL (riquadro Stop).</p>
<p>Questo esempio spiega il comportamento tipico dei segnali sul bus.</p>
<p>La comunicazione tra master e slave è risulta nella pratica più complessa di quanto espresso precedentemente. Per capire meglio è utile analizzare un esempio reale, perciò ho realizzato un semplice circuito che impiega un Pic 16F876 e un sensore di temperatura digitale MCP9803 che colloquiano utilizzando il bus I2C.</p>
<p>Lo schema elettrico è il seguente:</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-692 size-full" title="MCP9803" src="https://logicaprogrammabile.it/wp-content/uploads/2011/04/MCP9803.gif" width="653" height="559" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/04/MCP9803.gif 653w, https://logicaprogrammabile.it/wp-content/uploads/2011/04/MCP9803-300x256.gif 300w" sizes="auto, (max-width: 653px) 100vw, 653px" /></p>
<p>Il circuito utilizza un microcontrollore per comunicare con il sensore di temperatura MCP9803. I dati acquisiti vengono acquisiti e inviati tramite la porta UART del pic al pc. Il Max233 converte i segnali TTL in segnali RS232.</p>
<p>Partiamo con lo studio del datasheet del sensore MCP9803. Le caratteristiche principali sono riassunte nella tanella seguente:</p>
<table>
<tbody>
<tr>
<td>Intervallo di alimentazione</td>
<td>da 2.7Vdc a 5.5Vdc</td>
</tr>
<tr>
<td>Selezione risoluzione acquisizione</td>
<td>da 9 bit a 12 bit</td>
</tr>
<tr>
<td>Interfaccia di comunicazione</td>
<td>bus I2C</td>
</tr>
<tr>
<td>Frequenza bus I2C</td>
<td>da 10Khz a 400Khz</td>
</tr>
<tr>
<td>Intervallo temperatura</td>
<td>da -55°C a +125°C</td>
</tr>
<tr>
<td>Precisione</td>
<td>+-1°C da  da-10°C a +85°C</td>
</tr>
</tbody>
</table>
<p>Il pin 1 (SDA) del sensore è collegato direttamente al pin 15 del pic (SDA), mentre il pin 2 (SCLK) del sensore è collegato al pin 14 del pic (SCL).</p>
<p>I pin 5, 6, 7 del sensore (A0, A1, A2) permettono di definire l&#8217;indirizzo del dispositivo all&#8217;interno del bus. Sul datasheet possiamo leggere come viene impostato:</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-702 size-full" title="AddressPin" src="https://logicaprogrammabile.it/wp-content/uploads/2011/04/AddressPin.jpg" width="369" height="334" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/04/AddressPin.jpg 369w, https://logicaprogrammabile.it/wp-content/uploads/2011/04/AddressPin-300x271.jpg 300w" sizes="auto, (max-width: 369px) 100vw, 369px" />Per comporre l&#8217;indirizzo sono necessari 7 bit. Nei modelli 9800/xxxx gli indirizzi sono predefiniti, mentre nell&#8217;MCP9803 i bit A3, A4, A5, A6 sono scelti dalla casa costruttrice e i bit A0, A1, A2 sono impostabili dall&#8217;utente.</p>
<p>Nel circuito in questione, i pin A0, A1, A2 sono collegati a massa, quindi a valore logico 0, di conseguenza l&#8217;indirizzo del nostro sensore è 1001000 (0x48 in esadecimale).</p>
<p>Bene ora l&#8217;MCP9803 può essere identificato dal pic usando l&#8217;indirizzo a 7 bit.</p>
<p>Scorrendo il datasheet, andiamo nella sezione register:</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-706 size-full" title="register_pointer" src="https://logicaprogrammabile.it/wp-content/uploads/2011/04/register_pointer1.gif" width="646" height="238" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/04/register_pointer1.gif 646w, https://logicaprogrammabile.it/wp-content/uploads/2011/04/register_pointer1-300x110.gif 300w" sizes="auto, (max-width: 646px) 100vw, 646px" /></p>
<p>Il sensore ha un registro che permette di accedere ai vari registri interni, come ad esempio il Configuration Register dove possiamo cambiare la risoluzione del convertitore digitale. Vedremmo poi come cambiare la risoluzione da 9bit (valore di default) a 12bit.<br />
Quello che ci serve ora è leggere il dato del &#8216;Temperature Register&#8217;. Per selezionarlo è sufficiente porre il bit0(P0) e il bit1(P1) a 0 (Questo registro è a 0 per default ma eseguiamo comunque l&#8217;operazione ai fini didattici).</p>
<p>Ora studiamo la sezione dove è illustrata la sequenza di comunicazione tra il master ed il sensore MCP9803.</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-718 size-full" title="Read_Data" src="https://logicaprogrammabile.it/wp-content/uploads/2011/04/Read_Data.gif" width="516" height="222" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/04/Read_Data.gif 516w, https://logicaprogrammabile.it/wp-content/uploads/2011/04/Read_Data-300x129.gif 300w" sizes="auto, (max-width: 516px) 100vw, 516px" /></p>
<p>Si inizia con il comando di start (SDA va basso quando SCLK è alto &#8211; vedi box rosso &#8216;S&#8217;) poi il master scrive i 7 bit dell&#8217;indirizzo dello slave (1001000) più un bit che definisce se vogliamo leggere o scrivere nei registri dello slave (Se questo bit è a 1 leggeremo i dati dallo slave se è a 0 scriveremo i dati nello slave).<br />
Questa informazione del bit che definisce la lettura o la scrittura è presente in questa sezione del datasheet.</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-711 size-full" title="Add_Byte" src="https://logicaprogrammabile.it/wp-content/uploads/2011/04/Add_Byte.gif" width="355" height="516" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/04/Add_Byte.gif 355w, https://logicaprogrammabile.it/wp-content/uploads/2011/04/Add_Byte-206x300.gif 206w" sizes="auto, (max-width: 355px) 100vw, 355px" /></p>
<p>Il master invia il seguente valore binario 10010000 (0x90 in esadecimale) per scrivere sullo slave.<br />
Dopo l&#8217;invio del byte sul bus I2C, lo slave risponde con un acknowledges (pone la linea SDA bassa quando il SCLK è alto).<br />
Ora il master invia un secondo byte per scrivere sul <strong>register point</strong> il valore necessario a selezionare il registro <strong>Temperature Regiser</strong> (Bito e Bit1 a 0). Il sensore risponde con un altro acknowledges.</p>
<p>Adesso che abbiamo impostato il sensore, per leggere dal registro contenente il dato della temperatura, possiamo avviare l&#8217;operazione di lettura.<br />
Controlliamo ancora il datasheet  e appuriamo che il dato della temperatura è espresso con due byte.</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-714 size-full" title="TA_register" src="https://logicaprogrammabile.it/wp-content/uploads/2011/04/TA_register.gif" width="664" height="296" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/04/TA_register.gif 664w, https://logicaprogrammabile.it/wp-content/uploads/2011/04/TA_register-300x133.gif 300w" sizes="auto, (max-width: 664px) 100vw, 664px" /></p>
<p>L&#8217;operazione per leggere due byte consecutivi dal registro selezionato è rappresentata in figura:</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-721 size-full" title="Read_Data2byte" src="https://logicaprogrammabile.it/wp-content/uploads/2011/04/Read_Data2byte.gif" width="643" height="208" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/04/Read_Data2byte.gif 643w, https://logicaprogrammabile.it/wp-content/uploads/2011/04/Read_Data2byte-300x97.gif 300w" sizes="auto, (max-width: 643px) 100vw, 643px" /></p>
<p>Inviamo un comando si Start, poi l&#8217;indirizzo dello slave (0x48) ed il bit di selezione lettura/Scrittura impostato a 1(lettura). Il valore binario risultante è 10010001 (0x91 in esadecimale).</p>
<p>Il sensore risponde con un acknowledges. Il master esegue la lettura del primo byte, invia un acknowledges, legge il secondo byte ed invia un not acknowledges (indica allo slave la fine della lettura).<br />
Il master termina la comunicazione inviando un comando di stop (riquadro P).</p>
<p>Il codice che permette al pic di eseguire tutte queste operazioni è stato scritto utilizzando <strong>MikroC Pro</strong> della <strong>Mikroelektronika</strong>. Il linguaggio, basato sulla sintassi del C, risulta molto semplice e facile da scrivere.<br />
Inoltre sono disponibili molte librerie che svolgono molte operazioni tra le quali quella relativa all&#8217;uso del bus I2C.</p>
<p>Il codice caricato sul pic16F876 è il seguente:</p>
<pre class="lang:c# decode:true ">unsigned short Primo_Byte = 0;
unsigned short Secondo_Byte = 0;

void main()
{
//inizializzo la porta UART
//a 9600bps
UART1_Init(9600);
//Inizializzo la porta I2C
//con una velocità di 400Khz
I2C1_Init(400000);

//Attendo 100 millisecondi
Delay_ms(100);

//invio uno Start sul bus I2C
I2C1_Start();
//Invio l'indirizzo 1001000
//setto il bit per la scrittura
I2C1_Wr(0x90); //10010000
//scrivo sul Register point il valore 0
//per accedere al Temperature Register
I2C1_Wr(0x00);

//ciclo infinito per leggere
//continuamente la temperatura
while (1)
{
//invio uno Start sul bus I2C
I2C1_Start();

//Invio l'indirizzo 1001000
//setto il bit per la scrittura
I2C1_Wr(0x91); //10010001
//leggo il primo Byte ed invio un acknowledge
Primo_Byte = I2C1_Rd(1);
//leggo il primo Byte ed invio un NOT acknowledge
Secondo_Byte = I2C1_Rd(0);
//Invio uno stop sul bus I2C
I2C1_Stop();

//Invio sulla seriale i dati letti dal sensore
UART1_Write(Primo_Byte);
UART1_Write(Secondo_Byte);

//attendo 2 secondi tra una lettura e la
//sucessiva
Delay_ms(2000);

}
}</pre>
<p>&nbsp;</p>
<p>Il pic acquisisce il segnale ed invia i dati <span style="text-decoration: underline;"><strong>grezzi</strong></span> al pc che dovrà interpretarli ed elaborarli secondo la formula presente nel datasheet:</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-726 size-full" title="Equazione" src="https://logicaprogrammabile.it/wp-content/uploads/2011/04/Equazione.gif" width="355" height="185" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/04/Equazione.gif 355w, https://logicaprogrammabile.it/wp-content/uploads/2011/04/Equazione-300x156.gif 300w" sizes="auto, (max-width: 355px) 100vw, 355px" /></p>
<p>dove <strong>Code</strong> è il dato grezzo letto dal sensore, mentre <strong>n</strong> dipende dal valore di risoluzione del convertitore (-1 per 9bit di risoluzione, -2 per 10bit di risoluzione, -3 per 11bit di risoluzione e -4 per 12bit di risoluzione).</p>
<p>Il datasheet mostra una tabella di esempio che possiamo usare per capire come avviene questo calcolo:</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-730 size-full" title="Esempio_TA" src="https://logicaprogrammabile.it/wp-content/uploads/2011/04/Esempio_TA1.gif" width="693" height="411" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/04/Esempio_TA1.gif 693w, https://logicaprogrammabile.it/wp-content/uploads/2011/04/Esempio_TA1-300x177.gif 300w" sizes="auto, (max-width: 693px) 100vw, 693px" /></p>
<p>L&#8217;esempio con 9bit di risoluzione e una temperatura ambiente di 125°C produce un valore binario formato da 9bit, suddivisi in due byte, il primo con valore binario di <strong>01111101 </strong>e il secondo con valore binario <strong>0</strong>0000000 (vedi riquadri 1° Byte e 2° Byte). Questi due byte devono essere uniti per formare un valore intero.<br />
Il primo byte è quello più significativo mentre il secondo è quello meno significativo, quindi uniamo il bit del secondo byte al primo:</p>
<p style="text-align: center;"><strong>01111101 + 0 = 011111010 =&gt; 0xFA (esadeciale) =&gt; 250 (Decimale)</strong></p>
<p>Ora applichiamo la formula per calcolare la temperatura</p>
<p style="text-align: center;"><strong>250 * 2^-1 = 250 * 0.5 = 125°C</strong></p>
<p>Nella seconda parte illustrerò come acquisire i dati inviati dal pic con la seriale e come cambiare la risoluzione di campionamento da 9bit a 12bit.</p>
<p>Come sempre aspetto i vostri suggerimenti.</p>
<p>The post <a href="https://logicaprogrammabile.it/protocollo-i2c-e-sensore-di-temperatura-mcp9803-1%c2%b0parte/">Protocollo I2C e sensore di temperatura MCP9803 (1°parte)</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://logicaprogrammabile.it/protocollo-i2c-e-sensore-di-temperatura-mcp9803-1%c2%b0parte/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>MCP9700A Netduino e sensore di temperatura analogico</title>
		<link>https://logicaprogrammabile.it/mcp9700a-netduino-sensore-temperatura-analogico/</link>
					<comments>https://logicaprogrammabile.it/mcp9700a-netduino-sensore-temperatura-analogico/#respond</comments>
		
		<dc:creator><![CDATA[Marco Lai]]></dc:creator>
		<pubDate>Tue, 22 Mar 2011 14:03:51 +0000</pubDate>
				<category><![CDATA[Elettronica]]></category>
		<category><![CDATA[Tutorial Netduino]]></category>
		<category><![CDATA[DataLogger]]></category>
		<category><![CDATA[MCP9700A]]></category>
		<category><![CDATA[Sensore Temperatura]]></category>
		<guid isPermaLink="false">https://logicaprogrammabile.it/?p=441</guid>

					<description><![CDATA[<p>MCP9700A come leggere il valore di temperatura Sfruttiamo il Netduino per la realizzazione di un dispositivo che permette la lettura della temperatura tramite il sensore MCP9700A. Il sensore fornisce una tensione analogica proporzionale alla temperatura rilevata. E&#8217; un dispositivo molto semplice e compatto, ha tre...</p>
<p>The post <a href="https://logicaprogrammabile.it/mcp9700a-netduino-sensore-temperatura-analogico/">MCP9700A Netduino e sensore di temperatura analogico</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1>MCP9700A come leggere il valore di temperatura</h1>
<p>Sfruttiamo il <strong>Netduino </strong>per la realizzazione di un dispositivo che permette la lettura della temperatura tramite il sensore <strong>MCP9700A</strong>.<br />
Il sensore fornisce una tensione analogica proporzionale alla temperatura rilevata. E&#8217; un dispositivo molto semplice e compatto, ha tre pin, uno per l&#8217;alimentazione, uno per la massa e uno per la tensione analogica di uscita.</p>
<p style="text-align: left;"><img loading="lazy" decoding="async" class="aligncenter wp-image-448 size-medium" title="Sensore di temperatura tipo MCP9700A" src="https://logicaprogrammabile.it/wp-content/uploads/2011/03/SensTempPF-300x203.gif" alt="MCP9700A" width="300" height="203" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/03/SensTempPF-300x203.gif 300w, https://logicaprogrammabile.it/wp-content/uploads/2011/03/SensTempPF.gif 333w" sizes="auto, (max-width: 300px) 100vw, 300px" /></p>
<p style="text-align: left;">Per capire come collegare questo sensore al Netduino analizziamo prima le sue caratteristiche. Può essere alimentato da un intervallo di tensione che va da 2.3Vdc a 5.5Vdc, misura temperature che vanno da un minimo di -40°C a un massimo di 125°C con una precisione tipica di -+1°C (-+2°C massima). Ad una temperatura di 0°C il dispositivo eroga in uscita una tensione di 500mV utile come riferimento di partenza per il nostro circuito. La variazione di un grado produce una variazione di tensione di 10mV. La minima tensione in uscita dal sensore è di 100mV mentre quella massima è di 1.75V.<br />
Per approfondire tutti gli aspetti di questo sensore potete consultare il suo <a href="http://ww1.microchip.com/downloads/en/DeviceDoc/21942e.pdf" target="_blank">datasheet</a>.<br />
La tabella seguente mostra un riassunto di quanto detto:</p>
<table style="width: 315px;">
<tbody>
<tr>
<td style="text-align: center;">Descrizione</td>
<td></td>
<td style="text-align: center;">Valori</td>
</tr>
<tr>
<td>Alimentazione del sensore</td>
<td></td>
<td>da 2.3Vdc a 5.5Vdc</td>
</tr>
<tr>
<td>Intervallo di temperatura</td>
<td></td>
<td>da -40°C a 125°C</td>
</tr>
<tr>
<td>Precisione tipica</td>
<td></td>
<td>+/- 1°C da 0 a 70°C</td>
</tr>
<tr>
<td>Variazione di tensione</td>
<td></td>
<td>10mV per grado</td>
</tr>
<tr>
<td>Tensione di uscita a 0°C</td>
<td></td>
<td style="text-align: left;">500mV</td>
</tr>
<tr>
<td>Intervallo di tensione in uscita</td>
<td></td>
<td>da 100mV a 1.75V</td>
</tr>
</tbody>
</table>
<p>Il grafico seguente mostra invece la curva di risposta del sensore.</p>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="aligncenter wp-image-476 size-full" title="Curva di risposta MCP9700A" src="https://logicaprogrammabile.it/wp-content/uploads/2011/03/Curvadirisposta.gif" alt="Curva di risposta MCP9700A" width="324" height="212" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/03/Curvadirisposta.gif 324w, https://logicaprogrammabile.it/wp-content/uploads/2011/03/Curvadirisposta-300x196.gif 300w" sizes="auto, (max-width: 324px) 100vw, 324px" /></p>
<p>La precisione del sensore è garantita alimentandolo a 3.3Vdc. In effetti, a parità di temperatura rilevata, alimentandolo prima a 3.3Vdc e poi a 5Vdc ho notato delle differenze di tensione in uscita dal sensore.<br />
Come sappiamo il gli ingressi analogici del Netduino possono accettare una tensione massima di 3.3Vdc, l&#8217;MCP9700A può essere collegato direttamente all&#8217;ingresso analogico poiché la sua massima tensione in uscita è pari a 1.75Vdc.<br />
Il Netduino dispone di un&#8217;alimentazione da 3.3Vdc che ho utilizzato per alimentare il sensore.</p>
<p><span id="more-441"></span>Il valore di tensione in uscita dal sensore viene collegato all&#8217;ingresso A0 del Netduino per essere digitalizzato; questo dato viene inviato al PC usando la <a title="Netduino e collegamento alla seriale(RS232) del pc" href="https://logicaprogrammabile.it/netduino-e-collegamento-alla-serialers232-del-pc/">comunicazione RS232</a>.</p>
<p>Il circuito elettrico è il seguente.</p>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="aligncenter wp-image-447 size-full" title="Collegamento sensore di temperatura e Netduino" src="https://logicaprogrammabile.it/wp-content/uploads/2011/03/SensTemp.gif" alt="Netduino e sensore MCP9700A" width="623" height="423" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/03/SensTemp.gif 623w, https://logicaprogrammabile.it/wp-content/uploads/2011/03/SensTemp-300x203.gif 300w" sizes="auto, (max-width: 623px) 100vw, 623px" /></p>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="aligncenter wp-image-606 size-full" title="Foto_Circuito" src="https://logicaprogrammabile.it/wp-content/uploads/2011/03/DSCF09331.jpg" alt="Foto_Circuito_Netduino" width="350" height="420" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/03/DSCF09331.jpg 350w, https://logicaprogrammabile.it/wp-content/uploads/2011/03/DSCF09331-250x300.jpg 250w" sizes="auto, (max-width: 350px) 100vw, 350px" /></p>
<p>Il software per la gestione del circuito è composto da una parte relativa all&#8217;acquisizione del segnale analogico del sensore e da una parte che gestisce la comunicazione RS232 con il PC.<br />
Di seguito il codice C#:</p>
<pre class="lang:c# decode:true ">public static void Main()
{
SerialPort UART1 = new SerialPort("COM1", 9600, Parity.None,
8, StopBits.One);
AnalogInput AN0 = new AnalogInput(Pins.GPIO_PIN_A0);
Byte[] IntToByte = new Byte[2];
Int16 Analog0 = 0;

UART1.Open();

while (true)
{
//acquisisci il valore analogico
Analog0 = (Int16)AN0.Read();

//copio il valore intero in due byte
IntToByte[0] = (byte)(Analog0 &amp; 0xff);
IntToByte[1] = (byte)((Analog0 &gt;&gt; 8) &amp; 0xff);

//invia al pc un informazione
UART1.Write(IntToByte, 0, IntToByte.Length);
//attendi 500 millisecondi
Thread.Sleep(500);
}

UART1.Close();
}</pre>
<p>&nbsp;</p>
<p>Dopo aver definito gli oggetti per la comunicazione seriale e per l&#8217;acquisizione del segnale analogico, il programma entra in un ciclo infinito e ogni 500 millisecondi la funzione Read() esegue una lettura del segnale analogico proveniente dal sensore MCP9700A, questo valore è memorizzato in una variabile intera.<br />
Per poter spedire questo valore tramite l&#8217;oggetto UART1, devo convertirlo in un array di Byte. Le istruzioni seguenti svolgono questo compito</p>
<pre class="lang:c# decode:true ">//copio il valore intero in due byte
IntToByte[0] = (byte)(Analog0 &amp; 0xff);
IntToByte[1] = (byte)((Analog0 &gt;&gt; 8) &amp; 0xff);</pre>
<p>&nbsp;</p>
<p>Queste istruzioni servono a mettere i primi 8bit della variabile Analog0(16bit) nel primo byte dell&#8217;array e i successivi bit nel secondo byte dell&#8217;array.<br />
Ho realizzato questa illustrazione per spiegare meglio cosa avviene utilizzando le funzioni precendenti:</p>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="aligncenter wp-image-490 size-full" title="Conversione da In16 ad array di Byte" src="https://logicaprogrammabile.it/wp-content/uploads/2011/03/IntToByte.gif" alt="Conversione da In16 ad array di Byte" width="620" height="214" srcset="https://logicaprogrammabile.it/wp-content/uploads/2011/03/IntToByte.gif 620w, https://logicaprogrammabile.it/wp-content/uploads/2011/03/IntToByte-300x103.gif 300w" sizes="auto, (max-width: 620px) 100vw, 620px" /></p>
<p>Colleghiamo il Netduino al pc per alimentare il circuito ed eseguiamo il Debug(f5) per caricare il programma. A compilazione e programmazione avvenuta, avviamo<strong> hyper terminal</strong> per leggere i dati dalla seriale. Per maggiorni informazioni su hyper terminal potete rileggere l&#8217;articolo riguardante <a title="Netduino e collegamento alla seriale(RS232) del pc" href="https://logicaprogrammabile.it/netduino-e-collegamento-alla-serialers232-del-pc/">Netduino e RS232</a>.</p>
<p>Ora che tutto è funzionante dobbiamo ragionare sull&#8217;interpretazione dei dati inviati al pc. La proporzione seguente ci permette di ottenere il valore della tensione sull&#8217;ingresso analogico in base al valore intero che il Netduino invia al pc:</p>
<p style="text-align: center;"><strong>MaxTenADC : Risol_ADC = TensADC : ValInt</strong></p>
<blockquote>
<p style="text-align: left;">dove:<br />
<strong>MaxTenADC </strong>= 3.3Vdc tensione massima applicabile al pin analogico del Netduino<br />
<strong>Risol_ADC</strong> = 10bit (1024) massima risoluzione del convertitore analogico digitale del Netduino<br />
<strong>TensADC </strong>= tensione applicata al pin analogico<br />
<strong>ValInt </strong>= valore intero ottenuto dalla conversione</p>
</blockquote>
<p>Facciamo un esempio pratico, se il Netdino invia al pc un valore di 156 possiamo calcolare la tensione in ingresso in questo modo:</p>
<p style="text-align: center;">(MaxTenADC * ValInt) / Risol_ADC</p>
<p style="text-align: center;">(3.3Vdc * 156) / 1024 = 0.502 Vdc</p>
<p>quindi sull&#8217;ingresso analogico misureremo una tensione di circa 500 mVdc. Considerando la curva di risposta del sensore appuriamo che, con una tensione di 500mV, la temperatura misurata è di 0°C. Il datasheet ci dice che ad ogni variazione di grado corrisponde una variazione di 10mV, ciò ci permette di fare un calcolo per ottenere il valore in gradi in base al numero inviato dal Netduino via seriale.</p>
<p style="text-align: center;">(((3.3Vdc * 156) / 1024) &#8211; 0.5)/0.01 = 0.2°C</p>
<blockquote><p>dove:<br />
3.3Vdc è la tensione massima applicabile all&#8217;ingresso analogico<br />
156 è il valore intero ottenuto dalla conversione analogico digitale<br />
1024 è il massimo valore intero ottenibile con la conversione analogico digitale<br />
0.5 è la tensione del sensore a 0°C<br />
0.01 è la variazione di tensione per ogni grado (10mv/°C)</p></blockquote>
<p>con questo semplice esperimento abbiamo creato un termometro capace di inviare i dati ad un pc. Volendo possiamo acquistare un ulteriore sensore di temperatura e collegarlo ad un altro ingresso analogico per creare un termometro differenziale.<br />
In allegato trovate un file di progetto C# per leggere i dati dalla seriale.</p>
<p>Vi aspetto con commenti e suggerimenti e vi rimando al prossimo esperimento!</p>
<p>The post <a href="https://logicaprogrammabile.it/mcp9700a-netduino-sensore-temperatura-analogico/">MCP9700A Netduino e sensore di temperatura analogico</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://logicaprogrammabile.it/mcp9700a-netduino-sensore-temperatura-analogico/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
