Een ADC toevoegen aan je Raspberry Pi: Wat je moet weten
Belangrijkste opmerkingen
De Raspberry Pi kan analoge signalen niet rechtstreeks verwerken, maar kan worden uitgerust met externe analoog-digitaalomzetters (ADC’s) om fysieke spanningswaarden om te zetten in een digitaal formaat dat geschikt is voor gegevensopslag, -manipulatie en -beheer.
Populaire ADC’s zijn de MCP3004/MCP3008, die een balans bieden tussen snelheid en nauwkeurigheid, en de ADS111x, die een 16-bits resolutie biedt bij een lagere samplefrequentie.
De ADS1115, beschikbaar via Adafruit, is een elegante oplossing met een Programmeerbare Versterker (PGA), die detectie van minieme spanningsverschillen mogelijk maakt en dynamische aanpassing van de versterking tijdens gebruik vergemakkelijkt. Integratie met Raspberry Pi via I2C is geen enkel probleem.
Het feit dat de Raspberry Pi in eerste instantie geen analoge ingangen heeft, onderscheidt hem van microcontroller-georiënteerde platformen zoals de Arduino, waardoor zijn mogelijkheden beperkt zijn in vergelijking met die alternatieven.
Hoewel het ontmoedigend kan lijken, zijn er verschillende alternatieven om te onderzoeken. Je kunt beginnen met het gebruik van een Raspberry Pi samen met een externe analoog-digitaalomzetter (ADC) voor een naadloze werking.
Waarom ingangen toevoegen?
In de natuur zijn er talloze gebeurtenissen die gemakkelijk kunnen worden ingekapseld door gebruik te maken van elektrische potentialen. Door deze potentialen om te zetten in hun binaire equivalenten kunnen ze worden gearchiveerd, gemanipuleerd en gebruikt als middelen om aanvullende factoren te reguleren en andere mechanismen te activeren.
Iemand kan de vochtigheid van zijn aarde, de warmte van zijn broeikas of het gewicht van zijn knaagdier willen controleren. Je kunt een niveauregelaar in je Raspberry Pi willen inbouwen, een hele reeks schuifregelaars willen bouwen of een nieuwe joystick willen maken. De potentiële toepassingen zijn zeer uitgebreid en gevarieerd.
Opties voor ADC’s
Dus, welke ADC is het beste voor beginners?
Tot de populairste en eenvoudigste opties behoren de MCP3004 (en MCP3008 ) chips van Microchip. Je krijgt vier (of acht) kanalen van elk 10 bits, die tot 200 kSPS kunnen lezen. Aan de andere kant zijn er de ADS111x apparaten van Texas Instruments, die 16 bits lezen met 860 SPS. Er is dus een afweging tussen snelheid en precisie (en natuurlijk de prijs).
Verschillende microcontrollers zijn uitgerust met geïntegreerde analoog-digitaal-omzetters (ADC’s). De veelgebruikte ATMega in de meeste Arduino’s biedt bijvoorbeeld meerdere kanalen met 10-bits resolutie en andere functionaliteiten.Dankzij deze mogelijkheid kan het Arduino-platform analoge ingangssignalen ondersteunen die de beperkingen van de mogelijkheden van de Raspberry Pi te boven gaan. In gevallen waarin een bestaande Arduino in een project is opgenomen en 10-bits resolutie voldoende is voor de vereiste nauwkeurigheid, kan het gebruik van de direct beschikbare Arduino-oplossing de eenvoudigste oplossing blijken te zijn.
Inderdaad, omwille van de eenvoud zullen we in dit geval de ADS1115 van Adafruit gebruiken.
Wat is een programmeerbare versterker?
De geïntegreerde schakeling beschikt over verschillende intrigerende mogelijkheden, met name een ingebouwde programmeerbare versterker (PGA), die het mogelijk maakt om het gewenste amplitudespectrum digitaal in te stellen. De PGA maakt specificatie van het spanningsbereik tot op fracties van een volt mogelijk, waardoor minieme variaties van slechts enkele microvolt kunnen worden gedetecteerd dankzij de enorme reeks waarden die door de 16-bits resolutie worden vertegenwoordigd.
Een van de voordelen van deze specifieke chip is dat de versterking tijdens gebruik kan worden aangepast. Bepaalde andere apparaten, zoals de MCP3004, gebruiken daarentegen een alternatieve strategie door een extra pin op te nemen waarop een referentiespanning kan worden gezet.
Hoe zit het met multiplexing?
Een multiplexer, ook bekend als een mux, dient als een schakelapparaat dat het mogelijk maakt om een enkele analoog-digitaalomzetter (ADC) te gebruiken om gegevens van verschillende bronnen te bemonsteren. Als een geïntegreerde ADC een groot aantal ingangsklemmen heeft, is het duidelijk dat er intern een intrinsiek multiplexingproces plaatsvindt. De ADS1115 bevat bijvoorbeeld een mux-component met de capaciteit om maximaal vier verschillende ingangssignalen te verwerken, die selectief kunnen worden gekozen door manipulatie van de inherente registerconfiguratie.
Omgaan met registers
De ADS1115 biedt een scala aan functionaliteiten die eenvoudig toegankelijk zijn door manipulatie van diverse besturingsinstellingen. Deze omvatten de mogelijkheid om de meerdere
Het activeringsmechanisme voor elke individuele functie is verborgen binnen de grenzen van de verpakking van het product en manifesteert zich als minuscule opslagplaatsen van gegevens die bekend staan als “registers”. Om een specifieke functie in te schakelen, hoef je alleen maar het betreffende register te veranderen van de standaardtoestand van nul in een waarde van één.
Als je kijkt naar de ADS111x datasheet , dan zie je dat deze modellen geleverd worden met vier registers, inclusief de configuratieregisters die het gedrag van het apparaat bepalen.
In deze context worden bits 14 tot 12 gebruikt om de werking van een multiplexer te regelen. Door deze drie binaire cijfers te gebruiken, kan men kiezen uit acht verschillende configuraties. In het bijzonder is de gewenste configuratie in dit geval “100”, omdat deze het differentiële signaal tussen ingangskanaal 0 en massa bepaalt. Daarentegen zijn bits 7 tot 5 verantwoordelijk voor het regelen van de samplefrequentie. Om de hoogst mogelijke bemonsteringsfrequentie van 860 samples per seconde te bereiken, zou het ideaal zijn om deze bits op “111” in te stellen.
Als je eenmaal de juiste instellingen hebt geïdentificeerd, heb je toegang tot in totaal twee bits die kunnen worden doorgegeven aan de analoog-digitaalconverter. In het geval dat je later afzonderlijke bits wilt wijzigen, kun je dit doen door gebruik te maken van bitwise operaties in isolatie.
De weergave van individuele schakeltoestanden binnen een binair systeem kan tot enige verwarring leiden. Hoewel de binaire code zelf niet direct een specifieke numerieke waarde vertegenwoordigt, kan het gebruikt worden om de toestand van elke individuele schakelaar aan te geven. Deze informatie kan in verschillende formaten worden uitgedrukt, zoals decimale of hexadecimale notatie. Voor een goed begrip en om mogelijke complicaties te voorkomen, verdient het echter vaak de voorkeur om het binaire formaat te blijven gebruiken.
Bedrading
Dit apparaat kan gemakkelijk worden aangesloten op een breadboard. Het positieve spanningsingangsbereik loopt van 2 tot 5,5 volt, zodat het compatibel is met de 3,3 volt voeding van een Raspberry Pi.
Om met de werking te beginnen, sluit je de SDA- en SCL-pinnen van de MCP3008 aan op overeenkomstige poorten op de Raspberry Pi en verbind je tegelijkertijd de massa en 3,3V-aansluitingen. Plaats bovendien een potentiometer in serie tussen de massa en de spanningslijnen, waarna je een uiteinde van de middelste geleider van de potentiometer aan de eerste ingang van de analoog-digitaalconverter (ADC) bevestigt. Als deze stappen zijn voltooid, is je opstelling klaar voor gebruik.
Omgaan met I2C
Diverse analoog-digitaalomzetters (ADC’s) gebruiken verschillende communicatieprotocollen voor hun werking. In de context van onze ADS1115 gebruiken we bijvoorbeeld een specifieke interface die bekend staat als Inter-Integrated Circuit (I2C) voor communicatie en gegevensoverdracht.
Om Python te gebruiken voor de interface met een analoog-digitaalomzetter (ADC) op een Raspberry Pi, moet aan bepaalde voorwaarden worden voldaan. Gelukkig hebben recente versies van het besturingssysteem (OS) van de Raspberry Pi dit proces aanzienlijk gestroomlijnd.Om de installatieprocedure te starten, navigeer je naar “Voorkeuren” in het systeemmenu en selecteer je “Raspberry Pi Configuratie”. Van daaruit ga je naar het tabblad “Interfaces” en activeer je de optie “I2C”.
Om er zeker van te zijn dat alle componenten correct functioneren, kunt u een opdrachtregelinterface starten door een terminalvenster te openen en het volgende commando uit te voeren:
sudo i2cdetect -y 1
De gegeven tekst beschrijft een scenario waarin het uitvoeren van een bepaald commando een uitvoer op een rooster genereert, die informatie bevat over het adres van een analoog-digitaalomzetter (ADC). De auteur benadrukt dat deze hexadecimale waarde moet worden voorafgegaan door “0x” voordat deze wordt gebruikt in de daaropvolgende code. In dit geval wordt de waarde weergegeven als 0x48.
Met het verkregen adres kan de SMBus-bibliotheek worden gebruikt om I2C-commando’s te verzenden via twee verschillende procedures. Een van deze methoden is het gebruik van de functie write\_word_data(), die drie ingangen nodig heeft, namelijk het apparaatadres, het specifieke register waarnaar geschreven wordt en de gewenste gegevenswaarde die op de betreffende locatie wordt geschreven.
De functie read_word_data()
neemt als invoer een apparaatadres en een register en zorgt ervoor dat de analoog-digitaalomzetter (ADC) continu spanningswaarden bemonstert en opslaat in het opgegeven register. Hierdoor kunnen de opgeslagen gegevens later uit het register worden gehaald.
Men kan ervoor kiezen om de visuele presentatie van de uitvoer te verbeteren en deze vervolgens weer te geven. Voordat de iteratieve cyclus opnieuw wordt gestart, kan een korte pauze of vertraging worden geïmplementeerd. Een dergelijke aanpak helpt informatieoverbelasting te voorkomen.
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)
Nadat je het gegevenstype van je variabele hebt geconverteerd naar de voorkeursindeling, is het essentieel om de resulterende waarden in kaart te brengen met hun overeenkomstige tegenhangers in de oorspronkelijke schaal. Dit maakt zinvolle vergelijkingen tussen de twee reeksen waarden mogelijk. Daarna kun je ervoor kiezen om overtollige cijfers weg te laten door het juiste aantal decimalen in te stellen. Als u alleen bijgewerkte resultaten wilt weergeven, wijzigt u de afdrukfunctie zodanig dat nieuwe waarden alleen worden weergegeven als ze verschillen van de eerder weergegeven waarden. Voor meer informatie over max, min, en afronden, zie onze compilatie van de top 20 cruciale Python functies.
Omgaan met ruis
In gevallen waarin iemands omgeving een hoge mate van organisatie en ordelijkheid ontbeert, kan het duidelijk worden dat bepaalde ongewenste elementen aanwezig zijn in de verzamelde gegevens.Dit fenomeen kan worden toegeschreven aan het feit dat het gebruik van een kleiner waardenbereik, zoals 16-bits resolutie in plaats van 10-bits, leidt tot een grotere kans op het tegenkomen van deze storingen of “ruis”.
Door ingang één met massa te verbinden en het apparaat zo in te stellen dat ingangen één en twee worden vergeleken, wordt een grotere stabiliteit in de meetwaarden bereikt. Bovendien kunnen kortere startkabels met capaciteitsverbeteringen worden gebruikt in plaats van langere, lawaaiige versies. Verder kunnen aanpassingen aan het weerstandsniveau van de potentiometer ook de prestaties beïnvloeden.
Als alternatief kunnen softwareoplossingen gebruikt worden om gegevensfluctuaties te beheren. Een mogelijke aanpak is het berekenen van een voortschrijdend gemiddelde of het helemaal negeren van kleine veranderingen. Deze aanpak brengt echter een extra rekenlast met zich mee. Bij het werken met programmeertalen op hoog niveau zoals Python en het verwerken van talloze samples per seconde, kunnen deze kosten zich versneld opstapelen.
Verder gaan met vele mogelijke volgende stappen
I2C gebruiken voor leesdoeleinden is een relatief eenvoudig proces, zoals ook het geval is met alternatieve benaderingen zoals SPI. Ondanks de ogenschijnlijke verschillen tussen de diverse ADC-alternatieven, is de realiteit dat als men eenmaal een van deze opties met succes heeft geïmplementeerd, de opgedane expertise gemakkelijk kan worden toegepast op de rest.
Waarom zou je de grenzen van je nieuwe potentiometercontroller niet nog verder verleggen? Door meerdere potentiometers in serie te schakelen of te proberen variabelen zoals licht, geluid of temperatuur te meten, kun je nieuwe mogelijkheden voor interactie met je Raspberry Pi-systeem verkennen. Ga op een spannende reis door de mogelijkheden van je huidige project uit te breiden en een volledig interactieve ervaring te creëren door middel van praktische experimenten.