Оповещатель грязных рук

Общие сведения

В этом проекте мы соберём полуавтоматический напоминатель о выполнении процедуры гигиены рук. Он будет оповещать нас о необходимости мыть руки, кода мы или кто-нибудь ещё входит с лестничной площадки или улицы внутрь помещения.

Видео

Редактируется...

Нам понадобится

Подключение

Для удобства подключения мы воспользуемся 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

Скетч проекта

#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);
}

Ссылки

Обсуждение