Съдържание:

Arduino и PCF8591 ADC DAC IC: 7 стъпки
Arduino и PCF8591 ADC DAC IC: 7 стъпки

Видео: Arduino и PCF8591 ADC DAC IC: 7 стъпки

Видео: Arduino и PCF8591 ADC DAC IC: 7 стъпки
Видео: Модуль ADS1115, 16-Bit АЦП, Обзор 2024, Юли
Anonim
Arduino и PCF8591 ADC DAC IC
Arduino и PCF8591 ADC DAC IC

Искали ли сте някога повече аналогови входни щифтове във вашия Arduino проект, но не сте искали да се отдадете за Mega? Или искате да генерирате аналогови сигнали? След това проверете темата на нашия урок - IC NXP PCF8591.

Той решава и двата проблема, тъй като има единствен DAC (цифров към аналогов) преобразувател, както и четири ADC (аналогово -цифрови преобразуватели) - всички достъпни чрез I2C шината. PCF8591 се предлага в DIP, повърхностен монтаж и модулна форма, което улеснява експериментирането.

Преди да продължите, изтеглете информационния лист. PCF8591 може да работи както на 5V, така и на 3.3V, така че ако използвате Arduino Due, Raspberry Pi или друга 3.3 V платка за развитие, всичко е наред. Сега първо ще обясним DAC, след това ADC.

Стъпка 1: Използване на DAC (цифрово-аналогов конвертор)

Използване на DAC (цифрово-аналогов преобразувател)
Използване на DAC (цифрово-аналогов преобразувател)

DAC на PCF8591 има разделителна способност от 8 бита-така че може да генерира теоретичен сигнал между нула волта и референтното напрежение (Vref) в 255 стъпки. За демонстрационни цели ще използваме Vref от 5V, а вие можете да използвате по -нисък Vref, като 3.3V или каквото искате, максималната стойност да бъде … но тя трябва да бъде по -малка от захранващото напрежение.

Обърнете внимание, че когато има натоварване на аналоговия изход (ситуация в реалния свят), максималното изходно напрежение ще спадне-листът с данни (който сте изтеглили) показва 10% спад за 10kΩ натоварване. Сега за нашата демонстрационна схема.

Обърнете внимание на използването на 10kΩ издърпващи се резистори на I2C шината и 10μF кондензатор между 5V и GND. Адресът на I2C шината се задава от комбинация от пинове A0 ~ A2 и с всички тях до GND адресът е 0x90. Аналоговият изход може да бъде взет от щифт 15 (а на щифт 13. има отделен аналогов GND. Също така, свържете щифт 13 към GND и свържете GND към Arduino GND.

За да контролираме DAC, трябва да изпратим два байта данни. Първият е управляващият байт, който просто активира DAC и е 1000000 (или 0x40), а следващият байт е стойността между 0 и 255 (изходното ниво). Това е показано на следната скица:

// Пример 52.1 PCF8591 DAC демонстрация

#include "Wire.h" #deteine PCF8591 (0x90 >> 1) // I2C bus address void setup () {Wire.begin (); } void loop () {for (int i = 0; i <256; i ++) {Wire.beginTransmission (PCF8591); // събуждане PCF8591 Wire.write (0x40); // контролен байт - включете DAC (двоичен 1000000) Wire.write (i); // стойност за изпращане към DAC Wire.endTransmission (); // прекратяване на предаването}

за (int i = 255; i> = 0; --i)

{Wire.beginTransmission (PCF8591); // събуждане PCF8591 Wire.write (0x40); // контролен байт - включете DAC (двоичен 1000000) Wire.write (i); // стойност за изпращане към DAC Wire.endTransmission (); // прекратяване на предаването}}

Забелязахте ли битовото изместване на адреса на шината в израза #define? Arduino изпраща 7-битови адреси, но PCF8591 иска 8-битов, така че преместваме байта с един бит.

Стъпка 2:

Образ
Образ

Резултатите от скицата са показани на изображението, ние сме свързали Vref към 5V и сондата на осцилоскопа и GND съответно към аналоговия изход и GND.

Стъпка 3:

Образ
Образ

Ако харесвате криви, можете да генерирате синусоиди с скицата по -долу. Той използва таблица за търсене в масив, който съдържа необходимите предварително изчислени точки от данни:

// Пример 52.2 PCF8591 DAC демонстрационна синусоида

#include "Wire.h" #deteine PCF8591 (0x90 >> 1) // Адрес на I2C шина 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, 0xDx, 0xDx, 0xDx, 0xDx, 0xD, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6, 0xFx, 0xF5 0xED, 0xEB, 0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC, 0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9, 0xC7, 0xCx, 0xB3, 0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C, 0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83, 0x80, 0x7D, 0x7A, 0xD7x, 0x74, 0x74, 0x74, 0x74, 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, 0x10, 0x0, 0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15, 0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x26, 0x26 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37, 0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D, 0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E, 0x61, 0x64, 0x64, 0x64, 0x4 0x70, 0x74, 0x77, 0x7A, 0x7D}; void setup () {Wire.begin (); } void loop () {for (int i = 0; i <256; i ++) {Wire.beginTransmission (PCF8591); // събуждане PCF8591 Wire.write (0x40); // контролен байт - включете DAC (двоичен 1000000) Wire.write (sine_wave ); // стойност за изпращане към DAC Wire.endTransmission (); // прекратяване на предаването}}

Стъпка 4:

Образ
Образ

За следното изхвърляне на DSO изображение променихме Vref на 3.3V - обърнете внимание на промяната в максимумите на синусоидата.

Сега можете да експериментирате с DAC, за да създавате звукови ефекти, сигнали или да управлявате други аналогови схеми.

Стъпка 5: Използване на ADC (аналогово-цифрови преобразуватели)

Ако сте използвали функцията analogRead () на вашия Arduino (обратно в глава първа), тогава вече сте запознати с ADC. Без PCF8591 можем да прочетем напрежение между нула и Vref и то ще върне стойност между нула и 255, която е право пропорционална на нула и Vref.

Например, измерването на 3.3V трябва да върне 168. Разделителната способност (8-битов) на ADC е по-ниска от вградения Arduino (10-битов), но PCF8591 може да направи нещо, което ADC на Arduino не може. Но ще стигнем до това след малко. Първо, за просто да прочетете стойностите на всеки ADC пин, изпращаме контролен байт, за да каже на PCF8591 кой ADC искаме да прочетем. За ADC от нула до три байтът за управление е съответно 0x00, 0x01, ox02 и 0x03.

След това искаме два байта данни обратно от ADC и съхраняваме втория байт за използване. Защо два байта? PCF8591 първо връща предварително измерената стойност - след това текущия байт. (Вижте Фигура 8 в информационния лист). И накрая, ако не използвате всички ADC щифтове, свържете неизползваните такива към GND. Следващата примерна скица просто извлича стойности от всеки щифт на ADC една по една, след което ги показва в серийния монитор:

#include "Wire.h"

#define PCF8591 (0x90 >> 1) // Адрес на I2C шината #define ADC0 0x00 // контролни байтове за четене на отделни ADC #define ADC1 0x01 #define ADC2 0x02 #define ADC3 0x03 байтова стойност0, стойност1, стойност2, стойност3; void setup () {Wire.begin (); Serial.begin (9600); } void loop () {Wire.beginTransmission (PCF8591); // събуждане PCF8591 Wire.write (ADC0); // контролен байт - прочетете ADC0 Wire.endTransmission (); // край на предаването Wire.requestFrom (PCF8591, 2); value0 = Wire.read (); value0 = Wire.read (); Wire.beginTransmission (PCF8591); // събуждане PCF8591 Wire.write (ADC1); // контролен байт - прочетете ADC1 Wire.endTransmission (); // край на предаването Wire.requestFrom (PCF8591, 2); value1 = Wire.read (); value1 = Wire.read (); Wire.beginTransmission (PCF8591); // събуждане PCF8591 Wire.write (ADC2); // контролен байт - прочетете ADC2 Wire.endTransmission (); // край на предаването Wire.requestFrom (PCF8591, 2); value2 = Wire.read (); value2 = Wire.read (); Wire.beginTransmission (PCF8591); // събуждане PCF8591 Wire.write (ADC3); // контролен байт - прочетете ADC3 Wire.endTransmission (); // край на предаването Wire.requestFrom (PCF8591, 2); value3 = Wire.read (); value3 = Wire.read (); Serial.print (стойност 0); Serial.print (""); Serial.print (стойност1); Serial.print (""); Serial.print (стойност2); Serial.print (""); Serial.print (стойност3); Serial.print (""); Serial.println (); }

При стартиране на скицата ще ви бъдат представени стойностите на всеки ADC в серийния монитор. Въпреки че това беше проста демонстрация, за да ви покаже как да четете индивидуално всеки ADC, това е тромав метод за получаване на повече от един байт наведнъж от определен ADC.

Стъпка 6:

За да направите това, променете контролния байт, за да поискате автоматично увеличаване, което става чрез задаване на бит 2 от контролния байт на 1. Така че, за да започнем от ADC0, използваме нов контролен байт от двоичен 00000100 или шестнадесетичен 0x04. След това поискайте пет байта данни (отново пренебрегваме първия байт), което ще накара PCF8591 да върне всички стойности в една верига от байтове. Този процес е демонстриран на следната скица:

#include "Wire.h"

#define PCF8591 (0x90 >> 1) // I2C шина на адреса на байта стойност0, стойност1, стойност2, стойност3; void setup () {Wire.begin (); Serial.begin (9600); } void loop () {Wire.beginTransmission (PCF8591); // събуждане PCF8591 Wire.write (0x04); // контролен байт - прочетете ADC0, след което автоматично увеличете Wire.endTransmission (); // край на предаването Wire.requestFrom (PCF8591, 5); value0 = Wire.read (); value0 = Wire.read (); value1 = Wire.read (); value2 = Wire.read (); value3 = Wire.read (); Serial.print (стойност 0); Serial.print (""); Serial.print (стойност1); Serial.print (""); Serial.print (стойност2); Serial.print (""); Serial.print (стойност3); Serial.print (""); Serial.println (); }

По -рано споменахме, че PCF8591 може да направи нещо, което ADC на Arduino не може, и това предлага диференциален ADC. За разлика от единичния край на Arduino (т.е. връща разликата между положителното напрежение на сигнала и GND, диференциалният АЦП приема два сигнала (които не е задължително да се отнасят към земята) и връща разликата между двата сигнала Това може да бъде удобно за измерване на малки промени в напрежението за натоварващите клетки и т.н.

Стъпка 7:

Образ
Образ

Настройването на PCF8591 за диференциален ADC е прост въпрос за промяна на байта за управление. Ако се обърнете към седма страница на информационния лист, тогава помислете за различните видове програмиране на аналогов вход. Преди това използвахме режим '00' за четири входа, но можете да изберете другите, които са ясно илюстрирани, например изображението.

Така че, за да зададете контролния байт за два диференциални входа, използвайте двоичен 00110000 или 0x30. Тогава е прост въпрос да поискате байтове от данни и да работите с тях. Както можете да видите, има и комбиниран единичен/диференциален и сложен тридиференциален вход. Засега обаче ще ги оставим.

Надяваме се, че сте намерили това от интерес, независимо дали добавяте DAC към експериментите си или научавате малко повече за ADC. Моля, обмислете да поръчате вашия PCF8591 от PMD Way.

Тази публикация ви е предоставена от pmdway.com - всичко за производители и любители на електрониката, с безплатна доставка по целия свят.

Препоръчано: