Компоненты · 15 мин чтения

Лазерный модуль KY-008 и Arduino: лазерная сигнализация и таймер

Лазерный модуль KY-008 и Arduino: подключение, безопасность для глаз (5 mW, 650 нм), лазерный барьер с LDR, автоматическая калибровка порога, зеркала, таймер забега и уведомления с ESP32.

Лазерный модуль — одна из самых эффектных деталей для Arduino: он даёт тонкий красный луч, который проходит метры, почти не расходясь. Лазерный модуль KY-008 из любительских наборов — это лазерный диод 650 нм мощностью около 5 mW на маленькой плате; он подключается к одному цифровому пину Arduino и включается и выключается через digitalWrite(). Сам по себе это просто указка, но стоит поставить напротив датчик света — и получится лазерная сигнализация как в кино, счётчик людей, проходящих через дверь, или таймер забега с точностью до миллисекунды.

В этом руководстве ты узнаешь характеристики KY-008, насколько на самом деле опасен для глаз лазер на 5 mW и каких правил придерживаться, а также как правильно подключить модуль к Arduino Uno, ESP32 и Raspberry Pi Pico. Затем соберём лазерный барьер с LDR, научим Arduino самостоятельно измерять порог вместо того, чтобы подбирать его наугад, превратим один лазер в несколько лучей с помощью зеркал, будем считать проходы и измерять скорость, а с ESP32 — отправлять уведомление на телефон, когда луч прерывается.

Лазерный модуль KY-008 (650 нм, 5 mW)
Лазерный модуль KY-008: латунная лазерная головка 6 мм, токоограничивающий резистор на маленькой плате за ней и три пина (S, средний пин и −).

Что такое лазерный модуль KY-008 и как он работает?

Сердце модуля — маленький лазерный диод внутри латунной трубки. В отличие от обычного светодиода, лазерный диод, как только ток превышает определённый порог, излучает свет одной длины волны и упорядоченно (когерентно); крошечная линза на конце трубки превращает этот свет в почти параллельный луч. Поэтому свет светодиода расплывается уже через несколько сантиметров, а лазерная точка даже за несколько метров остаётся размером всего в несколько миллиметров. 650 нм — насыщенный красный, который глаз видит легко. Резистор на маленькой плате за лазерной головкой ограничивает ток через диод. Лазерные диоды гораздо чувствительнее к перегрузке по току, чем светодиоды; если обойти этот резистор и подать питание прямо на диод, он может сгореть за секунды.

ПараметрЗначение
МодельKY-008 (некоторые продавцы называют его HW-493)
Длина волны650 нм (видимый красный)
Выходная мощностьОколо 5 mW
Класс лазера3R (IEC 60825-1), IIIa в США
Рабочее напряжение5 V (при 3,3 V тусклее)
ТокМеньше 40 mA; отличается от платы к плате
Лазерная головкаЛатунная трубка 6 мм
ПиныS (сигнал), средний пин (+5V или не подключён на большинстве плат), − (GND)
Рабочая температураОт −10 до 40 °C

Безопасность для глаз: насколько опасен лазер на 5 mW?

Опасность лазера не в его общей мощности, а в том, что эта мощность собрана в крошечное пятно. Хрусталик глаза фокусирует параллельный луч в точку размером в микроны на сетчатке, поэтому 5 mW, безобидные на вид на стене, могут дать на сетчатке пятно ярче, чем если смотреть прямо на солнце. По этому риску лазеры делят на классы. У лазеров класса 2 мощностью ниже 1 mW обычно хватает защиты мигательного рефлекса (около 0,25 секунды). Класс 3R, к которому относится KY-008, допускает до пятикратного превышения этого предела: короткий случайный взгляд малоопасен, но смотреть в луч напрямую или через зеркало — значит рисковать повредить глаз.

КлассМощность (видимый свет)Риск
1Очень низкая, или луч закрыт внутри устройстваБезопасен при обычном использовании
2До 1 mWЗащищает мигательный рефлекс; не смотри в луч нарочно
3R1–5 mW (KY-008)Прямой взгляд может повредить глаз
3B5–500 mWОпасны прямой и отражённый от зеркала луч
4Выше 500 mWОпасность для глаз, кожи и риск пожара
  • Никогда не смотри в луч: не подноси выходной конец лазера к глазу и не размахивай включённым модулем в руке.
  • Держи луч ниже уровня глаз: монтируй лучи сигнализации и счётчика на высоте 20–50 см от пола. Эта высота совпадает с уровнем глаз ползающего малыша, маленького ребёнка, кошки или собаки, поэтому не оставляй лазер включённым, когда они рядом.
  • Берегись отражений: зеркала, стекло, циферблаты часов и блестящий металл отправляют луч в неожиданные стороны. Проверь путь луча от начала до конца и закончи его на матовой тёмной поверхности.
  • Детям нельзя работать с лазером в одиночку: лазер — не игрушка; в школьных проектах и на научных выставках работай под присмотром взрослых.
  • Не доверяй этикетке вслепую: реальная мощность дешёвых модулей может отличаться от указанной; считай любой модуль как минимум лазером класса 3R.
  • Выравнивай с листом бумаги: держи белый лист перед лучом и следи за точкой на бумаге; никогда не заглядывай в луч, чтобы понять, куда он идёт.
Направлять лазер на людей, животных, водителей или самолёты — значит рисковать травмами глаз и серьёзными авариями, а во многих странах это ещё и преступление. В любом проекте с KY-008 держи луч неподвижным, ниже уровня глаз и под контролем.

Подключение KY-008: Arduino Uno, ESP32 и Raspberry Pi Pico

У KY-008 три пина: S — сигнальный, при HIGH включает лазер, − — это GND, а немаркированный средний пин на большинстве плат идёт на +5V или вообще никуда не подключён. Лазер стоит между S и −, поэтому пин Arduino, подключённый к S, напрямую питает лазер током. Для коротких тестов на Arduino Uno это нормально, но ток модуля отличается от платы к плате и может приближаться к 40 mA. Это абсолютный максимум ATmega328P на один пин; рекомендуемое значение — 20 mA. Если лазер будет гореть часами, если лазеров несколько или работа идёт с ESP32 или Pico, питай лазер от 5V и коммутируй его NPN-транзистором (BC547, S8050 или 2N2222). Распиновку транзистора можно проверить в утилите распиновки транзисторов.

ПодключениеArduino UnoESP32Raspberry Pi Pico
KY-008 SD75V (VIN)VBUS (пин 40)
KY-008, средний пинНе подключён (5V, если лазер не горит)5V (VIN)VBUS (пин 40)
KY-008 −GNDКоллектор NPNКоллектор NPN
Эмиттер NPN–GNDGND (пин 38)
База NPN (через 1 kΩ)–GPIO 26GP15 (пин 20)
Ножка 1 LDR5V3V33V3(OUT) (пин 36)
Ножка 2 LDR + верхний вывод резистораA0GPIO 34GP26 (пин 31)
Нижний вывод резистора (3,3–10 kΩ)GNDGNDGND
Активный зуммер +D8GPIO 25GP14 (пин 19)
Пины ESP32 и Pico работают на 3,3 V и отдают мало тока; пин GPIO у Pico по умолчанию выдаёт всего 4 mA, а максимум — 12 mA. На этих платах не питай лазер прямо от пина, используй транзистор. А делитель с LDR всегда питай от пина 3V3: делитель, запитанный от 5V, при попадании лазера на LDR подаёт на аналоговый пин больше 3,3 V, и пин может выйти из строя. Активные зуммеры тоже могут потреблять 20–30 mA: пин ESP32 справится с ним напрямую, а на Pico управляй зуммером тоже через NPN-транзистор или выбери маломощный зуммер на 3 V.

Прежде чем переходить к скетчам, проверь лазер и LDR вместе небольшой тестовой программой ниже. Она включает и выключает лазер каждые полсекунды и выводит показание в обоих состояниях в монитор порта. Чем больше разрыв между двумя значениями, тем надёжнее барьер: на Uno разрыв больше 300 — это очень хорошо; меньше 100 — значит, луч попадает на LDR не точно или внешний свет слишком сильный.

C++ (Arduino IDE)
1// KY-008 + LDR ilk test: lazer açıkken ve kapalıyken değerleri gör / First test: see readings with the laser on and off
2const int LASER_PIN = 7;   // KY-008 S pini / KY-008 S pin
3const int LDR_PIN = A0;    // LDR bölücü çıkışı / LDR divider output
4
5void setup() {
6  Serial.begin(9600);
7  pinMode(LASER_PIN, OUTPUT);
8}
9
10void loop() {
11  digitalWrite(LASER_PIN, HIGH);   // lazer açık / laser on
12  delay(500);                      // LDR'nin oturmasını bekle / let the LDR settle
13  int onValue = analogRead(LDR_PIN);
14
15  digitalWrite(LASER_PIN, LOW);    // lazer kapalı / laser off
16  delay(500);
17  int offValue = analogRead(LDR_PIN);
18
19  Serial.print(F("Isin var / beam: "));
20  Serial.print(onValue);
21  Serial.print(F("  Isin yok / no beam: "));
22  Serial.print(offValue);
23  Serial.print(F("  Fark / gap: "));
24  Serial.println(onValue - offValue);
25}

Как работает лазерный барьер на LDR?

Идея лазерного барьера проста: лазерный луч постоянно падает на LDR (фоторезистор) на другой стороне. Когда на нём лазерная точка, сопротивление LDR падает до нескольких сотен ом; когда луч прерывается, оно растёт до десятков килоом. Если включить LDR с постоянным резистором в делитель напряжения, это изменение сопротивления превращается в изменение напряжения на аналоговом пине: при схеме 5V → LDR → A0 → резистор → GND на A0 высокое значение, пока луч на месте, и низкое, когда он прерван. Как только кто-то проходит через луч, значение падает, и Arduino поднимает тревогу.

LDR (фоторезистор)
LDR (фоторезистор)
NPN-транзистор (S8050)
NPN-транзистор (S8050)
Активный зуммер
Активный зуммер

Быстрый расчёт показывает, почему лазер так сильно действует на LDR: когда луч мощностью 5 mW собран в точку диаметром около 3 мм, интенсивность получается примерно 700 W на квадратный метр. Это тот же порядок, что и полуденный солнечный свет, и в сотни раз ярче, чем в хорошо освещённой комнате. И всё же главный враг барьера — внешний свет: перед солнечным окном LDR остаётся освещённым, даже когда луч прерван, и сигнализация ничего не замечает. Решение очень дешёвое: помести LDR на дно чёрной трубки длиной 3–5 см (пустой корпус шариковой ручки, чёрная соломинка или термоусадочная трубка). Трубка пропускает только лазер, идущий прямо спереди, и закрывает внешний свет с боков.

СитуацияСопротивление LDR (пример)analogRead с 10 kΩanalogRead с 3,3 kΩ
Лазер на LDR (в трубке)300 Ω993938
Луч прерван (в трубке)30 kΩ256101
Луч прерван (без трубки, светлая комната)3 kΩ787536
Разрыв между «есть луч» и «нет луча» (в трубке)–737837
Лучшее значение постоянного резистора делителя — среднее геометрическое сопротивлений LDR с лучом и без него: R = √(R_луч × R_прерв). Для 300 Ω и 30 kΩ из таблицы √(300 × 30 000) = 3000 Ω; ближайший стандартный номинал — 3,3 kΩ. Измерь оба сопротивления своего LDR мультиметром, проверь результат в утилите делителя напряжения и найди ближайший номинал в утилите стандартных номиналов.

Пошагово: лазерная сигнализация на Arduino

  1. Подключи пин S модуля KY-008 к D7, а пин − к GND; средний пин оставь неподключённым (если лазер не горит, подключи его к 5V).
  2. Одну ножку LDR подключи к 5V, другую — к A0; между A0 и GND поставь резистор 3,3 kΩ или 10 kΩ.
  3. Помести LDR на дно чёрной трубки и направь отверстие трубки на лазер.
  4. Подключи ножку + активного зуммера к D8, а ножку − к GND. Кнопку отключения звука поставь между D4 и GND; дополнительный резистор не нужен, потому что используется встроенная подтяжка.
  5. Закрепи лазер и LDR на прочном основании; сначала найди лазерную точку листом белой бумаги, затем заведи её в трубку.
  6. Загрузи скетч и открой монитор порта на скорости 9600 бод. При запуске перед лучом никого не должно быть: Arduino калибруется, один раз выключая и включая лазер.
C++ (Arduino IDE)
1// KY-008 lazer + LDR ile lazerli alarm / Laser tripwire alarm with KY-008 + LDR
2const int LASER_PIN = 7;       // KY-008 S pini ya da transistör bazı / KY-008 S pin or transistor base
3const int LDR_PIN = A0;        // LDR bölücü çıkışı / LDR divider output
4const int BUZZER_PIN = 8;      // aktif buzzer / active buzzer
5const int LED_PIN = 13;        // kart üzerindeki LED / on-board LED
6const int RESET_PIN = 4;       // susturma butonu, diğer ucu GND / silence button, other leg to GND
7
8const int BREAK_PCT = 40;                // %40'ın altı = ışın kesik / below 40% = beam broken
9const int RESTORE_PCT = 60;              // %60'ın üstü = ışın sağlam / above 60% = beam intact
10const unsigned long CONFIRM_MS = 30;     // en az bu kadar kesik kalmalı / must stay broken this long
11const unsigned long ALARM_MS = 10000;    // alarm süresi / alarm duration
12
13int onLevel = 0, offLevel = 0;           // ışınlı ve ışınsız ölçüm / reading with and without the beam
14bool beamOk = true;
15bool alarmOn = false;
16unsigned long brokenSince = 0;
17unsigned long alarmStart = 0;
18
19int readAvg() {
20  long sum = 0;
21  for (int i = 0; i < 8; i++) sum += analogRead(LDR_PIN);  // 8 ölçüm ortalaması / average of 8 readings
22  return sum / 8;
23}
24
25void calibrate() {
26  while (true) {
27    digitalWrite(LASER_PIN, LOW);        // lazer kapalı = kesik ışın / laser off = broken beam
28    delay(300);                          // LDR yavaştır, bekle / the LDR is slow, wait
29    offLevel = readAvg();
30    digitalWrite(LASER_PIN, HIGH);       // lazer açık = sağlam ışın / laser on = intact beam
31    delay(300);
32    onLevel = readAvg();
33    Serial.print(F("Isinli / beam: "));
34    Serial.print(onLevel);
35    Serial.print(F("  Isinsiz / no beam: "));
36    Serial.println(offLevel);
37    if (abs(onLevel - offLevel) >= 100) return;   // yeterli fark var / enough difference
38    Serial.println(F("Isin LDR'ye ulasmiyor, hizala! / Beam misses the LDR, align it!"));
39    delay(2000);
40  }
41}
42
43// 100 = ışın tam, 0 = ışın yok; LDR'nin yönü fark etmez / 100 = full beam, 0 = no beam; LDR polarity doesn't matter
44int beamPercent() {
45  return (long)(readAvg() - offLevel) * 100 / (onLevel - offLevel);
46}
47
48void setup() {
49  Serial.begin(9600);
50  pinMode(LASER_PIN, OUTPUT);
51  pinMode(BUZZER_PIN, OUTPUT);
52  pinMode(LED_PIN, OUTPUT);
53  pinMode(RESET_PIN, INPUT_PULLUP);
54  calibrate();
55  Serial.println(F("Alarm hazir / Alarm armed"));
56}
57
58void loop() {
59  unsigned long now = millis();
60  int pct = beamPercent();
61
62  if (beamOk && pct < BREAK_PCT) {       // ışın yeni kesildi / beam just broke
63    beamOk = false;
64    brokenSince = now;
65  } else if (!beamOk && pct > RESTORE_PCT) {
66    beamOk = true;                       // ışın geri geldi / beam restored
67  }
68
69  if (!beamOk && !alarmOn && now - brokenSince >= CONFIRM_MS) {
70    alarmOn = true;
71    alarmStart = now;
72    Serial.println(F("ALARM: isin kesildi! / beam broken!"));
73  }
74
75  if (alarmOn && (now - alarmStart >= ALARM_MS || digitalRead(RESET_PIN) == LOW)) {
76    alarmOn = false;                     // süre doldu ya da butona basıldı / timeout or button pressed
77  }
78
79  digitalWrite(LED_PIN, beamOk ? LOW : HIGH);
80  digitalWrite(BUZZER_PIN, (alarmOn && (now / 200) % 2) ? HIGH : LOW);  // kesik siren / beeping siren
81}

Скетч не использует фиксированный порог. При запуске calibrate() выключает лазер и измеряет значение LDR без луча, затем включает его и измеряет значение с лучом. beamPercent() по этим двум значениям переводит каждое показание в процент от 0 до 100: 100 означает, что луч приходит полностью, 0 — что он полностью перекрыт. Этому расчёту всё равно, стоит LDR вверху или внизу делителя: результат одинаков, растёт показание от света или падает. Если луч опускается ниже 40% и держится там не меньше 30 мс, сигнализация пищит 10 секунд, а кнопка на D4 выключает её раньше. Если луч по-прежнему прерван, тревога начинается снова, так что система не замолчит, пока кто-то стоит в луче.

Калибровка порога: почему не стоит вшивать число в код

Во многих примерах лазерной сигнализации в интернете используется фиксированный порог вроде «analogRead(A0) < 500». Вечером за столом на тесте это работает, но наутро, когда в комнату заглянет солнце, лазер сдвинется на пару миллиметров или LDR заменят, всё ломается. Правильный порог лежит ровно посередине между показаниями с лучом и без луча. Автоматическая калибровка, которая заново измеряет оба значения при каждом запуске, подстраивает систему под окружение. В скетче выше порог — не одно число, а два: луч считается прерванным, когда падает ниже 40%, и целым, когда поднимается выше 60%. Такой зазор называется гистерезисом; он не даёт сигнализации включаться и выключаться десятки раз в секунду, когда показание колеблется прямо у порога.

ПараметрЗначение в кодеЧто делает?Когда менять?
BREAK_PCT40Уровень, при котором луч считается прерваннымПодними до 60–70, чтобы ловить и полупрозрачные предметы (стекло, тонкую ткань)
RESTORE_PCT60Уровень, при котором луч снова считается целымВсегда держи на 15–20 пунктов выше BREAK_PCT
CONFIRM_MS30Игнорирует короткие помехи (насекомые, пыль, вибрация)При ложных срабатываниях подними до 100–200 мс; если быстрые проходы пропускаются, уменьши
Число усредняемых измерений8Сглаживает электрические помехи и мерцание лампНа Uno одно измерение занимает около 0,1 мс; 8 измерений укладываются меньше чем в 1 мс
Калибровочный разрыв100Останавливает настройку, если луч не доходит до LDRНа очень больших расстояниях или в очень светлых комнатах можно снизить до 50

В системе, которая работает долго, внешний свет в течение дня медленно меняется. Простой способ это компенсировать — снова вызывать calibrate(), когда луч цел и сигнализация молчит (например, раз в час). Arduino сама выключает лазер, поэтому не примет эту короткую темноту за нарушителя. Следить за показаниями очень удобно в «Плоттере по последовательному соединению» (Serial Plotter) Arduino IDE: проведи рукой через луч — и увидишь, насколько падает график и сколько времени нужно, чтобы он восстановился.

Несколько лучей с зеркалами: сеть из одного лазера

Один луч легко обойти, пригнувшись под ним или перешагнув через него. Чтобы построить лазерную сеть, как в фильмах, не обязательно давать каждому лучу свой лазер и LDR: один лазер можно пустить зигзагом с помощью зеркал. Зеркала ставят друг напротив друга по обеим сторонам двери или коридора; луч отскакивает от стороны к стороне и в конце попадает на LDR. Если прерывается любой участок, LDR темнеет, так что один LDR и тот же скетч охраняют всю сеть. Угол отражения равен углу падения, поэтому каждое зеркало нужно лишь чуть-чуть наклонить, чтобы оно отправляло луч в центр следующего.

Каждое зеркало теряет часть света. Обычное зеркало для ванной отражает около 90% и даёт слабую вторую точку (паразитное отражение) от переднего стекла. Зеркала с внешним отражающим слоем, у которых отражающее покрытие нанесено поверх стекла, отражают 95% и больше и дают одну чистую точку. Потери перемножаются, поэтому с каждым новым зеркалом свет, доходящий до LDR, быстро уменьшается:

Число зеркалОбычное зеркало (90%)Зеркало с внешним слоем (95%)
190%95%
281%90%
466%81%
653%74%
843%66%

Эта таблица показывает важную вещь: даже 43% более чем достаточно для откалиброванного скетча, потому что лазерная точка в сотни раз ярче внешнего света. Настоящая трудность не в потере мощности, а в юстировке. Чем длиннее путь луча, тем сильнее растёт маленькая ошибка угла: ошибка в 1 градус сдвигает точку примерно на 9 см на расстоянии 5 м. Луч дешёвого лазера к тому же немного расширяется по пути; через несколько метров точка может стать больше 5-миллиметровой поверхности LDR.

  1. Закрепи лазер, зеркала и трубку с LDR на прочных держателях (уголки на винтах, держатели, напечатанные на 3D-принтере, или деревянные бруски на термоклее); зеркало в руке никогда не держит юстировку.
  2. Притуши свет в комнате и найди лазерную точку, держа белый лист перед первым зеркалом.
  3. Выравнивай зеркала по порядку от начала к концу: наклоняй каждое совсем чуть-чуть, пока точка не попадёт в центр следующего зеркала.
  4. Направь последний луч в отверстие трубки с LDR и запусти тестовый скетч, чтобы найти положение, при котором разрыв в мониторе порта наибольший.
  5. Когда всё выровнено, зафиксируй угол зеркал термоклеем или стопорным винтом: даже лёгкий толчок стола может сбить юстировку.
  6. Проверь каждый участок сети, по очереди перекрывая его рукой, и убедись, что сигнализация каждый раз срабатывает.
Если хочется, чтобы вся проводка была с одной стороны, верни луч зеркалом на противоположной стене: лазер и LDR стоят рядом, а на другой стороне остаётся только зеркало, которому не нужно питание. В чистом воздухе лазерный луч сбоку не видно, видна только точка, куда он падает; чтобы увидеть путь луча, добавь в воздух немного водяного пара или дыма.

Счётчик проходов: сколько прошло и за какое время?

Тот же барьер может считать людей, проходящих через дверь, коробки на конвейере или мячи, падающие в корзину. Хитрость в том, чтобы считать каждый проход один раз. Скетч ниже запоминает момент, когда луч прерывается, и засчитывает проход, когда луч возвращается, поэтому человек, который какое-то время стоит в луче, всё равно считается одним проходом. Прерывания короче 15 мс считаются пылью или электрическими помехами и игнорируются. Скетч также выводит, сколько времени луч был перекрыт: если известна длина предмета, это время сразу даёт его скорость (v = L / t). Например, если игрушечная машинка длиной 25 см перекрывает луч на 50 мс, её скорость 0,25 / 0,05 = 5 м/с.

C++ (Arduino IDE)
1// Lazer bariyeriyle geçiş sayacı ve kesilme süresi / Laser barrier pass counter and block time
2const int LASER_PIN = 7;                 // KY-008 S pini / KY-008 S pin
3const int LDR_PIN = A0;                  // LDR bölücü çıkışı / LDR divider output
4const unsigned long MIN_BREAK_MS = 15;   // daha kısa kesintiler parazittir / shorter breaks are noise
5const float OBJECT_LENGTH_M = 0.0;       // cismin boyu biliniyorsa yaz (ör. 0.25) / object length if known (e.g. 0.25)
6
7int onLevel = 0, offLevel = 0;
8bool beamOk = true;
9unsigned long brokenSince = 0;
10unsigned long passCount = 0;
11
12int readAvg() {
13  long sum = 0;
14  for (int i = 0; i < 4; i++) sum += analogRead(LDR_PIN);  // 4 ölçüm yeterli ve hızlı / 4 readings: enough and fast
15  return sum / 4;
16}
17
18void calibrate() {
19  while (true) {
20    digitalWrite(LASER_PIN, LOW);
21    delay(300);
22    offLevel = readAvg();
23    digitalWrite(LASER_PIN, HIGH);
24    delay(300);
25    onLevel = readAvg();
26    if (abs(onLevel - offLevel) >= 100) return;
27    Serial.println(F("Isin LDR'ye ulasmiyor / Beam misses the LDR"));
28    delay(2000);
29  }
30}
31
32int beamPercent() {
33  return (long)(readAvg() - offLevel) * 100 / (onLevel - offLevel);
34}
35
36void setup() {
37  Serial.begin(9600);
38  pinMode(LASER_PIN, OUTPUT);
39  calibrate();
40  Serial.println(F("Sayac hazir / Counter ready"));
41}
42
43void loop() {
44  unsigned long now = millis();
45  int pct = beamPercent();
46
47  if (beamOk && pct < 40) {
48    beamOk = false;
49    brokenSince = now;                   // kesilme anı / moment of the break
50  } else if (!beamOk && pct > 60) {
51    beamOk = true;
52    unsigned long blocked = now - brokenSince;   // ışın ne kadar kesik kaldı / how long the beam was blocked
53    if (blocked >= MIN_BREAK_MS) {
54      passCount++;
55      Serial.print(F("Gecis / Pass #"));
56      Serial.print(passCount);
57      Serial.print(F("  Sure / Time: "));
58      Serial.print(blocked);
59      Serial.print(F(" ms"));
60      if (OBJECT_LENGTH_M > 0) {
61        float speed = OBJECT_LENGTH_M / (blocked / 1000.0);  // v = L / t
62        Serial.print(F("  Hiz / Speed: "));
63        Serial.print(speed, 2);
64        Serial.print(F(" m/s"));
65      }
66      Serial.println();
67    }
68  }
69}

Чтобы знать, в какую сторону идёт человек, используй два параллельных луча на расстоянии 10–15 см. Если сначала прерывается внешний луч A, а затем внутренний B, человек входит; если сначала B, а затем A — выходит. Если прерывается только A и луч возвращается, а B так и не прерывается, значит, человек подошёл к двери и передумал, и это не считается. Число людей внутри получается вычитанием выходов из входов, и его можно показать на 7-сегментном индикаторе или LCD-дисплее с I2C. Расстояние между лучами должно быть достаточно маленьким, чтобы тело человека перекрывало оба луча одновременно.

Таймер забега и измерение скорости

Измерение времени между двумя лазерными воротами даёт точный секундомер для бега, велосипеда, игрушечных машинок или физических опытов. Ворота старта и финиша ставят на известном расстоянии (d) друг от друга, а скорость равна v = d / t. Кто пробегает 10-метровую дорожку за 2,5 секунды, бежит со скоростью 4 м в секунду, то есть 14,4 км/ч. Чтобы включать и выключать оба лазера вместе, подключи пин − каждого к коллектору одного транзистора 2N2222 или S8050; пины S и средние пины соедини с 5V, эмиттер транзистора — с GND, а базу — с D7 через 1 kΩ. LDR ворот старта идёт на A0, а ворот финиша — на A1.

C++ (Arduino IDE)
1// İki lazer kapılı yarış zamanlayıcı ve hız ölçer / Two-gate laser race timer and speed meter
2const int LASER_PIN = 7;                 // iki lazer tek transistörle / both lasers through one transistor
3const int START_LDR = A0;                // başlangıç kapısı / start gate
4const int FINISH_LDR = A1;               // bitiş kapısı / finish gate
5const int BUZZER_PIN = 8;                // aktif buzzer / active buzzer
6const float DISTANCE_M = 10.0;           // kapılar arası mesafe (metre) / distance between the gates (m)
7const unsigned long TIMEOUT_MS = 60000;  // 60 sn'de bitmezse iptal / cancel after 60 s
8
9int onA, offA, onB, offB;
10enum State { READY, RUNNING, DONE };
11State state = READY;
12unsigned long startUs = 0;
13unsigned long startMs = 0;
14unsigned long doneMs = 0;
15
16int readAvg(int pin) {
17  long sum = 0;
18  for (int i = 0; i < 4; i++) sum += analogRead(pin);
19  return sum / 4;
20}
21
22bool isBroken(int pin, int on, int off) {
23  long pct = (long)(readAvg(pin) - off) * 100 / (on - off);
24  return pct < 40;                       // %40'ın altı = kesik / below 40% = broken
25}
26
27void calibrate() {
28  while (true) {
29    digitalWrite(LASER_PIN, LOW);        // iki lazer de kapalı / both lasers off
30    delay(300);
31    offA = readAvg(START_LDR);
32    offB = readAvg(FINISH_LDR);
33    digitalWrite(LASER_PIN, HIGH);       // iki lazer de açık / both lasers on
34    delay(300);
35    onA = readAvg(START_LDR);
36    onB = readAvg(FINISH_LDR);
37    if (abs(onA - offA) >= 100 && abs(onB - offB) >= 100) return;
38    Serial.println(F("Kapilardan biri hizali degil / One gate is misaligned"));
39    delay(2000);
40  }
41}
42
43void beep(int ms) {
44  digitalWrite(BUZZER_PIN, HIGH);
45  delay(ms);
46  digitalWrite(BUZZER_PIN, LOW);
47}
48
49void setup() {
50  Serial.begin(9600);
51  pinMode(LASER_PIN, OUTPUT);
52  pinMode(BUZZER_PIN, OUTPUT);
53  calibrate();
54  Serial.println(F("Hazir: baslangic kapisini gec / Ready: cross the start gate"));
55}
56
57void loop() {
58  if (state == READY && isBroken(START_LDR, onA, offA)) {
59    startUs = micros();                  // zamanı hemen al / grab the time immediately
60    startMs = millis();
61    state = RUNNING;
62    beep(30);
63  } else if (state == RUNNING) {
64    if (isBroken(FINISH_LDR, onB, offB)) {
65      unsigned long elapsedUs = micros() - startUs;
66      float seconds = elapsedUs / 1000000.0;
67      float speed = DISTANCE_M / seconds;            // v = d / t
68      Serial.print(F("Sure / Time: "));
69      Serial.print(seconds, 3);
70      Serial.print(F(" s  Hiz / Speed: "));
71      Serial.print(speed, 2);
72      Serial.print(F(" m/s = "));
73      Serial.print(speed * 3.6, 1);
74      Serial.println(F(" km/h"));
75      beep(300);
76      state = DONE;
77      doneMs = millis();
78    } else if (millis() - startMs > TIMEOUT_MS) {
79      Serial.println(F("Zaman asimi / Timeout"));
80      state = READY;
81    }
82  } else if (state == DONE && millis() - doneMs > 3000 &&
83             !isBroken(START_LDR, onA, offA) && !isBroken(FINISH_LDR, onB, offB)) {
84    state = READY;                       // 3 sn sonra yeni tur / new run after 3 s
85    Serial.println(F("Hazir / Ready"));
86  }
87}

Скетч работает как конечный автомат: в состоянии READY (готовность) он при прерывании стартового луча запоминает время через micros() и переходит в RUNNING (забег); при прерывании финишного луча выводит прошедшее время и скорость, а через 3 секунды готовится к следующему забегу. Если финишные ворота не пройдены за 60 секунд, забег отменяется. Честно о точности: сам код измеряет с разрешением лучше 1 мс, но LDR реагирует на темноту за 10–30 мс. К счастью, на обоих воротах стоит LDR одного типа, поэтому эта задержка возникает на обоих концах и в основном взаимно компенсируется; для бега и велосипеда результата более чем достаточно.

Для быстрых предметов, которые перекрывают луч меньше чем на 50 мс (брошенный мяч, быстрая игрушечная машинка), LDR не хватает: луч возвращается раньше, чем показание успевает упасть. В таком случае вместо LDR используй фототранзистор или фотодиод, которые реагируют за микросекунды, подключи выход к цифровому пину и фиксируй время через прерывание. Почему время лучше отсчитывать через millis() и micros(), а не через delay(), узнаешь из руководства millis и delay.

Уведомления на телефон с ESP32 (Telegram)

Чтобы сигнализация приносила пользу, когда дома никого нет, можно использовать ESP32: в момент прерывания луча она отправляет сообщение на телефон через Telegram. Подключение — как в таблице выше: лазер питается от 5V и коммутируется NPN-транзистором, подключённым к GPIO 26, а делитель с LDR питается от 3V3 и подключён к GPIO 34. Этот выбор не случаен: пины ADC2 у ESP32 не работают при включённом Wi-Fi, поэтому аналоговые датчики всегда подключай к пинам ADC1 (GPIO 32–39). АЦП ESP32 12-битный и возвращает значения от 0 до 4095, поэтому минимальный калибровочный разрыв в коде — 400. Как создать бота и получить токен и chat ID, мы подробно разобрали в руководстве Telegram-бот на ESP32; для скетча установи библиотеки UniversalTelegramBot и ArduinoJson через «Менеджер библиотек».

C++ (Arduino IDE)
1// ESP32 lazer bariyeri + Telegram bildirimi / ESP32 laser tripwire + Telegram notification
2#include <WiFi.h>
3#include <WiFiClientSecure.h>
4#include <UniversalTelegramBot.h>        // ArduinoJson kütüphanesi de gerekir / also needs the ArduinoJson library
5
6const char* WIFI_SSID = "WIFI_ADI";      // Wi-Fi ağının adı / your Wi-Fi name
7const char* WIFI_PASS = "WIFI_SIFRESI";  // Wi-Fi şifren / your Wi-Fi password
8#define BOT_TOKEN "1234567890:ABCdefGhIJKlmNoPQRstuVWXyz"  // BotFather'dan / from BotFather
9#define CHAT_ID "123456789"              // senin chat ID'n / your chat ID
10
11const int LASER_PIN = 26;                // NPN transistör bazına 1 kΩ ile / to the NPN base via 1 kΩ
12const int LDR_PIN = 34;                  // ADC1 pini, Wi-Fi ile çalışır / ADC1 pin, works with Wi-Fi
13const int BUZZER_PIN = 25;               // aktif buzzer / active buzzer
14const unsigned long CONFIRM_MS = 30;     // en az bu kadar kesik kalmalı / must stay broken this long
15const unsigned long SIREN_MS = 5000;     // siren süresi / siren duration
16const unsigned long COOLDOWN_MS = 30000; // iki deneme arası en az 30 sn / at least 30 s between attempts
17
18WiFiClientSecure client;
19UniversalTelegramBot bot(BOT_TOKEN, client);
20
21int onLevel = 0, offLevel = 0;
22bool beamOk = true;
23bool counted = false;                    // bu kesinti sayıldı mı / has this break been counted
24unsigned long brokenSince = 0;
25bool sirenOn = false;
26unsigned long sirenStart = 0;
27unsigned long breakCount = 0;
28bool pending = false;                    // gönderilecek bildirim var / a notification is waiting
29bool triedOnce = false;
30unsigned long lastTry = 0;
31
32int readAvg() {
33  long sum = 0;
34  for (int i = 0; i < 16; i++) sum += analogRead(LDR_PIN);  // 16 ölçüm ortalaması / average of 16 readings
35  return sum / 16;
36}
37
38void calibrate() {
39  while (true) {
40    digitalWrite(LASER_PIN, LOW);        // lazer kapalı = kesik ışın / laser off = broken beam
41    delay(300);
42    offLevel = readAvg();
43    digitalWrite(LASER_PIN, HIGH);       // lazer açık = sağlam ışın / laser on = intact beam
44    delay(300);
45    onLevel = readAvg();
46    Serial.printf("Isinli / beam: %d  Isinsiz / no beam: %d\n", onLevel, offLevel);
47    if (abs(onLevel - offLevel) >= 400) return;   // 12 bit ölçekte yeterli fark / enough gap on the 12-bit scale
48    Serial.println("Isin LDR'ye ulasmiyor / Beam misses the LDR");
49    delay(2000);
50  }
51}
52
53int beamPercent() {
54  return (long)(readAvg() - offLevel) * 100 / (onLevel - offLevel);
55}
56
57void setup() {
58  Serial.begin(115200);
59  pinMode(LASER_PIN, OUTPUT);
60  pinMode(BUZZER_PIN, OUTPUT);
61  calibrate();
62
63  WiFi.mode(WIFI_STA);
64  WiFi.begin(WIFI_SSID, WIFI_PASS);
65  client.setCACert(TELEGRAM_CERTIFICATE_ROOT);    // api.telegram.org kök sertifikası / root certificate
66  unsigned long start = millis();
67  while (WiFi.status() != WL_CONNECTED && millis() - start < 15000) {  // en fazla 15 sn bekle / wait up to 15 s
68    delay(500);
69    Serial.print(".");
70  }
71  if (WiFi.status() == WL_CONNECTED) {
72    Serial.println(WiFi.localIP());
73    bot.sendMessage(CHAT_ID, "Lazer alarmi devrede / Laser alarm armed", "");
74  }
75}
76
77void loop() {
78  unsigned long now = millis();
79  int pct = beamPercent();
80
81  if (beamOk && pct < 40) {              // ışın yeni kesildi / beam just broke
82    beamOk = false;
83    counted = false;
84    brokenSince = now;
85  } else if (!beamOk && pct > 60) {
86    beamOk = true;                       // ışın geri geldi / beam restored
87  }
88
89  if (!beamOk && !counted && now - brokenSince >= CONFIRM_MS) {
90    counted = true;                      // her kesinti bir kez sayılır / each break counts once
91    breakCount++;
92    pending = true;
93    sirenOn = true;
94    sirenStart = now;
95    Serial.printf("Kesinti / Break #%lu\n", breakCount);
96  }
97
98  if (sirenOn && now - sirenStart >= SIREN_MS) sirenOn = false;
99  digitalWrite(BUZZER_PIN, (sirenOn && (now / 200) % 2) ? HIGH : LOW);  // kesik siren / beeping siren
100
101  if (pending && (!triedOnce || now - lastTry >= COOLDOWN_MS)) {
102    triedOnce = true;
103    lastTry = now;
104    if (WiFi.status() == WL_CONNECTED) {
105      String text = "Lazer bariyeri kesildi! / Laser beam broken! Toplam / Total: " + String(breakCount);
106      if (bot.sendMessage(CHAT_ID, text, "")) pending = false;  // gitmezse 30 sn sonra yeniden / retry in 30 s if it fails
107    } else {
108      WiFi.reconnect();                  // bağlantı koptuysa yeniden dene / reconnect if the link dropped
109    }
110  }
111}

Каждое прерывание считается один раз, сирена звучит 5 секунд, а уведомление ставится в очередь. Отправка уведомлений пробуется не чаще раза в 30 секунд; новые прерывания за это время добавляются к общему числу и появляются в следующем сообщении. Так телефон не завалит сообщениями, пока кто-то ходит туда-сюда через луч. Если сообщение не отправилось, код пробует снова через 30 секунд, а если Wi-Fi отвалился, начинает переподключаться. sendMessage() занимает секунду-две, потому что открывает защищённое соединение HTTPS; в это время рисунок сирены замирает и луч не отслеживается — это нормально.

Лазерный барьер на Raspberry Pi Pico с MicroPython

На Raspberry Pi Pico ту же логику можно собрать в несколько строк MicroPython. Лазер питается от VBUS (USB 5 V, пин 40) и коммутируется NPN-транзистором, подключённым к GP15; делитель с LDR питается от пина 3V3(OUT) и подключён к GP26 (ADC0), а активный зуммер идёт на GP14. АЦП Pico через read_u16() возвращает значения от 0 до 65535, поэтому минимальный калибровочный разрыв — 6000. В коде тот же расчёт процентов, гистерезис и время подтверждения; он считает каждое прерывание, включает сирену на 5 секунд и выводит, сколько времени луч был перекрыт. Чтобы Pico работала без компьютера, сохрани файл на плату под именем main.py через Thonny.

MicroPython
1# Raspberry Pi Pico lazer bariyeri: alarm + geçiş sayacı / Laser barrier: alarm + pass counter
2from machine import Pin, ADC
3import time
4
5laser = Pin(15, Pin.OUT)        # NPN transistör bazına 1 kΩ ile / to the NPN base via 1 kΩ
6ldr = ADC(26)                   # GP26 = ADC0, bölücü 3V3'ten / divider fed from 3V3
7buzzer = Pin(14, Pin.OUT)       # aktif buzzer / active buzzer
8
9CONFIRM_MS = 30                 # en az bu kadar kesik kalmalı / must stay broken this long
10SIREN_MS = 5000                 # siren süresi / siren duration
11
12
13def read_avg(n=8):
14    total = 0
15    for _ in range(n):
16        total += ldr.read_u16()
17    return total // n
18
19
20def calibrate():
21    while True:
22        laser.value(0)          # lazer kapalı = kesik ışın / laser off = broken beam
23        time.sleep_ms(300)
24        off = read_avg(32)
25        laser.value(1)          # lazer açık = sağlam ışın / laser on = intact beam
26        time.sleep_ms(300)
27        on = read_avg(32)
28        print("Isinli / beam:", on, " Isinsiz / no beam:", off)
29        if abs(on - off) > 6000:          # 16 bit ölçekte yeterli fark / enough gap on the 16-bit scale
30            return on, off
31        print("Isin LDR'ye ulasmiyor / Beam misses the LDR")
32        time.sleep(2)
33
34
35on_level, off_level = calibrate()
36beam_ok = True
37counted = False
38broken_at = time.ticks_ms()
39siren_until = time.ticks_ms()
40count = 0
41
42while True:
43    now = time.ticks_ms()
44    pct = (read_avg() - off_level) * 100 // (on_level - off_level)   # 100 = ışın tam / full beam
45
46    if beam_ok and pct < 40:            # ışın yeni kesildi / beam just broke
47        beam_ok = False
48        counted = False
49        broken_at = now
50    elif not beam_ok and pct > 60:      # ışın geri geldi / beam restored
51        beam_ok = True
52        print("Kesik kaldigi sure / blocked for", time.ticks_diff(now, broken_at), "ms")
53
54    if not beam_ok and not counted and time.ticks_diff(now, broken_at) >= CONFIRM_MS:
55        counted = True                  # her kesinti bir kez sayılır / each break counts once
56        count += 1
57        siren_until = time.ticks_add(now, SIREN_MS)
58        print("Gecis / Pass:", count)
59
60    siren = time.ticks_diff(siren_until, now) > 0
61    buzzer.value(1 if siren and (now // 200) % 2 else 0)   # kesik siren / beeping siren

Идеи проектов с лазерным модулем

  • Лазерная домашняя сигнализация: объедини лучи у двери и в коридоре с PIR-датчиком движения и сведи все входы в один блок управления; подробности — в руководстве охранная сигнализация на Arduino.
  • Лазерная арфа: поставь рядом 5–7 лучей и при прерывании каждого играй свою ноту на пассивном зуммере.
  • Счётчик посетителей: раздели входы и выходы двумя лучами и показывай число людей внутри на дисплее.
  • Измеритель скорости для научной выставки: двумя воротами измеряй скорость предметов, скатывающихся по наклонной плоскости, и сравнивай трение; больше идей — в руководстве идеи проектов для научных выставок.
  • Игра «лазерный лабиринт»: построй зеркалами сеть лучей ниже уровня колена; засекай время игроков, которые пытаются пройти её, не задев, и начисляй штраф за каждое касание.
  • Охрана ящика и сейфа: фиксируй прерывание луча при открывании крышки и отправляй уведомление на телефон с ESP32.

Частые ошибки и как их исправить

СимптомВероятная причинаРешение
Лазер совсем не горитПерепутаны S и −, или плата, у которой средний пин требует питанияПроверь маркировку пинов, подключи средний пин к 5V и попробуй ещё раз
Лазер очень тусклыйМодуль питается от 3,3 V, или пин не даёт достаточно токаПитай лазер от 5V и коммутируй транзистором
Сообщение «Isin LDR'ye ulasmiyor» (луч не попадает на LDR)Точка не на LDR, или внешний свет слишком сильныйНайди точку с помощью бумаги и помести LDR в чёрную трубку
Сигнализация звучит без остановкиСбилась юстировка, шатается лазер или зеркалоНадёжно закрепи держатели и следи за показанием в плоттере
Сигнализация никогда не срабатываетДаже при прерванном луче солнце или лампа держат LDR освещённымДобавь трубку и отверни датчик от окна
Быстрые проходы не считаютсяВремя отклика LDR (10–30 мс) слишком великоУменьши CONFIRM_MS и MIN_BREAK_MS или используй фототранзистор
Arduino перезагружается или пин нагреваетсяНесколько лазеров питаются от одного пинаПитай лазеры от 5V и коммутируй транзистором
На ESP32 показание сбивается при запуске Wi-FiLDR подключён к пину ADC2Перенеси LDR на пин ADC1 в диапазоне GPIO 32–39
Сообщения в Telegram не приходятНеверный токен или chat ID, или боту ещё не писалиОтправь боту /start и ещё раз проверь токен и chat ID
После установки проверь систему в реальных условиях: затемни комнату, включи свет, открой шторы и каждый раз записывай разрыв между показаниями с лучом и без луча в мониторе порта. Если даже в худшем случае разрыв остаётся выше 100, барьер надёжен. Считай этот проект учебной и любительской сигнализацией; профессиональные охранные системы используют невидимые инфракрасные лучи и приёмники модулированного сигнала.

Лазерный модуль KY-008 открывает путь к одному из редких проектов, которые одной дешёвой деталью учат сразу оптике, делителям напряжения, калибровке и измерению времени. Начни с того, чтобы увидеть разрыв в тестовом скетче, затем собери сигнализацию и развивай проект зеркалами, счётчиком и таймером. В приложении BlueGrays есть пошаговые проекты «Лазерная сигнализация», «Лазерная охранная система», «Измерение освещённости с LDR», «Ночник на LDR» и «Сигнализация движения на ESP32 (PIR + зуммер + светодиод + Telegram)» со схемами и кодом.

Частые вопросы

Какое напряжение нужно лазерному модулю KY-008?

KY-008 рассчитан на 5 V, и благодаря токоограничивающему резистору модуля его можно подключать прямо к цифровому пину Arduino Uno. При 3,3 V он тоже светится, но тусклее. Никогда не подавай на модуль больше 5 V и никогда не питай лазерный диод без его резистора.

Может ли лазер на 5 mW повредить глаза?

Красный лазер на 5 mW относится к классу 3R: короткое случайное попадание в глаз обычно не оставляет стойких повреждений, но если смотреть в луч или поймать глазом отражение от зеркала, можно повредить сетчатку. Держи луч ниже уровня глаз, никогда не направляй его на людей или животных и в схемах с зеркалами проверяй весь путь луча.

На каком расстоянии работает лазерная сигнализация?

Расстояние ограничивают скорее юстировка и внешний свет, чем мощность лазера. С прочными держателями и LDR в чёрной трубке в помещении всё нормально работает на 10–20 м; на больших расстояниях точка растёт, и на LDR попадает меньше света. На улице солнце, туман и тряска от ветра заметно сокращают дальность.

Чем заменить LDR в лазерном барьере?

LDR дешёвый и простой, но его время отклика — 10–30 мс. Для таймеров и счётчиков, которым нужно более быстрое измерение, используют фототранзистор или фотодиод, которые реагируют за микросекунды. Есть и готовые модули лазерных приёмников: при попадании света они дают цифровой сигнал и подключаются прямо к цифровому пину.

Работает ли лазерный модуль с ESP32 и Raspberry Pi Pico?

Да, но вместо питания лазера прямо от пина лучше подавать на него 5V и коммутировать NPN-транзистором: пины Pico по умолчанию дают всего 4 mA. На этих платах питай делитель с LDR от 3V3, а на ESP32 используй пин ADC1 (GPIO 32–39), который работает вместе с Wi-Fi.

Инфракрасный барьер лучше лазерной сигнализации?

Профессиональные охранные системы используют невидимые инфракрасные лучи и приёмники модулированного сигнала: луч невозможно заметить, а модуляция делает его почти нечувствительным к солнечному свету. Красный лазер, напротив, виден, поэтому его очень легко выравнивать, и это делает его идеальным для учебных проектов, счётчиков и таймеров.

Все проекты
Измерение освещённости с LDR
#11Новичок

Измерение освещённости с LDR

Хочешь увидеть яркость своей комнаты в виде числа? LDR — маленькая деталь, реагирующая на свет, — измеряет освещённость вокруг, а Arduino каждые полсекунды выводит значение на экран компьютера. Закрой

4.6(81)
139
Ночник на LDR
#12Новичок

Ночник на LDR

Маленький ночник, который сам включается, когда темнеет, и гаснет, когда наступает утро. Датчик освещённости измеряет, насколько светло в комнате, и Arduino включает светодиод, когда достаточно темно,

4.8(102)
205
Измерение освещённости модулем LDR на ESP32
#113Новичок

Измерение освещённости модулем LDR на ESP32

Наблюдение в мониторе порта в реальном времени за сырым значением ADC модуля LDR и относительным процентом освещённости, вычисленным по опорным значениям темноты и света. Этот процент — не измерение в люксах. Учит логике калибровки модуля. Идеально выполнить его перед проектом 10, потому что он нужен для определения порога.

4.6(36)
55
Лазерная сигнализация
#22Средний
Premium

Лазерная сигнализация

Ты ставишь невидимую лучевую ограду, совсем как в кино. Лазер светит на датчик освещённости с другой стороны; как только кто-то проходит и прерывает луч, загорается светодиод и звучит зуммер, а когда

4.8(64)
83
Лазерная охранная система
#23Продвинутый
Premium

Лазерная охранная система

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

4.8(60)
77
Ночник на LDR с ESP32
#112Новичок
Premium

Ночник на LDR с ESP32

Ночник, в котором светодиод сам загорается в темноте и гаснет на свету. Используется пин D0 (цифровой выход) модуля датчика LDR — порог темноты задаётся маленьким потенциометром на модуле, а выход HIGH/LOW формирует сам модуль. ESP32 просто читает этот сигнал через digitalRead(), код очень простой.

4.6(17)
30
Сигнализация движения на ESP32 (PIR + зуммер + светодиод + Telegram)
#145Продвинутый
Premium

Сигнализация движения на ESP32 (PIR + зуммер + светодиод + Telegram)

Умная охранная сигнализация, которая при обнаружении движения PIR-датчиком включает зуммер и светодиод и одновременно сразу отправляет владельцу уведомление в Telegram. В ней есть 30-секундная пауза, ограничивающая частоту повторных тревог; этот механизм не проверяет срабатывания PIR и не устраняет ложные тревоги. Подходит для дома, гаража, склада или мастерской. С ESP32-CAM можно добавить уведомления с фото, а с обычной ESP32 DevKit V1 приходят текстовые.

0.0(0)
9