Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

12
voti

Umidità relativa, pirati e pitoni

Indice

Partenza e arrivo

Lavoro per una ditta che produce sensori che vengono utilizzati (tra l'altro) nell'industria bio-farmaceutica: produzione di vaccini, produzione di medicamenti, produzione a scopo di ricerca di virus e batteri.

In un ambito del genere è essenziale poter sterilizzare il sensore, in modo da non contaminare i prodotti quando si cambia processo. Una volta i sensori li si bollivano. Con il passare degli anni le esigenze in fatto di igiene sono diventate sempre piú severe. Oggi la sterilizzazione consiste in un bagno di vapore a 140 °C e 3.7 bar di sovrapressione durante mezz'ora.

Ovviamente l'elettronica non gradisce questo tipo di condizioni ambientali, quindi il sensore deve essere ermetico (e vi garantisco che non è facile!). Per testare la tenuta delle giunture ho costruito delle piccole schedine che montano un sensore di umidità e ho scritto un po' di software per leggere questi sensori.

In questo articolo presento il lavoro svolto e l'interfaccia usata, che credo possa tornare utile a molti hobbysti (o professionisti).

I componenti del sistema

Qui elenco brevemente i componenti che costituiscono il sistema. Nei capitoli seguenti scendo nei dettagli di ogni componente.

Sensore di umidità 
il sensore scelto è il Si7020 della Silabs
Interfaccia 
il collegamento con il computer avviene tramite un Bus Pirate
Software 
l'interfaccia utente è programmata in Python

Silabs Si7020

Ho scelto questo sensore per una serie di motivi:

  • temperatura compensata internamente
  • uscita digitale
  • piccolo (ho problemi di spazio)
  • costa poco
  • disponibilità presso i grossi distributori
  • resiste al trattamento brutale a cui lo sottopongo (temperature di stoccaggio fino a 150 °C)

Il circuito è preso pari pari dal datasheet. Non c'è molto da dire... Qui il layout del circuitino:

Layout (un solo layer) del circuito

Layout (un solo layer) del circuito

Ce l'ho fatto stare in 19 x 5 mm, monofaccia. Il rovescio della medaglia è che devo fare un ponticello tra il pad Vdd di destra e quello di sinistra. Nulla di tragico!

Visto che non c'è molto da dire, riempio la pagina caricando un paio di foto ;-)

Il PCB con il connettore standard dei nostri sensori

Il PCB con il connettore standard dei nostri sensori

Qui si vede un dettaglio del chip, con lo strato capacitivo. Si noti la notevole maestria nel saldare i componenti in modo che sembrino attaccati con lo sputo :-/

Qui si vede un dettaglio del chip, con lo strato capacitivo. Si noti la notevole maestria nel saldare i componenti in modo che sembrino attaccati con lo sputo :-/

Bus Pirate

In realtà tutto l'articolo è una scusa per parlare di questo giocattolo ;-) Ho notato che non se ne parla nel forum, ne deduco che probabilmente non è conosciuto alla maggiorparte dei parteciparti. E allora, signori e signore, eccolo qui, il Pirata dei Bus:

Bus Pirate (Versione 3.6)

Bus Pirate (Versione 3.6)

È una schedina grande quanto una carta di credito, con un collegamento USB e un connettore a 10 pin. La porta USB viene vista come UART (Virtual Com Port). Quando ci si collega via terminal il pirata offre un menu testuale per la gestione degli I/O. Questi sono configurabili (sorpresa sorpresa, chi l'avrebbe mai detto) con diversi protocolli di bus: I²C, SPI, 1-Wire,...

Questo aggeggino è utilissimo per lo sviluppo e il debugging. Se il vostro circuito accetta 5 V o 3.3 V e non richiede piú di 300 mA potete alimentarlo direttamente dal pirata. Ah, c'è anche un ingresso ADC, cosa volete di piú? Ciliegina sulla torta, costa 30 miseri dollari. Prima di darvi il link alla pagina del progetto, le canoniche 5 paroline: non-ho-percentuali-sulle-vendite ;-)

http://dangerousprototypes.com/docs/Bus_Pirate

Non è tutto oro quello che luccica: l'input/output avviene, come detto, via terminale. La velocità e 115 kbps, ma c'è tutto l'overhead legato al menu e alla gestione del protocollo. Questo limita la velocità sul lato bus. Inoltre il buffer è limitato, quindi benché il bus possa accettare dati a velocità piú sostenute, l'overflow è sempre in agguato.

Per mitigare questo problema c'è la possibilità di "spegnere" l'interfaccia sul terminal e usare il pirata in modo binario. Piú dettagli in merito nella sezione relativa al software, in cui useremo questo metodo per comunicare con il sensore.

Potrei spiegarvi vita e miracoli dell'utilizzo di questo oggetto, ma visto che online si trova la documentazione relativa, vi risparmio e mi limito ad uno screenshot e due parole:

Screenshot del menu in modalità SPI

Screenshot del menu in modalità SPI

Qui ho configurato il Bus Pirate in modalità SPI (è estremamente intuitivo, il menu chiede per esempio che velocità si vuole ed elenca diverse frequenze, si dà il numero corrispondente alla frequenza desiderata e si conferma con Enter, il menu passa al punto seguente, la polarità del clock, e così via...).

Inserendo "?" e dando Invio appare il menu che vedete. La colonna di sinistra è sempre uguale e serve a gestire le funzioni generali del pirata e a cambiare modo. La colonna di destra invece contiene i comandi specifici per il protocollo attivo.

Interessante è il comando v: elenca tutti i pin e dice a cosa corrispondono in questo specifico protocollo (nel caso dell'SPI avremo MOSI, MISO, CLK e CS, oltre a tutta la paccottiglia ausiliaria: GND, V3.3, V5, Pull-up, ADC...) assieme al loro stato (1, 0, Hi-Z,...). Come detto, se vi ho incuriosito, spulciate la documentazione ;-)

Software

Bam! Partiamo direttamente con il codice:

import sys
from PyQt4 import QtGui, QtCore, uic
from PyQt4.QtCore import QObject
from pyBusPirateLite.I2Chigh import *


class MainWindow(QtGui.QMainWindow,QObject):

    def __init__(self):
        super(MainWindow, self).__init__()
        
        # averaging:
        self.avg_n = 3
        
        self.initUI()
        

    def initUI(self):

        self.ui = uic.loadUi('GUI.ui')
        self.ui.show()
     
        #connectors
        self.connect(self.ui.v_start, QtCore.SIGNAL("clicked()"), self.startClick)

        

    def startClick(self):
        
        self.ui.v_rh.setMaxLength(15)
        self.ui.v_t.setMaxLength(15)
        self.ui.v_rh.setText('reading...')
        self.ui.v_t.setText('reading...')
        self.ui.repaint()

        i2c = I2Chigh("COM"+str( self.ui.v_com.value()), 115200, 5)
        i2c.BBmode()
        i2c.enter_I2C()
        i2c.cfg_pins(I2CPins.POWER)        
        i2c.set_speed(I2CSpeed._400KHZ)
        
        rh_sum = 0
        for i in range(0, self.avg_n):
            rh_sum = rh_sum + float(i2c.get_word(0x40, 0xE5)) * 125 / 65536 - 6
        rh = rh_sum / self.avg_n
        self.ui.v_rh.setText(str(rh))
        self.ui.v_rh.setMaxLength(5)
        self.ui.repaint()
        
        t_sum = 0
        for i in range(0, self.avg_n):
            t_sum = t_sum + float(i2c.get_word(0x40, 0xE3)) * 175.72 / 65536 - 46.85
        t = t_sum / self.avg_n
        self.ui.v_t.setText(str(t))
        self.ui.v_t.setMaxLength(5)
        
        i2c.resetBP()        
        
        return

                    

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    mainwindow = MainWindow()
    sys.exit(app.exec_())



I piú attenti avranno notato che si tratta di Python.

Piccolo excursus. Io odio Python. L'ho già detto qui: http://www.electroyou.it/forum/viewtopic.php?f=16&t=52459&p=506696 e la mia opinione è stata onorata con due punti negativi. I punti negativi non sono riusciti a farmi cambiare opinione. Ci sono i linguaggi di programmazione (C++, per esempio) e ci sono i languaggi di scripting (Python). Purtroppo la libreria per il Bus Pirate c'è solo per Python. È quella che importo all'inizio e si chiama pyBusPirateLite.

Descrivo brevemente il semplicissimo codice. Nel constructor dichiaro la variabile avg_n che definisce quanti samples vengono presi per fare la media del valore che verrà poi visualizzato. Dopodiché inizializzo l'interfaccia grafica. Questa viene caricata dal file GUI.ui (vedo con Admin se posso caricarlo, altrimenti, chi vuole averlo può mandarmi un messaggio... oppure come compito scriverlo in base a quanto si vede nel codice qui sopra ;-)). Nell'interfaccia grafica c'è un bottone "Start". Questo viene collegato alla funzione startClick. E qui il programma si ferma e aspetta che io clicchi il magico tasto.

Quando faccio click, parte la funzione startClick. Eccone il contenuto, punto per punto:

  • setto la massima lunghezza dei campi umidità e temperatura a 15 in modo da poterci scrivere "reading..."
  • setto il testo in ambo i campi a "reading..."
  • aggiorno la GUI in modo che il cambiamento venga visualizzato
  • creo un'instanza i2c della classe I2Chigh. La porta COM su cui è attaccato il pirata me la leggo dalla GUI
  • entro in modo binario
  • entro in modalità I2C
  • abilito i regolatori di tensione per il mio circuito
  • setto la velocità del bus

Fin qui tutto molto semplice. Niente paura, anche quello che segue è semplice ;-)

Ho due sezioni simili, una per la temperatura e l'altra per l'umidità. Sono costituite da un loop-for della lunghezza del numero di samples che abbiamo definito prima. Ad ogni ripetizione del loop aggiungo ad una somma che ho inizializzato con zero il valore letto. Questo si ricava con la formula contenuta nel datasheet del Si7020 partendo dal codice restituito sul bus. Come si ottiene il codice? Il cuore di tutta la faccenda è quel float(i2c.get_word(0x40, 0xE5)).


È un comando dato sulla classe i2c che abbiamo instanziato prima. Il comando è get_word, ovvero leggi un word dal bus. i Parametri sono 0x40, l'indirizzo I2C del sensore, e 0xE5, il registro in cui si trova il valore di umidità. Il cast su float è necessario perché altrimenti il codice verrebbe interpretato come un int e la divisione non darebbe il risultato aspettato.


Finito il loop, divido per il numero di addendi per ottenere la media, la scrivo nel campo della GUI (dopo averla convertita in una stringa), setto la lunghezza massima del campo a 5 (non ha molto senso avere 12 cifre significative su un sensore con il 3% di precisione...).


L'ultimo comando resetta il pirata, spegnendo l'alimentazione e uscendo dalla modalità I2C.

Il risultato

Ecco uno screenshot del programmino

Il programma in azione

Il programma in azione

Ed ecco il setup di misura, si noti la demoboard di Sensirion con il SHT11, lo scostamento dei valori misurati è ampiamente entro le tolleranze:

Confronto tra Si7020 e SHT11

Confronto tra Si7020 e SHT11

Spero che questo progettino vi possa tornare utile o, perlomeno, abbia suscitato un po' di interesse per il pirata ;-)

1

Commenti e note

Inserisci un commento

di ,

Bravo boiler, ho letto questo e gli altri tuoi articoli successivi. Apprezzo sia le informazioni (per me del tutto fantastiche ed esoteriche) e, soprattutto, lo stile di presentazione, equilibrato tra il professionale e il ludico. Ho una grande invidia per il tuo lavoro che ti porta a contatto (come una sonda?) con ambiente così vari e specialmente in birrerie (ma la taratura la fai scolandoti un birra?) Ottimo

Rispondi

Inserisci un commento

Per inserire commenti è necessario iscriversi ad ElectroYou. Se sei già iscritto, effettua il login.