Inhoudsopgave:
- Stap 1: Gebruik van de DAC (digitaal-naar-analoog converter)
- Stap 2:
- Stap 3:
- Stap 4:
- Stap 5: Gebruik van de ADC's (analoog-naar-digitaal converters)
- Stap 6:
- Stap 7:
Video: Arduino en PCF8591 ADC DAC IC - Ajarnpa
2024 Auteur: John Day | [email protected]. Laatst gewijzigd: 2024-01-30 11:17
Heb je ooit meer analoge ingangspinnen op je Arduino-project willen hebben, maar niet op zoek naar een Mega? Of wilt u analoge signalen genereren? Bekijk dan het onderwerp van onze tutorial – de NXP PCF8591 IC.
Het lost beide problemen op, aangezien het een enkele DAC (digitaal naar analoog) converter heeft en vier ADC's (analoog naar digitaal converters) - allemaal toegankelijk via de I2C-bus. De PCF8591 is verkrijgbaar in DIP-, opbouw- en modulevorm, waardoor het gemakkelijk is om mee te experimenteren.
Download het gegevensblad voordat u verder gaat. De PCF8591 kan zowel op 5V als op 3,3V werken, dus als je een Arduino Due, Raspberry Pi of een ander 3,3 V-ontwikkelbord gebruikt, zit je goed. Nu zullen we eerst de DAC uitleggen, daarna de ADC's.
Stap 1: Gebruik van de DAC (digitaal-naar-analoog converter)
De DAC op de PCF8591 heeft een resolutie van 8 bits, zodat hij in 255 stappen een theoretisch signaal tussen nul volt en de referentiespanning (Vref) kan genereren. Voor demonstratiedoeleinden gebruiken we een Vref van 5V, en u kunt een lagere Vref gebruiken, zoals 3,3V of wat u maar wilt, de maximale waarde is … deze moet echter lager zijn dan de voedingsspanning.
Merk op dat wanneer er een belasting is op de analoge uitgang (een praktijksituatie), de maximale uitgangsspanning zal dalen - het gegevensblad (dat u hebt gedownload) toont een daling van 10% voor een belasting van 10 kΩ. Nu voor ons demonstratiecircuit.
Let op het gebruik van 10kΩ pull-up weerstanden op de I2C-bus, en de 10μF condensator tussen 5V en GND. Het I2C-busadres wordt ingesteld door een combinatie van pinnen A0 ~ A2 en met allemaal naar GND is het adres 0x90. De analoge uitgang kan worden genomen van pin 15 (en er is een aparte analoge GND op pin 13. Sluit ook pin 13 aan op GND en schakel GND in op Arduino GND.
Om de DAC te besturen, moeten we twee bytes aan gegevens verzenden. De eerste is de besturingsbyte, die eenvoudig de DAC activeert en is 1000000 (of 0x40) en de volgende byte is de waarde tussen 0 en 255 (het uitgangsniveau). Dit wordt gedemonstreerd in de volgende schets:
// Voorbeeld 52.1 PCF8591 DAC-demo
#include "Wire.h" #define PCF8591 (0x90 >> 1) // I2C busadres void setup() { Wire.begin(); } void loop() { for (int i=0; i<256; i++) { Wire.beginTransmission (PCF8591); // wakker worden PCF8591 Wire.write (0x40); // control byte - schakel DAC in (binair 1000000) Wire.write (i); // waarde om te verzenden naar DAC Wire.endTransmission (); // eind transmissie }
voor (int i=255; i>=0; --i)
{ Wire.beginTransmission (PCF8591); // wakker worden PCF8591 Wire.write (0x40); // control byte - schakel DAC in (binair 1000000) Wire.write (i); // waarde om te verzenden naar DAC Wire.endTransmission (); // eindtransmissie } }
Heb je de bitverschuiving van het busadres opgemerkt in het #define-statement? Arduino verzendt 7-bits adressen, maar de PCF8591 wil een 8-bit, dus we verschuiven de byte met één bit.
Stap 2:
De resultaten van de schets worden getoond in de afbeelding, we hebben de Vref aangesloten op 5V en de oscilloscoop-sonde en GND op respectievelijk de analoge uitgang en GND.
Stap 3:
Als je van bochten houdt, kun je sinusgolven genereren met de onderstaande schets. Het gebruikt een opzoektabel in een array die de benodigde vooraf berekende gegevenspunten bevat:
// Voorbeeld 52.2 PCF8591 DAC-demo - sinusgolf
#include "Wire.h" #define PCF8591 (0x90 >> 1) // I2C-busadres uint8_t sine_wave[256] = { 0x80, 0x83, 0x86, 0x89, 0x8C, 0x90, 0x93, 0x96, 0x99, 0x9C, 0x9F, 0xA2, 0xA5, 0xA8, 0xAB, 0xAE, 0xB1, 0xB3, 0xB6, 0xB9, 0xBC, 0xBF, 0xC1, 0xC4, 0xC7, 0xC9, 0xCC, 0xCE, 0xD1, 0xD3, 0xD5, 0xD8, 0x 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC, 0xFE, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6, 0xF5, 0xF4, 0xF3, 0xF, 0xED, 0xEB, 0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC, 0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9, 0xC7, 0xC4, 0xC1, 0xB 0xB3, 0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C, 0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83, 0x80, 0x7D, 0x7A, 0x77, 0x74, 0x77, 0x74, 0x67, 0x64, 0x61, 0x5E, 0x5B, 0x58, 0x55, 0x52, 0x4F, 0x4D, 0x4A, 0x47, 0x44, 0x41, 0x3F, 0x 3C, 0x39, 0x37, 0x34, 0x32, 0x2F, 0x2D, 0x2B, 0x28, 0x26, 0x24, 0x22, 0x20, 0x1E, 0x1C, 0x1A, 0x18, 0x16, 0x15, 0x13, 0x11, 0,0, 0x0F, 0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0,x 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15, 0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x20, 0x22, 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37, 0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D, 0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E,x 0x67, 0x64 0x70, 0x74, 0x77, 0x7A, 0x7D }; void setup() { Wire.begin(); } void loop() { for (int i=0; i<256; i++) { Wire.beginTransmission (PCF8591); // wakker worden PCF8591 Wire.write (0x40); // control byte - schakel DAC in (binair 1000000) Wire.write (sine_wave ); // waarde om te verzenden naar DAC Wire.endTransmission (); // eindtransmissie } }
Stap 4:
Voor de volgende DSO-afbeeldingsdump hebben we de Vref gewijzigd in 3,3V - let op de verandering in de maxima op de sinusgolf.
Nu kun je experimenteren met de DAC om geluidseffecten, signalen te maken of andere analoge circuits aan te sturen.
Stap 5: Gebruik van de ADC's (analoog-naar-digitaal converters)
Als je de functie analogRead() op je Arduino hebt gebruikt (ver terug in hoofdstuk één), dan ben je al bekend met een ADC. Zonder PCF8591 kunnen we een spanning lezen tussen nul en de Vref en het zal een waarde tussen nul en 255 retourneren die recht evenredig is met nul en de Vref.
Het meten van 3,3 V zou bijvoorbeeld 168 moeten opleveren. De resolutie (8-bit) van de ADC is lager dan de Arduino aan boord (10-bit), maar de PCF8591 kan iets doen wat de ADC van de Arduino niet kan. Maar daar komen we zo op terug. Ten eerste, om eenvoudig de waarden van elke ADC-pin te lezen, sturen we een controlebyte om de PCF8591 te vertellen welke ADC we willen lezen. Voor ADC's nul tot drie is de controlebyte respectievelijk 0x00, 0x01, ox02 en 0x03.
Vervolgens vragen we twee bytes aan gegevens terug van de ADC en slaan de tweede byte op voor gebruik. Waarom twee bytes? De PCF8591 retourneert eerst de eerder gemeten waarde – daarna de huidige byte. (Zie afbeelding 8 in het gegevensblad). Als u ten slotte niet alle ADC-pinnen gebruikt, sluit u de ongebruikte pinnen aan op GND. De volgende voorbeeldschets haalt eenvoudig de waarden één voor één op van elke ADC-pin en geeft ze vervolgens weer op de seriële monitor:
#include "Wire.h"
#define PCF8591 (0x90 >> 1) // I2C-busadres #define ADC0 0x00 // control bytes voor het lezen van individuele ADC's #define ADC1 0x01 #define ADC2 0x02 #define ADC3 0x03 byte value0, value1, value2, value3; void setup() { Wire.begin(); Serieel.begin(9600); } void loop() { Wire.beginTransmission (PCF8591); // wakker worden PCF8591 Wire.write (ADC0); // controlebyte - lees ADC0 Wire.endTransmission (); // eindtransmissie Wire.requestFrom (PCF8591, 2); waarde0=Draad.lezen(); waarde0=Draad.lezen(); Wire.beginTransmission (PCF8591); // wakker worden PCF8591 Wire.write (ADC1); // controlebyte - lees ADC1 Wire.endTransmission (); // eindtransmissie Wire.requestFrom (PCF8591, 2); waarde1=Draad.lezen(); waarde1=Draad.lezen(); Wire.beginTransmission (PCF8591); // wakker worden PCF8591 Wire.write (ADC2); // controlebyte - lees ADC2 Wire.endTransmission (); // eindtransmissie Wire.requestFrom (PCF8591, 2); value2=Draad.lezen(); value2=Draad.lezen(); Wire.beginTransmission (PCF8591); // wakker worden PCF8591 Wire.write (ADC3); // controlebyte - lees ADC3 Wire.endTransmission (); // eindtransmissie Wire.requestFrom (PCF8591, 2); value3=Draad.lezen(); value3=Draad.lezen(); Serial.print(waarde0); Serieel.print(" "); Serial.print(waarde1); Serieel.print(" "); Serial.print(waarde2); Serieel.print(" "); Serial.print(waarde3); Serieel.print(" "); Serieel.println(); }
Bij het uitvoeren van de schets krijgt u de waarden van elke ADC in de seriële monitor te zien. Hoewel het een eenvoudige demonstratie was om u te laten zien hoe u elke ADC afzonderlijk kunt lezen, is het een omslachtige methode om meer dan één byte tegelijk van een bepaalde ADC te krijgen.
Stap 6:
Om dit te doen, wijzigt u de besturingsbyte om auto-increment aan te vragen, wat wordt gedaan door bit 2 van de besturingsbyte in te stellen op 1. Dus om vanaf ADC0 te beginnen, gebruiken we een nieuwe besturingsbyte van binair 00000100 of hexadecimaal 0x04. Vraag dan vijf bytes aan data aan (we negeren wederom de eerste byte), waardoor de PCF8591 alle waarden in één keten van bytes retourneert. Dit proces wordt gedemonstreerd in de volgende schets:
#include "Wire.h"
#define PCF8591 (0x90 >> 1) // I2C-busadres byte waarde0, waarde1, waarde2, waarde3; void setup() { Wire.begin(); Serieel.begin(9600); } void loop() { Wire.beginTransmission (PCF8591); // wakker worden PCF8591 Wire.write (0x04); // controlebyte - lees ADC0 en verhoog vervolgens automatisch Wire.endTransmission (); // eindtransmissie Wire.requestFrom (PCF8591, 5); waarde0=Draad.lezen(); waarde0=Draad.lezen(); waarde1=Draad.lezen(); value2=Draad.lezen(); value3=Draad.lezen(); Serial.print(waarde0); Serieel.print(" "); Serial.print(waarde1); Serieel.print(" "); Serial.print(waarde2); Serieel.print(" "); Serial.print(waarde3); Serieel.print(" "); Serieel.println(); }
Eerder vermeldden we dat de PCF8591 iets kan doen wat de ADC van de Arduino niet kan, en dit is een differentiële ADC. In tegenstelling tot de Arduino's single-ended (dwz het retourneert het verschil tussen de positieve signaalspanning en GND, accepteert de differentiële ADC twee signalen (die niet noodzakelijkerwijs naar aarde hoeven te worden verwezen) en retourneert het verschil tussen de twee signalen Dit kan handig zijn voor het meten van kleine veranderingen in spanningen voor loadcellen, enzovoort.
Stap 7:
Het instellen van de PCF8591 voor differentiële ADC is een kwestie van eenvoudig de besturingsbyte wijzigen. Als u naar pagina zeven van het gegevensblad gaat, overweeg dan de verschillende soorten analoge ingangsprogrammering. Voorheen gebruikten we modus '00' voor vier ingangen, maar u kunt de andere selecteren die duidelijk worden geïllustreerd, bijvoorbeeld de afbeelding.
Dus om de stuurbyte voor twee differentiële ingangen in te stellen, gebruikt u binair 00110000 of 0x30. Dan is het een kwestie van de bytes aan data opvragen en ermee werken. Zoals je kunt zien, is er ook een combinatie van enkelvoudig / differentieel en een complexe invoer met drie differentiëlen. We laten ze echter voorlopig staan.
Hopelijk vond je dit interessant, of je nu een DAC aan je experimenten toevoegt of iets meer leert over ADC's. Overweeg om uw PCF8591 bij PMD Way te bestellen.
Dit bericht aangeboden door pmdway.com - alles voor makers en elektronica-enthousiastelingen, met gratis levering wereldwijd.
Aanbevolen:
Hoe ADC Current Sense te maken: 5 stappen
Hoe ADC Current Sense te maken: In deze Instructable zullen we beschrijven hoe een 8-bit analoog-naar-digitaal-omzetter (ADC) in de SLG46855V kan worden geïmplementeerd die laadstroom en interface met een MCU via I2C kan detecteren. Dit ontwerp kan worden gebruikt voor verschillende stroomdetectietoepassingen zoals
7-segment om ADC #Arduino-waarden, #Arduino weer te geven: 4 stappen
7-segment om ADC weer te geven #Arduino Values, #Arduino: In dit artikel zal ik een project maken dat nog steeds gerelateerd is aan het vorige artikel. Namelijk het verwerken van ADC-gegevens. U heeft dus geen seriële monitor nodig om de waarde van de adc-gegevens te zien. in dit artikel zal ik een ADC Value viewer-weergave maken. dus jij niet
Huidige bron DAC AD5420 en Arduino: 4 stappen (met afbeeldingen)
Huidige bron DAC AD5420 en Arduino: Hallo. In dit artikel wil ik mijn ervaring delen met de AD5420 huidige digitaal-naar-analoogomzetter, die de volgende kenmerken heeft: 16-bits resolutie en monotonie Huidig uitgangsbereik: 4 mA tot 20 mA, 0 mA tot 20 mA, of 0 mA t
Arduino en de TI ADS1110 16-bit ADC: 6 stappen
Arduino en de TI ADS1110 16-bit ADC: In deze tutorial onderzoeken we hoe Arduino te gebruiken om te werken met de Texas Instruments ADS1110 - een ongelooflijk klein maar handig 16-bit analoog-naar-digitaal converter-IC. Het kan werken tussen 2,7 en 5,5 V, dus het is ook prima voor Arduino Due en andere lagere vol
Audio geluidsbestanden (Wav) afspelen met een Arduino en een DAC: 9 stappen
Audio-geluidsbestanden afspelen (Wav) Met een Arduino en een DAC: Speel wav-bestandsaudio af vanaf uw Audino SD-kaart. Deze Instructable laat je zien hoe een wav-bestand op je SD-kaart kan worden afgespeeld via een eenvoudig circuit naar een luidspreker. Het wav-bestand moet 8 bit mono zijn. Ik heb geen probleem gehad met het afspelen van 44 KHz-bestanden