iot

Nel caso si voglia collegare più dispositivi I2C dello stesso tipo sullo stesso bus è utile disporre di una semplice routine per effettuare il cambio di indirizzo degli slave ed evitare così conflitti. Infatti in alcuni casi è possibile cambiare l'indirizzo I2C dello slave all'interno di un numero prefissato di disponibilità selezionabili tramite collegamenti hardware di particolari pin, in altri casi, come con il sensore laser utilizzato nei nostri esempi si ha la libertà di impostare l'indirizzo che si vuole semplicemente scrivendolo in un particolare indirizzo di memoria. Questa procedura è obbligatoria ad ogni avvio visto che il sensore perde l'indirizzo quando gli viene levata l'alimentazione. 

Predisporre l'ambiente di sviluppo come indicato nei seguenti post:

A differenza dei precedenti post utilizzeremo la seriale RS232 per disporre di una consolle che ci permetta di inserire il nuovo indirizzo I2C da attribuire allo slave; per fare questo utilizzeremo la EUSART del micro anche in ricezione oltre che in trasmissione come abbiamo fino a qui fatto con la funzione prinf().

Avendo impostato la seriale del micro tramite il tool MCC esistono già le funzioni e gli interrupt necessari a gestire in modo bidirezionale la comunicazione, proviamo a capire come funziona il sistema. Ogni bit ricevuto sulla seriale genera un interrupt che viene gestito dal file interrupt_manager.c; ad ogni bit ricevuto il gestore chiama la funzione EUSART_Receive_ISR presente nel file eusart.c che accoda i bit ricevuti in un array di 8 bit chiamato eusartRxBuffer ed incrementa di conseguenza la variabile eusartRxCount che tiene il conto dei byte ricevuti. Per leggere il carattere ricevuto possiamo utilizzare la funzione che ci viene messa a disposizione: EUSART_Read(). Queste sono le variabili e le funzioni che utilizzeremo nel nostro programma per creare un colloquio con l'utente. Vediamone un breve estratto:

change addr 1

Nel corso del colloquio con l'utente via RS232 attraversiamo varie fasi in cui ci aspettiamo determinate risposte. Per tenere conto di queste fasi definiamo la variabile appStatus di tipo statuses il cui valore può essere uno di quelli elencati nell'immagine sopra. Ogni volta che viene fornita una risposta, tramite il costrutto switch, impostiamo lo stato che consente al programma di ricevere la risposta successiva.

Abbiamo appena detto che disponiamo della funzione EUSART_Read() che ci permette di leggere un byte (carattere) sulla seriale. Questo possiamo farlo tutte le volte che eusartRxCount è maggiore di zero:

change addr 3A noi interessa ricevere una risposta completa dall'utente, ovvero quando viene premuto "enter". Di conseguenza la funzione StringReceived() viene chiamata ad ogni ciclo per leggere la risposta dell'utente un carattere alla volta, quando si riceve il carattere LF vuol dire che è stato premuto "enter" la stringa è completa e posso restituire true avvisando il chiamante che la risposta è disponibile nel buffer.

Nel ciclo principale del programma (di cui riporto solo uno spezzone):

change addr 2

leggo la stringa di risposta, faccio una semplice verifica sulla lunghezza e sul tipo di carattere digitato, poi incamero il valore e imposto appStatus in modo che al ricevimento della stringa successiva il programma valuterà un nuovo dato.

Questa è l'esecuzione del programma a terminale:

Schermata 2017 12 30 alle 11.42.32E' possibile scaricare l'intero progetto da github:  download project