Corso su ARM: utilizziamo i sensori, il magnetometro MAG3110

eCompass

Siete pronti per questa nuova puntata? Oggi partiamo in quarta con un esperimento davvero interessante: vediamo di giocare con il magnetometro a bordo della nostra FRDM-KL46Z. È facile lavorare con i sensori? Come si pilota la comunicazione I2C su questa scheda? Servono componenti aggiuntivi? Quante linee di codice saranno necessarie? Scopritelo insieme a noi in questa nuova puntata del nostro corso di programmazione su ARM.

Siamo al quarto appuntamento della nostra terza fase del corso di programmazione su ARM. Vi avevamo annunciato che saremmo scesi nel dettaglio, che avremmo fatto degli esperimenti e ogni giorno stiamo diventando più approfonditi nello studio di questa straordinaria piattaforma di sviluppo.
Oggi vogliamo divertirci con il magnetometro. Lo piloteremo, lo controlleremo, acquisiremo dei valori e verificheremo il suo funzionamento.Tutto questo con la facilità che questa scheda permette.
Intanto cominciamo col dire che il magnetometro dovreste essere riusciti a trovarlo sulla scheda… Non è vero? Lo avete visto? Si tratta di un dispositivo dalle dimensioni davvero piccole: appena 2 mm x 2 mm e lo trovate localizzato vicino a C38 ed R31. Lo avete visto?

Parliamone

Per poterci lavorare sicuramente abbiamo bisogno prima di conoscerlo e tante delle sue caratteristiche saranno importanti anche per capire come si fa ad utilizzarlo. Già perchè lo abbiamo accennato: la cosa fondamentale è riuscire a comunicare con questo sensore così come con tutti gli altri.
Il Freescale Xtrinsic MMA3110 è un sensore digitale a tre assi con le seguenti caratteristiche:
  • interfaccia I2C con frequenza fino a 400 kHz;
  • profondità 16bit X, Y e Z;
  • fondo scala ±1000 µT e sensibilità 0.10 µT;
  • "Fast" mode, per la lettura di soli 8 bit;
  • Multiple data e oversampling rates;
  • sensore di temperatura (è necessaria la calibrazione!).
Naturalmente queste sono le caratteristiche che noi teniamo a conoscere ma c'è dell'altro se vogliamo lavorarci: serve che anche il Processor Expert le conosca. Per questo motivo andiamo subito a vedere come si fa a far lavorare il sensore.
Il componente ha tra le sue proprietà, le sue impostazioni, la possibilità di connettersi al bus I2C e di abilitare un pin di interrupt opzionale.
Ricordate il "Component Inspector"? Quel tool che vi permette di esaminare il dettaglio delle proprietà di un determinato componente che sia presente all'interno delle librerie? Ecco come viene rappresentato il magnetometro:
Anche per questo particolare sensore, se vi dovesse servire, sappiate che c'è la possibilità di inserire comandi opzionali direttamente da linee di codice.

Misuriamo la temperatura

La dotazione di questa scheda non smette di sorprendere soprattutto perché, all'interno del magnetometro, un registro dedicato permette la lettura della temperatura. Si tratta del DIE_TEMP, indirizzo 0x0F.
Potrebbe esserci qualche problema relativo alla componente di OFFSET di cui si parla nel datasheet. Al suo interno, infatti, si spiega che il registro contiene la temperatura del die espressa in gradi centigradi come un numero ad 8 bit in complemento a due. La sensibilità del sensore di temperatura è pari a 1°C/LSB mentre la componente di offset deve essere calibrata dall'utente a cui è richiesto di scrivere un software dedicato che gli permetta di raggiungere una maggiore precisione.
Vediamo, con la prossima immagine, proprio queste proprietà ed anche il campo in cui l'offset di temperatura può essere impostato
Questo componente, così come molti altri, di base non compare tra quelli disponibili e selezionabili all'interno del programma; è necessario, infatti, importare dei pacchetti che contengano, tra gli altri, anche il magnetometro.
Per farlo, come certamente avrete già imparato a fare per altri sensori e su altre piattaforme di sviluppo con altri programmi ed altri tool di scrittura e debug, la ricerca della documentazione e delle librerie opportune è la prima fase per poter lavorare correttamente. Questo post è stato di grande ispirazione. Seguendo i link suggeriti ho trovato che l'autore ha utilizzato GitHUB nel modo migliore: distribuire e divulgare documentazione!
Seguendo le indicazioni ci si ritrova di fronte ad un pacchetto davvero completo. Ecco alcuni dei componenti contenuti al suo interno di cui proprio non potete fare a meno:
  • 24AA_EEPROM;
  • 74HC164;
  • BitIO_to_PCA9554;
  • Bluetooth_EGBT;
  • BootLoaderDisk;
  • BootLoaderUSB;
  • ChLCD;
  • CTouchScanner;
  • CTouchSensor;
  • FAT_FileSystem;
  • FontDisplay;
  • FreeRTOS;
  • FreeRTOSTrace;
  • GDisplay;
  • GenericBitIO;
  • GenericI2;
  • I2CSpy;
  • LEDMatrix;
  • LEDSensor;
  • MAG3110;
  • MaxonF2140;
  • MC13192;
  • MMA7260Q;
  • MMA7455L;
  • MMA8451Q;
  • OLED;
  • RingBuffer;
  • RingBufferUInt8;
  • RTC_Maxim;
  • Servo;
  • Shell;
  • Timeout;
  • TouchScreen;
  • TouchScreenSensor;
  • Trigger;
  • Wait.
Naturalmente l'elenco è largamente più numeroso di quello che vi abbiamo riportato e sebbene si intuisca che tra accelerometri e touchscreen questo elenco sia piuttosto variegato, sappiate che c'è molto di più per tutti i gusti per equipaggiare i vostri software per la gestione di ben altro che questa semplice scheda.
Prendetevi del tempo per studiare con attenzione questo riferimento perché è davvero di grande valore. Oltre al fatto che notevole è l'impegno dell'autore nell'aggiornare costantemente questi stessi file.
Una volta che vi siete procurati questo materiale, la strada è relativamente in discesa.
 
Come tutti i componenti, anche il magnetometro è dotato di metodi per l'accesso alle singole funzioni ed ai registri che contiene
Se consideriamo come esempio il codice riportato qui (driver del dispositivo), al suo interno troviamo una serie di definizioni, com'è chiaro aspettarci, che rappresentano, per esempio, i registri della temperatura
/* die temperature (needs to add an offset as not factory trimmed) */
#define %'ModuleName'%.DIE_TEMP  0x0F /* die temperature register, signed 8bit in C */
quelli dei dati
/* data registers */
#define %'ModuleName'%.OUT_X_MSB 0x01 /* X output MSB address */
#define %'ModuleName'%.OUT_X_LSB 0x02 /* X output LSB address */
#define %'ModuleName'%.OUT_Y_MSB 0x03 /* Y output MSB address */
#define %'ModuleName'%.OUT_Y_LSB 0x04 /* Y output LSB address */
#define %'ModuleName'%.OUT_Z_MSB 0x05 /* Z output MSB address */
#define %'ModuleName'%.OUT_Z_LSB 0x06 /* Z output LSB address */
e così via dicendo. Una volta finito con i registri, si comincia a documentare le funzioni e i metodi, ad esempio
%-BW_METHOD_BEGIN GetXYZ16
%ifdef GetXYZ16
uint8_t %'ModuleName'%.%GetXYZ16(int16_t *xyz);
%define! Parxyz
%define! RetVal
%include Common\MAG3110GetRaw8XYZ.inc
%endif %- GetXYZ16
%-BW_METHOD_END GetXYZ16
oppure
%-BW_METHOD_BEGIN GetX
%ifdef GetX
word %'ModuleName'%.%GetX(int16_t *value);
%define! Parvalue
%define! RetVal
%include Common\MAG3110GetX.Inc
%endif %- GetX
%-BW_METHOD_END GetX
Volete sapere come lavora la correzione dell'Offset? Ecco il metodo che la realizza:
%-BW_METHOD_BEGIN GetUserOffsetCorrection
%ifdef GetUserOffsetCorrection
%define! Parx
%define! Pary
%define! Parz
%define! RetVal
%include Common\MAG3110GetUserOffsetCorrection.Inc
byte %'ModuleName'%.%GetUserOffsetCorrection(int16_t *x, int16_t *y, int16_t *z)
{
  uint8_t res;

  res = %'ModuleName'%.Read16bitBEValue(%'ModuleName'%.OFF_X_MSB, (uint16_t*)x);
  if(res!=ERR_OK) {
    return res; /* failure */
  }
  res = %'ModuleName'%.Read16bitBEValue(%'ModuleName'%.OFF_Y_MSB, (uint16_t*)y);
  if(res!=ERR_OK) {
    return res; /* failure */
  }
  res = %'ModuleName'%.Read16bitBEValue(%'ModuleName'%.OFF_Z_MSB, (uint16_t*)z);
  if(res!=ERR_OK) {
    return res; /* failure */
  }
  return ERR_OK;
}

%endif %- GetUserOffsetCorrection
%-BW_METHOD_END GetUserOffsetCorrection
Se volete utilizzare l'interfaccia seriale per lavorare con questi dati e comunicarli, potete sempre utilizzare tool come Terminal per il controllo del traffico su questa interfaccia. Tra l'altro la sua interfaccia risulta davvero completa.
Questa è certamente una lunga discussione che richiede l'analisi di tante proprietà.
Ma se siete già venuti a capo di quanto vi abbiamo raccontato, sappiate che il componente MAG3110 ha tanto da offrire e le sue applicazioni dimostrative non sono affatto concluse qui: Freescale, infatti, ha a disposizione un pacchetto software che prende il nome di eCompass. Lo trovate disponibile a questo indirizzo e sinceramente ve lo consigliamo caldamente.
Il software permette la calibrazione dei sensori Xtrinsic ed unisce i dati degli accelerometri e dei magnetometri per ottenere un'accurata misura dell'heading. Questo ambiente potrebbe essere molto utile per tutti coloro che debbano sviluppare applicazioni anche professionali su smartphone, tablet e dispositivi portatili più in generale.
Parlando delle caratteristiche di questo tool, abbiamo:
  • e-compass Tilt compensated;
  • calibrazione Hard e soft; 
  • Codice ANSI C standard fornito come codice sorgente;
  • Flash footprint 20 KB (circa);
  • RAM richiesta 6.5 KB (circa).

Conclusioni

Con questa puntata abbiamo raccolto delle idee necessarie per lavorare con il magnetometro studiando le proprietà, metodi e l'interfacciamento. Dal momento che lavorare con questo sensore ha imposto di iniziare a parlare di un'interfaccia di comunicazione complessa ed importantissima come l'I2C, nella prossima puntata ne approfondiremo un caso particolare.
Nel frattempo, come sempre, vi invitiamo a commentare questo articolo per chiarire eventuali dubbi, domande, perplessità e così via dicendo. Alla prossima.

 

                    

Per ulteriori informazioni potete scrivere a questa email: ggalletti@arroweurope.com

17 Comments

  1. Piero Boccadoro Piero Boccadoro 8 dicembre 2013
  2. Marven 28 novembre 2013
  3. Ultron 29 novembre 2013
  4. Marven 29 novembre 2013
  5. Ultron 30 novembre 2013
  6. Emanuele 30 novembre 2013
  7. Ultron 30 novembre 2013
  8. Piero Boccadoro Piero Boccadoro 30 novembre 2013
  9. Piero Boccadoro Piero Boccadoro 30 novembre 2013
  10. Piero Boccadoro Piero Boccadoro 30 novembre 2013
  11. Piero Boccadoro Piero Boccadoro 30 novembre 2013
  12. Ultron 30 novembre 2013
  13. Ultron 30 novembre 2013
  14. Piero Boccadoro Piero Boccadoro 1 dicembre 2013
  15. Ultron 2 dicembre 2013
  16. Piero Boccadoro Piero Boccadoro 4 dicembre 2013
  17. Ultron 4 dicembre 2013

Leave a Reply