Урок 10. Радиосвязь на 433 MHz. Охранная система



  • Цель урока

    Привет! Сегодня мы сделаем несложную охранную систему с использованием пары радиомодулей (FS1000A и MX-JS-05V), которая работает на частоте 433 МГц (в зависимости от вашего региона частоты могут несколько отличаться) (рис. 1 - 1.1). Научимся делать своими руками беспроводной датчик проникновения на базе модуля HC-SR501.

    Рисунок 1.

    Рисунок 1.1

    В качестве центра системы будет выступать M5STACK с подключенным радиоприемником и красным световым маячком.

    Беспроводной датчик проникновения сделаем своими руками. Датчик будет подключен к цепи постоянного тока напряжением 5 В. При отключении датчика от цепи питания или при удалении за радиус действия беспроводной сети центральное устройство начнёт сигнализировать миганием маячка и подачей звукового сигнала.

    Также будет возможность приостановки охраны с помощью центральной кнопки на заданный интервал.

    Перечень компонентов для урока

    • M5STACK;
    • кабель USB-C из стандартного набора;
    • цветные провода из стандартного набора (тип розетка-вилка);
    • цветные провода не из стандартного набора (тип розетка-розетка);
    • радиоприёмник MX-JS-05V;
    • световой маячок. Напряжение питания: 5 В;
    • радиопередатчик FS1000A;
    • телескопическая антенна. Длинна: 17.3 см;
    • модуль датчика движения HC-SR501;
    • Arduino Nano;
    • вилка штырьевая PLS-10;
    • светодиод оранжевый. Напряжение питания: 3.3 В;
    • резистор: 220 Ом;
    • термоклей;
    • паяльник и припой;
    • дрель;
    • сверло. Диаметр: 2 мм;
    • сверло. Диаметр: 3.5 мм;
    • сверло. Диаметр: 5 мм;
    • сверло перьевое. Диаметр: 23 мм;
    • маркер или фломастер;
    • линейка;
    • штангенциркуль.

    Немного теории

    Сегодня мы не представляем себе жизни без радиосвязи. Когда мы подъезжаем к своему дому мы используем пульт дистанционного управления для того, чтобы открыть гаражные ворота. Когда к нам приходят гости они нажимают на беспроводную кнопку для того, чтобы подать звонок. Когда мы гуляем по торговому центру мы спокойны за наш автомобиль. И это всего лишь нечтожная доля примеров. Главное то, что это объединяет - дециметровый диапазон (в нашем случаее 433 МГц). Благодаря трудам замечательных инженернов и программистов мы можем с легкостью использовать такую радиосвязь в наших проектах (рис. 2).

    Рисунок 2. Передатчик - слева, приёмник - справа

    Давайте ознакомимся с техническими характеристиками данной пары:

    • напряжение питания передатчика: 3 – 12 В;
    • напряжение питания приемника: 5 В;
    • несущая частота: 433 МГц;
    • потребляемый ток передатчиков: 8 мА;
    • потребляемый ток приемником: 4.5 мА;
    • чувствительность приемника: от −106 до -110 дБм;
    • выходная мощность передатчика: 32 мВт;
    • максимальная пропускная способность передатчика: 8 кб/с;
    • максимальная пропускная способность приемника: 5 кб/с;
    • диапазон рабочих температур: от −20 до 80 °C.

    Теперь давайте рассмотрим модуль датчика движения HC-SR501 (рис. 2.1).

    Рисунок 2.1. Модуль датчика движения HC-SR501

    Принцип работы модуля HC-SR501 заключается в регистрации инфракрасного излучения от подвижного объекта. Чувствительный элемент – пироэлектрический датчик 500BP. Он состоит из двух элементов заключенных в одном корпусе. Чувствительный элемент закрыт белым куполом – линзой Френеля. Особенности линзы Френеля таковы, что инфракрасное излучение от подвижного объекта попадает сначала на один элемент датчика 500BP, затем на другой. Микросхема отслеживает изменение сигнала от датчика и формирует логический сигнал на выходе согласно параметрам заданным переменными резисторами и перемычкой (рис. 2.2).

    Рисунок 2.2.

    В режиме L на выходе устанавливается высокий уровень при первичной регистрации движения. Высокий уровень на выходе остается во время работы таймера, которое установлено подстроечным резистором "Time adjust". В это время датчик не реагирует на другие события.
    В режиме H каждый перемещающийся объект перезапускает таймер. Это означает, что при первом зафиксированном объекте на выходе датчика присутствия HC-SR501 формируется высокий уровень и поддерживается, пока регистрируется наличие движений в зоне обнаружения.
    С помощью подстроечного резистора "Sensitivity" вы можете изменять чувствительность модуля, тем самым изменять радиус охвата.

    Начнём!

    Шаг 1. Нарисуем схему беспроводного датчика движения

    Мозгом датчика сделаем недорогую плату Arduino Nano, она удобна прежде всего доступностью на рынке сегодня. К ней мы подключим светодиод на контакт D3, радиопередатчик FS1000A на контакт D4 и модуль движения HC-SR501 на контакт D5. Питание всех модулей будем производить от Arduino Nano с контакта 5V. Саму плату Arduino мы будем питать от цепи постоянного тока напряжением 5 В на контакт VIN. Земля для всех устройств общая, подтянута на контакт GND. Таким образом получим следующую схему включения (рис. 3).

    Рисунок 3. Схема включения модулей беспроводного датчика движения

    Шаг 2. Выберем подходящий корпус

    В качестве корпуса Вы можете использовать, например: пластмассовую распределительную коробку от сети электропитания (можно найти в магазине электротоваров) (рис. 4). В нашем случае размеры корпуса 70 x 70 x 29 мм.

    Рисунок 4.

    Будущее расположение модулей хорошо отображено на рисунке 3. Более подробно поговорим об этом на следующих шагах данного урока.

    Шаг 3. Подготовка к работе

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

    Внимание! Производите действия под наблюдением взрослых и соблюдайте технику безопасности.

    Ознакомьтесь с чертежом, отображающий расположение отверстий в корпусе нашего будущего устройства на рисунке 5.

    Рисунок 5. Чертёж

    Шаг 4. Монтаж модуля датчика движения

    С помощью линейки отмерьте необходимое расстояние и нанесите точку с помощью маркера, возьмите дрель, установите сверло диаметром 3.5 мм и сделайте отверстите (рис. 6).

    Рисунок 6. Сверление отверстия диаметром 3.5 мм

    Теперь установите перьевое сверло диаметром 23 мм и поверх рассверлите большее отверстие (рис. 6.1).

    Рисунок 6.1. Сверление отверстия диаметром 23 мм

    После того, как отверстие будет рассвелено очистите корпус от пластмассовой стружки (рис. 6.2 - 6.3).

    Рисунок 6.2.

    Рисунок 6.3. Модуль готов к установке

    Переверните корпус установите ровно модуль и зафиксируйте его с помощью термоклея (рис. 6.4 - 6.5).

    Рисунок 6.4

    Рисунок 6.5

    На этом монтаж модуля датчика движения завершён.

    Шаг 5. Монтаж модуля радиопередатчика и антенны

    Аналогичным образом с помощью линейки отмерьте необходимое расстояние и нанесите точку с помощью маркера, возьмите дрель, установите сверло диаметром 2 мм и сделайте отверстите (рис. 7 - 7.1).

    Рисунок 7. Сверление отверстия диаметром 2 мм

    Рисунок 7.1

    Припаяйте проводник с кольцом на конце к отверстию на модуле с надписью ANT (рис. 7.2).

    Рисунок 7.2

    Прикрутите винт и шайбу на проводник (рис. 7.3).

    Рисунок 7.3

    Установите модуль в корпус и зафиксируйте с помощью термоклея (рис. 7.4). С обратной стороны корпуса удерживайте телескопическую антенну.

    Рисунок 7.4

    На этом установка радиопередатчика и антенны завершена.

    Шаг 6. Отверстия в боковой стенке

    Сделайте отверстия в боковой стенке и установите в них кабель типа (розетка-вилка) (рис. 8 - 8.1) и светодиод.

    Рисунок 8. Сверление отверстия диаметром 3.5 мм

    Рисунок 8.1. Сверление отверстия диаметром 5 мм

    Укоротите одну из ножек (+) светодиода и припаяйте резистор номиналом 220 Ом. Используйте термоусадку для изоляции (рис. 8.2).


    Рисунок 8.2.

    Далее установите светодиод в корпус (рис. 8.3).


    Рисунок 8.3.

    На этом монтаж светодиода и проводов питания завершён.

    Шаг 7. Делаем ответвители проводов

    Возьмите и откусите с помощью кусачиков вилку типа PLS-10 напополам. С помощью отрезанных ножек от ненужных радиокомпонентов припаяйте перемычки, чтобы все контакты стали замкнуты (рис. 9). Должно получиться два множителя.


    Рисунок 9.

    Шаг 8. Монтаж Arduino Nano и проводов

    Завершающим моментом является установка ардуино и монтаж всех проводников. Используйте множители для цепи питания и земли. Чтобы провода не занимали много места - накрутите их на маркер (рис. 10).


    Рисунок 10.

    Выполните соединение всех проводников (рис. 10.1) согласно схеме включения на рисунке 3.

    Рисунок 10.1

    На этом монтаж полностью завершён (рис. 10.2).

    Рисунок 10.2

    Шаг 9. Пишем скетч для беспроводного датчика

    Для работы с FS1000A на просторах интернета существует множество различных вариантов библиотек. Я предлагаю использовать библиотеку, написанную замечательными ребятами с сайта iarduino.ru. Сложного в использовании ничего особо нет. Инициализируем экземпляр класса, передав ему номер контакта, на который подключён радиоприёмник iarduino_RF433_Transmitter radioTX(radio); С помощью метода radioTX.begin(1000); устанавливаете скорость передачи в бит/с. Ещё разработчик добавил возможность организации "труб", как бы каналов, по которым будут передаваться данные не мешая друг-другу. Число труб можно изменять в любом месте кода от 0 до 7. radioTX.openWritingPipe(0);

    #include <iarduino_RF433_Transmitter.h> 
    
    int led = 3;                 
    int radio = 4;
    int pir = 5;    
    String sensorId = "ir-1";
    unsigned long prevTime = 0;
    iarduino_RF433_Transmitter radioTX(radio);              
    
    void sendString(String str) {
      int len = str.length() + 1;
      char bfr[len];  
      str.toCharArray(bfr, len);
      int n = 24 / str.length();
      for (int i = 0; i < n; i++)
      {
        radioTX.write(&bfr, sizeof(bfr)); 
      }
    }
    
    void setup() {
      pinMode(led, OUTPUT);    
      pinMode(pir, INPUT);
      prevTime = 0;  
      radioTX.begin(1000);
      radioTX.openWritingPipe(0);    
    }
     
    void loop() {
      if (digitalRead(pir) == LOW)
      {
        if ((millis() - prevTime) >= 3000)
        {
          prevTime = millis();
          sendString(sensorId + String((char)0x1d) + "LOW");
          digitalWrite(led, HIGH);
          delay(70);
          digitalWrite(led, LOW);
          delay(30);
        }
      }
      else
      {
        sendString(sensorId + String((char)0x1d) + "HIGH");
        digitalWrite(led, HIGH);
        delay(25);
        digitalWrite(led, LOW);
        delay(25);
      } 
    }
    

    Я написал простенькую функцию для отправки строки до 24 символов. Если строка несколько короче, то она будет передаваться неоднократно. Это сделано с целью некоторой помехозащищенности.
    Принцип работы заключается в том, что датчик каждые 3000 мс отправляет свой sensorId + значение, полученное от модуля движения - LOW и мигает светодиодом. Если поступит сигнал HIGH, то датчик моментально начнёт рассылать соответствующий уровень и мигать светодимодом чаще.

    Можете подключить Arduino Nano и загрузить данный скетч.

    После чего крышку датчика можно закрывать.

    Шаг 10. Пишем скетч для беспроводного охранного центра

    Обратите внимание на различие между именами заголовочных файлов. Действия подготовки приёмника к работе похожи на действия подготовки передатчика. Поступление данных от одной из труб можно отследить с помощью метода radioRX.available(&k), где k - номер трубы. Чтение производится с помощью вызова метода radioRX.read(&j, sizeof(j));, где j - массив символов размером 24.

    #include <M5Stack.h>
    #include <iarduino_RF433_Receiver.h>
    
    int radio = 5;
    int beacon = 22;
    uint8_t k;
    char j[24];
    unsigned long currentTime;
    unsigned long prevTime = 0;
    extern unsigned char beacon_logo[];
    iarduino_RF433_Receiver radioRX(radio);
    
    void alaram() {
      while (true)
      {
        if (m5.BtnB.wasPressed()) break; 
        digitalWrite(beacon, HIGH);
        m5.Speaker.tone(800);
        delay(150);
        digitalWrite(beacon, LOW);
        m5.Speaker.mute();
        delay(150);
        m5.update();
      }
      digitalWrite(beacon, LOW);
      m5.Speaker.mute();
      m5.update();
      int suspendTime = 15;
      for ( ; suspendTime > 0; suspendTime--)
      {
        message("protection suspended " + String(suspendTime) + "s");
        delay(1000);
      } 
      message("At protecting...");
    }
    
    String parseString(int idSeparator, char separator, String str) { // like a split JS
      String output = "";
      int separatorCout = 0;
      for (int i = 0; i < str.length(); i++)
      {
        if ((char)str[i] == separator)
        {
          separatorCout++;
        }
        else
        {
          if (separatorCout == idSeparator)
          {
            output += (char)str[i];
          }
          else if (separatorCout > idSeparator)
          {
            break;
          }
        }
      }
      return output;
    }
    
    void message(String text) {
      M5.Lcd.fillRect(0, 160, 320, 30, 0x7bef);
      M5.Lcd.setCursor(10, 167);
      M5.Lcd.setTextColor(0xffff);
      M5.Lcd.print(text);
      M5.Lcd.setTextColor(0x7bef);
    }
    
    void setup() {
      m5.begin();
      M5.Lcd.fillRoundRect(0, 0, 320, 240, 7, 0xffff);
      M5.Lcd.setTextColor(0x7bef);
      M5.Lcd.setTextSize(2);
      M5.Lcd.drawBitmap(35, 70, 59, 59, (uint16_t *)beacon_logo);  
      M5.Lcd.setCursor(120, 70);
      M5.Lcd.print("RADIO 433 MHz");
      M5.Lcd.setCursor(120, 90);
      M5.Lcd.print("ALRAM SYSTEM");
      M5.Lcd.setCursor(120, 110);
      M5.Lcd.print("ON M5STACK");
      message("radio is starting");
      pinMode(beacon, OUTPUT);
      radioRX.begin(1000);              
      radioRX.openReadingPipe(0);
      radioRX.startListening();
    }
    
    void loop() { 
      if (radioRX.available(&k))
      {
        radioRX.read(&j, sizeof(j));
        delay(1);
        String sensorInfo = parseString(0, (char)0x1d, j);
        String sensorType = parseString(0, '-', sensorInfo);
        String sensorId = parseString(1, '-', sensorInfo);
        if (sensorType == "ir")
        {
          prevTime = millis();
          String data = parseString(1, (char)0x1d, j);
          if (data == "HIGH")
          {
            message("Attention for " + sensorInfo);
            alaram();
            prevTime = millis();
          }
          else
          {
            message("At protecting...");
          }
        }
      }
      
      if ((millis() - prevTime) >= 10000)
      {
        message("Sensor unavailable.");
        alaram();
        prevTime = millis();
      }
    }
    

    Принцип работы центра заключается в ожидании данных от датчика. Если данные не придут вовремя (в течении 10 с), то сработает сирена и маячок. Для приостановки охраны на 15 с используется нажатие кнопки B (центральной).

    Можете подключить M5STACK и загрузить данный скетч.

    После чего не забудьте подключить радиоприёмник и маячок к соответствующим контактам.

    Шаг 11. Запуск!

    В разделе "Download" прилагаются видео с демонстрацией работы. На этом урок завершён.

    ДОМАШНЕЕ ЗАДАНИЕ

    • Задание 1 уровня сложности: сделайте дополнительные отверстия под отвертку для регулировки резисторов на модуле датчика движения;
    • Задание 2 уровня сложности: сделайте различный звуковой и световой сигнал для разных типов тревоги: когда датчик не выходит на связь и когда датчик зафиксировал движение;
    • Задание 3 уровня сложности: добавьте дополнительный синий светодиод на датчик, сигнализирующий о недавнем движении (5 минут спустя, например);
    • Задание 4 уровня сложности: сделайте автоматическую генерацию уникальных адресов датчиков и автоматическую регистрацию их в охранном центре.

    Download