Begynn å måle verden rundt deg med dette praktiske og omfattende prosjektet.

Viktige takeaways

  • Raspberry Pi mangler analog inngang, men du kan legge til eksterne ADC-er for å konvertere spenninger fra den virkelige verden til digital form for opptak, manipulering og kontroll.
  • Populære ADC-alternativer inkluderer MCP3004/MCP3008 for hastighet og presisjonsavveining eller ADS111x for 16-bits avlesninger med en lavere samplingshastighet.
  • ADS1115 fra Adafruit er et enkelt alternativ med en programmerbar forsterkningsforsterker (PGA) som lar deg oppdage små spenningsforskjeller og justere forsterkning under programmet. Det er enkelt å koble den til Raspberry Pi ved hjelp av I2C.

Ut av esken mangler Raspberry Pi en analog inngang. Dette setter den i en ulempe sammenlignet med mikrokontrollerbaserte kort som Arduino.

Men fortvil ikke: det er mange alternativer å vurdere. Kom i gang med Raspberry Pi og en ekstern ADC.

Hvorfor legge til innganger?

Den virkelige verden er full av fenomener som, hvis du har de riktige kretsene, enkelt kan beskrives ved hjelp av en spenning. Få disse spenningene i digital form, og du kan registrere dem, manipulere dem og bruke dem til å kontrollere andre parametere og enheter.

instagram viewer

Du er kanskje ute etter å overvåke fuktigheten i jorda, temperaturen i drivhuset eller vekten til hamsteren. Du vil kanskje legge til en volumkontroll til Pi-en din, bygge en hel bank med fadere eller designe en joystick fra bunnen av. Mulighetene er mer eller mindre ubegrensede.

Alternativer for ADC-er

Så, hvilken ADC er best for nybegynnere?

Blant de mest populære og enkle alternativene er MCP3004 (og MCP3008) brikker fra Microchip. Du får fire (eller åtte) kanaler på 10 biter hver, som kan lese opptil 200 kSPS. På den annen side er det ADS111x-enhetene fra Texas Instruments, som leser 16 bits ved 860 SPS. Så det er en avveining mellom hastighet og presisjon (og, naturligvis, pris).

Mange mikrokontrollere kommer med innebygde ADC-er. ATMegaen du finner på en gjennomsnittlig Arduino vil tilby flere 10-bits kanaler, på toppen av alt annet. Dette er det som gjør at Arduino kan gi analoge innganger der Raspberry Pi ikke kan. Hvis du allerede har en Arduino involvert i oppsettet ditt, og 10 bits er nok troskap, så kan dette faktisk være den enkleste veien å gå.

Her skal vi holde det enkelt, med en ADS1115 fra Adafruit.

Hva er en programmerbar forsterkerforsterker?

Denne brikken kommer med noen få interessante funksjoner, inkludert en programmerbar forsterkningsforsterker (PGA). Dette lar deg stille inn ønsket verdiområde digitalt, ned til en brøkdel av en volt. Med antallet verdier som 16 biter kan representere, vil dette tillate deg å oppdage forskjeller på bare noen få mikrovolt.

Fordelen her er at du kan endre gain midtveis i programmet. Andre brikker, som MCP3004, har en annen tilnærming; de kommer med en ekstra pinne, som du kan levere en referansespenning til.

Hva med multipleksing?

En multiplekser (eller mux) er en bryter som lar deg lese mange innganger ved å bruke en enkelt ADC. Hvis ADC-brikken din kommer med mange inngangspinner, er det noe intern multipleksing på gang. ADS1115s mux gir mulighet for fire innganger, som du kan velge via de interne registrene.

Håndtering av registre

ADS1115 gir disse alternativene, og noen flere i tillegg. Du kan håndtere multiplekseren, justere forsterkningen, aktivere den innebygde komparatoren, endre samplingsfrekvensen og sette enheten i dvalemodus for lavt strømforbruk, alt ved å snu noen få brytere.

Men hvor er disse bryterne? De er inne i pakken, i form av svært små minnebiter kalt registrerer. For å aktivere en gitt funksjon trenger du bare å sette den relevante biten til en 1, i stedet for en 0.

Ser på ADS111x dataarket, vil du finne at disse modellene kommer med fire registre, inkludert konfigurasjonsregistrene som styrer enhetens oppførsel.

For eksempel styrer bit 14 til 12 multiplekseren. Ved å bruke disse tre bitene kan du velge mellom åtte konfigurasjoner. Den du vil ha her er "100", som vil gi forskjellen mellom inngang null og jord. Bit 7 til 5, derimot, styrer samplingshastigheten. Hvis du vil ha maksimalt 860 prøver per sekund, kan du sette disse til "111".

Når du vet hvilke alternativer du skal angi, har du to byte å sende til ADC. Hvis du senere vil sette en enkelt bit her eller der, kan du håndtere dem individuelt ved å bruke bitvise operatorer.

Her kan det bli forvirrende. I dette tilfellet representerer binæren ikke en verdi, men verdiene til individuelle brytere. Du kan uttrykke disse variablene som ett stort tall, i desimal eller heksadesimal. Men hvis du vil unngå hodepine, bør du holde deg til den binære versjonen, som er lettere å lese.

Koble det opp

Du kan koble denne enheten rett inn i brødbrettet. Den positive spenningsinngangen vil akseptere hvor som helst mellom 2 og 5,5 V, noe som betyr at 3,3 V-skinnen på Raspberry Pi vil fungere bra.

Koble SDA- og SCL-inngangene til motparter på RPi, og gjør de samme tingene med bakken og 3.3v. Få et potensiometer mellom jord- og spenningslinjene, og sett den midterste ledningen inn i den første inngangen til ADC. Det er alt du trenger for å komme i gang!

Håndtere I2C

Ulike ADC-er fungerer via forskjellige protokoller. Når det gjelder vår ADS1115, vi skal bruke I2C.

Følgende eksempel vil samhandle med ADC ved hjelp av Python. Men før du gjør det, må du sette det opp. Nyere versjoner av Raspberry Pi OS har gjort dette veldig enkelt. Drar mot Innstillinger > Raspberry Pi-konfigurasjon. Deretter fra Grensesnitt fane, bytte I2C på.

For å sjekke at alt fungerer, åpne en terminal og kjør:

sudo i2cdetect -y 1

Denne kommandoen vil sende ut et rutenett. Forutsatt at alt fungerer, og du har koblet det opp riktig, vil du se en ny verdi i rutenettet. Dette er adressen til din ADC. Husk her at det er en heksadesimal verdi, så du må prefiksere den med "0x" når du bruker den i koden nedenfor. Her er det 0x48:

Når du har adressen, kan du bruke SMBus-biblioteket til å sende I2C-kommandoer. Du skal håndtere to metoder her. Den første er skrive_ord_data(), som godtar tre argumenter: enhetsadressen, registeret du skriver til og verdien du vil skrive.

Det andre er read_word_data(), som aksepterer bare enhetsadressen og registeret. ADC vil kontinuerlig lese spenninger og lagre resultatet i konverteringsregisteret. Med denne metoden kan du hente innholdet i det registeret.

Du kan forskjønne resultatet litt, og deretter skrive det ut. Før du går tilbake til starten av loopen, introduser en kort forsinkelse. Dette vil sikre at du ikke blir overveldet med data.

from smbus import SMBus
import time
addr = 0x48
bus = SMBus(1)

# set the registers for reading
CONFIGREG = 1
CONVERSIONREG = 0

# set the address register to point to the config register
# write to the config registers
bus.write_word_data(addr, CONFIGREG, (0b00000100 << 8 | 0b10000010))

# define the top of the range
TOP = 26300

whileTrue:
# read the register
b = bus.read_word_data(addr, CONVERSIONREG)

# swap the two bytes
b = ((b & 0xFF) << 8) | ((b >> 8) & 0xFF)

# subtract half the range to set ground to zero
b -= 0x8000

# divide the result by the range to give us a value between zero and one
b /= TOP

# cap at one
b = min(b, 1)

# bottom is zero
b = max(b, 0)

# two decimal places
b = round(b, 2)
print(b)
time.sleep(.01)

Du er omtrent ferdig. Kartlegg verdiområdet du får til den du foretrekker, og avkort deretter til ønsket antall desimaler. Du kan skreddersy utskriftsfunksjonen slik at du bare skriver ut en ny verdi når den er forskjellig fra den siste verdien. Hvis du er usikker på maks, min, og rund, du kan sjekk ut vår liste over de 20 viktigste Python-funksjonene!

Håndtere støy

Nå, med mindre oppsettet ditt er super, superryddig og ryddig, vil du merke noe støy. Dette er den iboende ulempen ved å bruke 16 bits i stedet for bare ti: den lille støyen vil være mer merkbar.

Ved å knytte den tilstøtende inngangen (inngang 1) til jord, og bytte modus slik at du sammenligner inngang en og to, kan du få mye mer stabile resultater. Du kan også bytte ut de lange, støyoppsamlende startkablene med små, og legge til noen få kondensatorer mens du er i gang. Verdien av potensiometeret ditt kan også gjøre en forskjell.

Det finnes også programvarealternativer. Du kan lage et rullende gjennomsnitt, eller bare se bort fra små endringer. Ulempen der er at ekstra kode vil påføre en beregningskostnad. Hvis du skriver betingede utsagn på et språk på høyt nivå som Python, og tar tusenvis av prøver hvert sekund, vil disse kostnadene øke raskt.

Gå videre med mange mulige neste trinn

Å ta avlesninger via I2C er ganske enkelt, og det samme gjelder stort sett andre metoder, som SPI. Selv om det kan virke som det er store forskjeller mellom de tilgjengelige ADC-alternativene, er sannheten at når du først har fått en av dem til å fungere, er det lett å bruke kunnskapen til de andre.

Så hvorfor ikke ta ting videre? Koble sammen flere potensiometre, eller prøv å lese lys, lyd eller temperatur. Utvid kontrolleren du nettopp har laget, og lag et Raspberry Pi-oppsett som er virkelig praktisk!