Arduino

Датчик наклона/вибрации SW-520D и датчик уровня воды

Введение

SW-520D — простой механический датчик, замыкающий или размыкающий контакт при наклоне или вибрации (шарик внутри корпуса перекатывается и замыкает контакты) — используется как простой триггер событий (упало устройство, кто-то его задел). Датчик уровня воды — плата с проводящими полосками, сопротивление между которыми меняется в зависимости от того, насколько высоко датчик погружён в воду. В статье разберём оба датчика как примеры простых «тревожных» сенсоров.

Концепция

SW-520D электрически ведёт себя как обычная кнопка с дребезгом — считывается через digitalRead() с тем же подходом дебаунса, но физическое событие (наклон/вибрация) может быть кратковременным и нерегулярным, в отличие от осознанного нажатия кнопки человеком. Датчик уровня воды — аналоговый, считывается через analogRead(), и значение пропорционально (хотя не строго линейно для всех моделей) высоте воды, в которую погружён сенсорный участок платы.

Пример кода

// firmware/src/main.cpp — датчик наклона/вибрации с дебаунсом и датчик уровня воды
#define TILT_SENSOR_PIN 4
#define WATER_LEVEL_PIN A5

bool lastTiltRawState = HIGH;
bool tiltDebouncedState = HIGH;
unsigned long tiltLastChangeTime = 0;
const unsigned long TILT_DEBOUNCE_DELAY = 50;

void setup()
{
    Serial.begin(9600);
    pinMode(TILT_SENSOR_PIN, INPUT_PULLUP);
    delay(100);
    Serial.println("READY");
}

void loop()
{
    const bool rawState = digitalRead(TILT_SENSOR_PIN);
    if (rawState != lastTiltRawState) {
        tiltLastChangeTime = millis();
        lastTiltRawState = rawState;
    }
    if (millis() - tiltLastChangeTime > TILT_DEBOUNCE_DELAY && tiltDebouncedState != rawState) {
        tiltDebouncedState = rawState;
        Serial.println(tiltDebouncedState == LOW ? "TILT:DETECTED" : "TILT:STABLE");
    }

    static unsigned long lastWaterTime = 0;
    if (millis() - lastWaterTime >= 1000) {
        const int waterValue = analogRead(WATER_LEVEL_PIN);
        const int waterPercent = map(waterValue, 0, 600, 0, 100); // 600 — типичный максимум для полного погружения,
                                                                    // конкретное значение калибруется под датчик
        Serial.print("WATER:");
        Serial.println(constrain(waterPercent, 0, 100));
        lastWaterTime = millis();
    }
}

Пояснения к коду

Обработка SW-520D повторяет проверенный паттерн дебаунса, применённый к одному датчику — несмотря на то, что физическая природа сигнала иная (вибрация, а не осознанное нажатие), электрически датчик ведёт себя идентично кнопке, и тот же алгоритм дебаунса полностью применим без изменений. Сообщение "TILT:DETECTED"/"TILT:STABLE" отражает скорее «сработал/не сработан» статус, чем непрерывное состояние, что соответствует природе датчика — он либо зафиксировал наклон/толчок, либо находится в спокойном состоянии.

Датчик уровня воды масштабируется через map() с верхней границей исходного диапазона, заданной как 600, а не теоретический максимум АЦП 1023 — это отражает реальное практическое поведение конкретной модели датчика, у которой даже при полном погружении сенсорной части показание АЦП обычно не достигает максимума, и точное значение верхней границы нужно откалибровать эмпирически для конкретного физического экземпляра датчика, погрузив его в воду на полную рабочую глубину и записав фактическое считанное значение.

Подводные камни

  • Окисление или коррозия проводящих полосок датчика уровня воды при длительном использовании (особенно в неочищенной воде) постепенно меняет его электрические характеристики, и калибровочные значения, актуальные сразу после покупки датчика, могут со временем «уплыть» — для проектов с длительной эксплуатацией датчика уровня воды стоит предусмотреть периодическую повторную калибровку, а не предполагать, что однократно определённые границы диапазона останутся точными навсегда.
  • Прямой контакт датчика уровня воды с электроникой Arduino без понимания, что сам сенсорный элемент должен находиться в воде, а сама плата с электронными компонентами — нет — попытка погрузить весь модуль целиком (а не только специально предназначенную для контакта с водой сенсорную часть) может привести к короткому замыканию или повреждению электроники модуля.
  • SW-520D — двухпозиционный датчик («есть значимое отклонение от вертикали» / «нет»), не дающий точного угла наклона — для проектов, которым требуется точное измерение угла (а не просто факт наклона/вибрации сверх некоторого механически заданного порога), нужен принципиально другой тип датчика (акселерометр/гироскоп), не входящий в данный базовый комплект.
  • Слишком короткий TILT_DEBOUNCE_DELAY для датчика вибрации может зафиксировать одно физическое событие (например, один удар) как множество отдельных «наклонов», если шарик внутри датчика несколько раз быстро перекатывается и обратно в ответ на единичный физический толчок — для проектов, где важно различать единичные дискретные события (а не непрерывную вибрацию), может потребоваться больший интервал «успокоения» после первого зафиксированного события, прежде чем датчик снова считается готовым зафиксировать следующее отдельное событие.