Сенсорный WiFi выключатель на ESP8266

Умный дом  /  Сделай сам  /  InternetOfThings  /  ESP8266  




Решил сделать себе сенсорный выключатель на кухню.


Обычно такие штуки делаются на Ардуине, однако с учетом падения цен на ESP8266, и более жирными ресурсами, захотелось сделать это на ESP8266, и заодно убить этим выстрелом второго зайца - сделать выключатель WiFi управляемым.



Вот список того что я запланировал получить в итоге:


1. При включении (точнее первом подаче электричества вообще) выключатель должен подключаться к WiFi, а потом слать на домашний сервер свой IP и набор поддерживаемых фич. Хочу так сделать, чтобы унифицировать управление устройствами из одного центрального узла. Грубо говоря, выключатель сам добавляет себя в базу данных как выключатель, а потом центральная программа видит новое устройство "выключатель" и начинает с ним работать исходя из параметров которые этот выключатель прислал;


2. Выключатель должен уметь выключать и включать свет в автономном режиме, без наличия или отсутствия WiFi;


3. Выключатель так же должен уметь включать и выключать свет по сети, при чем без использования хитрожопых протоколов;


4. Соответственно выключатель должен уметь запоминать свое состояние и возвращать его по запросу из сети;


5. У выключателя должна быть подсветка в режиме ночника, на одном светодиоде;


6. Эта подсветка так же должна уметь включаться и выключаться по сети;


7. Разумеется это все должно иметь возможность быть запихнутым в бокс.


Самое проблемное и казалось сперва, и оказалось в итоге - это питание.

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


В качестве сенсоров у меня был выбор, выбрать подешевле и поменьше, или подороже и побольше. Оба были у меня куплены для других проектов.


Разумеется выбрал я красненький, из-за двух факторов: меньшего размера, и отсутствия на стороне сенсора шероховатостей в виде деталей и разъемов. Честно говоря, производитель правого сенсора головой видимо не думал. Ну да ладно.


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


В качестве элемента питания использовал обычную пятивольтовую зарядку от мобильника, куда навесом напаял LM1117 (стабилизатор на 3.3в).



Родные кишки от выключателя за 30 гривен, я вытащил (видно на первой фотке), вместо этого приклеил сенсор силиконом на внутреннюю сторону того элемента, на который обычно нажимают.




В общем вся готовая конструкция на кухне выглядела вот так...



На удивление, и сенсор, и твердотельное реле - отлично работают от 3.3В.


Что касается программной части, то для нее я использовал Arduino IDE (в Арче лежит в стандартных репах) + плагин к ней. Язык отдаленно напоминает C++, а то и PHP. Специально перепрошивать ESP8266 ни под что не нужно, все шьется на лету, с закороченным GPIO0 (об этом лучше почитать в интернете, цель статьи - не научить вас шить ESP8266).


За прошивку я взял скетч веб-сервера из примеров, добавив туда необходимые фичи.

С гордостью представляю его вам..


#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <ESP8266HTTPClient.h>

const char* ssid = "u39_2.4G";
const char* password = "";
String ID="0001";
int status=0;
ESP8266WebServer server(80);

int n=0;

void handleNotFound(){
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET)?"GET":"POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i=0; i<server.args(); i++){
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
}

void setup(void){
  Serial.begin(115200);
  Serial.println("Starting Jarvis module: switcher...");
  // На пин 13 у нас подключен сенсор
  pinMode(13, INPUT);
  // На пин 13 у нас подключено реле
  pinMode(5, OUTPUT);
  // На пин 4 у нас подключена подсветка
  pinMode(4, OUTPUT);
  digitalWrite(5, 0);
  digitalWrite(4, 1);
  
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.print("Connecting to WiFi: ");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    n++;
    // Если за 60 сек (0.5 * 120) нет wifi-подключения, ребутаем девайс. Потенциальный баг, в случае отсутствия WiFi девайс упадет в бесконечный ребут, пофиксю в след ревизии
    if (n==120) {Serial.println("[ FAIL ]");Serial.println("1 minute is gone, no connection, restarting...");ESP.reset();}
    
  }
  Serial.println(" [OK] ");
  HTTPClient http;
  String IP=WiFi.localIP().toString().c_str();
  // Посылаем на сервер умного дома GET запрос с нашим IP и списком поддерживаемых фич
  // lightswitch означает что к этой IP можно будет обращаться http://192.168.1.X/lightswitch=1 или http://192.168.1.X/lightswitch=0 и это будет включать и выключать свет
  // backlight по сути означает то же самое, но для низкожрущей подсветки
  // remote означает то, что этим устройством можно управлять снаружи
  // alert - означает то, что это устройство поддерживает индикацию. Это можно использовать например для бесшумной индикации звонка в дверной звонок
  http.begin("http://192.168.1.2/init.php?ip="+IP+"&device=switcher&features=lightswitch,backlight,remote,alert&id="+ID);
  int httpCode = http.GET();
  http.end();
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  if (MDNS.begin("esp8266")) {
    Serial.println("MDNS responder started");
  }

  // http://192.168.1.X/status вернет нам 0 или 1 в зависимости от того включен свет или нет
  server.on("/status", [](){
  String st=String(status);
  server.send(200, "text/plain", st);
  });

 // http://192.168.1.X/backlight=1 включит подсветку
 server.on("/backlight=1", [](){
    digitalWrite(4, 1);
    server.send(200, "text/plain", "OK");
  });


 // http://192.168.1.X/backlight=1 выключит подсветку
 server.on("/backlight=0", [](){
    digitalWrite(4, 0);
    server.send(200, "text/plain", "OK");
  });



 // http://192.168.1.X/lightswitch=1 включит свет
 server.on("/lightswitch=1", [](){
    digitalWrite(5, 1);
    status=1;
    server.send(200, "text/plain", "OK");
  });

// http://192.168.1.X/lightswitch=0 выключит свет
 server.on("/lightswitch=0", [](){
    digitalWrite(5, 0);
    status=0;
    server.send(200, "text/plain", "OK");
  });

  server.onNotFound(handleNotFound);

  server.begin();
  Serial.println("HTTP server started");
}

void loop(void){
  server.handleClient();
  int value=digitalRead(13);
  
  // Если нажат сенсор, и свет выключен, то...
  
  if ((value==1)and(status==0)) {
  // Включаем свет
  digitalWrite(5, 1);
  // Меняем статус
  status=1;
  // Сбрасываем значение переменной сенсора. Если этого не сделать, то проверка ниже снова выключит свет
  value=0;
  delay(1000);
  }

  // Если нажат сенсор, и свет включен, то...
  
  if ((value==1)and(status==1)) {
  // Выключаем свет
  digitalWrite(5, 0);
  // Меняем статус
  status=0;
  // Сбрасываем значение переменной сенсора. Если этого не сделать, то проверка выше снова включит свет
  value=0;
  delay(1000);
  
  }

  delay(100);
}
Единственное что, светодиод подсветки я пока не припаял, выключатель работает в пилотном режиме, в связи с чем предоставляю вам видео, благодарю за чтение статьи, и готов ответить на вопросы, если такие появятся.





Метки текста: ESP8266,DIY,сенсорный выключатель


https://minidevices.info/images/ava.png
https://minidevices.info/images/ava.png
2018-06-01 16:48:21
root 01 июня в 16:48  0 

939
2018-06-01 16:48:21


Комментировать



Опубликовать запись