2.6 Вывод звука
Мы уже подключали светодиод к Arduino. Практически тем же способом можно подключить к Arduino пьезодинамик, что позволит нам создавать несложные звуки.
Пьезодинамик подключается к выводу Arduino примерно также, как и светодиод, через ограничительный резистор сопротивлением 100-200 Ом.
Для вывода звука используется функция tone, которая имеет два параметра - номер вывода и частоту звука. Для отключения звука есть функция со схожим названием noTone.
Простейший код, в котором Arduino будет издавать (весьма противные) звуки каждую секунду, выглядит так:
const int buzzer = 8; // arduino pin 8
void setup(){
pinMode(buzzer, OUTPUT);
}
void loop() {
tone(buzzer, 1000); // 1000Гц = 1КГц
delay(1000); // 1с
noTone(buzzer); // стоп
delay(1000); // пауза 1с
}
Кстати, в продаже бывают и так называемые “активные пьезодинамики” (active buzzer). Они имеют 3 входа, один из которых +5В, а второй управляющий.
Использование такого динамика проще - частоту можно не задавать, достаточно просто установить в “1” соответствующий вывод. Для этого достаточно заменить функцию tone(buzzer, 1000); на digitalWrite(buzzer, HIGH); и функцию noTone(buzzer); на digitalWrite(buzzer, LOW). Такой динамик обычно громче, но отсутствие возможности смены частоты звука может быть недостатком.
Самостоятельная работа #1: С помощью пьезодинамика воспроизвести гамму или несложную мелодию, воспользовавшись таблицей частот нот в герцах.
До
262
Соль
392
Ре
294
Ля
440
Ми
330
Си
494
Фа
349
До
523
Самостоятельная работа #2: Дополнить таймер из предыдущей главы возможностью вывода звука при окончании интервала. Для этого заменить функцию delay функцией воспроизведения соответствующего тона.
2.7 Подключаем датчик температуры DS1820
Мы уже упоминали термистор - резистор, сопротивление которого зависит от температуры, однако его точность весьма невелика. Большую точность можно получить с помощью цифрового датчика DS1820 - данные от него передаются в цифровой форме. Это не только точнее, но и удобнее - не нужно пересчитывать данные с помощью коэффициентов или таблиц, мы сразу имеем готовую величину, которую можно использовать в коде программы.
В отличие от рассмотренных выше аналоговых устройств, DS1820 “общается” с контроллером в цифровой форме, посылая данные в уже готовом, двоичном формате. Для этого используется специальный формат передачи, названный 1Wire, таким способом можно даже подключить несколько устройств к одному проводу.
Сам протокол связи достаточно сложный, но к счастью для нас, его поддержка уже добавлена в библиотеки для Arduino, почти ничего для этого делать не нужно.
Для установки библиотеки достаточно скачать библиотеку с сайта https://github.com/milesburton/Arduino-Temperature-Control-Library и установить ее в папку “Мои документы\Arduino\libraries” (для этого достаточно создать новую папку по этому адресу и скопировать файлы туда).
Сам датчик DS1820 имеет весьма много функций, например возможность установки верхнего и нижнего порога срабатываний. Простейший код подключения датчика для Arduino с выводом информации в serial port, выглядит так:
#include <OneWire.h>
#include <DallasTemperature.h>
// Номер порта для подключения датчика
int portPin = 2;
OneWire oneWire(portPin);
DallasTemperature sensors(&oneWire);
void setup(void)
{
// Открытие порта
Serial.begin(9600);
Serial.println("DS1820");
// Запуск датчика
sensors.begin();
}
void loop(void)
{
// Запрос температуры
sensors.requestTemperatures();
float tempInC = sensors.getTempCByIndex(0);
// Вывод в порт (опционально)
Serial.print("T = ");
Serial.println(tempInC, 2);
Serial.println();
delay(5000);
}
Как можно видеть, мы сначала запрашиваем данные с помощью функции requestTemperatures, затем читаем полученные данные с помощью getTempCByIndex(0). Цифра 0 здесь, это номер датчика, как было сказано выше, их может быть несколько. Вывод в порт используется лишь для удобства просмотра результатов.
Сам DS1820 имеет небольшой размер, и по форме напоминает транзистор.
Впрочем, они также продаются и в виде выносных датчиков в водонепроницаемом корпусе, что позволяет использовать DS1820 для измерения температуры в удаленных местах.
Такой датчик можно использовать, например, для измерения температуры за окном. Диапазон измеряемых температур составляет от -55 до 125°C, что будет достаточно даже в случае глобального потепления или похолодания.
Подключение датчика к Arduino весьма просто:
После подключения, достаточно загрузить вышеприведенную программу в Arduino, открыть serial monitor в Arduino IDE, в появившемся окне можно будет наблюдать значения температуры.
Самостоятельная работа #1: оставить компьютер с подключенным датчиком на сутки. Построить график температуры, например с помощью Excel или https://plot.ly/create/.
Самостоятельная работа #2: добавить в код зажигание светодиода, если температура становится выше определенного предела. Вместо светодиода можно также подключить пьезодинамик, как описано в предыдущей главе. Данная система может быть основой для автоматического контроля температуры, например в теплице.
2.8 Подключаем OLED-экран
Мы уже умеем обрабатывать нажатия кнопок, подключать разнообразные датчики и выводить информацию в компьютер через serial port. Осталось подключить отдельный экран, чтобы получить полностью автономно работающее устройство.
Обычный ЖК-экран может работать с Arduino, но для его подключения требуется задействовать слишком много выводов:
К счастью для нас, сейчас есть более удобный и современный путь - экраны, подключаемые по шине I2C. Шина I2C позволяет подключать различные устройства всего лишь с помощью двух проводов.
Мы будем использовать OLED-экран, имеющий 4 вывода для подключения - он показан на картинке слева. В продаже бывают и другие дисплеи, как на картинке справа - такой вариант не подойдет, при покупке важно не перепутать.
Само подключение при этом достаточно просто, для работы шины I2C требуется всего 4 провода - 2 линии данных, “земля” и “питание”. Также как и с 1Wire, на одной шине может быть подключено несколько разных устройств.
Само подключение показано на картинке:
На шине I2C может быть несколько устройств, поэтому чтобы передавать данные, мы должны знать адрес устройства. Удобнее всего для этого использовать программу i2c_scan, код которой показан ниже.
#include <Wire.h>
void setup()
{
Wire.begin();
Serial.begin(9600);
while (!Serial);
Serial.println("\nI2C Scanner");
}
void loop()
{
byte error, address;
Serial.println("Scanning...");
int nDevices = 0;
for(address = 1; address < 127; address++) {
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0) {
Serial.print("I2C device found at address 0x");
if (address<16)
Serial.print("0");
Serial.print(address,HEX);
Serial.println(" !");
nDevices++;
}
else if (error==4) {
Serial.print("Unknow error at address 0x");
if (address<16)