Contents

Lägga till en ADC till din Raspberry Pi: Vad du behöver veta

Viktiga slutsatser

Raspberry Pi kan inte bearbeta analoga signaler direkt, men den kan utrustas med externa Analog-till-Digital-omvandlare (ADC) som omvandlar fysiska spänningsvärden till ett digitalt format som är lämpligt för datalagring, manipulation och hantering.

Populära val av ADC (Analog to Digital Converter) omfattar MCP3004/MCP3008, som erbjuder en balans mellan hastighet och noggrannhet, samt ADS111x, som ger 16-bitars upplösning vid en lägre samplingsfrekvens.

ADS1115, som finns tillgänglig via Adafruit, är en elegant lösning med en programmerbar förstärkare (PGA) som möjliggör detektering av små spänningsskillnader och samtidigt underlättar dynamisk förstärkningsjustering under drift. Integration med Raspberry Pi via I2C innebär inga som helst utmaningar.

Raspberry Pi:s initiala brist på analoga ingångar skiljer den från mikrokontrollerorienterade plattformar som Arduino, vilket kan begränsa dess kapacitet jämfört med dessa alternativ.

Även om det kan verka avskräckande finns det flera alternativ att utforska. Du kan börja med att använda en Raspberry Pi tillsammans med en extern Analog-till-Digital-omvandlare (ADC) för sömlös drift.

Varför lägga till ingångar?

I den naturliga världen finns det många företeelser som enkelt kan sammanfattas med hjälp av elektriska potentialer. Genom att omvandla dessa potentialer till sina binära ekvivalenter kan de arkiveras, manipuleras och användas som medel för att reglera ytterligare faktorer och aktivera ytterligare mekanismer.

Man kan vilja övervaka fuktigheten i sin jord, värmen i sitt växthus eller tyngden hos sin gnagare. Man kan vilja bygga in en nivåregulator i sin Raspberry Pi, konstruera en hel uppsättning reglage eller skapa en ny joystick. De potentiella tillämpningarna är mycket omfattande och varierande.

Alternativ för ADC

Så vilken ADC är bäst för nybörjare?

Bland de mest populära och okomplicerade alternativen finns MCP3004 (och MCP3008 ) 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. Det är alltså en avvägning mellan hastighet och precision (och naturligtvis pris).

Flera mikrokontroller är utrustade med integrerade Analog-till-Digital-omvandlare (ADC). Den allmänt använda ATMega som finns i de flesta Arduinos ger till exempel flera kanaler med 10-bitars upplösning tillsammans med andra funktioner.Detta gör det möjligt för Arduino-plattformen att stödja analoga insignaler som överskrider gränserna för Raspberry Pis kapacitet. I de fall en befintlig Arduino ingår i ett projekt och 10 bitars upplösning är tillräckligt för den noggrannhet som krävs, kan det visa sig vara enklast att använda den lätt tillgängliga Arduino-lösningen.

För enkelhetens skull ska vi i detta fall använda ADS1115, som tillhandahålls av Adafruit.

/sv/images/ads1115_photo.png

Vad är en programmerbar förstärkare?

Den integrerade kretsen har flera spännande egenskaper, bland annat en inbyggd programmerbar förstärkare (PGA) som möjliggör digital inställning av önskat amplitudspektrum. PGA:n gör det möjligt att specificera spänningsområdet ner till bråkdelar av en volt, vilket gör det möjligt att upptäcka så små variationer som några mikrovolt tack vare den stora mängd värden som representeras av 16-bitarsupplösningen.

En av fördelarna med just detta chip är att det möjliggör justering av förstärkningen under drift. Vissa andra enheter, t.ex. MCP3004, använder däremot en alternativ strategi genom att införliva ett extra stift till vilket en referensspänning kan appliceras.

Hur är det med multiplexering?

En multiplexer, även kallad mux, fungerar som en omkopplingsenhet som gör det möjligt att använda en enda analog-till-digital omvandlare (ADC) för att sampla data från flera källor. I de fall där en integrerad ADC-krets har en mängd olika ingångsterminaler är det uppenbart att en inneboende multiplexeringsprocess äger rum internt. ADS1115 innehåller t.ex. en mux-komponent med kapacitet att hantera upp till fyra olika insignaler, som kan väljas selektivt genom manipulation av den inbyggda registerkonfigurationen.

Hantering av register

ADS1115 erbjuder en rad funktioner som enkelt kan nås genom manipulation av flera kontrollinställningar. Dessa inkluderar möjligheten att hantera flera

Aktiveringsmekanismen för varje enskild funktion är dold i produktens förpackning och manifesterar sig som små datalager som kallas “register”. För att aktivera en viss funktion behöver man bara ändra det aktuella registret från standardvärdet noll till ett värde på ett.

Om du tittar på ADS111x datablad , hittar du att dessa modeller levereras med fyra register, inklusive konfigurationsregistren som styr enhetens beteende.

/sv/images/as1115_config_register.jpg

I detta sammanhang används bitarna 14 till 12 för att styra driften av en multiplexer. Genom att använda dessa tre binära siffror kan man välja mellan åtta olika konfigurationer. Den önskvärda konfigurationen i detta fall är “100”, eftersom den bestämmer differentialsignalen mellan ingångskanal 0 och jord. Omvänt är bitarna 7 till 5 ansvariga för att reglera samplingsfrekvensen. För att uppnå högsta möjliga samplingsfrekvens på 860 samplingar per sekund, skulle det vara idealiskt att sätta dessa bitar till “111”.

När du har identifierat vilka inställningar som skall göras, har du tillgång till totalt två bitar som kan överföras till Analog-till-Digital-omvandlaren. Om du senare vill ändra enskilda bitar kan du göra det genom att använda bitvisa operationer isolerat.

Representationen av enskilda omkopplartillstånd i ett binärt system kan ge upphov till viss förvirring. Även om den binära koden i sig inte direkt representerar ett specifikt numeriskt värde, kan den användas för att ange tillståndet för varje enskild omkopplare. Denna information kan uttryckas i olika format som decimal eller hexadecimal notation, men för att underlätta förståelsen och förhindra potentiella komplikationer är det ofta att föredra att använda det binära formatet.

Koppla upp den

Denna enhet kan enkelt anslutas till ett breadboard. Den positiva spänningsingången sträcker sig från 2 till 5,5 volt, vilket garanterar kompatibilitet med Raspberry Pis 3,3 volts strömförsörjning.

För att starta driften, anslut SDA- och SCL-stiften från MCP3008 till motsvarande portar på Raspberry Pi och anslut samtidigt jord- och 3,3 V-anslutningarna. Sätt dessutom in en potentiometer i serie mellan jord- och spänningsledningarna, varefter du ansluter ena änden av potentiometerns mittledare till den första ingången på Analog-till-Digital-omvandlaren (ADC). När dessa steg är slutförda är din installation klar för användning.

Hantering av I2C

Olika analog-till-digital-omvandlare (ADC) använder olika kommunikationsprotokoll för sin drift. När det gäller vår ADS1115 kommer vi t.ex. att använda ett specifikt gränssnitt som kallas Inter-Integrated Circuit (I2C) för kommunikation och dataöverföring.

För att kunna använda Python i gränssnittet mot en Analog-till-Digital-omvandlare (ADC) på en Raspberry Pi måste vissa förutsättningar vara uppfyllda. Lyckligtvis har de senaste versionerna av Raspberry Pi-operativsystemet (OS) förenklat denna process avsevärt.För att starta installationsproceduren, navigera till “Preferences” i systemmenyn och välj “Raspberry Pi Configuration.” Gå sedan vidare till fliken “Interfaces” och aktivera alternativet “I2C”.

/sv/images/i2c_enable.jpg

För att säkerställa att alla komponenter fungerar korrekt kan du starta ett kommandoradsgränssnitt genom att öppna ett terminalfönster och utföra följande kommando:

 sudo i2cdetect -y 1 

Den medföljande texten beskriver ett scenario där utförandet av ett visst kommando kommer att generera en utgång på ett rutnät, som innehåller information om adressen till en Analog-till-Digital-omvandlare (ADC). Författaren betonar att detta hexadecimala värde måste föregås av “0x” innan det används i den efterföljande koden. I detta fall representeras värdet som 0x48.

/sv/images/20231108_18h24m38s_grim.jpg

Med hjälp av den erhållna adressen kan man använda SMBus-biblioteket för att överföra I2C-kommandon genom att använda två olika procedurer. En av dessa metoder innebär användning av funktionen write\_word\_data(), som kräver tre ingångar, nämligen enhetsadressen, det specifika register som ska skrivas till och det önskade datavärde som ska skrivas in på nämnda plats.

Funktionen read_word_data() tar emot en enhetsadress och ett register som indata och får ADC (Analog-to-Digital Converter) att kontinuerligt sampla och lagra spänningsvärden i det angivna registret. Detta möjliggör efterföljande hämtning av lagrade data från registret.

Man kan välja att förbättra den visuella presentationen av utdata och därefter visa den. Innan man återgår till den iterativa cykeln kan man göra en kort paus eller fördröjning. Ett sådant tillvägagångssätt hjälper till att förhindra överbelastning av information.

 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, (0b100 << 8 | 0b10000010))

 # define the top of the range
TOP = 26300

while True:
    # 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)

När du har konverterat datatypen för din variabel till önskat format är det viktigt att mappa de resulterande värdena till deras motsvarande motsvarigheter i den ursprungliga skalan. Detta möjliggör meningsfulla jämförelser mellan de två uppsättningarna av värden. Efteråt kan du välja att ta bort eventuella överflödiga siffror genom att ange lämpligt antal decimaler. För att endast visa uppdaterade resultat, modifiera utskriftsfunktionen så att nya värden endast visas om de skiljer sig från de som tidigare visats. För ytterligare information om max, min och round, se vår sammanställning av de 20 viktigaste Python-funktionerna.

Hantera brus

I fall där ens omgivning saknar en hög grad av organisation och ordning kan det bli uppenbart att vissa oönskade element finns i de data som samlas in.Detta fenomen kan tillskrivas det faktum att ett mindre värdeområde, t.ex. 16-bitars upplösning istället för 10-bitars, leder till en ökad sannolikhet att dessa störningar eller “brus” uppstår.

Om ingång ett ansluts till jord och enheten ställs in på att jämföra ingångarna ett och två uppnås större stabilitet i avläsningarna. Dessutom kan kortare bygelkablar med kapacitansförbättringar användas istället för längre, brusiga versioner. Dessutom kan justeringar av potentiometerns resistansnivå också påverka prestandan.

Alternativt kan man använda programvarulösningar för att hantera datafluktuationer. En möjlig metod är att beräkna ett glidande medelvärde eller att helt bortse från mindre förändringar. Detta tillvägagångssätt medför dock en ökad beräkningsbörda. När man arbetar med programmeringsspråk på hög nivå som Python och bearbetar många prover per sekund kan dessa kostnader ackumuleras i en accelererande takt.

Gå vidare med många möjliga nästa steg

Att använda I2C för avläsning är en relativt enkel process, vilket också är fallet med alternativa metoder som SPI. Trots de uppenbara skillnaderna mellan de olika ADC-alternativen är verkligheten den att när man väl har lyckats implementera något av dessa alternativ kan den förvärvade expertisen lätt tillämpas på resten.

Varför inte tänja på gränserna för din nykonstruerade potentiometerregulator ännu mer? Genom att seriekoppla flera potentiometrar eller försöka mäta variabler som ljus, ljud eller temperatur kan man utforska nya möjligheter för interaktion med sitt Raspberry Pi-system. Ge dig ut på en spännande resa genom att utöka funktionerna i ditt nuvarande projekt och skapa en helt interaktiv upplevelse genom praktiska experiment.