<?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>I2C Archives - Esperimenti con logiche programmabili</title>
	<atom:link href="https://logicaprogrammabile.it/tag/i2c/feed/" rel="self" type="application/rss+xml" />
	<link>https://logicaprogrammabile.it/tag/i2c/</link>
	<description>Tutorial in italiano per imparare a programmare usando Arduino, Raspberry PI, Netduino</description>
	<lastBuildDate>Fri, 28 Dec 2018 18: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>I2C Archives - Esperimenti con logiche programmabili</title>
	<link>https://logicaprogrammabile.it/tag/i2c/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Netduino, utilizzare il PCF8574AP</title>
		<link>https://logicaprogrammabile.it/netduino-utilizzare-pcf8574ap-port-expander/</link>
					<comments>https://logicaprogrammabile.it/netduino-utilizzare-pcf8574ap-port-expander/#comments</comments>
		
		<dc:creator><![CDATA[Marco Lai]]></dc:creator>
		<pubDate>Thu, 23 Jan 2014 17:51:12 +0000</pubDate>
				<category><![CDATA[Tutorial Netduino]]></category>
		<category><![CDATA[I2C]]></category>
		<category><![CDATA[InputPort]]></category>
		<category><![CDATA[OutputPort]]></category>
		<guid isPermaLink="false">https://logicaprogrammabile.it/?p=4049</guid>

					<description><![CDATA[<p>Come espandere le porte IO del Netduino tramite PCF8574AP Nel precedente articolo abbiamo visto come utilizzare l&#8217;integrato PCF8574AP per espandere le porte IO di Arduino. Lo stesso circuito può essere adattato anche alla scheda Netduino. Dato che ho utilizzato Arduino Leonardo, i pin SCL e...</p>
<p>The post <a href="https://logicaprogrammabile.it/netduino-utilizzare-pcf8574ap-port-expander/">Netduino, utilizzare il PCF8574AP</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h3>Come espandere le porte IO del Netduino tramite PCF8574AP</h3>
<p>Nel <a title="PCF8574AP come espandere porte IO" href="https://logicaprogrammabile.it/2014/pcf8574ap-espandere-porte-io/">precedente articolo</a> abbiamo visto come utilizzare l&#8217;integrato <strong>PCF8574AP</strong> per espandere le <strong>porte IO</strong> di Arduino. Lo stesso circuito può essere adattato anche alla scheda Netduino. Dato che ho utilizzato Arduino Leonardo, i pin <strong>SCL</strong> e <strong>SDA</strong>, relativi al bus I2C, sono dedicati, mentre <strong>Netduino</strong> rispecchia la pin function della Arduino UNO e quindi i pin SDA e SCL sono disponibili rispettivamente sui pin analogico 4 e pin analogico 5.</p>
<p>In definitiva, per far funzionare il circuito, dobbiamo collegare i pin secondo la tabella seguente</p>
<table align="center">
<tbody>
<tr>
<td style="text-align: center;"><strong>PCF8574AP</strong></td>
<td style="text-align: center;"><strong>Netduino</strong></td>
</tr>
<tr>
<td>PIN 14 SCL</td>
<td style="text-align: left;">Analog PIN 5 SCL</td>
</tr>
<tr>
<td>PIN 15 SDA</td>
<td>Analog PIN 4 SDA</td>
</tr>
</tbody>
</table>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2014/01/WP_20140123_11_21_31_Pro.jpg"><img fetchpriority="high" decoding="async" class="aligncenter size-full wp-image-4052" alt="Netduino e PCF8574AP" src="https://logicaprogrammabile.it/wp-content/uploads/2014/01/WP_20140123_11_21_31_Pro.jpg" width="444" height="250" srcset="https://logicaprogrammabile.it/wp-content/uploads/2014/01/WP_20140123_11_21_31_Pro.jpg 444w, https://logicaprogrammabile.it/wp-content/uploads/2014/01/WP_20140123_11_21_31_Pro-300x168.jpg 300w" sizes="(max-width: 444px) 100vw, 444px" /></a></p>
<p><span id="more-4049"></span></p>
<p>Per quanto riguarda il codice sorgente possiamo osservare il listato seguente che permette di accendere e spegnere i led collegati alle porte del <strong>PCF8574AP</strong></p>
<p>[csharp]<br />
//buffer per memoriaazare indirizzi<br />
//e dati<br />
Byte[] tx_write = new Byte[1];<br />
Byte[] tx_read = new Byte[1];</p>
<p>//Configurazione contenente l&#8217;indirizzo del PCF8574AP<br />
//e la frequenza del bus i2c<br />
I2CDevice.Configuration cnf = new I2CDevice.Configuration(0x38, 100);</p>
<p>//Creo un oggetto per eseguire le richieste di lettura e scrittura<br />
I2CDevice expanderPCF8574 = new I2CDevice(cnf);</p>
<p>//creo un oggetto I2CReadTransaction che viene associato al buffer tx_read<br />
//il buffer viene utilizzato per verificare lo stato delle porte del PCF8574AP<br />
I2CDevice.I2CReadTransaction[] rt_data = new<br />
I2CDevice.I2CReadTransaction[] { I2CDevice.CreateReadTransaction(tx_read) };</p>
<p>//creo un oggetto I2CWriteTransaction che viene associato al buffere tx_write<br />
//il buffer tx viene utilizzato per spedire lo stato delle porte del PCF8574AP<br />
I2CDevice.I2CWriteTransaction[] wt_write = new<br />
I2CDevice.I2CWriteTransaction[] { I2CDevice.CreateWriteTransaction(tx_write) };</p>
<p>while (true)<br />
{<br />
  //imposto tutte le porte a livello logico basso<br />
  tx_write[0] = (Byte)(0x00);<br />
  //eseguo il comando<br />
  expanderPCF8574.Execute(wt_write, 10);</p>
<p>  Thread.Sleep(1000);</p>
<p>  //imposto tutte le porte a livello logico alto<br />
  tx_write[0] = (Byte)(0xFF);<br />
  //eseguo il comando<br />
  expanderPCF8574.Execute(wt_write, 10);</p>
<p>  Thread.Sleep(1000);<br />
}<br />
[/csharp]</p>
<h3>Leggere lo stato delle porte</h3>
<p>la lettura dello stato delle porte del PCF8574AP avviene eseguendo il comando relativo all&#8217;oggetto i2creadtransaction:</p>
<p>[csharp]<br />
while (true)<br />
{<br />
  //eseguo il comando<br />
  expanderPCF8574.Execute(rt_data, 10);</p>
<p>  Debug.Print(tx_read[0].ToString());</p>
<p>  Thread.Sleep(1000);<br />
}<br />
[/csharp]</p>
<p>Anche utilizzando <strong>Netduino</strong> i comandi da eseguire per utilizzare il <strong>PCF8574AP</strong> sono molto semplici ed intuitivi.</p>
<p>The post <a href="https://logicaprogrammabile.it/netduino-utilizzare-pcf8574ap-port-expander/">Netduino, utilizzare il PCF8574AP</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://logicaprogrammabile.it/netduino-utilizzare-pcf8574ap-port-expander/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>PCF8574AP come espandere porte IO</title>
		<link>https://logicaprogrammabile.it/pcf8574ap-espandere-porte-io/</link>
					<comments>https://logicaprogrammabile.it/pcf8574ap-espandere-porte-io/#comments</comments>
		
		<dc:creator><![CDATA[Marco Lai]]></dc:creator>
		<pubDate>Wed, 22 Jan 2014 15:14:35 +0000</pubDate>
				<category><![CDATA[Tutorial Arduino]]></category>
		<category><![CDATA[I2C]]></category>
		<category><![CDATA[InputPort]]></category>
		<category><![CDATA[OutputPort]]></category>
		<guid isPermaLink="false">https://logicaprogrammabile.it/?p=4020</guid>

					<description><![CDATA[<p>Utilizzare un PCF8574ap per espandere le porte IO di Arduino Capita di trovarci a realizzare applicazioni in cui il numero dei pin digitali richiesti, supera quelli disponibili sulla scheda Arduino UNO. In questi casi potremmo utilizzare una scheda con un numero maggiore di pin IO...</p>
<p>The post <a href="https://logicaprogrammabile.it/pcf8574ap-espandere-porte-io/">PCF8574AP come espandere porte IO</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h3>Utilizzare un PCF8574ap per espandere le porte IO di Arduino</h3>
<p>Capita di trovarci a realizzare applicazioni in cui il numero dei <strong>pin digitali</strong> richiesti, supera quelli disponibili sulla scheda <strong>Arduino UNO</strong>. In questi casi potremmo utilizzare una scheda con un numero maggiore di <strong>pin IO</strong> (ad esempio la Arduino MEGA, la Arduino DUE &#8230;) o scegliere dei <strong>circuiti esterni</strong> che danno la possibilità di espandere le porte IO utilizzando una comunicazione seriale <strong>I2C</strong> o <strong>SPI</strong>.</p>
<p>L&#8217;integrato <strong>PCF8574AP</strong> permette di risolvere questo problema fornendo<strong> 8 porte IO</strong> che possono essere gestite utilizzando il collegamento <strong>seriale I2C</strong>. Lo schema elettrico seguente mostra come collegare il <strong>pcf8574ap</strong> alla scheda <strong>Arduino Leonardo</strong>. L&#8217;unica osservazione riguarda le uscite del <strong>PCF8574</strong>, infatti come potete osservare i led non sono collegati direttamente alle porte dell&#8217;integrato ma bensì sono collegati tramite una resistenza alla linea dei 5Vdc. Questo perché l&#8217;integrato non è in grado di fornire la corrente sufficiente per alimentare il led; è quindi necessaria una resistenza di<strong> pull-up</strong>.</p>
<p><span id="more-4020"></span></p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2014/01/PCF8574ap.png"><img decoding="async" class="aligncenter size-full wp-image-4034" alt="Arduino Leonardo PCF8574AP" src="https://logicaprogrammabile.it/wp-content/uploads/2014/01/PCF8574ap.png" width="724" height="407" srcset="https://logicaprogrammabile.it/wp-content/uploads/2014/01/PCF8574ap.png 724w, https://logicaprogrammabile.it/wp-content/uploads/2014/01/PCF8574ap-300x168.png 300w" sizes="(max-width: 724px) 100vw, 724px" /></a></p>
<p>Quando impostiamo, per esempio, il pin <strong>P0</strong> al livello logico alto, otteniamo l&#8217;accensione del led perché la corrente che fluisce dall&#8217;alimentazione attraversa la resistenza e poi il led. Quando impostiamo il pin <strong>P0</strong> al livello logico basso il led si spegne perché la corrente viene &#8216;assorbita&#8217; dall&#8217;integrato. Nelle figure seguenti potete osservare quanto detto:</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2014/01/PCF8574_Led_ON.png"><img decoding="async" class="aligncenter size-full wp-image-4038" alt="PCF8574ap led on" src="https://logicaprogrammabile.it/wp-content/uploads/2014/01/PCF8574_Led_ON.png" width="331" height="374" srcset="https://logicaprogrammabile.it/wp-content/uploads/2014/01/PCF8574_Led_ON.png 331w, https://logicaprogrammabile.it/wp-content/uploads/2014/01/PCF8574_Led_ON-265x300.png 265w" sizes="(max-width: 331px) 100vw, 331px" /></a></p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2014/01/PCF8574_Led_OFF.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-4037" alt="PCF8574 Led off" src="https://logicaprogrammabile.it/wp-content/uploads/2014/01/PCF8574_Led_OFF.png" width="313" height="384" srcset="https://logicaprogrammabile.it/wp-content/uploads/2014/01/PCF8574_Led_OFF.png 313w, https://logicaprogrammabile.it/wp-content/uploads/2014/01/PCF8574_Led_OFF-244x300.png 244w" sizes="auto, (max-width: 313px) 100vw, 313px" /></a></p>
<p>Il codice per testare il circuito è molto semplice e permette di accendere e spegnere i led collegati ai pin delle porte dell&#8217;integrato <strong>PCF8574AP</strong>:</p>
<p>[c]<br />
#include &lt;Wire.h&gt;</p>
<p>void setup()<br />
{<br />
  Wire.begin();<br />
  delay(1000);<br />
}</p>
<p>void loop()<br />
{<br />
  //imposto tutti i pin al livello<br />
  //logico alto<br />
  Wire.beginTransmission(0x38);<br />
  //invio un byte<br />
  Wire.write((byte)0b11111111);<br />
  //fine trasmissione<br />
  Wire.endTransmission();</p>
<p>  delay(1000);</p>
<p>  //imposto tutti i pin al livello<br />
  //logico basso<br />
  Wire.beginTransmission(0x38);<br />
  //invio un byte<br />
  Wire.write((byte)0b00000000);<br />
  //fine trasmissione<br />
  Wire.endTransmission();</p>
<p>  delay(1000);<br />
}<br />
[/c]</p>
<p>Avendo espresso il valore in forma binaria riusciamo facilmente ad accendere o spegnere ogni led cambiando il valore di ogni singolo bit. Ad esempio questo codice accende e spegne solo il led sulla porta <strong>P0</strong>:</p>
<p>[c]<br />
#include &lt;Wire.h&gt;</p>
<p>void setup()<br />
{<br />
  Wire.begin();<br />
  delay(1000);<br />
}</p>
<p>void loop()<br />
{<br />
  //imposto il pin P0 al livello<br />
  //logico alto<br />
  Wire.beginTransmission(0x38);<br />
  //invio un byte<br />
  Wire.write((byte)0b00000001);<br />
  //fine trasmissione<br />
  Wire.endTransmission();</p>
<p>  delay(1000);</p>
<p>  //imposto il pin P0 al livello<br />
  //logico basso<br />
  Wire.beginTransmission(0x38);<br />
  //invio un byte<br />
  Wire.write((byte)0b00000000);<br />
  //fine trasmissione<br />
  Wire.endTransmission();</p>
<p>  delay(1000);<br />
}<br />
[/c]</p>
<h3>Leggere i valori in ingresso</h3>
<p>La lettura degli ingressi avviene semplicemente effettuando una richiesta di un byte al <strong>PCF8574AP</strong>. L&#8217;integrato provvederà automaticamente, tramite la sua architettura interna, a fornire al master lo stato delle porte. Possiamo ad esempio collegare i pin da P0 a P7 a massa o alla +5Vdc e successivamente effettuare una lettura:</p>
<p>[c]<br />
#include &lt;Wire.h&gt;</p>
<p>void setup()<br />
{<br />
  Serial.begin(9600);<br />
  delay(6000);</p>
<p>  Wire.begin();<br />
  delay(1000);<br />
}</p>
<p>void loop()<br />
{<br />
  Wire.requestFrom(0x38,1);<br />
  if(Wire.available())<br />
  {<br />
    Serial.println(Wire.read(), BIN);<br />
  }</p>
<p>  delay(1000);<br />
}<br />
[/c]</p>
<p>il codice precedente printa in binario lo stato di ogni singola porta del <strong>PCF8574AP</strong>, ad esempio proviamo a mettere a massa i pin <strong>P0</strong>, <strong>P1</strong>, <strong>P2</strong> e <strong>P3</strong> e colleghiamo alla +5Vdc i pin <strong>P5</strong>, <strong>P6</strong>, <strong>P7</strong>, <strong>P8</strong>, sul serial monitor osserveremo la stringa <strong>11110000</strong>.</p>
<p>Per semplicità ho utilizzato delle variabili scrivendole in binario ma nulla ci vieta di utilizzare le <a href="https://logicaprogrammabile.it/2012/operatori-spostare-bit/" target="_blank">funzioni di bitwise</a> per creare codice più professionale.</p>
<p>The post <a href="https://logicaprogrammabile.it/pcf8574ap-espandere-porte-io/">PCF8574AP come espandere porte IO</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://logicaprogrammabile.it/pcf8574ap-espandere-porte-io/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Netduino impiegare la memoria 24LC256</title>
		<link>https://logicaprogrammabile.it/netduino-impiegare-la-memoria-24lc256/</link>
					<comments>https://logicaprogrammabile.it/netduino-impiegare-la-memoria-24lc256/#respond</comments>
		
		<dc:creator><![CDATA[Marco Lai]]></dc:creator>
		<pubDate>Thu, 16 Jan 2014 12:49:22 +0000</pubDate>
				<category><![CDATA[Tutorial Netduino]]></category>
		<category><![CDATA[bus]]></category>
		<category><![CDATA[I2C]]></category>
		<guid isPermaLink="false">https://logicaprogrammabile.it/?p=4010</guid>

					<description><![CDATA[<p>Come usare la memoria 24LC256 con Netduino dopo aver scritto l&#8217;articolo sull&#8217;utilizzo della memoria 24LC256 utilizzando una scheda Arduino ho realizzato questo piccolo tutorial per tutti gli utenti che possiedono una scheda Netduino. La parte teorica e lo schema elettrico del circuito rimangono invariati, l&#8217;unica...</p>
<p>The post <a href="https://logicaprogrammabile.it/netduino-impiegare-la-memoria-24lc256/">Netduino impiegare la memoria 24LC256</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h3>Come usare la memoria 24LC256 con Netduino</h3>
<p>dopo aver scritto<a title="24LC256 utilizzare una memoria seriale su bus I2C" href="https://logicaprogrammabile.it/2014/utilizzare-una-memoria-seriale-24lc256/"> l&#8217;articolo sull&#8217;utilizzo della memoria 24LC256</a> utilizzando una scheda <strong>Arduino</strong> ho realizzato questo piccolo tutorial per tutti gli utenti che possiedono una scheda <strong>Netduino</strong>.<br />
La parte teorica e lo schema elettrico del circuito rimangono invariati, l&#8217;unica ovvia differenza è la scrittura del codice che in questo caso si basa sul <strong>linguaggio C#</strong>.</p>
<p><span id="more-4010"></span></p>
<p>Questo è il codice:</p>
<p>[csharp]<br />
//buffer per memorizzare indirizzi<br />
//e dati<br />
Byte[] tx_write = new Byte[3];<br />
Byte[] tx_read = new Byte[2];<br />
Byte[] rx_data = new Byte[1];</p>
<p>Int16 indirizzo = 0;<br />
Byte data = 0;<br />
Int32 ciclo = 0;</p>
<p>//creo un oggetto per usare il led onboard<br />
OutputPort led = new OutputPort(Pins.ONBOARD_LED, false);</p>
<p>//accendo il led onboard<br />
led.Write(true);</p>
<p>//Configurazione contenente l&#8217;indirizzo della memoria 24LC256<br />
//e la frequenza del bus i2c<br />
I2CDevice.Configuration cnf = new I2CDevice.Configuration(0x50, 100);</p>
<p>//Creo un oggetto per eseguire le richieste di lettura e scrittura<br />
I2CDevice mem24LC256 = new I2CDevice(cnf);</p>
<p>//creo un oggetto I2CReadTransaction che viene associato al buffer rx_data<br />
//il buffer tx viene utilizzato per contenere i dati letti dalla memoria 24LC256<br />
I2CDevice.I2CReadTransaction[] rt_data = new<br />
    I2CDevice.I2CReadTransaction[] { I2CDevice.CreateReadTransaction(rx_data) };</p>
<p>//creo un oggetto I2CWriteTransaction che viene associato al buffere tx_write<br />
//il buffer tx viene utilizzato per spedire i due byte dell&#8217;indirizzo della<br />
//locazione di memoria che vogliamo utilizzare e il byte contenente il dato<br />
//da memorizzare nella memoria<br />
I2CDevice.I2CWriteTransaction[] wt_write = new<br />
    I2CDevice.I2CWriteTransaction[] { I2CDevice.CreateWriteTransaction(tx_write) };</p>
<p>//creo un oggetto I2CWriteTransaction che viene associato al buffere tx_read<br />
//il buffer tx_read viene utilizzato per selezionare la locazione di memoria<br />
//da cui vogliamo leggere il contenuto<br />
I2CDevice.I2CWriteTransaction[] wt_read = new<br />
    I2CDevice.I2CWriteTransaction[] { I2CDevice.CreateWriteTransaction(tx_read) };</p>
<p>//info di debug<br />
Debug.Print(&quot;START Scrittura&quot;);</p>
<p>//eseguo un ciclo per memorizzare dati in tutti e 32KB<br />
for(ciclo = 0; ciclo &lt; 32000; ciclo++)<br />
{<br />
    //compongo il buffer con l&#8217;indirizzo di memoria<br />
    //che voglio utilizzare ed il dato che voglio<br />
    //scrivere al suo interno<br />
    tx_write[0] = (Byte)((indirizzo &gt;&gt; 8) &amp; 0xff);<br />
    tx_write[1] = (Byte)(indirizzo &amp; 0xff);<br />
    tx_write[2] = data;</p>
<p>    //eseguo il comando<br />
    mem24LC256.Execute(wt_write, 10);</p>
<p>    //incremento il valore di data e lo resetto<br />
    //quando raggiunge il valore 255<br />
    data++;</p>
<p>    if (data == 255)<br />
        data = 0;</p>
<p>    //incremento il valore della<br />
    //locazione di memoria da usare<br />
    indirizzo++;</p>
<p>}</p>
<p>Debug.Print(&quot;Fine Scrittura&quot;);</p>
<p>//attendo 1 secondo<br />
Thread.Sleep(1000);</p>
<p>Debug.Print(&quot;Inizio lettura&quot;);</p>
<p>//resetto il valore dell&#8217;indirizzo<br />
indirizzo = 0;</p>
<p>for (ciclo = 0; ciclo &lt; 32000; ciclo++)<br />
{<br />
    //utilizzo il buffer tx_read per caricare<br />
    //l&#8217;indirizzo della locazione di memoria da dove<br />
    //leggere i dati<br />
    tx_read[0] = (Byte)((indirizzo &gt;&gt; 8) &amp; 0xff);<br />
    tx_read[1] = (Byte)(indirizzo &amp; 0xff);</p>
<p>    //eseguo il comando<br />
    mem24LC256.Execute(wt_read, 10);</p>
<p>    //attendo 5 ms<br />
    Thread.Sleep(5);</p>
<p>    //ora eseguo il comando per leggere i dati dalla<br />
    //locazione di memoria precedentemente selezionata<br />
    //il dato letto viene memorizzato nelbuffer rx_data<br />
    mem24LC256.Execute(rt_data, 10);</p>
<p>    //printo l&#8217;indirizzo della locazione di memoria corrente<br />
    //ed il suo contenuto<br />
    Debug.Print(indirizzo.ToString() + &quot;:&quot; + rx_data[0].ToString());</p>
<p>    //incremento il valore della<br />
    //locazione di memoria da usare<br />
    indirizzo++;<br />
}</p>
<p>Debug.Print(&quot;Fine lettura&quot;);</p>
<p>//spengo il led onboard a fine lettura<br />
led.Write(false);</p>
<p>[/csharp]</p>
<p>Il codice è ricco di commenti che spiegano cosa eseguono le istruzioni!</p>
<p>The post <a href="https://logicaprogrammabile.it/netduino-impiegare-la-memoria-24lc256/">Netduino impiegare la memoria 24LC256</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://logicaprogrammabile.it/netduino-impiegare-la-memoria-24lc256/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>24LC256 utilizzare una memoria seriale su bus I2C</title>
		<link>https://logicaprogrammabile.it/utilizzare-una-memoria-seriale-24lc256/</link>
					<comments>https://logicaprogrammabile.it/utilizzare-una-memoria-seriale-24lc256/#comments</comments>
		
		<dc:creator><![CDATA[Marco Lai]]></dc:creator>
		<pubDate>Mon, 13 Jan 2014 23:06:15 +0000</pubDate>
				<category><![CDATA[Tutorial Arduino]]></category>
		<category><![CDATA[Bus I2C]]></category>
		<category><![CDATA[I2C]]></category>
		<guid isPermaLink="false">https://logicaprogrammabile.it/?p=3970</guid>

					<description><![CDATA[<p>Come usare una memoria 24LC256 su bus I2C Il limite di memoria di una scheda Arduino può essere superato utilizzando delle memorie esterne che permettono di aggiungere capacità di memorizzazione per tutte quelle applicazioni che richiedono la registrazione di dati. Possiamo scegliere tantissimi tipi di...</p>
<p>The post <a href="https://logicaprogrammabile.it/utilizzare-una-memoria-seriale-24lc256/">24LC256 utilizzare una memoria seriale su bus I2C</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h3>Come usare una memoria 24LC256 su bus I2C</h3>
<p>Il limite di memoria di una scheda Arduino può essere superato utilizzando delle memorie esterne che permettono di aggiungere capacità di memorizzazione per tutte quelle applicazioni che richiedono la registrazione di dati. Possiamo scegliere tantissimi tipi di memorie a seconda del tipo di interfaccia (I2C, SPI, parallela&#8230;) e dalla loro capacità.</p>
<p>Per questo tutorial ho scelto una comunissima<strong> EEPROM Seriale</strong> prodotta da <strong>Microchip</strong>, la <strong>24LC256</strong>. Questa memoria può essere collegata alle schede Arduino tramite bus I2C e offre 256 Kbits di memoria (32KB). La pin function della memoria è rappresentata in figura:</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2014/01/24LC256_PF.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3978" src="https://logicaprogrammabile.it/wp-content/uploads/2014/01/24LC256_PF.png" alt="24LC256" width="494" height="314" srcset="https://logicaprogrammabile.it/wp-content/uploads/2014/01/24LC256_PF.png 494w, https://logicaprogrammabile.it/wp-content/uploads/2014/01/24LC256_PF-300x190.png 300w" sizes="auto, (max-width: 494px) 100vw, 494px" /></a></p>
<p><span id="more-3970"></span></p>
<p>i pin <strong>A0</strong>, <strong>A1</strong>, <strong>A2</strong> permettono di specificare l&#8217;indirizzo del dispositivo sul bus I2C, i pin <strong>Vcc</strong> e <strong>Vss</strong> sono rispettivamente l&#8217;alimentazione (5Vdc) e la massa (Gnd), il pin <strong>WP</strong> (Write Protect) abilita (se collegato a Gnd) o disabilita (se collegato a Vcc) la scrittura della EEPROM, i pin <strong>SCL</strong> e <strong>SDA</strong> sono relativi al collegamento I2C.</p>
<p>secondo il datasheet del produttore possiamo riassumere alcune caratteristiche fondamentali:</p>
<table>
<tbody>
<tr>
<td>Massimo tempo di scrittura</td>
<td>5mS</td>
</tr>
<tr>
<td>Cicli di scrittura/lettura</td>
<td>100000</td>
</tr>
<tr>
<td>Conservazione dei dati</td>
<td>&gt;200 anni</td>
</tr>
<tr>
<td>Consumo di corrente in scrittura</td>
<td>3mA (alimentazione a 5Vdc)</td>
</tr>
<tr>
<td>Consumo di corrente in lettura</td>
<td>400uA (alimentazione a 5Vdc)</td>
</tr>
<tr>
<td>Consumo di corrente in stand-by</td>
<td>100nA (alimentazione a 5Vdc)</td>
</tr>
<tr>
<td>Intervallo di temperature versione industriale</td>
<td>da -40°C a +85°C</td>
</tr>
<tr>
<td>Intervallo di temperature versione automotive</td>
<td>da -40°C a +125°C</td>
</tr>
</tbody>
</table>
<p>Per questo tutorial ho utilizzato una <strong>Arduino Leonardo</strong>. La figura seguente mostra i collegamenti del circuito.</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2014/01/Schema.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3980" src="https://logicaprogrammabile.it/wp-content/uploads/2014/01/Schema.png" alt="Schema elettrico Leonardo 24LC256" width="398" height="349" srcset="https://logicaprogrammabile.it/wp-content/uploads/2014/01/Schema.png 398w, https://logicaprogrammabile.it/wp-content/uploads/2014/01/Schema-300x263.png 300w" sizes="auto, (max-width: 398px) 100vw, 398px" /></a></p>
<p>Nello schema possiamo osservare che i pin <strong>A0</strong>, <strong>A1</strong>, <strong>A2</strong> sono connessi a massa. Questi pin permettono di personalizzare l&#8217;indirizzo del dispositivo all&#8217;interno del bus I2C. Nel data sheet verifichiamo come viene formato il <strong>control byte address</strong>:</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2014/01/AddressChip.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3989" src="https://logicaprogrammabile.it/wp-content/uploads/2014/01/AddressChip.png" alt="Control Byte Address" width="335" height="201" srcset="https://logicaprogrammabile.it/wp-content/uploads/2014/01/AddressChip.png 335w, https://logicaprogrammabile.it/wp-content/uploads/2014/01/AddressChip-300x180.png 300w" sizes="auto, (max-width: 335px) 100vw, 335px" /></a>i 4 bit più significativi sono preimpostati (<strong>Control Code</strong>) mentre i bit <strong>A0</strong>, <strong>A1</strong> e <strong>A2</strong> sono personalizzabili da noi. Il bit meno significativo <strong>R/W</strong>, serve per selezionare una operazione di scrittura o una operazione di lettura.<br />
Avendo a massa i pin A0, A1 e A2 i campi <strong>Chip Select Bits</strong> sono a zero. L&#8217;indirizzo del dispositivo è quindi il seguente:</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2014/01/SetAddressChip.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3991" src="https://logicaprogrammabile.it/wp-content/uploads/2014/01/SetAddressChip.png" alt="Set address bit" width="334" height="116" srcset="https://logicaprogrammabile.it/wp-content/uploads/2014/01/SetAddressChip.png 334w, https://logicaprogrammabile.it/wp-content/uploads/2014/01/SetAddressChip-300x104.png 300w" sizes="auto, (max-width: 334px) 100vw, 334px" /></a></p>
<p style="text-align: left;">in esadecimale otteniamo il valore:</p>
<p style="text-align: center;"><strong>0x50</strong></p>
<p style="text-align: left;">Per poter eseguire operazioni di scrittura e lettura della memoria EEPROM del 24LC256, è necessario inviare, oltre al <strong>Control Byte</strong> (che specifica l&#8217;indirizzo del dispositivo nel busI2C), altri due byte che indicano l&#8217;indirizzo della locazione di memoria EEPROM del 24LC256 che vogliamo scrivere o leggere:</p>
<p style="text-align: left;"><a href="https://logicaprogrammabile.it/wp-content/uploads/2014/01/MemAddressAssignment.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3993" src="https://logicaprogrammabile.it/wp-content/uploads/2014/01/MemAddressAssignment.png" alt="Memoria EEPROM 24LC256" width="481" height="148" srcset="https://logicaprogrammabile.it/wp-content/uploads/2014/01/MemAddressAssignment.png 481w, https://logicaprogrammabile.it/wp-content/uploads/2014/01/MemAddressAssignment-300x92.png 300w" sizes="auto, (max-width: 481px) 100vw, 481px" /></a></p>
<p style="text-align: left;">il dispositivo <strong>24LC256</strong> possiede <strong>256Kbit</strong> di memoria, quindi le locazioni di memoria che possiamo scrivere e leggere sono<strong> 32000 byte</strong> (256000 / 8).<br />
Avendo a disposizione 2 byte per selezionare l&#8217;indirizzo (<strong>Address High Byte</strong> e <strong>Address Low Byte</strong>) possiamo utilizzare una <strong>variabile int</strong> (formata appunto da 2 Byte) che impiegheremmo per specificare il valore dell&#8217;indirizzo della locazione di memoria (da 0 a 31999).</p>
<p style="text-align: left;">La libreria <strong>Wire</strong> non permette comunque di passare un valore intero perciò potremmo semplicemente effettuare <a href="https://logicaprogrammabile.it/2012/operatori-spostare-bit/">una operazione bitwise</a> per dividere la variabile intera in due byte. Fortunatamente esistono già delle funzioni che semplificano questa operazione, <a href="http://arduino.cc/en/Reference/HighByte" target="_blank" rel="noopener">highByte </a>e <a href="http://arduino.cc/en/Reference/LowByte" target="_blank" rel="noopener">lowByte</a>.</p>
<p style="text-align: left;">Il codice di esempio seguente permette di scrivere tutti i  32000 byte della mem0rie a di eseguire una lettura degli stessi:</p>
<pre class="lang:arduino decode:true  ">#include &lt;Wire.h&gt;

int indirizzo = 0;
int data = 0;
int ciclo = 0;
void setup()
{
  //init seriale
  Serial.begin(9600);
  //per la Arduino Leonardo devo
  //attendere l'inizializzazione del modulo
  while (!Serial)
  {
    ;
  }

  //attendo ulteriori 5 secondi
  //prima di inviare un dato sulla seriale
  delay(5000);
  //invio un messaggio al serial monitor
  Serial.println("Start");
  //inizializzo la porta I2C della Arduino
  Wire.begin();
}

void loop()
{
  //avviso dell'inizio della
  //scrittura dei dati sulla seriale
  Serial.println("Inizio Scrittura");
  //init variabile
  indirizzo = 0;
  //eseguo ciclicamente la scrittura di
  //tutte e 32000 locazioni di memoria
  for (ciclo = 0; ciclo &amp; lt; 32000; ciclo++)
  {
    //invio il control byte specificando
    //una richiesta di scrittura
    Wire.beginTransmission(0x50);
    //invio due byte contenenti l'indirizzo della
    //locazione di memoria che voglio scrivere un byte
    Wire.write(highByte(indirizzo));
    Wire.write(lowByte(indirizzo));
    //scrivo un byte nella locazione di memoria
    //precedentemente selezionata
    Wire.write(byte(data));
    //fine trasmissione
    Wire.endTransmission();
    //incrementa il valore di data
    data++;
    //quando la variabile data arriva a 255
    //resetto il suo valore a zero
    if (data == 255)
      data = 0;

    //incrementa il valore dell'indirizzo
    indirizzo++;
    //attendi 5ms per poter terminare le operazioni di
    //scrittura sulla memoria
    delay(5);
  }

  //avvisami quando la scrittura di 32000 byte
  //è terminata
  Serial.println("Fine Scrittura");
  //attendi 1/2 secondo
  delay(500);
  //avvisami dell'inizio della lettura
  Serial.println("Inizio lettura");

  //init variabile
  indirizzo = 0;
  for (ciclo = 0; ciclo &amp; lt; 32000; ciclo++)
  {
    //invio il control byte specificando
    //una richiesta di scrittura
    Wire.beginTransmission(0x50);
    //invio due byte per selezionare la locazione
    //di memoria da leggere
    Wire.write(highByte(indirizzo));
    Wire.write(lowByte(indirizzo));
    Wire.endTransmission();
    //incremento la variabile indirizzo
    indirizzo++;
    //richiedo un byte al 24LC256
    Wire.requestFrom(0x50, 1);
    //attendo la disponibilità di dati sul bus i2c

    while (Wire.available())
    {
      Serial.print(ciclo);
      Serial.print(": ");
      //leggo dal bus il dato relativo alla
      //locazione di memoria precedentemente specificata
      byte c = Wire.read();
      //invio il dato al serial monitor
      Serial.println(c);
    }
  }
  delay(1000);
}
</pre>
<p>&nbsp;</p>
<p style="text-align: left;">la scrittura di 32000 byte richiederà qualche minuto poiché il codice impiega circa 5ms per scrivere un byte (32000 * 0.005 =&gt; 160 secondi). La lettura invece risulta più fluida ed è anche influenzata dalla velocità della seriale, che per questo esempio è impostata a 9600bps.</p>
<p style="text-align: left;">
<p>The post <a href="https://logicaprogrammabile.it/utilizzare-una-memoria-seriale-24lc256/">24LC256 utilizzare una memoria seriale su bus I2C</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://logicaprogrammabile.it/utilizzare-una-memoria-seriale-24lc256/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Usare la porta DAC del PCF8591P</title>
		<link>https://logicaprogrammabile.it/arduino-usare-porta-dac-pcf8591p/</link>
					<comments>https://logicaprogrammabile.it/arduino-usare-porta-dac-pcf8591p/#respond</comments>
		
		<dc:creator><![CDATA[Marco Lai]]></dc:creator>
		<pubDate>Mon, 04 Nov 2013 10:17:55 +0000</pubDate>
				<category><![CDATA[Tutorial Arduino]]></category>
		<category><![CDATA[DAC]]></category>
		<category><![CDATA[I2C]]></category>
		<guid isPermaLink="false">https://logicaprogrammabile.it/?p=3886</guid>

					<description><![CDATA[<p>Come generare una tensione analogica da un dato digitale Nel precedente articolo abbiamo imparato a gestire i quattro ingressi analogici del dispositivo PCF8591P. In questo tutorial impareremo a utilizzare la porta DAC (Digital to Analog Converter) per creare una tensione continua partendo da un dato...</p>
<p>The post <a href="https://logicaprogrammabile.it/arduino-usare-porta-dac-pcf8591p/">Usare la porta DAC del PCF8591P</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1>Come generare una tensione analogica da un dato digitale</h1>
<p>Nel<a title="Come usare l’integrato PCF8591" href="https://logicaprogrammabile.it/arduino-usare-integrato-pcf8591/"> precedente articolo</a> abbiamo imparato a gestire i quattro ingressi analogici del dispositivo <strong>PCF8591P</strong>. In questo tutorial impareremo a utilizzare la porta <strong><a href="http://it.wikipedia.org/wiki/Convertitore_digitale-analogico" target="_blank" rel="noopener">DAC</a></strong> (<strong>Digital to Analog Converter</strong>) per creare una tensione continua partendo da un dato digitale.</p>
<p>Lo schema elettrico rimane pressoché invariato. L&#8217;unica modifica riguarda l&#8217;eliminazione dei collegamenti sui pin analogici <strong>AIN</strong> ed il collegamento al <strong>pin AOUT</strong> di un diodo led rosso da 3mm e di una resistenza (R) da 100Ohm:</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/10/SchemaElettricoPCF8591P_ANA.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3889" src="https://logicaprogrammabile.it/wp-content/uploads/2013/10/SchemaElettricoPCF8591P_ANA.png" alt="Usare DAC pcd8591p" width="375" height="274" srcset="https://logicaprogrammabile.it/wp-content/uploads/2013/10/SchemaElettricoPCF8591P_ANA.png 375w, https://logicaprogrammabile.it/wp-content/uploads/2013/10/SchemaElettricoPCF8591P_ANA-300x219.png 300w" sizes="auto, (max-width: 375px) 100vw, 375px" /></a><span id="more-3886"></span></p>
<p>L&#8217;indirizzo del <strong>PCF8591P</strong> sul bus I2C non viene modificato, rispetto <a title="Come usare l’integrato PCF8591" href="https://logicaprogrammabile.it/arduino-usare-integrato-pcf8591/">all&#8217;articolo precedente</a>, dato che i pin A0, A1 e A2 sono collegati a massa.<br />
Possiamo sempre gestire l&#8217;acquisizione dai pin ADC (AIN0, AIN1, AIN2, AIN3), una funzione non esclude l&#8217;altra.</p>
<p>La risoluzione del convertitore digitale analogico è di 8bit quindi i valori possibili possono essere espressi con 256 valori digitali (da 0 a 255). Il valore di tensione associato per ogni valore digitali dipende dalla tensione presente sul pinVref e sul pin AGnd secondo questo grafico:</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/10/DAC_Graph.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3891" src="https://logicaprogrammabile.it/wp-content/uploads/2013/10/DAC_Graph.png" alt="DAC_Graph" width="381" height="294" srcset="https://logicaprogrammabile.it/wp-content/uploads/2013/10/DAC_Graph.png 381w, https://logicaprogrammabile.it/wp-content/uploads/2013/10/DAC_Graph-300x231.png 300w" sizes="auto, (max-width: 381px) 100vw, 381px" /></a></p>
<p>Nel circuito precedente il pin14 VRef è collegato alla 5Vdc mentre il pin13 Agnd è collegato a massa. Quindi per conoscere il valore di tensione associato alla variazione di un singolo bit possiamo eseguire questo calcolo:</p>
<p style="text-align: center;"><strong>tensione_rif/bit_totali = (Vref-Agnd) / 256 =&gt; (5-0)/256 =&gt; 19,5 mVdc per variazione d bit<br />
</strong></p>
<p>ad esempio se caricassi sul <strong>DAC data register</strong> il valore decimale <strong>127</strong> otterrei in uscita dal <strong>pin15</strong> del PCF8591 la tensione di:</p>
<p style="text-align: center;"><strong>Vout = ValDAC * ValStep =&gt; 127 * 19.5mVdc =&gt; 2.47Vdc</strong></p>
<p>Cambiando il valore di Vref, ad esempio portandolo a 3.3Vdc otteniamo delle variazioni di tensione per bit più piccole. Questa scelta dipende dal tipo di progetto che vogliamo realizzare.</p>
<p>Per attivare la <strong>porta DAC</strong> del PCF8591P dobbiamo settare al livello alto il <strong>bit7</strong> (Analog Output Enable Flag) del registro <strong>Control Byte</strong>.</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/10/ControlRegister_ANA.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3890" src="https://logicaprogrammabile.it/wp-content/uploads/2013/10/ControlRegister_ANA.png" alt="Grafico DAC" width="427" height="183" srcset="https://logicaprogrammabile.it/wp-content/uploads/2013/10/ControlRegister_ANA.png 427w, https://logicaprogrammabile.it/wp-content/uploads/2013/10/ControlRegister_ANA-300x128.png 300w" sizes="auto, (max-width: 427px) 100vw, 427px" /></a></p>
<p>La sequenza di byte da inviare al <strong>PCF8591P</strong> segue lo schema rappresentato nella figura seguente:</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/10/PCF8591P_DAC_Register.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3894" src="https://logicaprogrammabile.it/wp-content/uploads/2013/10/PCF8591P_DAC_Register.png" alt="PCF8591 DAC Register" width="557" height="150" srcset="https://logicaprogrammabile.it/wp-content/uploads/2013/10/PCF8591P_DAC_Register.png 557w, https://logicaprogrammabile.it/wp-content/uploads/2013/10/PCF8591P_DAC_Register-300x80.png 300w" sizes="auto, (max-width: 557px) 100vw, 557px" /></a></p>
<p>ovvero, dopo aver &#8216;selezionato&#8217; sul bus I2C il dispositivo tramite il suo indirizzo, inviamo il byte di configurazione e successivamente il byte contenente il valore digitale che verrà poi convertito in segnale analogico.</p>
<p>Passando al codice di esempio ho realizzato uno sketch che ha il compito di  far variare la tensione sul pin15 da 5Vdc sino a scendere gradualmente a 0Vdc per poi ritornare, sempre gradualmente, a 5Vdc, ottenendo un effetto fade sul diodo led collegato come da schema:</p>
<pre class="lang:arduino decode:true ">#include &lt;Wire.h&gt;
byte ciclo=0;

void setup()
{
 //inizializzo la libreria Wire come Master
 Wire.begin();
}

void loop()
{
 for(ciclo = 255; ciclo &gt; 0; ciclo--)
 {
  Wire.beginTransmission(0x48);
  //invio un byte
  Wire.write(byte(0x40));
  Wire.write(byte(ciclo));
  //fine trasmissione
  Wire.endTransmission();
  delay(10);
 }
 
 for(ciclo = 0; ciclo &lt; 255; ciclo++)
 {
  Wire.beginTransmission(0x48);
  //invio un byte
  Wire.write(byte(0x40));
  Wire.write(byte(ciclo));
  //fine trasmissione
  Wire.endTransmission();
  delay(10);
 }
}</pre>
<p>&nbsp;</p>
<p>The post <a href="https://logicaprogrammabile.it/arduino-usare-porta-dac-pcf8591p/">Usare la porta DAC del PCF8591P</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://logicaprogrammabile.it/arduino-usare-porta-dac-pcf8591p/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Come usare l&#8217;integrato PCF8591</title>
		<link>https://logicaprogrammabile.it/arduino-usare-integrato-pcf8591/</link>
					<comments>https://logicaprogrammabile.it/arduino-usare-integrato-pcf8591/#respond</comments>
		
		<dc:creator><![CDATA[Marco Lai]]></dc:creator>
		<pubDate>Wed, 23 Oct 2013 14:28:26 +0000</pubDate>
				<category><![CDATA[Tutorial Arduino]]></category>
		<category><![CDATA[DataLogger]]></category>
		<category><![CDATA[I2C]]></category>
		<guid isPermaLink="false">https://logicaprogrammabile.it/?p=3854</guid>

					<description><![CDATA[<p>Utilizzare Arduino per controllare l&#8217;integrato PCF8591 L&#8217;integrato PCF8591 prodotto da NXP dispone di 4 ingressi analogici con risoluzione di 8 bit e di una uscita analogica sempre ad 8 bit. La sua gestione avviene tramite bus I2C, permettendo così il collegamento nel bus di diversi...</p>
<p>The post <a href="https://logicaprogrammabile.it/arduino-usare-integrato-pcf8591/">Come usare l&#8217;integrato PCF8591</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1>Utilizzare Arduino per controllare l&#8217;integrato PCF8591</h1>
<p>L&#8217;integrato <strong>PCF8591</strong> prodotto da NXP dispone di <strong>4 ingressi analogici</strong> con risoluzione di 8 bit e di <strong>una uscita analogica</strong> sempre ad <strong>8 bit</strong>. La sua gestione avviene tramite<strong> bus I2C</strong>, permettendo così il collegamento nel bus di diversi integrati (per un massimo di 127 unità). Avendo una gestione software semplice ed un costo intorno ai 3€ viene impiegato in diversi <strong>shield Arduino</strong> per aumentare il numero di <strong>porte ADC</strong>, inoltre la presenza di una uscita analogica programmabile (DAC) permette di generare segnali utili in diversi progetti e applicazioni.</p>
<p>Nella figura seguente viene mostrato lo schema a blocchi del <strong>PCF8591:</strong></p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/10/SchedaBlocchiPCF8591P.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3860" src="https://logicaprogrammabile.it/wp-content/uploads/2013/10/SchedaBlocchiPCF8591P.png" alt="Schema Blocchi PCD8591P" width="640" height="373" srcset="https://logicaprogrammabile.it/wp-content/uploads/2013/10/SchedaBlocchiPCF8591P.png 640w, https://logicaprogrammabile.it/wp-content/uploads/2013/10/SchedaBlocchiPCF8591P-300x174.png 300w" sizes="auto, (max-width: 640px) 100vw, 640px" /></a></p>
<p><span id="more-3854"></span></p>
<p>Per specificare l&#8217;<strong>indirizzo</strong> del dispositivo all&#8217;interno del <strong>bus I2C</strong> vengono impiegati i<strong> pin A0, A1 e A2</strong>. La scelta del canale ADC che vogliamo impiegare avviene tramite il registro control byte, configurabile via software come anche la gestione dell&#8217;uscita analogica, che in questo tutorial non verrà trattata.</p>
<p>Il circuito di esempio che  utilizza un integrato PCF8591P ed un Arduino UNO, di seguito lo schema:</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/10/SchemaElettricoPCF8591P.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3866" src="https://logicaprogrammabile.it/wp-content/uploads/2013/10/SchemaElettricoPCF8591P.png" alt="Schema Elettrico PCF8591P" width="414" height="295" srcset="https://logicaprogrammabile.it/wp-content/uploads/2013/10/SchemaElettricoPCF8591P.png 414w, https://logicaprogrammabile.it/wp-content/uploads/2013/10/SchemaElettricoPCF8591P-300x213.png 300w" sizes="auto, (max-width: 414px) 100vw, 414px" /></a></p>
<p>I <strong>pin A0, A1,e A2</strong> sono collegati a massa, quindi il loro valore logico è pari a zero. Sul datasheet del componente possiamo dedurre quale sarà l&#8217;indirizzo sul bus I2C seguendo questa tabella:</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/10/PCF8591_Address.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3868" src="https://logicaprogrammabile.it/wp-content/uploads/2013/10/PCF8591_Address.png" alt="PCF8591 Table Address" width="679" height="132" srcset="https://logicaprogrammabile.it/wp-content/uploads/2013/10/PCF8591_Address.png 679w, https://logicaprogrammabile.it/wp-content/uploads/2013/10/PCF8591_Address-300x58.png 300w" sizes="auto, (max-width: 679px) 100vw, 679px" /></a></p>
<p>i quattro bit piu significativi sono fissi e non possono essere cambiati, mentre i tre bit meno significativi sono appunto collegati ai pin A0 A1 e A2. Nello schema essendo collegati a massa, otterremo l&#8217;indirizzo del dispositivo che  corrisponderà, al valore binario seguente:</p>
<p style="text-align: center;"><strong>0b1001000</strong></p>
<p>che convertito in esadecimale diventa:</p>
<p style="text-align: center;"><strong>0x48</strong></p>
<p>Una volta stabilito l&#8217;indirizzo, è necessario configurare il dispositivo tramite il registro &#8216;control byte&#8217;. Questo registro permette di scegliere il canale analogico da rendere attivo per l&#8217;acquisizione (bit 0 e bit 1 A/D Channell Number) e la configurazione degli ingressi analogici (bit4 e bit5 Analog Input Programming).<br />
Le informazioni di questo registro sono riassunte in questo schema, presente nel datasheet:</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/10/ControlRegister.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3873" src="https://logicaprogrammabile.it/wp-content/uploads/2013/10/ControlRegister.png" alt="Control register" width="443" height="654" srcset="https://logicaprogrammabile.it/wp-content/uploads/2013/10/ControlRegister.png 443w, https://logicaprogrammabile.it/wp-content/uploads/2013/10/ControlRegister-203x300.png 203w" sizes="auto, (max-width: 443px) 100vw, 443px" /></a></p>
<p>Tralasciamo il bit per l&#8217;uscita analogica (bit6) e il bit  auto increment (bit2), assegnandoli il valore logico zero.<br />
I valori da assegnare al control byte per selezionare i diversi ingressi analogici in configurazione <strong>four single-ended inputs </strong>(bit4 e bit5 a zero) dovranno essere:</p>
<p style="text-align: center;"><strong>0b00000000 -&gt; 0x00 -&gt; attiva l&#8217;ingrasso analogico AIN0</strong><br />
<strong>0b00000001 -&gt; 0x01 -&gt; attiva l&#8217;ingrasso analogico AIN1</strong><br />
<strong>0b00000010 -&gt; 0x02 -&gt; attiva l&#8217;ingrasso analogico AIN2</strong><br />
<strong>0b00000011 -&gt; 0x03 -&gt; attiva l&#8217;ingrasso analogico AIN3</strong></p>
<p>La sequenza di byte da inviare è la seguente:</p>
<p><a href="https://logicaprogrammabile.it/wp-content/uploads/2013/10/PCF8591P_ControlByte.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3869" src="https://logicaprogrammabile.it/wp-content/uploads/2013/10/PCF8591P_ControlByte.png" alt="Registro controllo" width="427" height="104" srcset="https://logicaprogrammabile.it/wp-content/uploads/2013/10/PCF8591P_ControlByte.png 427w, https://logicaprogrammabile.it/wp-content/uploads/2013/10/PCF8591P_ControlByte-300x73.png 300w" sizes="auto, (max-width: 427px) 100vw, 427px" /></a></p>
<p>quindi tramite le dovute istruzioni, invieremo sul bus I2C un primo byte contenente l&#8217;indirizzo del dispositivo e un secondo byte riguardante la configurazione interna del dispositivo.<br />
L&#8217;integrato PCF8591 è così pronto ad acquisire ed inviare il dato sul canale I2C.<br />
Il codice seguente permette di acquisire un dato analogico sul pin AIN0 e sul pin AIN1 del dispositivo e di inviarlo al serial monitor dell&#8217; IDE Arduino:</p>
<pre class="lang:arduino decode:true ">//libreria I2C
#include &lt;Wire.h&gt;

void setup()
{
 //inizializzo la libreria Wire
 Wire.begin();
 //init seiale
 Serial.begin(9600);
 //avviso che il programma è avviato
 Serial.println("START");
}

void loop()
{
 //avvio una richiesta di scrittura al
 //dispositivo con indirizzo 0x48
 Wire.beginTransmission(0x48);
 //invio il byte di configurazione
 //in questo caso abilito il canale analogico AIN0
 Wire.write(byte(0x00));
 //fine trasmissione
 Wire.endTransmission();
 //richiedo un byte allo slave che ha indirizzo 0x48
 Wire.requestFrom(0x48, 1);
 //attendo la disponibilità di dati sul bus i2c
 while(Wire.available())
 {
  //leggo il byte che mi invia il PCD8591
  byte c = Wire.read();
  //invio il dato al serial monitor
  Serial.println(c);
 }
 //pausa 10 millis
 delay(10);
 //avvio una richiesta di scrittura al
 //dispositivo con indirizzo 0x48
 Wire.beginTransmission(0x48);
 //invio il byte di configurazione
 //in questo caso abilito il canale analogico AIN01
 Wire.write(byte(0x01));
 //fine trasmissione
 Wire.endTransmission();
 //richiedo un byte allo slave che ha indirizzo 0x04
 Wire.requestFrom(0x48, 1);
 //attendo la disponibilità di dati sul bus i2c
 while(Wire.available())
 {
  //leggo dal bus il dato relativo alla
  //conversione a/d sul pin AIN01
  byte c = Wire.read();
  //invio il dato al pc
  Serial.println(c);
 }
 //esegui il codice ogni secondo
 delay(1000);
}</pre>
<p>&nbsp;</p>
<p>Sinteticamente viene prima configurato, tramite il &#8216;control byte&#8217;, il dispositivo PCF8591 e successivamente viene avviata una richiesta di lettura dal dispositivo. Per eseguire la lettura dei quattro, è necessario eseguire quattro configurazioni e quattro letture.</p>
<p>&nbsp;</p>
<p>The post <a href="https://logicaprogrammabile.it/arduino-usare-integrato-pcf8591/">Come usare l&#8217;integrato PCF8591</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://logicaprogrammabile.it/arduino-usare-integrato-pcf8591/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Comunicazione tra Arduino tramite I2C</title>
		<link>https://logicaprogrammabile.it/comunicazione-tra-arduino-tramite-i2c/</link>
					<comments>https://logicaprogrammabile.it/comunicazione-tra-arduino-tramite-i2c/#comments</comments>
		
		<dc:creator><![CDATA[Marco Lai]]></dc:creator>
		<pubDate>Wed, 10 Oct 2012 12:49:36 +0000</pubDate>
				<category><![CDATA[Programmazione]]></category>
		<category><![CDATA[Tutorial Arduino]]></category>
		<category><![CDATA[Bus I2C]]></category>
		<category><![CDATA[comunicazione tra circuiti]]></category>
		<category><![CDATA[I2C]]></category>
		<guid isPermaLink="false">https://logicaprogrammabile.it/?p=3081</guid>

					<description><![CDATA[<p>Come collegare due Arduino usando il bus I2C. Una caratteristica che reputo molto interessante è la possibilità di espandere Arduino tramite l&#8217;uso di shield. La maggior parte di queste schede aggiuntive sono però progettate per compiere una funzione specifica, non programmabile. Esistono alcuni metodi che...</p>
<p>The post <a href="https://logicaprogrammabile.it/comunicazione-tra-arduino-tramite-i2c/">Comunicazione tra Arduino tramite I2C</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h3>Come collegare due Arduino usando il bus I2C.</h3>
<p>Una caratteristica che reputo molto interessante è la possibilità di espandere Arduino tramite l&#8217;uso di shield. La maggior parte di queste schede aggiuntive sono però progettate per compiere una funzione specifica, non programmabile.<br />
Esistono alcuni metodi che permettono di comunicare con altri dispositivi utilizzando come canale di trasmissione dati i protocolli seriali (I2C, SPI o RS232). Questo rende possibile demandare ad una scheda slave funzioni di elaborazione gravose, che non vogliamo far eseguire alla scheda master. Ho realizzato questo piccolo tutorial usando il bus I2C per creare uno scambio dati tra un Arduino ed un chip ATmega328 standalone.</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3088" title="Bus_i2c" src="https://logicaprogrammabile.it/wp-content/uploads/2012/10/Bus_i2c.png" alt="Bus i2c" width="630" height="255" srcset="https://logicaprogrammabile.it/wp-content/uploads/2012/10/Bus_i2c.png 630w, https://logicaprogrammabile.it/wp-content/uploads/2012/10/Bus_i2c-300x121.png 300w" sizes="auto, (max-width: 630px) 100vw, 630px" /></p>
<p>Il bus I2C, basandosi su due fili, non permette la comunicazione contemporanea tra Master e Slave. Lo scambio dati deve essere gestito dal Master tramite gli indirizzi (univoci) degli slave. Il flusso può essere sintetizzato in questo modo</p>
<ol>
<li>Il Master invia sul bus un bit di start</li>
<li>Il Master invia sul bus l&#8217;indirizzo dello slave con cui vuole comunicare</li>
<li>Il Master decide se scrivere o leggere dal dispositivo</li>
<li>Lo Slave legge o scrive in base alla richiesta del Master</li>
</ol>
<p><span id="more-3081"></span></p>
<p>La <a href="http://arduino.cc/en/Reference/Wire" target="_blank">libreria Wire</a> dispone di tutte le funzioni necessarie alla realizzazione Master-Slave tra due schede Arduino. Lo schema del circuito che ho realizzato è visibile nella figura seguente.</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3094" title="I2C_Master_Slave" src="https://logicaprogrammabile.it/wp-content/uploads/2012/10/I2C_Master_Slave.png" alt="Collegamento Master Slave tra due Arduino UNO" width="423" height="391" srcset="https://logicaprogrammabile.it/wp-content/uploads/2012/10/I2C_Master_Slave.png 423w, https://logicaprogrammabile.it/wp-content/uploads/2012/10/I2C_Master_Slave-300x277.png 300w" sizes="auto, (max-width: 423px) 100vw, 423px" /></p>
<p>Come detto precedentemente lo schema si basa su Arduino Uno impiegato come Master e con un ATmega328 impiegato come slave.</p>
<p>Il codice permette di inviare un dato numerico allo slave, che provvederà ad incrementarlo per poi rispedirlo al Master.</p>
<p>[c]<br />
//MASTER<br />
#include &lt;Wire.h&gt;</p>
<p>byte x = 0;<br />
byte num = 0;</p>
<p>void setup()<br />
{<br />
  //inizializzo la libreria Wire come Master<br />
  Wire.begin();</p>
<p>  //init seiale<br />
  Serial.begin(9600);<br />
  //avviso che il programma è avviato<br />
  Serial.println(&quot;START&quot;);</p>
<p>}</p>
<p>void loop()<br />
{<br />
  //invio sul bus I2C un byte al device<br />
  //che ha come indirizzo il valore 0x04<br />
  //start trasmissione<br />
  Wire.beginTransmission(0x04);<br />
  //invio un byte<br />
  Wire.write(x);<br />
  //fine trasmissione<br />
  Wire.endTransmission();</p>
<p>  delayMicroseconds(500);</p>
<p>  //richiedo un byte allo slave che ha indirizzo 0x04<br />
  Wire.requestFrom(0x04, 1);</p>
<p>  //attendo la disponibilità di dati sul bus i2c<br />
  while(Wire.available())<br />
  {<br />
    //quando è presente un dato avvia<br />
    //la lettura<br />
    num = Wire.read();<br />
  }</p>
<p>  //incrementa il valore del byte<br />
  x++;</p>
<p>  //verifico che il byte letto dallo slave sia stato<br />
  //incrementato<br />
  if(num != x)<br />
    Serial.println(&quot;ERRORE&quot;);</p>
<p>  delay(5);</p>
<p>}</p>
<p>[/c]</p>
<p>Il codice seguente è relativo allo Slave</p>
<p>[c]<br />
//SLAVE<br />
#include &lt;Wire.h&gt;</p>
<p>byte x = 0;</p>
<p>void setup()<br />
{<br />
  //inizializzo la libreria<br />
  //imposto l&#8217;indirizzo dello slave<br />
  Wire.begin(0x04);</p>
<p>  //eventi per la ricezione del dato<br />
  //e per la richiesta del dato<br />
  Wire.onReceive(receiveEvent);<br />
  Wire.onRequest(requestEvent);<br />
}</p>
<p>void loop()<br />
{<br />
  //esegui qualcosa<br />
  delay(1000);<br />
}</p>
<p>void receiveEvent(int data)<br />
{<br />
 //questo evento viene generato quando sul bus<br />
 //è presente un dato da leggere</p>
<p> //eseguo la lettura<br />
  x = Wire.read();</p>
<p>  //elaboro il dato letto<br />
  x++;<br />
}</p>
<p>void requestEvent()<br />
{<br />
  //questo evento viene generato quando il master<br />
  //richiede ad uno specifico slave<br />
  //una richiesta di dati</p>
<p>  //spedisco il dato al Master<br />
  Wire.write(x);</p>
<p>}</p>
<p>[/c]</p>
<p>I commenti presenti nel codice permettono di capire ciò che avviene tra i due dispositivi.</p>
<p>Di seguito uno screenshot dei dati scambiati sul bus</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3107" title="TEK00004" src="https://logicaprogrammabile.it/wp-content/uploads/2012/10/TEK00004.png" alt="Scambio dati master slave su bus i2c" width="640" height="480" srcset="https://logicaprogrammabile.it/wp-content/uploads/2012/10/TEK00004.png 640w, https://logicaprogrammabile.it/wp-content/uploads/2012/10/TEK00004-300x225.png 300w" sizes="auto, (max-width: 640px) 100vw, 640px" /></p>
<p>Di seguito invece la trasmissione del Master</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3108" title="TEK00005" src="https://logicaprogrammabile.it/wp-content/uploads/2012/10/TEK00005.png" alt="Trasmissione i2c Master" width="640" height="480" srcset="https://logicaprogrammabile.it/wp-content/uploads/2012/10/TEK00005.png 640w, https://logicaprogrammabile.it/wp-content/uploads/2012/10/TEK00005-300x225.png 300w" sizes="auto, (max-width: 640px) 100vw, 640px" /></p>
<p>The post <a href="https://logicaprogrammabile.it/comunicazione-tra-arduino-tramite-i2c/">Comunicazione tra Arduino tramite I2C</a> appeared first on <a href="https://logicaprogrammabile.it">Esperimenti con logiche programmabili</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://logicaprogrammabile.it/comunicazione-tra-arduino-tramite-i2c/feed/</wfw:commentRss>
			<slash:comments>15</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>
	</channel>
</rss>
