Ad5245

Scritto da Andrea Martin

In questo articolo vi presento l “Ad5245”, questo componente è un potenziometro digitale. Tutti abbiamo usato consciamente o incosciamente questi dispositivi, quando alzavamo ad esempio il volume dello stereo, o sia andava modificare qualche settaggio nei dispositivi elettronici. In sostanza un potenziometro (generico) è una resistenza che può variare il suo valore da un minimo, prossimo allo zero, ad un massimo che è il suo valore nominale (ad esempio 10KOhm). L’Ad5245 non è molto diverso, soltanto che per variare il suo valore non c’e la manopolina, ma gli si invia un segnale, in questo caso via I2C. In elettronica questi dispositivi possono essere assai utili per svariati scopi, e per questo ho deciso di scrivere un’apposita libreria pronta all’uso in caso di necessità. La libreria è pensata per lavorare sul PR2040, ma potrebbe funzionare ad esempio anche su Arduino (non testata). Il suo uso è davvero banale, e questo articolo non vule spiegare l’implementazione ma l’uso sul “campo”. Una piccola nota che mi sento di fare è ringraziare i ragazzi che si occupano del wrapper in nim per questo dispositivo (picostdlib) che dalla versione 0.3.0 non occore più editare a mano il file “CMakeLists.txt” ed aggiungere i moduli di sistema come I2C, ma lo fa in automatico. Conclusa la degressione torniamo a noi, in questa libreria ci son nove procedure pubbliche che ora vediamo:

  1. initAd5245 initAd5245*(blokk: I2cInst, address: uint8, resValue: int): questa procedura va ad inizzializzare l’oggetto
    • blokk = sono i blocchi in cui è diviso l’Rp2040 e puo assumere i valori i2c0 oppure i2c1.
    • address = è l’indirizo del AD5245 (ad esempio 0X2C).
    • resValue = è la resistenza nominale del dispositivo in Ohm (5000, 10000, 50000, 100000).
  2. setInstruction setInstruction*(self: Ad5245, instruction: uint8): procedura per passare dei “comandi”
    • istruzione RS = porta il dispositivo a metà scala (valore 0x40)
    • istruzione RD = porta in alta impedenza le uscite A-W, e a zero B-W (valore 0x20).
  3. setValue setValue*(self: Ad5245, data: var uint8): scrive il numero (0-255) nel registro, ogni numero corrisponde ad un valore resitivio.
  4. setResWa setResWA*(self: Ad5245, ohmValue: var int): questa procedura prende come argomento il valore in Ohm desiderato, e provvede a calcolare il valore da scrivere nel registro per settare il valore ohmnico desiderato, questo valore sarà quello visto tra le uscite A-W.
  5. setResWB setResWB*(self: Ad5245, ohmValue: var int): questa procedura prende come argomento il valore in Ohm desiderato, e provvede a calcolare il valore da scrivere nel registro per settare il valore ohmnico desiderato, questo valore sarà quello visto tra le uscite B-W.
  6. setVoltage setVoltage*(self: Ad5245, vOut: var float, voltA: float, voltB: float = 0.0): questa procedura calcola il valore da scrivere nel registro per avere in uscita (W) il valore di tensione desiderato.
  7. getResWA getResWA*(self: Ad5245): ritorna il valore (calcolato) della resistenza attualmente presente tra A&W.
  8. getResWB* getResWB*(self: Ad5245): ritorna il valore (calcolato) della resistenza attualmente presente tra B&W.
  9. getValue getValue*(self: Ad5245): ritorna il valore (0-255) attualmente presente nel registro.

Perchè ci sono due procedure specifiche per settare il valore resistivo ovvero setResWA e setResWB? La risposta è semplice, perchè in un potenziometro la resistenza vista tra il cursore (w) e i capi della resistenza (A & B), a meno di non essere al centro, dove è uguale su entrambi i rami una parte sarà complementare all’altra (ad esempio se tra Wed A ho zero Ohm, tra W e B avro l’intero valore nominale) e quindi va calcolata in modo diverso. Anche la procedura setValue setta il valore del potenziometro, ma in maniera più astratta; mentre con le procedure appena viste dichiariamo il valore della resitenza desiderato, qui diamo direttamente un numero (0-255) che non ha riferimenti a valori ohmnici, ma può essere utile magari incrementando il suo valore per avvicinarci il più possibile al valore corretto. La procedura setVoltage la si usa quando anzichè usare il potenziometro per settare una valore ohminico, si vuole usarlo come partiore di tensione, in sostanza per ridurre la tensione di ingresso ad una sua frazione. ATTENZIONE!! non si può mettere qualsiasi valore di tensione in ingresso, ma solo uguale o inferiore alla tensione di alimentazione (tipicamente 3.3V o 5V e comunque MAI più di 5.5V!). Le procedure * getResWA* e getResWB ritorna il valore in Ohm del valore che assumono i rami WA e WB, mentre getValue ritorna il valore numerico (astratto) scritto nel registro (0-255).

La libreria la si può trovare in : https://github.com/Martinix75/Raspberry_Pico/tree/main/Libs/Ad5245

Di seguito un piccolo esempio dell’uso della libreria (che trovi nel esempio che accompagna la libreria) l’esempio per funzionare necessita della libreria picousb che puoi trovare in: https://github.com/Martinix75/Raspberry_Pico/tree/main/Utils/picoUsb .

import picostdlib/[stdio, gpio, i2c, time]
import std/[strutils]
import ad5245
import picousb

stdioInitAll()
setupI2c(blokk = i2c1, psda = 18.Gpio, pscl = 19.Gpio, freq = 100_000) #max 400khz.
let potenz = initAd5245(blokk = i2c1, address = 0x2C, resValue = 5000) #set blol & address sugar mode.
let usb = PicoUsb() #for comication whit ad5425

var
  usbVal: string
  splitList: seq[string]
  tempNum8: uint8
  tempNumF: float
  tempNumI: int
while true:
  if usb.isReady == true:
    usbVal = usb.readLine()
    splitList = split(usbVal, '#')
    case splitList[0] 
    of "setvalue":
      tempNum8 = uint8(parseInt(splitList[1]))
      potenz.setValue(tempNum8)
    of "setreswa":
      tempNumI = parseInt(splitList[1])
      potenz.setResWA(tempNumI)
    of "setreswb":
      tempNumI = parseInt(splitList[1])
      potenz.setResWB(tempNumI)
    of "setvoltage":
      tempNumF = parseFloat(splitList[1])
      potenz.setVoltage(tempNumF, voltA=3.3)
    of "getreswa":
      print("The resistance between A&W is of: " & $potenz.getResWA() & " Ohm" & '\n')
    of "getreswb":
      print("The resistance between B&W is of: " & $potenz.getResWB() & " Ohm" & '\n')
    of "getvalue":
      print("The value in the register is of: " & $potenz.getvalue() & " Number" & '\n')
    of "ver":
      print("Lib ad5425 Version is: " & ad5245Ver & '\n')
    else:
      print("!!! Command NOT found !!!" & '\n')
  sleep(50)

Per vedere i riusultati aprire un terminale per la conessione seriale (io uso cutecom), e digitare i vari comandi ad esempio: setreswa#1370 per settare tra A&W 1370 Ohm.