Статья Определяем кто дома с помощью ESP8266

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

1549988406227.png


Введение.
Функция этого проекта заключается в чтении близлежащего трафика Wi-Fi.Обнаруженные пакеты сравниваются со списком MAC-адресов, которые мы хотим отслеживать, и если MAC-адрес пакета соответствует одному в списке, мы включаем определенный светодиод, который связан с пользователем, владеющим устройством(в нашем случае - член семьи).

Например, когда кто-то из семьи возвращается домой, передача пакетов с его телефона будет обнаружена и заставит, например, синий светодиод включится.
Мы будем обнаруживать более одного устройства одновременно.

1549987434936.png


Смартфоны и другие устройства с поддержкой Wi-Fi отправляют радиосигналы, называемые зондирующими(пробными) кадрами(Probe Frame), для обнаружения близлежащих беспроводных сетей, что позволяет легко отслеживать их, прослушивая их уникальный MAC-адрес.
На эту тему было мною было написано несколько статей
- Пассивная слежка через WIFI с помощью Probequest
- Детектор деаутентификации (диссоциации) клиентов. Часть 2

Чтобы показать, как работает этот вид отслеживания, мы можем запрограммировать NodeMCU Arduino на прослушивание пакетов любого устройства, которое мы хотим отслеживать, включая светодиод, когда он обнаруживается поблизости.
Широкое отслеживание представляет собой серьезную проблему конфиденциальности, побуждая большинство производителей применять такие меры безопасности, как рандомизация MAC-адресов, которая защищает от произвольного мониторинга MAC-адресов.

Проблема рандомизиции MAC-адресов.

1549983484004.png


Рандомизация MAC-адресов полезна для предотвращения некоторых типов отслеживания, но в тестах на различных телефонах Android было выясненно, что рандомизация MAC-адресов далека от совершенства. Существует несколько условий, при которых телефон возвращается к своему реальному MAC-адресу.
После обнаружения знакомой сети, сохраненной в списке предпочтительных сетей, устройство попытается подключиться к сети и может стать доступным для отслеживания.

Помимо просмотра сети Wi-Fi в списке предпочтительных сетей, активное подключение к сети устройство также будет активно показывать(палить) свой постоянный MAC-адрес. Это означает, что если вы захотите отследить кого-то, приходящего домой или проходящего мимо кафе с общим именем сети, рандомизация MAC-адресов не помешает вам это сделать.

К сожалению, большинство Android устройств генерируют пакеты тестовых кадров, используя реальный MAC-адрес, каждый раз, когда вы включаете Wi-Fi или открываете меню выбора сети Wi-Fi.

Отслеживание с помощью Arduino.
Чтобы показать, как легко отслеживать устройства,мы будем использовать Arduino, который использует встроенный чип Wi-Fi для отслеживания MAC-адресов.
На самом деле уже существует проект - Friend Detector.
Этот удивительный проект берет любой MAC-адрес, который вы хотите отслеживать, и прослушивает пакеты, содержащие этот адрес. Это действительно круто, потому что Friend Detector просматривает типы пакетов, которые отправляют смартфоны как при подключении, так и при отключении от сети Wi-Fi, что облегчает обнаружение устройства в любом состоянии.

Чтобы сделать этот проект более наглядным и обеспечить легкий способ обнаружения, когда ваше устройство передает свой реальный MAC-адрес, я решил изменить код, включив в него несколько светодиодов и возможность отслеживать столько MAC-адресов, сколько имеется доступных контактов для управления светодиодами.
В нашем случае будем отслеживать 4 устройства.

Есть некоторые проблемы, которые нам нужно преодолеть при использовании светодиода, например, тот факт, что использование задержки для удержания светодиода в течение достаточно долгого времени, чтобы его можно было заметить, что таймер приводил к сбою в работе светодиодов(далее будет объяснена проблема).

Чтобы решить эту проблему, я добавил таймер, который включал бы светодиод при обнаружении пакета с совпадающим MAC-адресом и оставлял его включенным до тех пор, пока не будет обнаружено установленное количество пакетов, которые не соответствуют искомому MAC-адресу; Это позволяет нам легко изменять продолжительность работы светодиода.

Шаг 1. Поиск MAC-адреса устройства.
Сперва стоит определить какие устройства мы будем обнаруживать, для этого получим их MAC-адреса.
Лучший способ это подключиться к сети, в которой есть устройство, которое вы хотите отслеживать, и затем запустить сканирование сети с помощью Fing или Nmap.
Я лично поступил по старинке и заглянул в аренду DCHP адресов в настройках роутера.

1549984770799.png


Шаг 2. Необходимое оборудование.
После того, как мы получим необходимые MAC-адреса, нужно определиться что нам необходимо для построение “чудо-устройства”.
А нам необходимо иметь:
  • NodeMCU ESP8266.
  • Кабель Micro-USB.
  • Макетная плата.
  • Четырехконтактный трехцветный светодиод или столько светодиодов, сколько их требуется.
  • Компьютер с установленной Arduino IDE для программирования и прошивки.
  • Резистор(можно без него).

Шаг 3. Настройка IDE Arduino.
Прежде чем мы приступим к написанию кода, нам нужно настроить Arduino IDE для работы с NodeMCU. Для этого скопируйте следующий URL-адрес и вставьте его в поле - Файл - Настройки - Дополнительные ссылки для Менеджера плат:
  • , ,
Все эти ссылки необходимо вставить в поле Дополнительные ссылки для Менеджера плат.

1549985423131.png


Далее вам нужно добавить NodeMCU в Boards Manager .
Для этого вам нужно нажать «Инструменты», а затем навести курсор на раздел «Плата», чтобы увидеть раскрывающийся список поддерживаемых плат. Вверху нажмите «Менеджер плат», чтобы открыть окно, которое позволит нам добавить больше плат.
Когда откроется окно Boards Manager, введите «esp8266» в строку поиска. Выберите «esp8266» от «ESP8266 Community» и установите его, чтобы добавить поддержку NodeMCU в вашу Arduino IDE. Затем нужно выбрать «NodeMCU 1.0.».

1549985554367.png


1549985622441.png


Шаг 4. Скачиваем проект Friend Detector.
Затем мы можем скачать код для Friend Detector на GitHub , в форке оригинального проекта.
Ссылка: skickar/FriendDetector

Шаг 5. Смотрим код.
Чтобы понять, что делает этот код, давайте заглянем внутрь.
Первый раздел кода устанавливает переменные. Здесь мы определяем размер списка MAC-адресов, которые мы отслеживаем, фактические MAC-адреса в списке и имена целей, связанных с MAC-адресами в списке.

C-подобный:
uint8_t friendmac[LIST_SIZE][ESPPL_MAC_LEN] = {
  {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA} //blue
  , {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA} //green
  , {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA} //red
  , {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA} //yelow
};
/*
   This is your friend's name list
   put them in the same order as the MAC addresses
*/
String friendname[LIST_SIZE] = {
  "Sharp aquos s2" //blue
  , "Nexus 5" //green
  , "HTC" //red
  , "Onda" //yellow
};

Затем у нас есть раздел настроек, в котором мы устанавливаем выводы D5, D6, D7 и D8 для вывода, чтобы мы могли использовать их для управления светодиодами.

C-подобный:
pinMode(D5, OUTPUT);
pinMode(D6, OUTPUT);
pinMode(D7, OUTPUT);
pinMode(D8, OUTPUT);

Чтобы включить этот светодиод, нам просто нужно использовать функцию «digitalWrite (pin, mode)».
Наконец, у нас имеется функция под названием «turnoff ()», которые отключит все светодиоды, которые включены, если пакеты не обнаруживаются в течение достаточно долгого времени.
C-подобный:
void turnoff() {
  digitalWrite(D7, LOW), digitalWrite(D5, LOW), digitalWrite(D6, LOW), digitalWrite(D8, LOW);
}

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

Поэтому на данном этапе были добавлены свои таймеры для каждого устройства.
C-подобный:
int TimerBlue = 0;
int TimerGreen = 0;
int TimerRed = 0;
int TimerYellow = 0;

Теперь перейдем к той части кода, которая контролирует логику того, что происходит, когда мы обнаруживаем пакеты. Здесь мы видим строку, которая выглядит:
C-подобный:
for (int i=0; i<LIST_SIZE; i++) {
    if (maccmp(info->sourceaddr, friendmac[i]) || maccmp(info->receiveraddr, friendmac[i])) {

Здесь у нас имеется обычный цикл, который пытается сопоставить адреса отправителя и получателя в обнаруженном пакете с MAC-адресами в нашем списке(которые мы отслеживаем).

Вот фрагмент кода, который управляет тем, что происходит, когда мы обнаруживаем искомый MAC-адрес. Во-первых, мы видим, что мы печатаем имя устройства в последовательный порт, который вы открыть, щелкнув меню «Инструменты» в Arduino IDE, а затем выбрав опцию «Монитор последовательного порта».

1549986382583.png


C-подобный:
void cb(esppl_frame_info *info) {
  for (int i = 0; i < LIST_SIZE; i++) {
    if (maccmp(info->sourceaddr, friendmac[i]) || maccmp(info->receiveraddr, friendmac[i])) {
      Serial.printf("\n%s is here! :)", friendname[i].c_str());

Шаг 6. Настройка.
Теперь вы должны настроить некоторые настройки, а именно таймер и список MAC-адресов, которые мы будем отслеживать.
Для таймера я установил значение 100, но вы можете настроить его в зависимости от ваших потребностей.
Это означает, что каждый раз, когда мы обнаруживаем пакет с MAC, который мы ищем, светодиод будет гореть, пока не будет обнаружено 100 пакетов, которые не соответствуют ни одному из устройств в нашем списке, и при обнаружение одного из MAC остальные таймера также уменьшаются.
Я сделал это, чтобы обойти проблему с неспособностью создать задержку, чтобы держать светодиод включенным.
C-подобный:
if (i == 0) {
        TimerBlue = 1000;
        TimerGreen--;
        TimerRed--;
        TimerYellow--;
        blue();
        check();

Чтобы контролировать цвет светодиода, я использовал оператор «if», который говорит, что если мы обнаружили пакет с MAC-адресом, совпадающим с нашим в нашем списке, подсвечиваем цвет в соответствующий цвет.

Поскольку большинство списков в программировании начинаются с 0, примером может быть то, что первым MAC-адресом в списке будет индекс 0 и установлен синий цвет. Второй MAC-адрес будет индексом 1 и установлен в красный цвет. И третий будет индекс 2 и будет установлен в зеленый цвет.

1549988514468.png


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

Окончательный код должен выглядеть следующим образом:
C-подобный:
#include "./esppl_functions.h"
#include <ESP8266WiFi.h>
#define LIST_SIZE 4
/*
   This is your friend's MAC address list
  Format it by taking the mac address aa:bb:cc:dd:ee:ff
  and converting it to 0xaa,0xbb,0xcc,0xdd,0xee,0xff
*/
uint8_t friendmac[LIST_SIZE][ESPPL_MAC_LEN] = {
  {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA} //blue
  , {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA} //green
  , {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA} //red
  , {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA} //yelow
};
/*
   This is your friend's name list
   put them in the same order as the MAC addresses
*/
String friendname[LIST_SIZE] = {
  "Sharp aquos s2" //blue
  , "Nexus 5" //green
  , "HTC" //red
  , "Onda" //red
};

// start variables package - Skickar 2018 hardware LED for NodeMCU on mini breadboard //
void setup() {
  delay(500);
  pinMode(D5, OUTPUT); // sets the pins to output mode
  pinMode(D6, OUTPUT);
  pinMode(D7, OUTPUT);
  pinMode(D8, OUTPUT);
  Serial.begin(115200);
  esppl_init(cb);
}

/* You cannot use a time delay here to keep the LED on, so will need to use ratio of
  detected packets to overall packets to keep LED on for longer. If you try to use a
  delay to keep the light on for long enough to be useful, the watchdog timer kills the
  process and it dies */
int TimerBlue = 0;
int TimerGreen = 0;
int TimerRed = 0;
int TimerYellow = 0;

void red() {
  digitalWrite(D7, HIGH);
}  // Turn ON the red LED
void blue() {
  digitalWrite(D5, HIGH);
} // Turn ON the blue LED
void green() {
  digitalWrite(D6, HIGH);
} // Turn ON the green LED
void yellow(){
  digitalWrite(D8, HIGH);
}
void turnoff() {
  digitalWrite(D7, LOW), digitalWrite(D5, LOW), digitalWrite(D6, LOW), digitalWrite(D8, LOW);
}

/* end exparimental variable package */

bool maccmp(uint8_t *mac1, uint8_t *mac2) {
  for (int i = 0; i < ESPPL_MAC_LEN; i++) {
    if (mac1[i] != mac2[i]) {
      return false;
    }
  }
  return true;
}

void check(){
  if (TimerBlue > 0) {
    TimerBlue--;
  }
  if (TimerGreen > 0) {
    TimerGreen--;
  }
  if (TimerRed > 0){
    TimerRed--;
  }
  if (TimerYellow > 0){
    TimerYellow--;
  }
  if (TimerBlue <= 0){
    digitalWrite(D5, LOW);
  }
  if (TimerGreen <= 0){
    digitalWrite(D6, LOW);
  }
  if (TimerRed <= 0){
    digitalWrite(D7, LOW);
  }
  if (TimerYellow <= 0){
    digitalWrite(D8, LOW);
  }
}

void cb(esppl_frame_info *info) {
  for (int i = 0; i < LIST_SIZE; i++) {
    if (maccmp(info->sourceaddr, friendmac[i]) || maccmp(info->receiveraddr, friendmac[i])) {
      Serial.printf("\n%s is here! :)", friendname[i].c_str());
      if (i == 0) {
        TimerBlue = 1000;
        TimerGreen--;
        TimerRed--;
        TimerYellow--;
        blue();
        check();
      } // Here we turn on the blue LED until turnoff() is called
      else if(i == 1){
        TimerGreen = 1000;
        TimerBlue--;
        TimerRed--;
        TimerYellow--;
        green();
        check();
      }else if(i == 2){
        TimerRed = 1000;
        TimerBlue--;
        TimerGreen--;
        TimerYellow--;
        red();
        check();
      }else if (i ==3){
        TimerYellow = 1000;
        TimerBlue--;
        TimerGreen--;
        TimerRed--;
        yellow();
        check();
      }
    }else{
      check();
    }
  }
}


void loop() { // I didn't write this part but it sure looks fancy.
  esppl_sniffing_start();
  while (true) {
    for (int i = ESPPL_CHANNEL_MIN; i <= ESPPL_CHANNEL_MAX; i++ ) {
      esppl_set_channel(i);
      while (esppl_process_frames()) {
        //
      }
    }
  }
}

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

1549986803032.png


Шаг 7. Сборка.
В этом коде я сохранил простоту компоновки, используя выводы D5, D6, D7 и D8 для управления светодиодами.
Если вы хотите сохранить свои светодиоды, я рекомендую вместо этого подключить выводы D5, D6, D7 и D8 к светодиоду в другом месте на плате, а затем добавить резистор (или потенциометр), чтобы уменьшить напряжение и продлить срок службы светодиодов.

1549987318071.png


Для тех кому не понятно, то черный провод соединяете с - на макетной плате и пином GND на NodeMCU.
Все остальные контакты D5, D6, D7, D8 с + светодиода.

После этого можно подключить USB-кабель и проверить работоспособность. Как только устройства из списка отслеживаемых отправит пакет, соответствующий светодиод загорится. Я лично долго тестировал и работало все на отлично.

Полный код можете получить выше.
Если у вас появятся вопросы - готов ответить, а на этом все. Спасибо за внимание.

1549988200782.png


1549988252693.png
 

Debug

Red Team
07.07.2017
217
445
BIT
6
А по какому признаку можно понять, что frame отправлен клиентом (а не роутером)? И наоборот - клиенту?

В статье сказано, что при wlan.fc.type_subtype==4 (Probe Request) идёт запрос от клиента на поиск сетей, попробовал на своих гаджетах - ни один не отправил такой фрейм. Может ещё есть какой-то способ понять, что фрейм от клиента?
Mac свой подставили?
 

ktototam45

New member
04.02.2020
1
0
BIT
0
Технически возможно ли собрать похожее устройство, но которое будет определять номера телефонов юзеров в каком-то даже не большом радиусе (10-20 метров)? К примеру имитируемуя из себя базовую станцию оператора.
Возможно существуют уже какие то реализации?
 
Последнее редактирование:

lvd

New member
31.12.2019
3
0
BIT
0
В смысле без него? 4 - это не мак а формат пакета если не ошибаюсь
Чтобы было более понятно, вот немного изменённая функция cb:
C-подобный:
void cb(esppl_frame_info *info) {
  for (int i=0; i< LIST_SIZE; i++) {
    if (maccmp(info->sourceaddr, friendmac[i]) || maccmp(info->receiveraddr, friendmac[i])) {
      if (i == 0) {
        red();
        TimerRed = 1000;
      }
      if (i == 1) {
        blue();
        TimerBlue = 1000;
      }
      if (info->frametype == ESPPL_MANAGEMENT && info->framesubtype == ESPPL_MANAGEMENT_PROBE_REQUEST) {
        printSerialFrameInfo(info);
      }
      if (info->frametype == ESPPL_MANAGEMENT && info->framesubtype == ESPPL_MANAGEMENT_PROBE_RESPONSE) {
        printSerialFrameInfo(info);
      }
    }
  }
 
  check();
}
где printToSerialFrameInfo - функция вывод полей esppl_frame_info
__
п.с. немного разобрался: когда wifi-роутер включен до того, как телефон вошёл в зону файфая, вывода по коду выше нет. Но если выключить роутер, то сразу появляются фреймы с подтипом 4 и 5.
 

RusRus

Member
08.12.2019
10
0
BIT
0
Интересно, а как модель телефона узнавать, можно ли. Думаю девайс к blynk.cc подключить , что инфа отправлялась мне на смартфон. Придется вторую ардуину ставить и строки парсить по uarty
 

RusRus

Member
08.12.2019
10
0
BIT
0
Железка определяет подключенные устройства к роутеру, если их маки есть в списке устройств. Получается, если по WiFi связи нет (телефон не подключен к точке доступа) то железка не определит этот телефон?
Думаю как сделать определение новых устройств, которых нет в списке скетча программы.
 

Debug

Red Team
07.07.2017
217
445
BIT
6
Железка определяет подключенные устройства к роутеру, если их маки есть в списке устройств. Получается, если по WiFi связи нет (телефон не подключен к точке доступа) то железка не определит этот телефон?
Думаю как сделать определение новых устройств, которых нет в списке скетча программы.
Если мне не изменяет память, то подключение устройства к Wi-Fi не обязательно, так как устройства при включенном Wi-Fi модуле отправляет пробные кадры. С обнаружением новых устройств проблем возникать не должно, делов на 5 минут.
 
  • Нравится
Реакции: RusRus

shinji2009

One Level
19.05.2020
4
2
BIT
0
привет. можно сюда комментарием свою версию пингера на esp8266 запостить? он проверяет по ip. ваша инструкция легко гуглится, но вдруг кому надо будет проверять по ip а не по mac. по ip в инете я не нашёл, написал сам. ну и заодно скажете где я был неправ написав такой код)
 

Debug

Red Team
07.07.2017
217
445
BIT
6
привет. можно сюда комментарием свою версию пингера на esp8266 запостить? он проверяет по ip. ваша инструкция легко гуглится, но вдруг кому надо будет проверять по ip а не по mac. по ip в инете я не нашёл, написал сам. ну и заодно скажете где я был неправ написав такой код)
Конечно можете, хотя я не понимаю в чем прикол? Если устройство не подключено к сети, то NodeMCU не обнаружит устройство.
 

shinji2009

One Level
19.05.2020
4
2
BIT
0
ну да в этом и прикол. при этом мой пингер может проверять не только устройства подключенные по wifi, но и по кабелю (при условии что к wifi роутеру, к которому он подключен, подключены устройства по кабелю), и наличие интернета. просто мне так было нужно) дело в том что у меня есть несколько устройств которые иногда виснут, в их числе и роутер. и уходя утром на работу я конечно не проверяю их все. а когда с работы мне надо получить доступ к одному из них, оказывается что что-то случилось. когда-нибудь я конечно разберусь со всеми глюками, но пока я решил сделать что-то вроде индикатора состояния сетевых устройств, мельком взглянув на который, можно бы получить нужную информацию. поэтому я начал искать в инете подобные проекты и нашёл ваш и ещё вот этот пример использования пинга с помощью специально библиотеки и ещё нашёл информацию что пингом можно проверять состояние устройства, что если оно зависло то оно не будет пинговаться. чтобы пингер работал как надо, придётся всем проверяемым устройствам назначить статический ip адрес, кроме того для wifi в роутере надо отключить изоляцию клиентов (если есть. эта настройка запрещает устройствам wifi связываться между собой, соотвественно пинг от пингера не будет доходить). листинг который я привёл написан для 4 устройств и 1 dns google, я видел что пинг на 8.8.8.8 часто используется в программах как проверка наличия инетрнета. 4 устройства в моей внутрисети пингуются поочереди практически непрерывно, (скорость ограничивается скорее всего библиотекой пинга, утройства пингуются примерно раз 5 сек) потому что это моя сеть и никто не примет это за ddos) dns гугла же из этого опасения пингуется примерно раз в 20 минут. принцип индикации простой: светодиод горит - устройство в сети. светодиод не горит - устройство не в сети. кроме того, я сделал чтобы светодиоды мигали, когда устройство пингуется. по очерёдному миганию светодиодов каждые 5 секунд можно быстро определить, а не завис ли, собственно, сам пингер). даже если все устройства оказываются не в сети, светодиоды поочереди коротко вспыхивают. при включении первым делом пингуется 8.8.8.8, потому что он пингуется реже всех. светодиоды на всякий случай подключил через резисторы 220 Ом. при включении пингера светодиоды выключены, но по мере появления устройств в сети они один за другим загораются. да я не программист, очевидно что программу можно было написать проще и понятнее, а то что я сделал скорее контрл-цэ, контрл-вэ отсюда и из гугла) но она работает. может кому-нибудь пригодится.

C-подобный:
#include <ESP8266WiFi.h>
#include <ESP8266Ping.h> // библиотеки скачать по ссылке https://github.com/dancol90/ESP8266Ping
                          // и распаковать папку из архива в папку с библиотеками arduino ide
                          // у меня это \имя пользователя\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\libraries\

const char* ssid = "SSID"; // здесь надо написать имя вашей сети
const char* password = "PASS"; // ваш пароль wifi

const IPAddress remote5_ip(192, 168, 0, 1);  // ip которые надо проверять, их 5 штук, введите свои
const IPAddress remote6_ip(192, 168, 0, 1);  // писать ip надо именно так, через запятую
const IPAddress remote7_ip(192, 168, 0, 1);  // число в названиях переменных означает контакт esp8266: D5. D6 и т.д.
const IPAddress remote2_ip(192, 168, 0, 1);  // можно взять почти любые контакты какие удобно
const IPAddress remote1_ip(8, 8, 8, 8);      // это адрес dns google для проверки интернета
                                             //используемые функции так же имеют число в названии
                                             //так что при изменении количества пингуемых устройств
                                             //сразу видно какие константы, переменные и функции надо добавить
                                             //либо закомментировать

int  State5 = 0;    //это изначальное состояние всех устройств и светодиодов
int  State6 = 0;    // 0 значит не в сети и не горит
int  State7 = 0;
int  State2 = 0;
int  State1 = 0;

void setup() {      // это первичный цикл, после его выполнения очередь передаётся главному  

  delay(500);
  pinMode(D5, OUTPUT); // программируем используемые контакты как выходы
  pinMode(D6, OUTPUT);
  pinMode(D7, OUTPUT);
  pinMode(D2, OUTPUT);
  pinMode(D1, OUTPUT);

  digitalWrite(D5, LOW); // и на всякий случай выставляем на них 0
  digitalWrite(D6, LOW);
  digitalWrite(D7, LOW);
  digitalWrite(D2, LOW);
  digitalWrite(D1, LOW);
 
Serial.begin(115200);   // здесь остались команды которые выдают в монитор com-порта информацию
delay(10);              // оставил их потому что они никому не мешают и могут помочь при диагностике

// We start by connecting to a WiFi network

Serial.println();
Serial.println("Connecting to WiFi");

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");      // пока wifi не подключится в монитор порта будут печататься точки
}

Serial.println();
Serial.print("WiFi connected with ip ");  // в монитор напечатаеся ip пингера
Serial.println(WiFi.localIP());

Check1();                     // вызываем функцию которая проверяет состояние интернета
                              // пингуя dns google
  if (State1 == 1) {          // она возвращает 1 если интернет есть
  digitalWrite(D1, LOW);      // тогда коротко выключаем светодиод
  delay(100);
  digitalWrite(D1, HIGH);     // и включаем его снова
} else {                      // если же интернета нет
  digitalWrite(D1, HIGH);     // то коротко включаем светодиод
  delay(100);
  digitalWrite(D1, LOW);      // и выключаем его снова
}

}                             // конец первичного цикла

void Check5() {               // это функции проверки пинга остальных устройств

Serial.print("Pinging ip ");
Serial.println(remote5_ip);

// Ping
if (Ping.ping(remote5_ip)) {
  State5 = 1;
} else {
  State5 = 0;
}
}

void Check6() {

Serial.print("Pinging ip ");
Serial.println(remote6_ip);

// Ping
if (Ping.ping(remote6_ip)) {
  State6 = 1;
} else {
  State6 = 0;
}
}

void Check7() {

Serial.print("Pinging ip ");
Serial.println(remote7_ip);

// Ping
if (Ping.ping(remote7_ip)) {
  State7 = 1;
} else {
  State7 = 0;
}
}

void Check2() {

Serial.print("Pinging ip ");
Serial.println(remote2_ip);

// Ping
if (Ping.ping(remote2_ip)) {
  State2 = 1;
} else {
  State2 = 0;
}
}

void Check1() {

Serial.print("Pinging ip ");
Serial.println(remote1_ip);

// Ping
if (Ping.ping(remote1_ip)) {
  State1 = 1;
} else {
  State1 = 0;
}
}

void loop() {                     // это главный цикл

for (int i = 0; i < 30; i++){     // этот цикл задаёт сколько раз будут
                                  // пинговаться устройства внутри сети
                                  // прежде чем пинганётся 8.8.8.8

Check2();                         // пингуем

if (State2 == 1) {                // и соотвественно зажигаем или гасим светодиод
  digitalWrite(D2, LOW);
  delay(100);
  digitalWrite(D2, HIGH);
} else {
  digitalWrite(D2, HIGH);
  delay(100);
  digitalWrite(D2, LOW);
}

Check5();                       // и т.д. для остальных

if (State5 == 1) {
  digitalWrite(D5, LOW);
  delay(100);
  digitalWrite(D5, HIGH);
} else {
  digitalWrite(D5, HIGH);
  delay(100);
  digitalWrite(D5, LOW);
}

Check6();

if (State6 == 1) {
  digitalWrite(D6, LOW);
  delay(100);
  digitalWrite(D6, HIGH);
} else {
  digitalWrite(D6, HIGH);
  delay(100);
  digitalWrite(D6, LOW);
}

Check7();

if (State7 == 1) {
  digitalWrite(D7, LOW);
  delay(100);
  digitalWrite(D7, HIGH);
} else {
  digitalWrite(D7, HIGH);
  delay(100);
  digitalWrite(D7, LOW);
}

}                     // здесь кончился цикл проверки устройств внутрисети

Check1();             // проверяем состояние интернета

  if (State1 == 1) {
  digitalWrite(D1, LOW);
  delay(100);
  digitalWrite(D1, HIGH);
} else {
  digitalWrite(D1, HIGH);
  delay(100);
  digitalWrite(D1, LOW);
}

// delay(1000);

// loop
}                   // возвращаемся в начало главного цикла
 
  • Нравится
Реакции: Debug

shinji2009

One Level
19.05.2020
4
2
BIT
0
...иии оказалось что одна esp у меня так чётенько виснет что всё равно продолжает пинговаться, но при этом абсолютно не работает. так что возможно что для esp это не очень надёжный способ проверки. и ещё оказалось что 5 малюсеньких светодиодиков ночью светят как прожектор локомотива, так что гораздо лучше сделать чтобы если устройство пингуется, то светодиод, за него отвечающий, не горел. в принципе это даже логичнее, ибо именно аварийная ситуация должна индицироваться и привлекать наше внимание зажжённым светодиодом. для того чтобы изменить принцип индикации в предыдущем листинге надо во всех строках if (State == 1) поменять на if (State == 0). ещё в начале в void setup поменять все пять int State на 1, потому что теперь 1 будет считаться что устройство не пингуется, и пять штук digitalWrite(D , LOW) поменять на digitalWrite(D , HIGH), чтобы при включении они все загорались, пока не пропингованы, а потом по одному гасли.
 

shinji2009

One Level
19.05.2020
4
2
BIT
0
да и перед WiFi.begin конечно же надо WiFi.mode(WIFI_STA);
оно конечно и так работает, но без этого esp создаёт ненастроенную точку доступа которая будет мешать и жрать ток
 
  • Нравится
Реакции: Debug

AntArt

Green Team
14.02.2018
11
35
BIT
14
Как-то раз с помощью opencv и ардуино делал что светодиоды маргали при виде знакомого лица, получилось но это было ужасно, потому что все было честно стырено из разных проектов и непойми как запиханно в 1. Как это работало до сих пор удивляюсь, но было весело) а статья классная, спасибо.
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!