Begin met het meten van de wereld om je heen met dit praktische en uitgebreide project.

Belangrijkste leerpunten

  • Raspberry Pi heeft geen analoge ingang, maar je kunt externe ADC's toevoegen om spanningen uit de echte wereld om te zetten in digitale vorm voor opname, manipulatie en controle.
  • Populaire ADC-opties zijn onder meer MCP3004/MCP3008 voor een compromis tussen snelheid en precisie, of ADS111x voor 16-bits metingen met een lagere bemonsteringssnelheid.
  • De ADS1115 van Adafruit is een eenvoudige optie met een Programmable Gain Amplifier (PGA) waarmee je tijdens het programma kleine spanningsverschillen kunt detecteren en de versterking kunt aanpassen. Het aansluiten op Raspberry Pi met behulp van I2C is eenvoudig.

Out of the box mist de Raspberry Pi een analoge ingang. Dit brengt het in het nadeel ten opzichte van op microcontrollers gebaseerde borden zoals de Arduino.

Maar wanhoop niet: er zijn genoeg opties om te overwegen. Ga aan de slag met Raspberry Pi en een externe ADC.

Waarom invoer toevoegen?

De echte wereld zit vol met verschijnselen die, als je over de juiste circuits beschikt, gemakkelijk kunnen worden beschreven met behulp van een spanning. Breng die spanningen in digitale vorm, en je kunt ze opnemen, manipuleren en gebruiken om andere parameters en apparaten te besturen.

Mogelijk wilt u de vochtigheid van uw grond, de temperatuur van uw kas of het gewicht van uw hamster in de gaten houden. Misschien wil je een volumeregelaar aan je Pi toevoegen, een hele reeks faders bouwen of een geheel nieuwe joystick ontwerpen. De mogelijkheden zijn min of meer onbeperkt.

Opties voor ADC's

Dus welke ADC is het beste voor beginners?

Een van de meest populaire en eenvoudige opties zijn 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 bij 860 SPS. Er is dus een afweging tussen snelheid en precisie (en natuurlijk prijs).

Veel microcontrollers worden geleverd met ingebouwde ADC's. De ATMega die je op de gemiddelde Arduino aantreft zal naast al het andere verschillende 10-bits kanalen aanbieden. Hierdoor kan de Arduino analoge ingangen leveren waar de Raspberry Pi dat niet kan. Als je al een Arduino bij je installatie hebt betrokken en 10 bits voldoende betrouwbaarheid is, dan is dit misschien wel de gemakkelijkste manier om te gaan.

Hier houden we het simpel, met een ADS1115 van Adafruit.

Wat is een programmeerbare versterkingsversterker?

Deze chip wordt geleverd met een paar interessante functies, waaronder een Programmable Gain Amplifier (PGA). Hiermee kunt u het gewenste waardenbereik digitaal instellen, tot op een fractie van een volt. Met het aantal waarden dat 16 bits kan vertegenwoordigen, kun je hiermee verschillen van slechts enkele microvolts detecteren.

Het voordeel hiervan is dat u de versterking halverwege het programma kunt wijzigen. Andere chips, zoals de MCP3004, hanteren een andere aanpak; ze worden geleverd met een extra pin, waaraan je een referentiespanning kunt leveren.

Hoe zit het met multiplexen?

Een multiplexer (of mux) is een schakelaar waarmee u met één enkele ADC veel ingangen kunt lezen. Als uw ADC-chip wordt geleverd met veel invoerpinnen, is er sprake van interne multiplexing. De mux van de ADS1115 biedt vier ingangen, die u via de interne registers kunt selecteren.

Omgaan met registers

De ADS1115 biedt deze opties, en nog een paar meer. Je kunt omgaan met de multiplexer, de versterking aanpassen, de ingebouwde comparator activeren, de bemonsteringssnelheid wijzigen en het apparaat in de energiezuinige slaapmodus zetten, allemaal door een paar schakelaars om te zetten.

Maar waar zijn die schakelaars? Ze zitten in de verpakking, in de vorm van hele kleine stukjes geheugen genoemd registreert. Om een ​​bepaalde functie te activeren, hoeft u alleen maar de relevante bit op een 1 in te stellen in plaats van op een 0.

Kijken naar het ADS111x-gegevensblad, zult u merken dat deze modellen worden geleverd met vier registers, inclusief de configuratieregisters die het gedrag van het apparaat bepalen.

De bits 14 tot en met 12 besturen bijvoorbeeld de multiplexer. Met deze drie bits kunt u kiezen uit acht configuraties. Degene die je hier nodig hebt is "100", wat het verschil geeft tussen ingang nul en aarde. Bits 7 tot en met 5 regelen daarentegen de bemonsteringssnelheid. Als u het maximum van 860 samples per seconde wilt, kunt u deze op “111” zetten.

Zodra je weet welke opties je moet instellen, heb je twee bytes om naar de ADC te sturen. Als u later hier of daar een enkele bit wilt instellen, kunt u deze afzonderlijk afhandelen met behulp van bitwise-operatoren.

Hier kan het verwarrend worden. In dit geval vertegenwoordigt het binaire bestand geen waarde, maar de waarden van individuele schakelaars. Je zou deze variabelen kunnen uitdrukken als één groot getal, in decimaal of in hexadecimaal. Maar als u hoofdpijn wilt voorkomen, moet u zich aan de binaire versie houden, die gemakkelijker te lezen is.

Bedrading

U kunt dit apparaat rechtstreeks op het breadboard aansluiten. De positieve spanningsingang accepteert ergens tussen de 2 en 5,5 V, wat betekent dat de 3,3 V-rail op de Raspberry Pi goed zal werken.

Verbind de SDA- en SCL-ingangen met tegenhangers op de RPi en doe dezelfde dingen met de aarde en 3,3 V. Plaats een potentiometer tussen de aarde- en spanningslijnen en steek de middelste draad in de eerste ingang van de ADC. Dat is alles wat je nodig hebt om aan de slag te gaan!

Omgaan met I2C

Verschillende ADC's werken via verschillende protocollen. In het geval van onze ADS1115, we gaan I2C gebruiken.

In het volgende voorbeeld wordt interactie met de ADC uitgevoerd met behulp van Python. Maar voordat u dat doet, moet u het instellen. Recente versies van Raspberry Pi OS hebben dit heel eenvoudig gemaakt. Ga naar Voorkeuren > Raspberry Pi-configuratie. Vervolgens vanaf de Interfaces tabblad, schakelaar I2C op.

Om te controleren of alles werkt, opent u een terminal en voert u het volgende uit:

sudo i2cdetect -y 1

Met deze opdracht wordt een raster uitgevoerd. Ervan uitgaande dat alles werkt en u de bedrading correct hebt aangesloten, ziet u een nieuwe waarde in het raster verschijnen. Dit is het adres van uw ADC. Houd er rekening mee dat het een hexadecimale waarde is, dus u moet er een voorvoegsel aan toevoegen “0x” wanneer u het in de onderstaande code gebruikt. Hier is het 0x48:

Zodra u het adres heeft, kunt u de SMBus-bibliotheek gebruiken om I2C-opdrachten te verzenden. Je hebt hier te maken met twee methoden. De eerste is schrijf_woord_data(), dat drie argumenten accepteert: het apparaatadres, het register waarnaar u schrijft en de waarde die u wilt schrijven.

De tweede is lees_woord_data(), dat alleen het apparaatadres en het register accepteert. De ADC leest voortdurend spanningen en slaat het resultaat op in het conversieregister. Met deze methode kunt u de inhoud van dat register ophalen.

U kunt het resultaat een beetje verfraaien en vervolgens afdrukken. Voordat u teruggaat naar het begin van de lus, introduceert u een korte vertraging. Zo zorg je ervoor dat je niet overspoeld wordt met 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)

Je bent bijna klaar. Breng het bereik van de waarden die u krijgt in kaart met het bereik van uw voorkeur, en kap vervolgens af tot het gewenste aantal decimalen. U kunt de afdrukfunctie zo aanpassen dat u alleen een nieuwe waarde afdrukt als deze afwijkt van de vorige waarde. Als u er niet zeker van bent maximaal, min, En ronde, jij kan bekijk onze lijst met de 20 belangrijkste Python-functies!

Omgaan met lawaai

Tenzij je opstelling super, super netjes en opgeruimd is, zul je wat ruis opmerken. Dit is het inherente nadeel van het gebruik van 16 bits in plaats van slechts tien: dat kleine beetje ruis zal beter waarneembaar zijn.

Door de aangrenzende ingang (ingang 1) met aarde te verbinden en de modus zo te schakelen dat je ingangen één en twee vergelijkt, kun je veel stabielere resultaten krijgen. Je kunt ook die lange, geluidverzamelende startkabels vervangen door kleine, en een paar condensatoren toevoegen terwijl je toch bezig bent. De waarde van uw potentiometer kan ook een verschil maken.

Er zijn ook software-opties. U kunt een voortschrijdend gemiddelde maken of kleine wijzigingen eenvoudigweg negeren. Het nadeel is dat extra code rekenkosten met zich meebrengt. Als je voorwaardelijke instructies schrijft in een taal op hoog niveau, zoals Python, en elke seconde duizenden voorbeelden neemt, zullen deze kosten snel oplopen.

Ga verder met veel mogelijke volgende stappen

Metingen uitvoeren via I2C is vrij eenvoudig en hetzelfde geldt grotendeels voor andere methoden, zoals SPI. Hoewel het lijkt alsof er grote verschillen zijn tussen de beschikbare ADC-opties, is de waarheid dat als je eenmaal een van de opties hebt werkend, het gemakkelijk is om de kennis op de andere toe te passen.

Dus waarom zouden we niet verder gaan? Bind meerdere potentiometers aan elkaar, of probeer licht, geluid of temperatuur af te lezen. Breid de controller uit die je zojuist hebt gemaakt en creëer een Raspberry Pi-opstelling die echt praktisch is!