Spisu treści:

Arduino i PCF8591 ADC DAC IC: 7 kroków
Arduino i PCF8591 ADC DAC IC: 7 kroków

Wideo: Arduino i PCF8591 ADC DAC IC: 7 kroków

Wideo: Arduino i PCF8591 ADC DAC IC: 7 kroków
Wideo: Модуль ADS1115, 16-Bit АЦП, Обзор 2024, Lipiec
Anonim
Arduino i układ scalony przetwornika cyfrowo-analogowego PCF8591 ADC
Arduino i układ scalony przetwornika cyfrowo-analogowego PCF8591 ADC

Czy kiedykolwiek chciałeś mieć więcej analogowych pinów wejściowych w swoim projekcie Arduino, ale nie chciałeś rozwidlać się na Mega? A może chcesz generować sygnały analogowe? Następnie zapoznaj się z tematem naszego samouczka – układem scalonym NXP PCF8591.

Rozwiązuje oba te problemy, ponieważ posiada pojedynczy przetwornik DAC (cyfrowo-analogowy) oraz cztery ADC (przetworniki analogowo-cyfrowe) – wszystkie dostępne przez magistralę I2C. PCF8591 jest dostępny w wersji DIP, montażu powierzchniowego i modułowej, co ułatwia eksperymentowanie.

Zanim przejdziesz dalej, pobierz kartę katalogową. PCF8591 może działać zarówno przy napięciu 5 V, jak i 3,3 V, więc jeśli używasz Arduino Due, Raspberry Pi lub innej płytki rozwojowej 3,3 V, wszystko jest w porządku. Teraz najpierw wyjaśnimy DAC, a następnie ADC.

Krok 1: Korzystanie z DAC (przetwornika cyfrowo-analogowego)

Korzystanie z DAC (przetwornika cyfrowo-analogowego)
Korzystanie z DAC (przetwornika cyfrowo-analogowego)

DAC w PCF8591 ma rozdzielczość 8 bitów – dzięki czemu może generować teoretyczny sygnał od zera woltów do napięcia odniesienia (Vref) w 255 krokach. Do celów demonstracyjnych użyjemy Vref 5 V i możesz użyć niższego Vref, takiego jak 3,3 V lub jakakolwiek chcesz, aby maksymalna wartość była… jednak musi być mniejsza niż napięcie zasilania.

Zwróć uwagę, że w przypadku obciążenia wyjścia analogowego (w rzeczywistości), maksymalne napięcie wyjściowe spadnie – karta danych (którą pobrałeś) pokazuje spadek o 10% dla obciążenia 10 kΩ. Teraz czas na nasz obwód demonstracyjny.

Zwróć uwagę na użycie rezystorów podciągających 10kΩ na magistrali I2C i kondensatora 10μF między 5V a GND. Adres magistrali I2C jest ustawiany przez kombinację pinów A0~A2, a przy ich wszystkich do GND adres to 0x90. Wyjście analogowe można pobrać z pinu 15 (a na pinie 13 jest osobne analogowe GND). Podłącz również pin 13 do GND, a obwód GND do Arduino GND.

Aby sterować DAC, musimy wysłać dwa bajty danych. Pierwszy to bajt kontrolny, który po prostu aktywuje przetwornik cyfrowo-analogowy i wynosi 1000000 (lub 0x40), a następny bajt to wartość z zakresu od 0 do 255 (poziom wyjściowy). Widać to na poniższym szkicu:

// Przykład 52.1 PCF8591 demo DAC

#include "Wire.h" #define PCF8591 (0x90 >> 1) // adres magistrali I2C void setup() { Wire.begin(); } void loop() { for (int i=0; i<256; i++) { Wire.beginTransmission(PCF8591); // obudź PCF8591 Wire.write(0x40); // bajt kontrolny - włącz DAC (binarny 1000000) Wire.write(i); // wartość do wysłania do DAC Wire.endTransmission(); // zakończ transmisję }

for (int i=255; i>=0; --i)

{ Wire.beginTransmission(PCF8591); // obudź PCF8591 Wire.write(0x40); // bajt kontrolny - włącz DAC (binarny 1000000) Wire.write(i); // wartość do wysłania do DAC Wire.endTransmission(); // zakończ transmisję } }

Czy zauważyłeś przesunięcie bitowe adresu magistrali w instrukcji #define? Arduino wysyła adresy 7-bitowe, ale PCF8591 chce 8-bitowe, więc przesuwamy bajt o jeden bit.

Krok 2:

Obraz
Obraz

Wyniki szkicu są pokazane na obrazku, podłączyliśmy Vref do 5V, a sondę oscyloskopową i GND odpowiednio do wyjścia analogowego i GND.

Krok 3:

Obraz
Obraz

Jeśli lubisz krzywe, możesz wygenerować fale sinusoidalne za pomocą poniższego szkicu. Wykorzystuje tabelę przeglądową w tablicy, która zawiera niezbędne, wstępnie obliczone punkty danych:

// Przykład 52.2 PCF8591 DAC demo - sinusoida

#include "Wire.h" #define PCF8591 (0x90 >> 1) // adres magistrali I2C uint8_t sinus_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, 0xFD, 0xFEFD, 0x 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6, 0xF5, 0xF4, 0xF3, 0x 0xED, 0xEB, 0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC, 0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9, 0xC7, 0xC4, 0xC9, 0xB6, 0xBF 0xB3, 0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C, 0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83, 0x80, 0x7D, 0x7A, 0x77, 0x6D 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, 0x10, 0x0F 0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15, 0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x22 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37, 0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D, 0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E, 0x6A, 0x 0x70, 0x74, 0x77, 0x7A, 0x7D }; void setup() { Wire.begin(); } void loop() { for (int i=0; i<256; i++) { Wire.beginTransmission(PCF8591); // obudź PCF8591 Wire.write(0x40); // bajt kontrolny - włącz DAC (binarny 1000000) Wire.write(sine_wave); // wartość do wysłania do DAC Wire.endTransmission(); // zakończ transmisję } }

Krok 4:

Obraz
Obraz

Dla poniższego zrzutu obrazu DSO zmieniliśmy Vref na 3,3 V – zwróć uwagę na zmianę maksimów na fali sinusoidalnej.

Teraz możesz eksperymentować z przetwornikiem cyfrowo-analogowym, aby tworzyć efekty dźwiękowe, sygnały lub sterować innymi obwodami analogowymi.

Krok 5: Korzystanie z przetworników ADC (przetworników analogowo-cyfrowych)

Jeśli używałeś funkcji analogRead() na swoim Arduino (wracając do rozdziału pierwszego), to znasz już ADC. Bez PCF8591 możemy odczytać napięcie od zera do Vref i zwróci wartość od zera do 255, która jest wprost proporcjonalna do zera i Vref.

Na przykład pomiar 3,3 V powinien zwrócić 168. Rozdzielczość (8-bitowa) ADC jest niższa niż wbudowanego Arduino (10-bitowego), jednak PCF8591 może zrobić coś, czego ADC Arduino nie może. Ale za chwilę do tego dojdziemy. Po pierwsze, aby po prostu odczytać wartości każdego pinu ADC, wysyłamy bajt kontrolny, aby poinformować PCF8591, który ADC chcemy odczytać. Dla przetworników ADC od zera do trzech bajt kontrolny to odpowiednio 0x00, 0x01, ox02 i 0x03.

Następnie prosimy o dwa bajty danych z powrotem z ADC i zapisujemy drugi bajt do użytku. Dlaczego dwa bajty? PCF8591 najpierw zwraca poprzednio zmierzoną wartość – potem bieżący bajt. (Patrz Rysunek 8 w arkuszu danych). Na koniec, jeśli nie używasz wszystkich pinów ADC, podłącz nieużywane do GND. Poniższy przykładowy szkic po prostu pobiera wartości z każdego pinu ADC pojedynczo, a następnie wyświetla je na monitorze szeregowym:

#include "Drut.h"

#define PCF8591 (0x90 >> 1) // adres magistrali I2C #define ADC0 0x00 // bajty kontrolne do odczytu poszczególnych ADC #define ADC1 0x01 #define ADC2 0x02 #define ADC3 0x03 bajt wartość0, wartość1, wartość2, wartość3; void setup() { Wire.begin(); Serial.początek(9600); } void loop() { Wire.beginTransmission(PCF8591); // obudź PCF8591 Wire.write(ADC0); // bajt kontrolny - odczyt ADC0 Wire.endTransmission(); // zakończ transmisję Wire.requestFrom(PCF8591, 2); wartość0=Przewód.odczyt(); wartość0=Przewód.odczyt(); Wire.beginTransmission (PCF8591); // obudź PCF8591 Wire.write(ADC1); // bajt kontrolny - odczyt ADC1 Wire.endTransmission(); // zakończenie transmisji Wire.requestFrom(PCF8591, 2); wartość1=Przewód.odczyt(); wartość1=Przewód.odczyt(); Wire.beginTransmission (PCF8591); // obudź PCF8591 Wire.write(ADC2); // bajt kontrolny - odczyt ADC2 Wire.endTransmission(); // zakończenie transmisji Wire.requestFrom(PCF8591, 2); wartość2=Przewód.odczyt(); wartość2=Przewód.odczyt(); Wire.beginTransmission (PCF8591); // obudź PCF8591 Wire.write(ADC3); // bajt kontrolny - odczyt ADC3 Wire.endTransmission(); // zakończenie transmisji Wire.requestFrom(PCF8591, 2); wartość3=Przewód.odczyt(); wartość3=Przewód.odczyt(); Serial.print(wartość0); Serial.print(" "); Serial.print(wartość1); Serial.print(" "); Serial.print(wartość2); Serial.print(" "); Serial.print(wartość3); Serial.print(" "); Serial.println(); }

Po uruchomieniu szkicu zostaną przedstawione wartości każdego ADC na monitorze szeregowym. Chociaż była to prosta demonstracja pokazująca, jak indywidualnie czytać każdy ADC, jest to kłopotliwa metoda uzyskiwania więcej niż jednego bajtu na raz z konkretnego ADC.

Krok 6:

Aby to zrobić, zmień bajt kontrolny, aby zażądać auto-inkrementacji, co odbywa się poprzez ustawienie bitu 2 bajtu kontrolnego na 1. Tak więc, aby zacząć od ADC0, używamy nowego bajtu kontrolnego binarnego 00000100 lub szesnastkowego 0x04. Następnie zażądaj pięciu bajtów danych (znowu ignorujemy pierwszy bajt), co spowoduje, że PCF8591 zwróci wszystkie wartości w jednym łańcuchu bajtów. Proces ten ilustruje poniższy szkic:

#include "Drut.h"

#define PCF8591 (0x90 >> 1) // adres magistrali I2C bajt wartość0, wartość1, wartość2, wartość3; void setup() { Wire.begin(); Serial.początek(9600); } void loop() { Wire.beginTransmission(PCF8591); // obudź PCF8591 Wire.write(0x04); // bajt kontrolny - odczyt ADC0, a następnie autoinkrementacja Wire.endTransmission(); // zakończenie transmisji Wire.requestFrom(PCF8591, 5); wartość0=Przewód.odczyt(); wartość0=Przewód.odczyt(); wartość1=Przewód.odczyt(); wartość2=Przewód.odczyt(); wartość3=Przewód.odczyt(); Serial.print(wartość0); Serial.print(" "); Serial.print(wartość1); Serial.print(" "); Serial.print(wartość2); Serial.print(" "); Serial.print(wartość3); Serial.print(" "); Serial.println(); }

Wcześniej wspomnieliśmy, że PCF8591 może zrobić coś, czego ADC Arduino nie może, a to oferuje różnicowy ADC. W przeciwieństwie do single-ended Arduino (tj. zwraca różnicę między dodatnim napięciem sygnału a GND, różnicowy ADC akceptuje dwa sygnały (które niekoniecznie muszą być odniesione do masy) i zwraca różnicę między dwoma sygnałami Może to być wygodne do pomiaru małych zmian napięcia dla ogniw obciążnikowych i tak dalej.

Krok 7:

Obraz
Obraz

Konfiguracja PCF8591 dla różnicowego przetwornika ADC to prosta kwestia zmiany bajtu kontrolnego. Jeśli przejdziesz do strony siódmej arkusza danych, rozważ różne rodzaje programowania wejść analogowych. Wcześniej używaliśmy trybu „00” dla czterech wejść, jednak można wybrać inne, które są wyraźnie zilustrowane, na przykład obraz.

Aby ustawić bajt kontrolny dla dwóch wejść różnicowych, użyj binarnego 00110000 lub 0x30. Wtedy jest to prosta sprawa żądania bajtów danych i pracy z nimi. Jak widać, istnieje również połączenie pojedynczego/różnicowego i złożonego wejścia trójróżnicowego. Jednak na razie je zostawimy.

Mam nadzieję, że znalazłeś to interesujące, niezależnie od tego, czy dodasz przetwornik cyfrowo-analogowy do swoich eksperymentów, czy dowiesz się nieco więcej o przetwornikach ADC. Rozważ zamówienie PCF8591 od PMD Way.

Ten post został dostarczony przez pmdway.com – wszystko dla producentów i entuzjastów elektroniki, z darmową dostawą na całym świecie.

Zalecana: