Общие сведения
В этом проекте мы соберём полуавтоматический напоминатель о выполнении процедуры гигиены рук. Он будет оповещать нас о необходимости мыть руки, кода мы или кто-нибудь ещё входит с лестничной площадки или улицы внутрь помещения.
Видео
Нам понадобится
- Датчик отрытой двери/окна
- Инфракрасный датчик препятствий
- Trema-модуль Pull Switch UP/DOWN
- Trema-модуль зуммер
- Trema-модуль светодиод RGB
- Trema-модуль датчик освещённости flash-i2c
- Trema Shield, для удобства подключения
- Arduino/Piranha UNO
Подключение
Для удобства подключения мы воспользуемся Trema Shield для Arduino.
Для начала подключим Trema Shield к Piranha UNO
Следующим шагом подключим датчик освещённости Flash-I2C к колодке I2C
Подключим RGB светодиод, зуммер и модуль подтяжки к указанным выводам
RGB светодиод | Piranha UNO |
---|---|
G | GND |
V | VCC |
R | D4 |
G | D5 |
B | D6 |
Зуммер | Piranha UNO |
---|---|
G | GND |
V | VCC |
S | D7 |
Модуль Pull UP/DOWN | Piranha UNO |
---|---|
G | GND |
V | VCC |
2 | 2 |
И, наконец подключим инфракрасный датчик препятствий и датчик открытой двери
Перед установкой инфракрасного датчика препятствий в прихожей необходимо настроить дальность срабатывания. Сделать это можно при помощи подстроечного резистора на самом датчике
Датчик препятствий | Piranha UNO |
---|---|
Синий | GND |
Коричневый | VCC |
Чёрный | 3 |
Датчик двери | Модуль Pull UP/DOWN |
---|---|
Провод 1 | GND |
Провод 2 | 2 |
Переключатель модуля Pull UP/DOWN должен находиться в положении UP
Скетч проекта
// Подключаем библиотеку для работы с аппаратной шиной I2C, до подключения библиотеки iarduino_I2C_DSL. #include <Wire.h> #include <iarduino_I2C_DSL.h> // Определяем выводы, к которым подключены модули #define PIN_DOOR 2 #define PIN_IR 3 #define PIN_R 4 #define PIN_G 5 #define PIN_B 6 #define PIN_ZUM 7 // Определяем интервалы #define BLINK_INTERVAL 500 #define WASH_INTERVAL 20000 #define BEEP_INTERVAL_SHORT 200 #define BEEP_INTERVAL_LONG 2000 // Инстанцируем объект библиотеки датчика освещённости и препятсвий Flash-I2C iarduino_I2C_DSL prox; // Переменные для хранения текущих millis unsigned long last_millis; unsigned long wash_millis; unsigned long beep_millis; // Переменная счёта звукового оповещения uint8_t zum_beep_count; // Переменные состояния светодиодов bool red_state; bool blue_state; bool green_state; // Переменная состояния утсройства uint8_t device_state; // Определяем возможные состояния устройства enum { // Ожидание wait, // Оповещение alert, // Мытьё washing, // Завершение мытья finish_wash }; void setup() { Serial.begin(9600); // Выключаем всё и устанавливаем значения по умолчанию reset(); // Инициируем работу с датчиком освещённости и препятствий Flash-I2C prox.begin(); } void loop() { // Если режим ожидания, дверь открыта и в коридоре кто-то есть... if (device_state == wait && checkDoor()) { // Ждём две секунды delay(2000); // Если сработал инфракрасный датчик в прихожей... if (checkIR()) { // переключаем устройство в режим оповещения device_state = alert; } } // Если режим оповещения и датчик препятсвий ещё не сработал if (device_state == alert && !readProx()) { // Включить оповещение beep(); blinkRedBlue(); } // Если режим оповещения и датчик препятствий сработал if (device_state == alert && readProx()) { // Сохраняем время срабатывания wash_millis = millis(); // Выключаем световое оповещение ledsOff(); // Переводим режим в режим мытья device_state = washing; } // Если режим мытья if (device_state == washing) { // Включаем крастный светодиод blink(PIN_R); // Выключаем звуковое оповещение noBeep(); } // Если пришло время заканчивать мытьё и датчик препятствий ещё не сработал if (device_state == washing && millis() - wash_millis > WASH_INTERVAL && !readProx()) { // Выключаем светодиоды ledsOff(); // Переводим режим в режим завершения мытья device_state = finish_wash; } // Если режим завершения мытья if (device_state == finish_wash) { // Включаем оповещение beep(); blink(PIN_G); } // Если режим завершения и сработал датчик препятствий if (device_state == finish_wash && readProx()) { // Выключаем звуковое оповещение noBeep(); // Включаем зелёный светодиод solidGreen(); // Ждём две секунды delay(2000); // Перезапускаем устройство reset(); } delay(100); } // Функция сброса установок на изначальные void reset() { zum_beep_count = 0; last_millis = 0; wash_millis = 0; beep_millis = 0; red_state = true; blue_state = false; green_state = false; device_state = wait; ledsOff(); noBeep(); } // Функция проверки состояния двери bool checkDoor() { if (digitalRead(PIN_DOOR) == HIGH) return true; else return false; } // Функция проверки состояния датчика bool checkIR() { if (digitalRead(PIN_IR) == LOW) return true; else return false; } // Функция включения звукового оповещения void beep() { int interval; if (zum_beep_count < 3) { interval = BEEP_INTERVAL_SHORT; } else if (zum_beep_count < 4) { interval = BEEP_INTERVAL_LONG; } else { zum_beep_count = 0; } if (millis() - beep_millis > interval) { pinMode(PIN_ZUM, OUTPUT); digitalWrite(PIN_ZUM, HIGH); Serial.println(zum_beep_count); zum_beep_count++; beep_millis = millis(); } else { pinMode(PIN_ZUM, INPUT); } } // Функция выключения звукового оповещения void noBeep() { pinMode(PIN_ZUM, INPUT); zum_beep_count = 0; } // Функция чтения датчика препятствий bool readProx() { if (prox.getProximity() > 50) return true; else return false; } // Функция светового оповещения void blinkRedBlue() { pinMode(PIN_R, OUTPUT); pinMode(PIN_G, OUTPUT); if (millis() - last_millis > BLINK_INTERVAL) { red_state = !red_state; blue_state = !blue_state; last_millis = millis(); } digitalWrite(PIN_R, red_state); digitalWrite(PIN_B, blue_state); } // Функция включения зелёного светодиода void solidGreen() { pinMode(PIN_G, OUTPUT); digitalWrite(PIN_G, HIGH); } // Функция моргания светодиодом void blink(uint8_t pin) { pinMode(pin, OUTPUT); if (millis() - last_millis > BLINK_INTERVAL) { green_state = !green_state; last_millis = millis(); } digitalWrite(pin, green_state); } // Функция выключения светодиодов void ledsOff() { pinMode(PIN_R, INPUT); pinMode(PIN_G, INPUT); pinMode(PIN_B, INPUT); }
Обсуждение