PCF8574

Scritto da Andrea Martin

In questo articolo parlerò un pò del PCF8574, ma a cosa fa capo questa strana sigla? il PCF8574 è integrato I/O expander quasi-biderezionale a 8 bit indirizzabile sul bus I2c. Il nostro Raspbery Pico ha molti pin utilizzabili come ingressi o uscite digitali, ma possono esaurirsi veramente in fretta se il nostro progetto ne richiede molti, per non parlare se poi dovessimo utilizzare un display. Allora ecco che questo piccolo ma utile componente ci da la possibilità di avere molti più pin disponibili, sia in ingresso che in uscita. Se hai notato prima ho scritto “quasi-bidirezionale”, sta a significare che si lui può operare in come uscita o come ingresso, ma non entrambe le cose, in altre parole, o lo si usa sempre come input o sempre come output per tutti i bit. Il suo uso di base è molto semplce, si manda un byte sulla i2c e lui lo ripopone sulle sue uscite in maniera trasparente.

https://www.ti.com/lit/ds/symlink/pcf8574.pdf

esempio: mando su I2c il byte 10101010 (0xaa) –> sul pcf avro p7=1, p6=0, p5=1… p0=0

Fio a qui nulla di complicato, si complica un pò quando uno vorrebbe scrivre o leggere un solo bit, magari per accendere un led, ecco che allora bisogna cominciare a “giocare” con i bit e le maschere, ma niente paura ho sviluppato una libreria ovviamente in Nim che si prende lei in carico il lavoro noioso e a te non resta altro che dire quale bit leggere o scrivere in maniera molto semplice; ecco un esempio:

import pcf8574
stdioInitAll()
let exp1 = Pcf8574(addressDevice: 0x20, blockk: i2c1)# buffer: 0x00 initializes the object if necessary
const sda = 2.Gpio 
const scl = 3.Gpio 
const address = 0x20
init(i2c1,10000)
sda.setFunction(I2C); sda.pullUp()
scl.setFunction(I2C); scl.pullUp()

  while true:
    exp1.setHigh() #set all led on
    sleep(1000)
    exp1.digitWrite(p1, on) #turn on the bit "p1" 
    sleep(1000)
    exp1.digitWrite(p4, on) #turn on the bit "p4" 
    sleep(1000)
    exp1.digitWrite(p1, off) #turn off the bit "p1" 
    sleep(1000)
    exp1.digitWrite(p4, off) #turn off the bit "p4" ]#
    sleep(1000)
    exp1.writeBytex(0xaa) #alternating leds 
    sleep(1000)
    exp1.setLow() #set all led off
    sleep(1000)

Come detto prima questo componente è (quasi)bidirezionale, quindi possiamo anche andare a leggere il byte presente sui pin dell’integrato e si può fare come nell’esempio sotto(scrivero solo il pezzo dentro al while:

while true:
    var lettura = [uint8(0)] #create a variable uint8 = 0
    exp1.readBytex(lettura) #read all byte on device 
    print("Leggo sul expander: " & $lettura[0]) #stampa tutto il byte
    var p3val = exp1.digitRead(p3) #assigns p3val only the value of bit p3 (bool) 
    print("P3= " & $p3val) #prints the value of bit p3

Ora che si può conoscere lo stato di quel singolo bit, si può per esempio collegaci un pulsante o un qualche sensore on/off, poi compito del programmatore vedre che farne. Si la sintassi di configurazione di I2c è un pò macchinosa, ma nel caso accettino il commit fatto per semplificarla provvederò ad aggiornare. Come di consueto la libreria si pò trovare in:

https://github.com/Martinix75/Raspberry_Pico