Выбрать главу

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)