Вольтметр
01.Basics: AnalogReadSerial
Serial Plotter
01.Basics: ReadAnalogVoltage
Светодиод с плавной регулировкой
03.Analog: AnalogInput
03.Analog: AnalogInOutSerial
03.Analog: Smoothing
05.Control: IfStatementConditional
На плате UNO есть шесть выводов, которые подписаны от A0 до A5 (у других плат может быть другое число выводов). Они работают с напряжением от 0 до 5V.
Благодаря встроенному АЦП (аналого-цифровой преобразователь), данные входы могут считывать напряжение подаваемое на них. Микроконтроллеры Atmega328, используемые в Arduino UNO, содержат шестиканальный АЦП, разрешение которого составляет 10 бит.
Это позволяет на выходе получать значения от 0 до 1023 (всего 1024 градации).
Для чтения показания напряжения есть встроенный метод analogRead(), возвращающий значение от 0 до 1023. Значение 0 относится к 0V, а 1023 к 5V. Таким образом, если мы хотим конвертировать значение от 0 до 5, то нужно произвести деление 1023/5 = 204.6
Имеется также функция analogReference(type). Она задаёт опорное напряжение, относительно которого происходят аналоговые измерения. В проектах для новичков она не используется, поэтому не будем обращать на неё внимания.
Кроме того, аналоговые выходы могут работать как цифровые и обозначаются как 14, 15, 16, 17, 18, 19 вместо A0..A5.
И, наоборот, цифровые порты с символом тильды ~ (3, 5, 6, 9, 10, 11) могут работать как аналоговые выходы, используя ШИМ.
Аналоговые выводы, в отличие от цифровых, не нужно объявлять как вход или выход в начале программы.
Изучим простой пример с одним проводом и аналоговым выводом. Соединим проводом порты A0 и 3.3V. Напишем скетч.
int analogPin = A0;
void setup() {
Serial.begin(9600);
}
void loop() {
int rawReading = analogRead(analogPin);
float volts = rawReading / 204.6;
Serial.println(volts);
delay(1000);
}
Откройте окно Serial Monitor и наблюдайте за показаниями. Должны выводиться числа, близкие к значению 3.3: 3.1, 3.2, 3.3. Если, не закрывая программу, вытащить конец провода из порта 3.3V и вставить в порт 5V, то показания изменятся, а на экране появятся числа 5.0. Если перекинуть конец провода на GND, то увидим значения 0.
Таким образом мы видим, что можем получать значения напряжения из аналоговых портов.
Вольтметр
Если мы можем снимать значения из аналоговых портов, то можем использовать микроконтроллер как вольтметр. Достаточно вставить провода в выводы GND и A0 и соединить их с контактами на батарее (минус и плюс соответственно).
Вообще такой способ не является суперточным. Хотя он и показывал правдоподобные результаты на пальчиковой батарее 1.5 В и «Кроне» на 9 В, но также показывал результаты, когда провода вообще ни к чему не были присоединены.
Но для общего развития оставлю.
/*
The simplest voltmeter
*/
const int analogIn = A0;
int raw = 0;
float voltage = 0;
void setup() {
pinMode(analogIn, INPUT);
Serial.begin(9600);
}
void loop() {
raw = analogRead(analogIn);
voltage = (raw * 5.0 ) / 1024.0;
Serial.print(«Raw Value = » );
Serial.print(raw);
Serial.print(» Voltage = «);
Serial.println(voltage, 3); // 3 цифры после запятой
delay(500);
}
01.Basics | AnalogReadSerial (Чтение аналоговых выводов через потенциометр)
С помощью потенциометра мы можем менять напряжение и считывать данные с выводов.
Продолжим изучение работы с аналоговыми выводами через пример AnalogReadSerial из меню File | Examples | 01.Basics. Цель урока — плавно изменять напряжение и подавать его на аналоговый вывод, чтобы получить с него текущее значение напряжения.
Нам понадобятся плата Arduino, потенциометр и несколько проводов (или перемычек). Соединяем парные ножки с выводами на плате 5V и GND. Среднюю ножку необходимо соединить с аналоговым выводом на плате, помеченную как A0.
Не важно, какая из крайних ножек потенциометра будет подключена к 5V, а какая к GND, поменяется только направление, в котором нужно крутить ручку для изменения напряжения.
Сам сигнал считывается со средней ножки, которая связана с аналоговым портом. Для считывания аналогового сигнала, принимающего широкий спектр значений, а не просто 0 или 1, подходят только порты, помеченные на плате как ANALOG IN.
Они все пронумерованы с префиксом A (A0-A5).
Схема готова. Вращая регулятором потенциометра, мы можем менять сопротивление от 5 Вольт до 0. Arduino позволяет считывать текущее напряжение, которое подаётся на среднюю ножку при помощи аналогового вывода. Результаты могут колебаться от 0 до 1023.
Код
void setup() {
// инициализируем соединение на скорости 9600 бит в секунду:
Serial.begin(9600);
}
void loop() {
// Считываем данные с аналогового вывода A0
int sensorValue = analogRead(A0); // получаем текущее значение
Serial.
println(sensorValue); // выводим результат на монитор
delay(1); // небольшая задержка для стабильности вывода результатов
}
Код очень простой. При инициализации устанавливаем нужную скорость связи: Serial.begin(9600);. Далее в цикле мы постоянно считываем данные, поступающие с потенциометра при помощи метода analogRead().
Так как значения будут находиться в диапазоне от 0 до 1023, мы можем использовать тип int для переменной sensorValue.
Полученный результат будем выводить в окно последовательного монитора.
Проверка (Serial Monitor)
Запустите программу, а также откройте окно последовательного монитора. Вращая регулятором потенциометра, вы можете наблюдать, как в окне будут меняться значения от 0 до 1023.
Пример интересен своей универсальностью. Потенциометр является ручным делителем напряжения. Существуют другие детали, которые выполняют такую же работу. Например, фоторезистор меняет напряжение в зависимости от освещённости.
Также напряжение может меняться от нажатия, от температуры и т.д. При этом нам не нужно менять программу, просто одну деталь меняем на другую и код будет выполняться.
Единственное различие будет в выводимых результатах — каждый делитель напряжения имеет свои характеристики и, соответственно, будет давать свои показания.
Проверка (Serial Plotter)
Начиная с версии Arduino IDE 1.6.6, в настройках появился новый инструмент Plotter (Tools | Serial Plotter), позволяющий выводить простенький график. Обратите внимание, что он не может работать одновременно с последовательным монитором, который следует закрыть.
Вращая ручку потенциометра, можем наблюдать изменение графика.
01.Basics | ReadAnalogVoltage (Напряжение аналоговых выводов через потенциометр)
Рассмотрим урок ReadAnalogVoltage из меню File | Examples | 01.Basics.
Он практически идентичен примеру AnalogReadSerial, только мы будем конвертировать значения от аналогового вывода (0…1023) в значения напряжения (0…5). Для примера нам понадобится потенциометр.
Цель урока — плавно изменять напряжение и подавать его на аналоговый вывод, чтобы получить текущее значение напряжения.
Схема прежняя, ничего не меняем. Соединяем парные ножки с выводами на плате 5V и GND. Среднюю ножку необходимо соединить с аналоговым выводом на плате, помеченную как A0.
Схема готова. Вращая регулятором потенциометра, мы можем менять сопротивление от 5 Вольт до 0. Arduino позволяет считывать текущее напряжение, которое подаётся на среднюю ножку при помощи аналогового вывода. Результаты могут колебаться от 0 до 1023.
Код
void setup() {
Serial.begin(9600);
}
void loop() {
// читаем данные с вывода A0:
int sensorValue = analogRead(A0);
// Конвертируем данные от 0 до 1023) в значения напряжения (0 — 5V):
float voltage = sensorValue * (5.0 / 1023.0);
// Выводим результат
Serial.
println(voltage);
}
Если сравнить два примера, то разница в одной строке float voltage = sensorValue * (5.0 / 1023.0);. В цикле считываем данные, поступающие с потенциометра при помощи метода analogRead().
Так как значения будут находиться в диапазоне от 0 до 1023, мы можем использовать тип int для переменной sensorValue. Используем элементарную математику и делим результат на коэффициент.
Полученный результат будем выводить в окно последовательного монитора.
Запустите программу, а также откройте окно последовательного монитора. Вращая регулятором потенциометра, вы можете наблюдать, как в окне будут меняться значения от 0.00 до 5.00.
Светодиод с плавной регулировкой
Усложним конструкцию, добавив светодиод. Первую часть схему можно было не трогать. Но для экономии в предыдущем примере я соединил ножку потенциометра сразу с портом GND. На этот раз сделаем соединение из двух проводов. Это необходимо, чтобы светодиод тоже мог соединиться с заземлением. Поэтому финальный макет будет следующим.
Принципиальная схема.
Напишем код.
int potPin = A0;
int ledPin = 9;
void setup() {
// порт для светодиода на выход
pinMode(ledPin, OUTPUT);
// пин с потенциометром — вход
// мы хотим считывать напряжение,
// выдаваемое им
pinMode(potPin, INPUT);
Serial.begin(9600);
}
void loop() {
// значение напряжения с потенциометра
int rotation;
// значение яркости
int brightness;
// считываем напряжение с потенциометра от 0 до 1023
// пропорциональное углу поворота ручки
rotation = analogRead(potPin);
// в brightness записываем полученное ранее значение rotation
// делённое на 4. Дробная часть от деления будет отброшена.
// В итоге мы получим целое число от 0 до 255
brightness = rotation / 4;
// выдаём результат на светодиод
analogWrite(ledPin, brightness);
// выводим результат в Serial Monitor
Serial.println(brightness);
delay(1); // задержка для стабильности
}
Практически все инструкции вам знакомы. Тут нужно уяснить момент, что яркость светодиода управляется нашим кодом, а не подачей напряжения через потенциометр. Мы считываем показания потенциометра, как в первом варианте и переводим получаемые значения в диапазон от 0 до 255.
Затем воспроизводим старый пример с плавной регулировкой светодиода и подаём ему нужные значения. Теперь при вращении ручки потенциометра мы одновременно управляем степенью накала светодиода.
Напомню, что светодиод следует подключить к портам с тильдой, например, ~9
Небольшая модификация примера с миганием светодиода. Частота мигания будет зависеть от показаний потенциометра. Можно использовать встроенный светодиод или установить свой. Общая схема остаётся как у первого примера.
int sensorPin = A0; // аналоговый вывод A0 для потенциометра
int ledPin = 13; // вывод для светодиода
int sensorValue = 0; // значение, поступаемое от потенциометра
void setup() {
// устанавливаем режим для светодиода
pinMode(ledPin, OUTPUT);
}
void loop() {
// считываем показание с потенциометра
sensorValue = analogRead(sensorPin);
// включаем светодиод
digitalWrite(ledPin, HIGH);
// делаем задержку на значение от потенциометра в мсек
delay(sensorValue);
// выключаем светодиод
digitalWrite(ledPin, LOW);
// делаем задержку на значение от потенциометра в мсек
delay(sensorValue);
}
Получая показания от потенциометра в интервале 0-1023 мы регулируем задержку между миганием светодиода в интервале от 0 до 1.023 секунд.
Считываем данные с потенциометра и распределяем их в интервале от 0 до 255 с помощью функции map(). Данный интервал удобно использовать для выводов с PWM (ШИМ). Применим получаемые значения для управления яркостью светодиода, а также будем выводить информацию в Serial Monitor.
const int analogInPin = A0; // потенциометр к A0
const int analogOutPin = 9; // светодиод на выводе 9
int sensorValue = 0; // значения от потенциометра
int outputValue = 0; // значения для PWM
void setup() {
Serial.begin(9600);
}
void loop() {
// считываем данные из потенциометра
sensorValue = analogRead(analogInPin);
// распределяем данные из интервала 0-1023 в интервал 0-255
outputValue = map(sensorValue, 0, 1023, 0, 255);
// подаём сигнал на светодиод:
analogWrite(analogOutPin, outputValue);
// печатаем результаты в Serial Monitor
Serial.print(«sensor = «);
Serial.print(sensorValue);
Serial.print(» output = «);
Serial.println(outputValue);
// ждём 2 миллисекунды
delay(2);
}
Запускаем скетч, крутим ручку потенциометр, наблюдаем за показаниями на экране и следим за яркостью светодиода.
03.Analog: Smoothing
Если показания аналогового датчика «прыгают», то имеет смысл вычислить среднее значение за определённый промежуток времени и результат выдавать на экран. Таким образом мы получим более плавные значения.
Для демонстрации можно использовать потенциометр, хотя он выдаёт обычно нормальные данные, но нам важно узнать принцип.
Схема обычная, берём из примеров выше.
// число показаний для получения среднего значения (подбирается индивидуально)
const int numReadings = 10;
int readings[numReadings]; // массив данных от аналогового вывода
int readIndex = 0; // текущий индекс
int total = 0; // общее значение
int average = 0; // среднее значение
int inputPin = A0; // Аналоговый вывод А0
void setup() {
Serial.begin(9600);
// заполняем массив из 10 элементов нулями
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
readings[thisReading] = 0;
}
}
void loop() {
// вычитаем значение
total = total - readings[readIndex];
// считываем с датчика
readings[readIndex] = analogRead(inputPin);
// добавляем полученное значение
total = total + readings[readIndex];
// переходим на следующую позицию в массиве
readIndex = readIndex + 1;
// если достигли конца массива...
if (readIndex >= numReadings) {
// …возвращаемся в начало:
readIndex = 0;
}
// подсчитываем среднее значение
average = total / numReadings;
// посылаем данные на компьютер
Serial.println(average);
delay(1); // небольшая задержка для стабильности
}
05.Control: IfStatementConditional
В примере File | Examples | 05.Control | IfStatementConditional рассматривается случай, когда показания достигают определённой величины. При достижении заданного порога включается светодиод. Урок знакомит новичка с оператором условия if (Если).
Схема без изменений (см. рисунки выше). Среднюю ножку потенциометра соединяем с аналоговым выводом A0, остальные две ножки соединяем с питанием 5В и землёй. При желании установите внешний светодиод на цифровой вывод 13 (можно обойтись встроенным светодиодом).
const int analogPin = A0; // аналоговый вывод для потенциометра
const int ledPin = 13; // цифровой вывод для светодиода
const int threshold = 400; // произвольный порог для показаний потенциометра
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
// считываем данные с потенциометра
int analogValue = analogRead(analogPin);
// Если показания выше чем заданный порог, то включаем светодиод
if (analogValue > threshold) {
digitalWrite(ledPin, HIGH);
} else {
digitalWrite(ledPin, LOW); // иначе держим светодиод выключенным
}
// выводим показания на Serial monitor
Serial.println(analogValue);
delay(1); // задержка для стабильности
}
Другие примеры
07.Display: barGraph (Световая шкала и потенциометр)
04.Communication: Graph (Рисуем график в Processing)
Реклама
Датчик температуры TMP36 и Arduino
Аналоговый датчик температуры простой в освоении, дешевый и при этом позволяет в режиме реального времени контролировать температуру окружающей среды!
Эти датчики используют технологии твердотельной электроники для для опредения температуры. То есть, в них нет ртути (как в старых термометрах) или биметаллических пластин. Вместо в них установлены термисторы (чувствительные к температур резисторы).
В термисторах при повышении температуры, повышается напряжение в диоде (технически это разность напряжений между базой и эмиттером в транзисторе). Точный съем показаний напряжения дает возможность генерировать аналоговый сигнал, пропорциональный температуре.
Конечно, технология не настолько линейна, но по сути именно так и меряется температура.
В этих датчиках нет подвижных частей, они точные, практически не изнашиваются, не требуют калибровки, могут работать в различных окружающих средах. Кроме того, как уже упоминалось выше, эти датчики недорогие и легки в эксплуатации.
Эти технические характеристики относятся к аналоговым датчикам температуры TMP36 (-40 до 150 градусов по цельсию).
Технические характеристики очень схожи также с датчиками модели LM35/TMP35 (выходой сигнал в цельсиях) и LM34/TMP34 (в фаренгейтах). Основное преимущество модели ’36 перед ’35 или ’34 – этот датчик температуры имеет широкий диапазон чувствительности и не генерирует отрицательные значения напряжения при минусовой температуре. Во всем остальном функционал одинаковый.
- Размер: корпус TO-92 (около 0.2″ x 0.2″ x 0.2″) с тремя коннекторами
- Цена: $2.00 в магазине Adafruit (Китай, конечно же предлагает дешевле)
- Диапазон измеряемых температур: от — 40°C до 150°C / -40°F до 302°F
- Диапазон сигнала на выходе: от 0.1В (-40°C) до 2.0В (150°C), но точность падает после 125°C
- Питание: от 2.7 В до 5.5 В, сила тока — 0.05 мА
- Даташит
Как измерить температуру
Для использования TMP36 достаточно подключить левый коннектор к источнику питания (2.7 — 5.5В), а правый – к земле. Со среднего коннектора мы будем снимать аналоговое значения напряжения, которое прямопропорционально (линейная зависимость) температуре. Значение аналогового напряжения не зависит от источника питания.
- Для преобразования напряжения в температуру используется зависимость:
- Temp in °C = [(Vout in mV) — 500] / 10
- То есть, например, если напряжение на выходе равно 1 В, температура равна:
- ((1000 mV — 500) / 10) = 50 °C
- Если вы используете датчик температуры LM35 или подобный ему, используйте линию “a” на рисунке выше и формулу:
- Temp in °C = (Vout in mV) / 10
Проблемы, которые могут возникнуть при работе с несколькими датчиками
Если при добавлении в ваш проект нескольких датчиков вы замечаете, что данные температуры противоречивы, это означает, что сенсоры создают друг другу помехи при сцитывании аналоговых данных. Исправить это можно, добавив задержку между считываниями.
Проверка датчика температуры
Проверить эти датчики несложно. Для этого вам понадобятся батарейки или источник питания.
Подключите источник питания 2.7 – 5.5 В (отлично подходят также 2-4 батарейки АА) таким образом, что земля подключена к 3 пину (справа), а напряжение питания – к 1 пину (слева).
После этого выставьте на своем мультиметре режим DC (постоянный ток). Подключите его его к земле и свободному среднему (2) коннектору. Если у вас датчик температуры TMP36 и вокруг комнатная температура (около 25 °C), напряжение дожно быть около 0.75 В. Обратите внимание, что если вы используете LM35, напряжение составит 0.25 В.
Датчик показывает температуру 26.3 °C, что равно 79.3 F
Напряжение на выходе можно легко изменить, зажав пластиковый корпус датчика пальцами. В результате вы увидите как напряжение/температура растут.
С пальцами на датчике температура поднялась до 29.7°C / 85.5°F:
Или вы можете коснуться датчика кусочком льда (желательно так, чтобы влага с него не попала на ваше электрическую цепь). В результате температура уменьшится.
С кусочком льда на сенсоре температура опустилась до 18.6°C / 65.5°F.
Использование датчика температуры
Подключение датчика температуры
Внутри подобных датчиков находится маленький чип. Чип достаточно тонкий, так что устанавливать датчик надо осторожно. Будьте аккуратны со статическим электричеством при установке датчика. Убедитесь, что питание подключено правильно и находится в диапазоне от 2.7 до 5.5 В – постоянный ток. Не используйте батарейки на 9 В!
Чувствительный элемент датчика находится в пластиковом обрезанном по одной грани цилиндре с тремя «ногами». «Ноги» легко изгибаются для установки на монтажной плате. К ним можно припаять провода. Если вы хотите сделать ваш датчик водонепроницаемым – вот отличный проект с Instructables.
Считывание аналоговых значений температуры
В отличие от датчиков силы и фоторезисторов TMP36 и подобные датчики не работают как резистор. В связи с этим считывать данные температуры получится только с использованием аналогового пина на плате Arduino.
Не забудьте, что для питания необходим диапазон от 2.7 до 5.5 вольт. В приведенной выше схеме подключения датчика температура к Arduino используется пин 5 вольт. Но можно использовать и пин 3.3 вольта. Вне зависимости от напряжения питания, считываемое аналоговое значение напряжения будет находится в диапахоне от 0 до 1.75 В.
- Если вы используете 5 В Arduino и подключаете датчик напрямую к аналоговому пину, можно использовать следующие формулы для преобразования 10-битных аналоговых значений в температуру:
- Напряжение на пине в миливольтах = (значения с аналогового пина ADC) * (5000/1024)
- С помощью этой зависимости мы преобразуем числовое значение в диапазоне 0-1023 с аналогового пина в 0-5000 миливольт (= 5 вольт)
- Если вы используете 3.3 Arduino, используйте следующую зависимость:
- Напряжение на пине в миливольтах = (значения с аналогового пина ADC) * (3300/1024)
- Эта зависимость преобразовывает числовое значение 0-1023 с аналогового пина в 0-3300 миливольт (= 3.3 вольт)
- После этого, для преобразования милливольт в температуру, используйте формулу:
- Температура в цельсиях = [(аналоговое напряжение в милливольт) — 500] / 10
Простой термометр на Arduino
В этом примере программы для Arduino показано как можно быстро создать термометр с использованием датчика температуры. Текущее значение температуры будет отображаться в серийном мониторе в градусах по Цельсию и по Фаренгейту.
- //TMP36 переменные
- int sensorPin = 0; //аналоговый пин, к которому подключен датчик температуры TMP36 //разрешающая способность равна 10 мВ/градус по Цельсию
- //с отступом 500 мВ для отрицательных температур
- /*
- * setup() – эта функция отрабатывает один раз при запуске Arduino
- * Инициализация серийного протокола связи с компьютером
- */
- void setup()
- {
- Serial.begin(9600); //Начало обмена данными с компьютером по серийному протоколу,
- // чтобы отобразить результат измерений в серийном мониторе
- }
- void loop() // запускается вновь и вновь
- {
- //получаем значения напряжения с датчика температуры
- int reading = analogRead(sensorPin);
// преобразовываем полученные данные в напряжение. Если используем Arduino 3.3 В, то меняем константу на 3.3
- float voltage = reading * 5.0;
- voltage /= 1024.0;
- // отображаем напряжение
Serial.print(voltage); Serial.println(» volts»);
- // теперь отображаем температуру
- float temperatureC = (voltage — 0.5) * 100 ; //конвертируем 10 мВ на градус с учетом отступа 500 мВ
- //в градусы ((напряжение – 500 мВ) умноженное на 100)
Serial.print(temperatureC); Serial.println(» degrees C»);
// преобразуем в градусы по Фаренгейту
float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;
Serial.print(temperatureF); Serial.println(» degrees F»);
delay(1000); //ожидаем 1 секунду
}
Повышаем точность измерений датчиком температуры
Для более точных показаний с меньшими внешними шумами, можно использовать источник питания 3.3 В, который подключен к пину AREF вместо 5 В.
В примере дополнительно использован фоторезистор, но вы можете его спокойно проигнорировать.
Обратите внимание, что мы подключили датчик температуры TMP36 к пину A1.
При использовании пина 3.3 В для питания датчика не забудьте указать «analogReference(EXTERNAL)» в функции setup() как это сделано в коде ниже:
/* Пробный скетч для датчика температуры
*/
#define aref_voltage 3.3// мы подключаем 3.3 В к AREF и проверяем напряжение мультиметром!
- //TMP36 пременные
- int tempPin = 1;//аналоговый пин, к которому подключен аналоговый датчик температуры TMP36
- //разрешающая способность 10 мВ/градус по Цельсию
- //с отступом 500 мВ для отрицательных температур
- int tempReading;// считывание аналоговых значений с датчика
- void setup(void) {
- // подключаем серийный протокол для обмена данными с Arduino
- Serial.begin(9600);
- // Если вы подключаете aref к источнику питания, который не равен 5 В
- analogReference(EXTERNAL);
- }
- void loop(void) {
- tempReading = analogRead(tempPin);
- Serial.print(«Temp reading = «);
- Serial.print(tempReading);// необработанные аналоговые значения
- // преобразовываем полученные значения в напряжение
- float voltage = tempReading * aref_voltage;
- voltage /= 1024.0;
- // отображаем значения напряжения
- Serial.print(» — «);
Serial.print(voltage); Serial.println(» volts»);
- // теперь отображаем температуру
- float temperatureC = (voltage — 0.5) * 100 ; //преобразовываем 10 мВ на градус по цельсию с учетом поправки 500 мВ
- //в градусы ((напряжение — 500mV) умножить на 100)
Serial.print(temperatureC); Serial.println(» degrees C»);
// конвертируем в градусы по Фаренгейту
float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;
Serial.print(temperatureF); Serial.println(» degrees F»);
delay(1000);
}
Подключение аналоговых 3-проводных сенсоров к Arduino
Существует большое количество сенсоров с аналоговым сигналом совместимых с Arduino, которые подключаются по трём проводам:
- Питание (Vcc) — красный провод. На него должно подаваться напряжение, указанное в документации на сенсор. Чаще всего 5 В — это норма.
- Земля (GND) — чёрный провод. Должен быть соединён с землёй микроконтроллера.
- Сигнальный (S) — синий провод. С него считываются показания сенсора.
При использовании аналогового сигнала, показания датчика передаются в виде переменного напряжения на сигнальном проводе. Сигнальное напряжение может принимать значение от 0 В до напряжения питания. Хотя обычно «рабочий диапазон» напряжений более узкий.
Между измеряемой величиной и возвращаемым обратно напряжением установлена определённая зависимость. Например: чем больше величина, тем больше напряжение; или наоборот: чем больше величина, тем напряжение меньше.
Иногда зависимость более сложная: напряжение растёт до определённого значения, затем падает пропорционально ему. Всё зависит от сенсора.
Так например, инфракрасный дальномер измеряет расстояние до объекта перед ним. Для него чем меньше расстояние, тем больше напряжение. Если объект находится на расстоянии 20 см, сенсор выдаёт ~2.
5 В на сигнальном проводе; на расстоянии 60 см ~ 1 В; на расстоянии 150 см ~ 0.4 В. Точная диаграмма зависимости напряжения от расстояния для инфракрасного дальномера от Sharp приведена в его datasheet’е.
Для других сенсоров диаграммы можно так же найти в документации или получить экспериментально.
На Arduino Uno имеется 6 аналоговых входов с помощью которых можно считывать переменное напряжение, и исходя из его значения получать значения с датчика. Эти входы объединены на плате в группу «Analog In» и пронумерованы от A0 до A5.
Провода на таких сенсорах с одного конца обжаты коннектором для подключения к плате сенсора, а с другого конца — коннектором предназначенным для включения в штырьковые контакты на принимающей стороне.
IO Shield, плата расширения для Arduino делает процесс подключения сенсора к нужным контактам микроконтроллера тривиальным: она, помимо всего прочего, имеет 6 троек штырьковых контактов, соединённых с соответствующими входами A0-A5 на Arduino.
Для подключения сенсора достаточно просто включить его коннектор в одну из троек.
Обратите внимание на маркировку возле контактов и убедитесь что она соответствует назначению проводов, выходящих из коннектора к сенсору. Если вы вставите коннектор вверх ногами, сенсор просто не заработает: никаких повреждений приченено не будет.
Считать данные с аналогового сенсора крайне просто. Для этого в Arduino существует стандартная функция analogRead. Так, например, если вы подключили сенсор к контакту A5, чтобы получить показания сенсора в переменную value достаточно исполнить:
int value = analogRead(A5);
Диапазон входного напряжения от 0 до 5 В в программе проецируется на диапазон целочисленных значений от 0 до 1023. Перевести полученное значение в физические единицы, такие как, например, расстояние, поможет функция map. Подробнее об этом рассказывает Джереми Блюм, в своём 4-м видеоуроке по Arduino.
Таким образом, программа, которая раз в секунду считывает показания аналогового сенсора, подключенного к контакту А5, и посылает их на компьютер может выглядеть так:
analogSensorRead.pde
#define SENSOR_PIN A5
void setup()
{ Serial.begin(9600);
}
void loop()
{ delay(1000); int val = analogRead(SENSOR_PIN); Serial.println(val);
}
Преимуществом сенсоров с аналоговым сигналом является крайняя простота их использования с Arduino. Кроме того, поскольку показания датчика можно считывать «из коробки» всего одной командой, драгоценные килобайты памяти на микроконтроллере не расходуются на хранение алгоритма расшифровки протокола, присущего цифровым сенсорам.
Главным недостатком аналогового сигнала является неустойчивость к внешним шумам. Если провод от сенсора до микроконтроллера будет достаточно длинным, он начнёт работать как антенна и улавливать внешние электромагнитные поля: провод сам будет влиять на выходное напряжение и тем самым искажать показания. Поэтому разумный предел длины провода для аналогового сенсора — не более 50 см.
Аналоговый сигнал при чтении на Arduino может иметь максимум 1024 градации, чего может оказаться недостаточно для высокоточных измерений.
На ATmega328p, установленном на Arduino, как и на большинстве других микроконтроллеров аналоговых входов не много. Поэтому количество одновременно контролируемых аналоговых сенсоров ограничено. У Arduino Uno — их 6, у Arduino Mega 2560 — 16.
Если какой-либо из недостатков существеннен для вашего проекта, обратите внимание на цифровые сенсоры.
Подключение цифровых датчиков к Arduino
Для платформы Arduino существует огромное количество датчиков. Эта статья будет посвящена цифровым датчикам.
Они так называются потому, что на выходе каждого из них сигнал дискретен, то есть имеет два уровня – логические ноль (напряжение земли/общего провода, нулевое) и единица(обычно 3,3 либо 5 вольт).
Пятивольтовые Arduino–платы могут работать с уровнями 3,3 В, а вот для трёхвольтовых плат с пятивольтовыми датчиками требуется согласование уровней.
Обычно эти датчики имеют следующие выводы:
– G (GND).Минус напряжения питания.
– V (VTG или +5V, VCC).Плюс напряжение питания.
– S (DO (Digital Output), SIG, OUT).Цифровой выход.
G подключается к земле (вывод GND). V подключается к выводу +5V либо 3V3 (читайте описание датчика). S подключается к заданному программно цифровому выводу (он может быть любым), аналоговые выводы тоже можно использовать как цифровые, считывание состояния этого вывода в Arduino IDE осуществляется при помощи функции digitalRead().
Пример кода программы для считывания показания датчиков. Показания датчика будут выводиться в последовательный порт компьютера. Просмотреть их можно будет при помощи монитора порта в Arduino IDE.
Подключение цифровых датчиков к Arduino void setup() {
Serial.begin(9600); // Скорость работы монитор порта
pinMode(4, INPUT); // Инициализируем цифровой pin 4 как вход
}
void loop() {
int sensorValue = digitalRead(4); // Задаем переменную sensorValue для считывания состояния
Serial.println(sensorValue); // Выводим состояние кнопки в порт
delay(500); // Ждем пол секунды
}
Serial.begin(9600); // Скорость работы монитор порта pinMode(4, INPUT); // Инициализируем цифровой pin 4 как вход int sensorValue = digitalRead(4); // Задаем переменную sensorValue для считывания состояния Serial.println(sensorValue); // Выводим состояние кнопки в порт delay(500); // Ждем пол секунды |
Логично было бы, если бы при срабатывании датчика на его выходе была логическая единица, однако большинство датчиков работают наоборот.
В программе можно управлять какими-либо параметрами в зависимости от показаний датчиков. Поэтому теперь приведём более наглядный пример. При считывании единицы с датчика будет загораться встроенный в плату Arduino светодиод (пин 13).
Подключение цифровых датчиков к Arduino void setup() {
pinMode(4, INPUT); // Инициализируем цифровой pin 4 как вход
}
void loop() {
int sensorValue = digitalRead(4); // Задаем переменную sensorValue для считывания состояния
if (sensorValue == 1) // Если на цифровом входе единица
{
// Выполняем действие
digitalWrite(13, HIGH); // Включаем светодиод
}
else // В ином случае (если на цифровом входе 0)
{
// Выполняем действие
digitalWrite(13, LOW); // Выключаем светодиод
}
delay(500);
}
pinMode(4, INPUT); // Инициализируем цифровой pin 4 как вход int sensorValue = digitalRead(4); // Задаем переменную sensorValue для считывания состояния if (sensorValue == 1) // Если на цифровом входе единица digitalWrite(13, HIGH); // Включаем светодиод else // В ином случае (если на цифровом входе 0) digitalWrite(13, LOW); // Выключаем светодиод |
Существуют также комбинированные датчики. Они имеют как цифровой, так и аналоговый выходы. При достижении определённого значения на аналоговом выходе (большинство плат Arduino различают 1024 его уровня) сигнал на цифровом выходе меняет значение на противоположное. Такими бывают, например, датчики громкости звука.
Датчик температуры TMP36 и его подключение к Arduino
- Чтобы перевести напряжение в температуру просто воспользуйтесь следующей формулой (Vout измеряется в милливольтах):
- Температура в °C = [Vout — 500] / 10
- Например, выходное напряжение составляет 1 В, это значит, что температура равна ((1000 мВ — 500) / 10) = 50 °C.
- Если вы используете датчики температуры типа LM35 и ему подобные, то ориентируйтесь на линию ‘a’ графика, показанного выше. Формула тогда будет следующая:
- Температура в °C = Vout / 10
- Проблема при использовании нескольких датчиков
Если вы используете несколько датчиков температуры, то можете заметить, что показания температуры непостоянны.
Это значит, что датчики влияют друг на друга, когда цепь считывания аналогового сигнала переключается с одного вывода на другой. Вы можете исправить это, организовав задержку между двумя считываниями.
Подключаем датчик температуры к Arduino, Подключение датчика довольно простое
В данном случае мы подключили датчик к напряжению 5 В, но также можно его подключать к 3.3 В. Не важно к какой линии питания вы его подключите, его выходное напряжение все равно не превысит 2 В. С учетом того, что АЦП в Arduino 10-и разрядный, то будет справедлива следующая формула:
Напряжение на выводе в мВ = (показания АЦП) * (5000/1024)
Эта формула преобразует число от 0 до 1023 с АЦП в 0-5000мВ (= 5В). При использовании питания 3.3 В формула будет следующая:
- Напряжение на выводе в мВ = (показания АЦП) * (3300/1024)
- Далее, чтобы перевести милливольты в температуру, нужно воспользоваться формулой:
- Температура в цельсиях = [(аналоговое напряжение в мВ) — 500] / 10
- Простой термометр на Arduino
Нижеприведенный пример кода показывает, насколько просто можно сделать термометр на Arduino. В данном случае в последовательный порт выводятся показания температуры в цельсиях и фаренгейтах.
int sensorPin = 0; //аналоговый ввод для выхода датчика TMP36
//разрешение 10 мВ / градус цельсия со смещением на 500 мВ
//для отрицательной температуры
void setup()
{
Serial.begin(9600);
}
void loop()
{
//считываем напряжение датчика
int reading = analogRead(sensorPin);
// преобразуем показания в напряжение, для 3.3v используйте значение 3.3
float voltage = reading * 5.0;
voltage /= 1024.0;
// выводим напряжение
Serial.print(voltage); Serial.println(» volts»);
// теперь выводим температуру
float temperatureC = (voltage — 0.5) * 100 ; //исходя из 10 мВ на градус со смещением 500 мВ
Serial.print(temperatureC); Serial.println(» degrees C»);
// в фаренгейтах
float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;
Serial.print(temperatureF); Serial.println(» degrees F»);
delay(1000); //ждем секунду
}
Повышаем точность измерения температуры
Для получения более точного результата с меньшим уровнем шумов можно задействовать опорное напряжение 3.3V с ARef. На рисунке ниже показана схема соединения. Следует отметить, что TMP36 в этом случае подключен к аналоговому вводу A1. Также не следует забывать, что при использовании вывода 3.3v в качестве опорного в коде нужно прописывать analogReference(EXTERNAL).
#define aref_voltage 3.3 // подтягиваем 3.3V к ARef
int tempPin = 1; // подсоединяем датчик теперь к аналоговому вводу 1
int tempReading;
void setup(void) {
Serial.begin(9600);
analogReference(EXTERNAL);
}
void loop(void) {
tempReading = analogRead(tempPin);
Serial.print(«Temp reading = «);
Serial.print(tempReading); // сырые данные
// преобразуем эти данные в напряжение относительно опорного напряжения
float voltage = tempReading * aref_voltage;
voltage /= 1024.0;
// выводим напряжение
Serial.print(» — «);
Serial.print(voltage); Serial.println(» volts»);
// выводим температуру
float temperatureC = (voltage — 0.5) * 100 ;
Serial.print(temperatureC); Serial.println(» degrees C»);
// в фаренгейтах
float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;
Serial.print(temperatureF); Serial.println(» degrees F»);
delay(1000);
}