Begynd at måle verden omkring dig med dette praktiske og omfattende projekt.
Nøgle takeaways
- Raspberry Pi mangler analog input, men du kan tilføje eksterne ADC'er for at konvertere spændinger fra den virkelige verden til digital form til optagelse, manipulation og kontrol.
- Populære ADC-muligheder omfatter MCP3004/MCP3008 for hastighed og præcision afvejning eller ADS111x for 16-bit aflæsninger med en langsommere samplingshastighed.
- ADS1115 fra Adafruit er en enkel mulighed med en programmerbar forstærkningsforstærker (PGA), der giver dig mulighed for at registrere små spændingsforskelle og justere forstærkningen under programmet. At forbinde det med Raspberry Pi ved hjælp af I2C er ligetil.
Ud af æsken mangler Raspberry Pi en analog indgang. Dette stiller det til en ulempe sammenlignet med mikrocontroller-baserede boards som Arduino.
Men fortvivl ikke: Der er masser af muligheder at overveje. Kom i gang med Raspberry Pi og en ekstern ADC.
Hvorfor tilføje input?
Den virkelige verden er fuld af fænomener, som, hvis du har det rigtige kredsløb, nemt kan beskrives ved hjælp af en spænding. Få disse spændinger i digital form, og du kan optage dem, manipulere dem og bruge dem til at styre andre parametre og enheder.
Du søger måske at overvåge fugten i din jord, temperaturen i dit drivhus eller vægten af din hamster. Du søger måske at tilføje en volumenkontrol til din Pi, bygge en hel bank af fadere eller designe et joystick fra bunden. Mulighederne er mere eller mindre ubegrænsede.
Muligheder for ADC'er
Så hvilken ADC er bedst for begyndere?
Blandt de mest populære og ligetil muligheder er MCP3004 (og MCP3008) chips fra Microchip. Du får fire (eller otte) kanaler på 10 bit hver, som kan læse op til 200 kSPS. På den anden side er der ADS111x-enhederne fra Texas Instruments, som læser 16 bit ved 860 SPS. Så der er en afvejning mellem hastighed og præcision (og naturligvis pris).
Mange mikrocontrollere kommer med indbyggede ADC'er. Den ATMega du finder på den gennemsnitlige Arduino vil tilbyde flere 10-bit kanaler, oven i alt andet. Dette er det, der gør det muligt for Arduino at levere analoge input, hvor Raspberry Pi ikke kan. Hvis du allerede har en Arduino involveret i din opsætning, og 10 bits er nok troskab, så kan dette faktisk være den nemmeste vej at gå.
Her vil vi holde det enkelt med en ADS1115 fra Adafruit.
Hvad er en programmerbar forstærkerforstærker?
Denne chip kommer med et par interessante funktioner, herunder en Programmerbar Gain Amplifier (PGA). Dette vil lade dig indstille det ønskede område af værdier digitalt, ned til en brøkdel af en volt. Med det antal værdier, som 16 bits kan repræsentere, vil dette give dig mulighed for at opdage forskelle på blot nogle få mikrovolt.
Fordelen her er, at du kan ændre gain midtvejs i programmet. Andre chips, som MCP3004, har en anden tilgang; de kommer med en ekstra pin, som du kan levere en referencespænding til.
Hvad med multipleksing?
En multiplexer (eller mux) er en switch, der lader dig læse mange input ved hjælp af en enkelt ADC. Hvis din ADC-chip kommer med mange input-ben, så er der noget intern multipleksing i gang. ADS1115s mux giver mulighed for fire indgange, som du kan vælge via de interne registre.
Håndtering af registre
ADS1115 giver disse muligheder, og et par flere. Du kan håndtere multiplekseren, justere forstærkningen, aktivere den indbyggede komparator, ændre samplingsfrekvensen og sætte enheden i dvaletilstand med lavt strømforbrug, alt sammen ved at dreje et par kontakter.
Men hvor er de kontakter? De er inde i pakken, i form af meget små stykker hukommelse kaldet registre. For at aktivere en given funktion skal du blot sætte den relevante bit til 1 i stedet for 0.
Ser på ADS111x databladet, vil du opdage, at disse modeller kommer med fire registre, inklusive de konfigurationsregistre, der styrer enhedens adfærd.
For eksempel styrer bit 14 til 12 multiplekseren. Ved at bruge disse tre bits kan du vælge mellem otte konfigurationer. Den, du vil have her, er "100", som vil give forskellen mellem input nul og jord. Bit 7 til 5 styrer på den anden side samplingshastigheden. Hvis du vil have maksimalt 860 prøver pr. sekund, kan du indstille disse til "111".
Når du ved, hvilke muligheder du skal indstille, har du to bytes til at sende til ADC'en. Hvis du senere vil indstille en enkelt bit her eller der, så kan du håndtere dem individuelt ved hjælp af bitvise operatorer.
Her kan det blive forvirrende. I dette tilfælde repræsenterer det binære ikke en værdi, men værdierne af individuelle switches. Du kan udtrykke disse variable som ét stort tal, i decimal eller i hexadecimal. Men hvis du vil undgå hovedpine, bør du holde dig til den binære version, som er nemmere at læse.
Forbind det
Du kan tilslutte denne enhed direkte til brødbrættet. Den positive spændingsindgang vil acceptere hvor som helst mellem 2 og 5,5 V, hvilket betyder, at 3,3 V-skinnen på Raspberry Pi vil fungere fint.
Forbind SDA- og SCL-indgangene til modparter på RPi, og gør de samme ting med jorden og 3.3v. Få et potentiometer mellem jord- og spændingsledningerne, og sæt den midterste ledning ind i den første indgang på ADC'en. Det er alt hvad du behøver for at komme i gang!
Beskæftiger sig med I2C
Forskellige ADC'er fungerer via forskellige protokoller. I tilfældet med vores ADS1115, vi skal bruge I2C.
Følgende eksempel vil interagere med ADC'en ved hjælp af Python. Men før du gør det, skal du konfigurere det. Nylige versioner af Raspberry Pi OS har gjort dette meget enkelt. Gå til Præferencer > Raspberry Pi-konfiguration. Derefter fra Grænseflader fane, skifte I2C på.
For at kontrollere, at alt fungerer, skal du åbne en terminal og køre:
sudo i2cdetect -y 1
Denne kommando udsender et gitter. Forudsat at alt fungerer, og du har tilsluttet det korrekt, vil du se en ny værdi vises i gitteret. Dette er adressen på din ADC. Husk her, at det er en hexadecimal værdi, så du er nødt til at præfikse den med "0x" når du bruger det i koden nedenfor. Her er det 0x48:
Når du har adressen, kan du bruge SMBus-biblioteket til at sende I2C-kommandoer. Du skal her beskæftige dig med to metoder. Den første er skrive_ord_data(), som accepterer tre argumenter: enhedsadressen, det register, du skriver til, og den værdi, du vil skrive.
Det andet er read_word_data(), som kun accepterer enhedsadressen og registret. ADC'en vil løbende læse spændinger og gemme resultatet i konverteringsregisteret. Med denne metode kan du hente indholdet af det pågældende register.
Du kan forskønne resultatet en lille smule, og derefter printe det. Før du går tilbage til starten af løkken, indfør en kort forsinkelse. Dette sikrer, at du ikke bliver overvældet 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 = 26300whileTrue:
# 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 lige ved at være færdig. Kortlæg rækken af værdier, du får, til den, du foretrækker, og afkort derefter til det ønskede antal decimaler. Du kan skræddersy printfunktionen, så du kun udskriver en ny værdi, når den er forskellig fra den sidste værdi. Hvis du er usikker på max, min, og rund, du kan tjek vores liste over de 20 vigtigste Python-funktioner!
Håndtering af støj
Medmindre din opsætning er super, super pæn og ryddelig, vil du bemærke noget støj. Dette er den iboende ulempe ved at bruge 16 bit frem for kun ti: den lille smule støj vil være mere mærkbar.
Ved at binde den tilstødende input (input 1) til jorden og skifte tilstand, så du sammenligner input et og to, kan du få meget mere stabile resultater. Du kan også bytte de lange, støjopsamlende startkabler ud med små, og tilføje et par kondensatorer, mens du er i gang. Værdien af dit potentiometer kan også gøre en forskel.
Der er også software muligheder. Du kan oprette et rullende gennemsnit eller blot se bort fra små ændringer. Ulempen der er, at ekstra kode vil pålægge en beregningsomkostning. Hvis du skriver betingede udsagn på et højt niveau sprog som Python, og tager tusindvis af prøver hvert sekund, vil disse omkostninger forværres hurtigt.
Gå videre med mange mulige næste trin
At tage aflæsninger via I2C er ret ligetil, og det samme er stort set tilfældet med andre metoder, såsom SPI. Selvom det kan se ud til, at der er store forskelle mellem de tilgængelige ADC-muligheder, er sandheden, at når først du har fået en af dem til at fungere, er det nemt at anvende viden på de andre.
Så hvorfor ikke tage tingene videre? Bind flere potentiometre sammen, eller prøv at læse lys, lyd eller temperatur. Udvid den controller, du lige har lavet, og opret en Raspberry Pi-opsætning, der virkelig er praktisk!