Visualizzazione post con etichetta i2c. Mostra tutti i post
Visualizzazione post con etichetta i2c. Mostra tutti i post

domenica 22 marzo 2015

Studio PIC 18F (18F4431) #8 :: "Comunicare con il PIC via i2c (pic slave, raspberry pi master)"


Vai al precedente POST della serie

Il protocollo i2c (Inter Integrated Circuit), inventato da Philips nel lontano 1982, permette, con solo due connessioni (più la massa), la comunicazione bidirezionale tre due o più dispositivi.
In rete troviamo ovviamente ampia documentazione in merito ma non sempre troviamo chiare indicazioni per implementarlo con successo con i PIC.

In questo articolo vediamo come poter controllare il nostro PIC, via i2c, da qualsiasi altro dispositivo esterno che possa comportarsi da MASTER.
L'i2c infatti prevede, per i dispositivi connessi, due ruoli: il MASTER (padrone) e lo SLAVE (servo).

Entrambi possono ricevere e inviare i dati ma solo il MASTER inizia il dialogo e decide la frequenza di lavoro generando il segnale di sincronismo del BUS.

Il BUS è composto da soli due segnali o linee : la linea di clock (SCL) e quella di dati (SDA).
Sul BUS possono coesistere fino a 127 dispositivi SLAVE in quanto il protocollo prevede di poter assegnare ad ogni dispositivo SLAVE un proprio indirizzo (ADDR): sarà il MASTER a decidere con chi parlare ogni volta che vuole inviare o ricevere dei dati.

E' anche possibile che uno SLAVE possa diventare MASTER occupando il BUS in modo da poter a sua volta dialogare con un altro SLAVE: questa modalità però non è oggetto del presente articolo.

Quindi, riassumendo, il protocollo i2c:
  1. è di tipo sincrono (linea SCL)
  2. permette il colloquio bidirezionale su un'unica linea (linea SDA)
  3. permette il colloquio tra un MASTER e molti SLAVE (ma uno alla volta)
  4. la velocità di scambio dati si esprime indicando la frequenza degli impulsi di clock e può essere: 100KHZ/sec (standard), 400KHZ/sec (fast), 3,4MHZ/sec (high)
Come dispositivo MASTER andrò ad utilizzare il Raspberry Pi configurato come indicato in questo mio precedente post.
Il Raspberry Pi supporta l'i2c con clock a 100KHZ/sec.

Da notare che i resistori di pull-up, necessari per mantenere sempre a livello logico alto i segnali SCL e SDA (in assenza di traffico dati), sono già integrati dal Raspberry Pi e pertanto, e solo in questo caso, possono essere omessi nel circuito.


Implementazione i2c dei PIC 18F

I PIC 18F dispongono internamente di un modulo hardware dedicato ai protocolli seriali sincroni chiamato SSP: Synchronous Serial Port.
Tale modulo consente di implementare, con estrema semplicità, sia l'i2c che lo SPI (che vedremo in futuro).

I registri di cui abbiamo bisogno per implementare uno SLAVE i2c sono:
  • SSPCON: dove impostare la configurazione del modulo SSP e controllare il bit CKP
  • SSPADD: dove impostare l'indirizzo i2c del nostro PIC SLAVE
  • TRISC o TRISD: dove configurare i pin scelti come uscite digitali
  • INTCON: dove abilitare gli interrupt settando i bit GIE e PEIE
  • PIE1: dove abilitare gli interrupt della periferica SPP settando il bit SSPIE
  • PIF1: dove verificare che la fonte dell'interrupt sia la eriferica SPP leggendo e azzerando il bit SSPIF
  • SSPBUF; dove leggere e scrivere i byte da ricevere o da inviare sul BUS
  • SSPSTAT: dove verificare lo stato del modulo SPP e intraprendere il corretto comportamento per portare a termine con successo il dialogo i2c con il MASTER 

Ci sono alcuni punti di attenzione, da tenere presente, quanto utilizziamo il modulo SPP come SLAVE i2c:
  1. versione del PIC 18F
  2. configurazione dei pin i2c
  3. tempo limite operativo durante gli interrupt SSP (timing)
La prima trappola da evitare riguarda il fatto che l'implementazione del modulo SPP è leggermente diversa tra alcuni (più vecchi) 18F (tra cui il mio 4431 e famiglia) e i più recenti 18F..
Tali differenze, riportate nel documento Microchip AN734 (appendice C), riguardano gli stati dei bit del registro SSPSTAT in particolare per le operazioni RA (read address) e NACK.
Quindi è sempre bene verificare il datasheet del particolare modello di PIC che intendiamo utilizzare e leggere il documento AN734.

La seconda trappola riguarda il PIC 4431 che permette di scegliere, tra due porte diverse, i pin che vogliamo impegnare per l'i2c: questi posso essere o la coppia RC4(23) e RC5(24) o la coppia RD2(21) e RD3(22).
E' bene quindi non ignorare il settaggio di tale configurazione tramite il bit SSPMX del registro CONFIG3H: se 0 saranno i pin RD2-RD3; se 1 quelli RC4-RC5.

La terza trappola fa proprio la differenza tra successo e fallimento dato che ad un evento i2c dobbiamo rispondere entro un tempo limite altrimenti la comunicazione non va a buon fine.
E' importante quindi avere ben chiaro di quanti cicli operativi (istruzioni PIC) si dispone per gestire un evento i2c.

Operazioni i2c

L'i2c nasce per permettere di impostare o leggere i registri interni ad un dispositivo.

Tipicamente l'operazione di scrittura richiede prima di specificare quale registro scrivere (o da quale iniziare a scrivere) i byte che seguiranno.
Lo SLAVE deve disporre quindi di un registro indice il cui valore viene indicato dal primo byte ricevuto.

Ovviamente possiamo utilizzare l'i2c anche per trasferimenti seriali con una diversa struttura dei dati; ad esempio questo display OLED si controlla via i2c inviando dei comandi e non specificando dei registri interni.

Ogni byte trasferito richiede nove impulsi di clock: 8 per i bit del dato + 1 per il bit di ACK/NACK.
Il bit di ACK/NACK è impostato dalla controparte: MASTER scrive SLAVE risponde ACK/NACK e viceversa SLAVE scrive e MASTER risponde ACK/NACK.
Lo scopo del nono bit di ACK/NACK è quello di indicare di procedere (ACK) o meno (NACK) con l'invio di altri dati.

La sequenza di WRITE, inviata dal MASTER, è composta dai seguenti comandi: 


La prima riga in azzurro mostra i livelli della linea dati (SDA), la seconda in giallo quelli della linea di clock (SCL) e l'ultima in verde gli eventi di interrupt generati dal modulo SSP del PIC.
Il timing, indicato in basso, ha lo scopo di mostrare di quanto tempo (micro secondi) si dispone prima che venga generato da SSP l'interrupt successivo.

Il primo byte inviato è l'indirizzo dello SLAVE, nel mio caso 0x20, spostato però a sinistra di un bit (0x40) in quanto il bit 0 indica se il MASTER vuole inviare dati allo SLAVE (0=WRITE) o riceverne (1 = READ): quindi 0x40 sta per "scrivo sul dispositivo 0x20", mentre 0x41 sta per "leggo dal dispositivo 0x20".

Il secondo byte indica allo SLAVE il valore da impostare nel registro puntatore: è in pratica l'indce del primo registro delle SLAVE che il MASTER vuole impostare.

I restanti byte sono i valori da impostare nel corrente registro che lo SLAVE determina incrementando il suo registro puntatore per ogni byte ricevuto.
In questo caso il MASTER non vuole scrivere in altri registri oltre al primo e chiude il colloquio con un segnale di STOP.


L'operazione di lettura richiede prima una scrittura in modo che lo SLAVE imposti il registro puntatore al registro dal quale iniziare a leggere
.
La sequenza di READ, inviata dal MASTER, è quindi preceduta da una sequenza di WRITE:


Come visto sopra il MASTER invia una sequenza di scrittura verso lo slave 0x20 di un solo byte dati:l'indice del primo registro da leggere.

Dopo lo STOP il MASTER invia una seconda sequenza stavolta di lettura dello SLAVE 0x20.
Sarà adesso lo SLAVE a scrivere sulla linea dati (SDA) i bit corrispondenti al valore da trasmettere al MASTER.
Lo SLAVE è sempre vincolato dal segnale di clock (SCL) generato dal MASTER che legge lo stato della SDA nei punti indicati dalla freccetta in su.
Come sa lo SLAVE se il MASTER vuole ricevere il valore del successivo registro?
Il MASTER, dopo aver letto tutti gli otto bit dal dato al nono impulso setta SDA a 0 (ACK) se vuole ricevere il successivo valore/registro, a 1 (NACK) se non vuole ricevere ulteriori dati.

Stati del modulo SPP

Di seguito il dettaglio di tutti i possibili stati gestiti dal modulo SPP:
  • S: start
    SPP monitora il BUS e genera questo evento non appena un MASTER impegna il BUS per iniziare una sequenza W o R (anche se destinata ad altro SLAVE)
  • WA: write address
    SPP colleziona i bit indirizzo inviati sul BUS per controllare se destinati a lui; il valore ricevuto è quindi l'indirizzo i2c che verrà comparato da SPP con quanto scritto in SSPADD; solo se uguali SPP genera l'evento WA e tutti i successivi fino allo stop.
  • WD: write data
    SPP genera questo evento per ogni byte ricevuto successivamente all'indirizzo i2c
  • P: stop
    SPP genera questo evento quando un MASTER libera il BUS avendo terminato la sequenza di invio o ricezione
  • RA: read address
    Come per WA solo che il MASTER vuole leggere il valore del corrente registro
  • RW: read data
    Come per WD solo che il MASTER vuole leggere il valore del successivo registro

ACK e NACK

In ricezione dati SSP genera per noi i segnali di ACK, al nono impulso di clock, ogni volta che riesce a caricare il registro SPPBUF con gli 8 bit dati ricevuti.
E' importante far sempre trovare il buffer SPPBUF scarico/libero leggendo il precedente valore ricevuto prima che arrivi del successivo: in caso contrario SPP andrà in errore di "write collision":
  1. generando un segnale di NACK sul BUS
  2. impostando il bit WCOL in SSPCON (che va poi azzerato manualmente per ripristinare il funzionamento di SPP)
In invio dati invece siamo noi che dobbiamo verificare che il MASTER abbia segnalato un ACK o un NACK e questo verificando il bit CKP di SSPCON: se 0 ACK, se 1 NACK.


Mano al codice

Il codice di prova, ben commentato, lo trovate qui.
Si tratta di un esempio d'implementazione i2c slave dove il PIC espone 3 registri:
  • add1 (indirizzo 0x00)
  • add2 (indirizzo 0x01)
  • sum  (indirizzo(0x02)
Scrivendo in 'add1' e in 'add2' due valori si potrà leggere la loro somma tramite il registro 'sum'.


Circuito elettrico

Da notare che il quarzo del PIC è, in questo caso, da 16  MHZ.
VDD deve essere 3.3 volt per garantire la compatibilità con i livelli logici del RaspberryPi.

Attenzione: non interfacciate mai dispositivi a 3.3 volt con altri a 5.0 volt senza adattare i livelli tramite appositi circuiti.
Non prelevate mai la VDD a 3.3 volt direttamente dal Raspberry: rischiate di danneggiarlo seriamente.

Utilizzo

Dalla console del Raspberry Pi:
  1. digitare il comando  "sudo i2cset -y 1 0x20 0x00 0x0A 0x0B i"
    questo imposta entrambi i registri add1=0x0b (10) e add2=0x0B (11)
  2. digitare il comando "sudo i2cget -y 1 0x20 0x00"
    questo ci ritorna il valore di add1 cioè 0x0A (10)
  3. digitare il comando "sudo i2cget -y 1 0x20 0x01"
    questo ci ritorna il valore di add2 cioè 0x0B (11)
  4. digitare il comando "sudo i2cget -y 1 0x20 0x02"
    questo ci ritorna la somma di add1 e add2 ciaoè 0x15 (21)

Partendo da questa semplice base, possiamo realizzare interessanti funzioni, controllabili via i2c, con il nostro PIC 18F.

In un prossimo articolo andrò a realizzare, con il PIC 18F, un controller per servomotori basato su i2c.



Stay tuned!
ap


NB: l'autore non risponde di eventuali danni causati da omissioni, inesattezze o errori eventualmente presenti nell'articolo pubblicato.
Prego, segnalare suggerimenti e migliorie commentando questo post o inviando una email a padnest@gmail.com.

sabato 15 novembre 2014

RaspberryPi #1: setup completo per sperimentazioni

In questo articolo vado a riassumere tutti i passaggi necessari per utilizzare il RaspberryPi nei nostri progetti o esperimenti di elettronica.
Per chi non sapesse che cosa sia il RaspberryPi consiglio di iniziare a documentarsi sul sito ufficiale

I passi che andiamo ad eseguire sono riassumibili nei seguenti punti:
  1. Installazione del sistema operativo
  2. Configurazione del sistema operativo
  3. Installazione delle componenti aggiuntive utili allo scopo

Il materiale necessario è:
  1. RaspberryPi (nel mio caso il modello B rev 2)
  2. SD card dedicata da almeno 8 GB
  3. SD card reader
  4. WI-FI dongle usb (compatibile con il RaspberryPi)
  5. Monitor/TV (solo per i primi passaggi)

Installazione del sistema operativo

Per prima cosa scarichiamo l'immagine della distribuzione 'Raspbian Debian Wheezy' disponibile qui.
Nel mio caso ho scaricato l'ultima versione disponibile al momento della scrittura di questo post cioè quella con release date 2014-09-09.

Di seguito scarichiamo e installiamo sul PC il software gratuito Win32DiskImager.

Colleghiamo il card reader al PC e inseriamo la scheda SD: attenzione tutti i dati presenti sulla SD verranno eliminati in modo definitivo!
Scompattiamo l'immagine Raspbian e tramite il programma Win32DiskImager salviamola sulla SD.
Al termine chiudiamo il programma e smontiamo, in modo pulito, la SD da Windows prima di rimuoverla dal card reader.

Inseriamo la SD nel RaspberryPi ancora spento, colleghiamolo ad un monitor o alla TV, colleghiamoci una tastiera usb e accendiamolo.

Dopo alcuni istanti comparirà il menu del tool di configurazione 'raspi-config'.


Configurazione del sistema :: raspi-config

Il raspi-config è accessibile in qualsiasi momento lanciando il comando 'sudo raspi-config'.

Con il tasto TAB si può passare dalla lista a i pseudo-tasti (Select, Cancel, ecc.) in modo ciclico.
Con il tasto invio si entra direttamente nella voce di menu selezionata.

Procediamo quindi a:
  • espandere il file system in modo da sfruttare tutto lo spazio possibile della SD card
    • selezionare la voce 'Expand File System' e seguire le istruzioni a video
  • cambiare (se vogliamo) la password dell'utente 'pi' che di default è 'raspberry'
    • selezionare la voce 'Change User Password' e seguire le istruzioni a video
  • impostare il time-zone
    • selezionare la voce 'Internationalization Options'
    • selezionare poi 'Change Time Zone' e seguire le istruzioni a video
  • impostare il layout della tastiera connessa
    • selezionare la voce 'Internationalization Options'
    • selezionare poi 'Change Keyboard Layout' e seguire le istruzioni a video (il layout si imposta dopo aver confermato il modello di tastiera)
  • abilitare il servizio SSH per il controllo remoto (via putty.exe)
    • selezionare la voce 'Advanced Options'
    • selezionare poi 'SSH'  e seguire le istruzioni a video
  • abilitare il supporto SPI
    • selezionare la voce 'Advanced Options'
    • selezionare la voce 'SPI'
  • abilitare il supporto I2C
    • selezionare la voce 'Advanced Options'
    • selezionare la voce 'I2C'
Torniamo al menu principale e usciamo selezionando Finish.
Acconsentiamo al reboot del sistema se ce lo chiede...


Configurazione del sistema :: aggiornamento

Installiamo gli ultimi pacchetti aggiornati disponibili post rilascio della distribuzione:
  • eseguire il comando 'sudo apt-get update'
  • al termine eseguire il comando 'sudo apt-get upgrade' (confermare con Y e invio)
  • attendere che termini l'esecuzione dell'upgrade

Configurazione del sistema :: ip statico

Dato che vogliamo accedere al RaspberryPi comodamente dal nostro PC (tramite putty) e preferibile assegnargli un ip di rete statico (per default è attiva la configurazione in dhcp):

  • eseguire il comando 'sudo nano /etc/network/interfaces'
  • cambiare la riga 'iface eth0 inet dhcp' in 'iface eth0 inet static'
  • subito sotto alla riga cambiata aggiungere le seguenti linee (i valori sono solo di esempio):
    • address 192.168.1.10 
    • netmask 255.255.255.0
    • gateway 192.168.1.1
  • uscire salvando le modifiche al file ('CTRL+X' poi 'Y' poi invio)
  • eseguire il comando 'sudo reboot'
  • dopo il riavvio eseguire il comando 'ifconfig' verificando che l'ip della eth0 sia quello impostato
  • avviare putty.exe sul PC e verificare che non ci siano problemi a connettersi via SSH alla porta 22

Installazione componenti :: configuratore rete wi-fi

Un adattatore usb per la connessione WI-FI è sicuramente l'ideale per accedere da remoto al RaspberryPi senza lo scomodo cavo di rete:
  • eseguire il comando 'sudo apt-get install wicd-curses'
  • avviare con 'sudo wicd-curses'
  • configurare la rete WI-FI selezionandola dalla lista (e premento il tasto freccia destra)
    • settare ip statico, netmask e gateway
    • settare il DNS#1 a 8.8.8.8 e DNS#2 a 8.8.4.4 (o altro a piacere)
    • settare il DHCP Hostname a 'raspberrypi' (o altro a piacere)
    • settare 'Automatically connect... network'
    • settare 'Use Encryption' e impostare la password WPA della rete WI-FI
    • confermare con F10
  • selezionare la rete WI-FI e premere C (Connect) per verificare che si connetta
  • se tutto ok uscire premento Q
  • staccare il cavo di rete
  • avviare putty.exe sul PC e verificare che non ci siano problemi a connettersi via SSH alla porta 22
Da questo momento il RaspberryPi utilizzerà la rete WI-FI configurata in assenza di una connessione via cavo in automatico.
A questo punto possiamo liberare il Raspberry da tutte le connessioni a monitor/TV, tastiera e cavo di rete... e proseguire con i prossimi passi via putty dal PC.

Installazione componenti :: server ftp

Avere un server ftp a bordo del RaspberryPi ci permette di trasferirci dei file senza doverli copiare sulla SD.
Da PC posso connettermi utilizzando uno dei diversi client ftp gratuiti disponibili in rete.
Io, fra tutti, preferisco il FileZilla ftp client.

  • colleghiamoci via putty al RaspberryPi
  • eseguire il comando 'sudo apt-get install vsftpd' e completare l'installazione
  • eseguire il comando 'sudo nano /etc/vsftpd.conf'
    • decommentare e impostare 'anonymous_enable=NO'
    • decommentare e impostare 'local_enable=YES'
    • decommentare e impostare 'write_enable=YES'
    • aggiungere in fondo 'force_dot_files=YES'
  • salvare il file modificato ('CTRL+X' poi 'Y' poi invio)
  • eseguire il comando 'sudo service vsftpd restart'
A questo punto siamo in grado di connetterci, al RapsberryPi tramite il nostro client ftp, alla porta di default (21) e vedere la lista dei file presenti nella cartella dell'utente 'pi'.

Connessi con successo al server ftp del RaspberryPi

Installazione componenti :: i tool per i2c

Il RaspberryPI può anche essere un utile strumento di debug delle nostre applicazioni i2c grazie a questi tool: qui trovate la documentazione completa per l'utilizzo.

  • eseguire il comando 'sudo apt-get install i2c-tools'
  • eseguire il comando 'sudo nano /etc/modprobe.d/raspi-blacklist.conf'
    • commentare linea 'blacklist i2c-bcm2708'
    • salvare il file modificato
  • eseguire il comando 'sudo nano /etc/modules'
    • aggiungere la linea 'i2c-dev'
    • aggiungere la linea 'i2c-bcm2708'
    • salvare il file modificato
  • eseguire il comando 'sudo reboot'
Non appena il RaspberryPi ha terminato il riavvio ci possiamo riconnettere per provare a lanciare il comando 'sudo i2cdetect -y 1' che dovrebbe presentarci la mappa dei dispositivi connessi al bus i2c con successo.

Nessun dispositivo connesso al bus i2c al momento

Installazione componenti :: java (jdk8 + pi4j)

Per chi come me intende sviluppare applicazioni in java per i RaspberryPi provare a lanciare in comando 'java -version'.
Se il comando non è riconosciuto eseguire 'sudo apt-get install oracle-java8-jdk'.

Procedere quindi all'installazione di pi4j: 
  • eseguire il comando 'curl -s get.pi4j.com | sudo bash'
  • eseguire il comando 'cd /opt/pi4j/examples'
  • eseguire il comando 'javac -classpath .:classes:/opt/pi4j/lib/'*' -d . ControlGpioExample.java'
A questo punto verificare che venga eseguito con successo la classe di esempio ControlGpioExample lanciando il comando: sudo java -classpath .:classes:/opt/pi4j/lib/'*' ControlGpioExample



Il nostro RaspberryPi è adesso pronto per i futuri post della serie...


Stay tuned!
ap

NB: l'autore non risponde di eventuali danni causati da omissioni, inesattezze o errori eventualmente presenti nell'articolo pubblicato.
Prego, segnalare suggerimenti e migliorie commentando questo post o inviando una email a padnest@gmail.com.

lunedì 25 gennaio 2010

Servo controller con Pic18F su i2c (parte 2)

E' giunto il momento di dettagliare il protocollo di comando del controller che, come indicato nel titolo, è basato su i2c (se non hai letto la precedente parte clicca qui).

Di seguito i comandi inviabili (ovviamente ogni byte comando va preceduto dal byte address i2c per poter essere ricevuto):

SetServoPosition
Posiziona il servo connesso al canale specificato di n gradi a destra o a sinistra rispetto alla posizione centrale. Alla ricezione di questo comando viene automaticamente abilitata la generazione del segnale di pilotaggio sul canale relativo.
Richiede l'invio di 2 byte: il byte comando e il byte parametro che indica la posizione in gradi da 0 a 90.
Il bit DIR rappresenta la direzione di spostamento: 1 a sinistra, 0 a destra.
I bit CH rappresentano il canale selezionato: da 000 (0) a 111 (7).
Cmd byte
Param byte
1
1
0
0
DIR
CH
CH
CH
0
X
X
X
X
X
X
X


AdjustServoCentralPosition
Regola finemente la posizione centrale del servo connesso al canale specificato.
Richiede l'invio di 2 byte: il byte comando e il byte parametro che indica l'offset da 0 a 15.
Il bit OFS indica la direzione vero la quale applicare l'offset: 1 verso sinistra, 0 verso destra.
I bit CH rappresentano il canale selezionato: da 000 (0) a 111 (7).
Cmd byte
Param byte
1
1
0
1
OFS
CH
CH
CH
0
0
0
0
X
X
X
X
Il valore ideale va ricavato sperimentalmente e varia da servo a servo. Per effettuare la regolazione inviate al controller il comando SetServoPosition su 0 gradi in modo da posizionare il servo al centro. Consiglio poi di etichettare il servo con il valore di trimming ricavato in modo da non dover ripetere l'operazione in futuro.
Attenzione: ogni incremento del valore di offset rappresenta 4uSec in +/- di aggiustamento del segnale di pilotaggio e quindi valori troppo elevati potrebbero causare problemi di mancato stop della rotazione agli angoli estremi.


SetServoOutputState
Setta lo stato del canale specificato permettendo di abilitare o disabilitare la generazione del segnale.
Richiede l'invio del solo byte comando.
Il bit STS indica lo stato del canale: 1 abilitato, 0 disabilitato.
I bit CH rappresentano il canale selezionato: da 000 (0) a 111 (7).
Cmd byte
1
0
0
0
STS
CH
CH
CH


ResetAll
Resetta il controller allo stato iniziale disattivando tutti i canali e reimpostando i valori di trimming centrale a 0.
Richiede l'invio del solo byte comando.
Cmd byte
1
0
1
1
0
0
0
0

Questo è quanto andremo ad implementare nella logica del controller. Posso anticiparvi che il firmware che gestirà tale logica sarà facilmente adattabile ad ogni PIC della serie 18F che disponga del modulo i2c hardware (in quanto non lo emulerò via software).

Stay tuned!
ap

NB: l'autore non risponde di eventuali danni causati da omissioni, inesattezze e errori eventualmente presenti nell'articolo pubblicato.

mercoledì 20 gennaio 2010

Servo controller con Pic18F su i2c (parte 1)

Iniziamo il progetto analizzando il funzionamento di un servo RC e come ci dobbiamo interfacciare per poterne controllare il movimento/posizionamento.

Il servo RC analogico standard, e comunque ideale per questo controller, possiede le seguenti caratteristiche: escursione max di rotazione 180°, posizione centrale 1500 uSec.

Dal servo escono 3 fili di diverso colore (solitamente rosso, nero, giallo/bianco):
  • filo nero: GND
  • filo rosso: SUPPLY (generalmente +5 volt)
  • filo giallo/bianco: SIGNAL (segnale di pilotaggio logico 0/1)

Il servo possiede un'elettronica interna che è in grado di azionare il motorino collegato al proprio asse in relazione al segnale logico ricevuto.
Quindi per poterlo controllare dobbiamo generare un segnale, ad onda quadra, abbastanza preciso ed estremamente stabile:
  1. da livello 0 a 1 con durata minima di 600 uSec (posizione 0° cioè tutto a sinistra)
  2. eventuale mantenimento a livello 1 per un massimo di 1800 uSec in relazione all'angolo di posizionamento dell'asse voluto (angolo 0° = asse tutto a sinistra = 0 uSec, angolo 90° = posizione centrale = 900 uSec, angolo 180° = posizione tutto a destra = 1800 uSec)
  3. da livello 1 a 0 e ripezizione segnale dal punto 1 con frequenza di 50 HZ (20 mSec di intervallo)

In pratica abbiamo una variazione dell'impulso di +900 uSec dalla posizione tutto a sinistra (0°) a quella centrale (90°) e di +900 uSec tra quella centrale (90°) e quella tutto a destra (180°).
La durata dell'impulso va quindi da un minimo di 600uSec ad un massimo di 600 + 900 + 900 = 2400 uSec. Per posizionare il servo al centro l'impulso deve durare 600 + 900 = 1500 uSec.





Possiamo affermare che, per questa tipologia di servo, ogni grado angolare corrisponde a circa 10 uSec di variazione della lunghezza del segnale di livello 1.
Per posizionare l'asse a circa 45° (quindi verso sinistra) dobbiamo generare un impulso di 600 + 45*10 = 600 + 450 = 1050 uSec.
Invece per posizionare l'asse a circa 135° (quindi verso desta) dobbiamo generare un impulso di 600 + 135*10 = 600 + 1350 = 1950 uSec.

E' importante non tanto la precisione al uSec quanto la stabilità dell'impulso in quanto dovrà essere ripetuto identico ogni 20 millisecondi e comunque fino al termine della rotazione.

Infatti un impulso non stabile causa l'oscillazione continua della posizione con relativo inutile assorbimento di preziosi mA da parte del motore interno in continuo movimento.
Inoltre impulsi di durata inferiore ai 600 uSec o superiore ai 2.400 uSec sono altrettanto pericolosi in quanto provocano l'arresto a fine corsa della rotazione dell'asse del servo con conseguente continuo sforzo del motore.

Il controller potrà supportare anche servi RC analogici che abbiano escursioni di rotazione inferiori a 180° e voltaggio di alimentazione diverso da 5 volt.
Dobbiamo anche prevedere un sistema di taratura della posizione centrale in quanto anche fornendo lo stesso segnale a due servi identici (stesso modello) non si ottiene lo stesso identico posizionamento (tolleranza o errore).

Nella prossima parte vi parlerò del protocollo di comando del controller basato su i2c.

Stay tuned!
ap

NB: l'autore non risponde di eventuali danni causati da omissioni, inesattezze e errori eventualmente presenti nell'articolo pubblicato.