Börja mäta världen omkring dig med detta praktiska och omfattande projekt.
Viktiga takeaways
- Raspberry Pi saknar analog ingång, men du kan lägga till externa ADC: er för att omvandla spänningar från den verkliga världen till digital form för inspelning, manipulation och kontroll.
- Populära ADC-alternativ inkluderar MCP3004/MCP3008 för hastighet och precision avvägning eller ADS111x för 16-bitars avläsningar med en långsammare samplingshastighet.
- ADS1115 från Adafruit är ett enkelt alternativ med en programmerbar förstärkningsförstärkare (PGA) som låter dig upptäcka små spänningsskillnader och justera förstärkningen under programmets gång. Att koppla upp det med Raspberry Pi med I2C är enkelt.
Ur lådan saknar Raspberry Pi en analog ingång. Detta gör det till en nackdel jämfört med mikrokontrollerbaserade kort som Arduino.
Men misströsta inte: det finns många alternativ att överväga. Kom igång med Raspberry Pi och en extern ADC.
Varför lägga till ingångar?
Den verkliga världen är full av fenomen som, om du har rätt kretsar, lätt kan beskrivas med hjälp av en spänning. Få dessa spänningar i digital form, så kan du spela in dem, manipulera dem och använda dem för att styra andra parametrar och enheter.
Du kanske vill övervaka fukten i din jord, temperaturen i ditt växthus eller vikten på din hamster. Du kanske funderar på att lägga till en volymkontroll till din Pi, bygga en hel bank med faders eller designa en joystick från grunden. Möjligheterna är mer eller mindre obegränsade.
Alternativ för ADC
Så vilken ADC är bäst för nybörjare?
Bland de mest populära och enkla alternativen är MCP3004 (och MCP3008) chips från Microchip. Du får fyra (eller åtta) kanaler på 10 bitar vardera, som kan läsa upp till 200 kSPS. Å andra sidan finns ADS111x-enheterna från Texas Instruments, som läser 16 bitar vid 860 SPS. Så det finns en avvägning mellan hastighet och precision (och, naturligtvis, pris).
Många mikrokontroller kommer med inbyggda ADC. Den ATMega du hittar på en genomsnittlig Arduino kommer att erbjuda flera 10-bitars kanaler, utöver allt annat. Detta är vad som gör att Arduino kan tillhandahålla analoga ingångar där Raspberry Pi inte kan. Om du redan har en Arduino inblandad i din installation, och 10 bitar är tillräckligt med trohet, så kan detta faktiskt vara den enklaste vägen att gå.
Här ska vi hålla det enkelt, med en ADS1115 från Adafruit.
Vad är en programmerbar förstärkningsförstärkare?
Detta chip kommer med några intressanta funktioner, inklusive en PGA (Programmable Gain Amplifier). Detta låter dig ställa in önskat värdeintervall digitalt, ner till en bråkdel av en volt. Med det antal värden som 16 bitar kan representera, gör detta att du kan upptäcka skillnader på bara några mikrovolt.
Fördelen här är att du kan ändra förstärkningen mitt i programmet. Andra chips, som MCP3004, har ett annat tillvägagångssätt; de kommer med ett extra stift, till vilket du kan mata en referensspänning.
Hur är det med multiplexering?
En multiplexer (eller mux) är en switch som låter dig läsa många ingångar med en enda ADC. Om ditt ADC-chip kommer med många ingångsstift, pågår det viss intern multiplexering. ADS1115:s mux tillåter fyra ingångar, som du kan välja via de interna registren.
Att hantera register
ADS1115 ger dessa alternativ, och några fler dessutom. Du kan hantera multiplexern, justera förstärkningen, aktivera den inbyggda komparatorn, ändra samplingsfrekvensen och sätta enheten i viloläge med låg effekt, allt genom att vrida några strömbrytare.
Men var är dessa switchar? De är inuti paketet, i form av mycket små minnesbitar som kallas register. För att aktivera en given funktion behöver du bara ställa in den relevanta biten till en 1, snarare än en 0.
Tittar på ADS111x datablad, kommer du att upptäcka att dessa modeller kommer med fyra register, inklusive de konfigurationsregister som styr enhetens beteende.
Till exempel styr bitarna 14 till 12 multiplexorn. Med dessa tre bitar kan du välja mellan åtta konfigurationer. Den du vill ha här är "100", vilket ger skillnaden mellan ingång noll och jord. Bitarna 7 till 5, å andra sidan, styr samplingshastigheten. Om du vill ha maximalt 860 sampel per sekund kan du ställa in dessa på "111".
När du väl vet vilka alternativ du ska ställa in har du två byte att skicka till ADC. Om du senare vill ställa in en enskild bit här eller där, kan du hantera dem individuellt med hjälp av bitvisa operatorer.
Här kan det bli förvirrande. I det här fallet representerar binären inte ett värde, utan värdena för enskilda switchar. Du kan uttrycka dessa variabler som ett stort tal, i decimal eller hexadecimal. Men om du vill undvika huvudvärk bör du hålla dig till den binära versionen som är lättare att läsa.
Koppla upp den
Du kan ansluta den här enheten direkt till brödbrädan. Den positiva spänningsingången kommer att acceptera någonstans mellan 2 och 5,5 V, vilket betyder att 3,3 V-skenan på Raspberry Pi kommer att fungera bra.
Koppla SDA- och SCL-ingångarna till motsvarigheter på RPi och gör samma saker med jord och 3,3v. Skaffa en potentiometer mellan jord- och spänningsledningarna, och sätt den mittersta ledningen i den första ingången på ADC. Det är allt du behöver för att komma igång!
Hanterar I2C
Olika ADC: er fungerar via olika protokoll. När det gäller vår ADS1115, vi kommer att använda I2C.
Följande exempel kommer att interagera med ADC med Python. Men innan du gör det måste du ställa in det. De senaste versionerna av Raspberry Pi OS har gjort detta väldigt enkelt. Bege dig till Inställningar > Raspberry Pi-konfiguration. Sedan, från Gränssnitt flik, växla I2C på.
För att kontrollera att allt fungerar, öppna en terminal och kör:
sudo i2cdetect -y 1
Detta kommando kommer att mata ut ett rutnät. Förutsatt att allt fungerar och du har kopplat upp det korrekt, kommer du att se ett nytt värde i rutnätet. Detta är adressen till din ADC. Tänk här på att det är ett hexadecimalt värde, så du måste prefixa det med "0x" när du använder den i koden nedan. Här, det är 0x48:
När du väl har adressen kan du använda SMBus-biblioteket för att skicka I2C-kommandon. Du kommer att hantera två metoder här. Den första är write_word_data(), som accepterar tre argument: enhetens adress, registret du skriver till och värdet du vill skriva.
Den andra är read_word_data(), som bara accepterar enhetens adress och registret. ADC: n kommer att kontinuerligt läsa av spänningar och lagra resultatet i konverteringsregistret. Med den här metoden kan du hämta innehållet i det registret.
Du kan försköna resultatet lite och sedan skriva ut det. Innan du går tillbaka till början av loopen, inför en kort fördröjning. Detta säkerställer att du inte blir överväldigad 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 är precis klar. Kartlägg intervallet av värden du får till det du föredrar och trunkera sedan till önskat antal decimaler. Du kan skräddarsy utskriftsfunktionen så att du bara skriver ut ett nytt värde när det skiljer sig från det senaste värdet. Om du är osäker på max, min, och runda, du kan kolla in vår lista över de 20 viktigaste Python-funktionerna!
Hantera buller
Nu, om inte din installation är super, superprydlig och snygg, kommer du att märka lite brus. Detta är den inneboende nackdelen med att använda 16 bitar snarare än bara tio: det lilla bruset blir mer märkbart.
Genom att knyta den intilliggande ingången (ingång 1) till jord och byta läge så att du jämför ingång ett och två, kan du få mycket mer stabila resultat. Du kan också byta ut de långa, brusuppsamlande startkablarna mot små och lägga till några kondensatorer medan du håller på. Värdet på din potentiometer kan också göra skillnad.
Det finns också mjukvarualternativ. Du kan skapa ett rullande medelvärde eller helt enkelt bortse från små förändringar. Nackdelen där är att extra kod kommer att medföra en beräkningskostnad. Om du skriver villkorliga uttalanden på ett högnivåspråk som Python och tar tusentals prover varje sekund, kommer dessa kostnader att öka snabbt.
Gå vidare med många möjliga nästa steg
Att ta avläsningar via I2C är ganska enkelt och detsamma gäller i stort sett för andra metoder, som SPI. Även om det kan tyckas att det finns stora skillnader mellan de tillgängliga ADC-alternativen, är sanningen att när du väl har fått ett av dem att fungera är det lätt att tillämpa kunskapen på de andra.
Så varför inte ta saker längre? Koppla ihop flera potentiometrar eller prova att läsa ljus, ljud eller temperatur. Utöka kontrollern du just har skapat och skapa en Raspberry Pi-installation som verkligen är praktisk!