云天 发表于 2022-1-5 21:45:02

【智能开关】手机控灯(改造家用开关,不搞破坏)

本帖最后由 云天 于 2022-1-5 21:47 编辑

【项目背景】
智能控制开关,是我很早就在考虑的一个项目。一直没有做主要是因为,我有以下几个要求:1、不破坏原有的器件(媳妇不让)。
2、不动220V(危险)
3、具有一定可调整性(开关大小不一致)。
我见过最简单的方法是,把舵机直接用热熔胶粘在开关边上(简单粗暴)。有的把设置粘在墙面上(有破坏性)。
我发现一个现象,就是一般的开关都是要突出于墙面,应该是方便拆卸(外面是一个壳,用力能抠下来,里面有螺丝)。而突出这部分正是我可以利用的,因为我没有3D打印和激光切割机,只能使用一些金属构件。
【项目设计】
主控使用,FireBeetle Board ESP32 E,主要原因是它有蓝牙、Wifi功能,可无线控制。驱动开关使用SG90舵机,小巧且不用单独供电。
方案1:使用蓝牙和WIfi热点,手机app控制。
方案2:使用通过STA 模式:ESP32模块通过路由器连接互联网,手机通过互联网实现对设备的远程控制。
方案3:通过红外模块,使用遥控器控制


方案1的优点是,手机是随身携带物品,且不用连接互联网。缺点是使用前需连接蓝牙或热点。
方案2的优点是,手机一般情况都是连着互联网的。缺点是,FireBeetle Board ESP32 E需要一直连接互联网,当然家里如果Wifi一直不关的话,也不是问题。
方案3的优点是,遥控器拿起来就用,不像手机还要解锁、开程序等,使用方便。缺点是,我们不会把遥控器一直带在身上,当然开关灯也不会频繁进行,遥控器放在床边或办公桌上就可以。还有一个缺点就是使用遥控器,显得不高大上。

下面将使用方案1进行测试,“WIfi热点”。
【编程环境】
Arduino IDE 编译环境配置,参考:https://wiki.dfrobot.com.cn/_SKU ... rd_ESP32_E#target_6
【硬件设备】
1、FireBeetle ESP32-E是一款基于ESP-WROOM-32E双核芯片的主控板,它专为IoT设计。它支持WIFI和蓝牙双模通信并具有体积小巧、超低功耗、板载充电电路、接口易用等特性。FireBeetle ESP32-E深度支持ArduinoIDE编程。https://mc.dfrobot.com.cn/forum.php?mod=attachment&aid=MTMxMjY2fDg0OWUzNGU4fDE2NDEzNTU0NTh8ODI3Nzg0fDMxMDI0OQ%3D%3D&noupdate=yeshttps://mc.dfrobot.com.cn/forum.php?mod=attachment&aid=MTMxMjY3fGYwODdiNmIwfDE2NDEzNTU0NTh8ODI3Nzg0fDMxMDI0OQ%3D%3D&noupdate=yes2、扩展板https://mc.dfrobot.com.cn/forum.php?mod=attachment&aid=MTMxMjY5fDFlNDE5MGZlfDE2NDEzNTU0NTh8ODI3Nzg0fDMxMDI0OQ%3D%3D&noupdate=yes
[*]接口方式:Gravity标准接口
[*]GDI显示接口,单线连接显示屏
[*]支持数字输入输出:13
[*]支持模拟输入:5
[*]支持I2C*3
[*]支持UART
[*]支持SPI
[*]支持SP
[*]支持低功耗
[*]支持外接电源
https://mc.dfrobot.com.cn/forum.php?mod=attachment&aid=MTMxMjgyfDg5MjYzYjU5fDE2NDEzNTU0NTh8ODI3Nzg0fDMxMDI0OQ%3D%3D&noupdate=yes
https://mc.dfrobot.com.cn/forum.php?mod=attachment&aid=MTMxMjgxfDVhNWU4NjU1fDE2NDEzNTU0NTh8ODI3Nzg0fDMxMDI0OQ%3D%3D&noupdate=yes
【控制舵机】
esp32 在arduino ide环境下控制180°舵机
180°的舵机在arduino 板子上控制是很方便的。当我们用esp32板子编写的时候,。这时候我们应该去IDE那边下载个esp32专用的舵机库(ServoESP32)。
https://mc.dfrobot.com.cn/forum.php?mod=attachment&aid=MTM3MjMwfGY4MTc3YWZjfDE2NDEyOTU3NzR8ODI3Nzg0fDMxMTI1Nw%3D%3D&noupdate=yes
以下为测试程序

#include <Servo.h>

Servo myservo;// 创建舵机对象以控制舵机
                // 最多可以创建八个伺服对象

int pos = 0;    // 变量来存储伺服位置

void setup()
{
myservo.attach(2);//舵机连接在引脚2(扩展板对应D9)
}


void loop()
{
for(pos = 0; pos < 180; pos += 20)
{                                 
    myservo.write(pos);            
    delay(3000);                     
}
for(pos = 180; pos>=1; pos-=20)
{                              
    myservo.write(pos);
    delay(3000);         
}
}

https://www.bilibili.com/video/BV12a411z7WK?share_source=copy_web
【开热点】
ESP32具有WIFI功能,以下示例使用ESP32创建了一个wifi服务器,使用客户端连接到该服务器,遥控LED的亮灭。
/*WiFiAccessPoint.ino 创建了一个wifi热点并提供了一个web服务
Steps:1. 连接到这个wifi "yourAp"
2. 访问 http://192.168.4.1/H 来开灯或者访问http://192.168.4.1/L 来关灯
   OR   Run raw TCP "GET /H" and "GET /L" on PuTTY terminal with 192.168.4.1 as IP address and 80 as port
*/
#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiAP.h>


// 热点设置你的wifi与密码
const char *ssid = "";
const char *password = "";

WiFiServer server(80);

void setup() {
pinMode(LED_BUILTIN, OUTPUT);//将LED引脚设置为输出模式
Serial.begin(115200);
Serial.println();
Serial.println("Configuring access point...");

// 配置wifi以及获取IP地址.
WiFi.softAP(ssid, password);
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
server.begin();

Serial.println("Server started");
}

void loop() {
WiFiClient client = server.available();   // listen for incoming clients

if (client) {                           // if you get a client,
    Serial.println("New Client.");         // print a message out the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
      char c = client.read();             // read a byte, then
      Serial.write(c);                  // print it out the serial monitor
      if (c == '\n') {                  // if the byte is a newline character

          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();

            // the content of the HTTP response follows the header:
            client.print("Click <a href=\"/H\">here</a> to turn ON the LED.<br>");
            client.print("Click <a href=\"/L\">here</a> to turn OFF the LED.<br>");

            // The HTTP response ends with another blank line:
            client.println();
            // break out of the while loop:
            break;
          } else {    // if you got a newline, then clear currentLine:
            currentLine = "";
          }
      } else if (c != '\r') {// if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
      }

      // Check to see if the client request was "GET /H" or "GET /L":
      if (currentLine.endsWith("GET /H")) {
          digitalWrite(LED_BUILTIN, HIGH);               // GET /H turns the LED on
      }
      if (currentLine.endsWith("GET /L")) {
          digitalWrite(LED_BUILTIN, LOW);                // GET /L turns the LED off
      }
      }
    }
    // close the connection:
    client.stop();
    Serial.println("Client Disconnected.");
}
}
https://www.bilibili.com/video/BV1sL411V7NX?share_source=copy_web
【手机控制】
将开热点程序与控制舵机程序相结合,并通过App Inventor2,编写手机端程序。
1、FireBeetle Board ESP32 E主板程序:
#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiAP.h>
#include <Servo.h>
Servo myservo;
// 热点设置你的wifi与密码
const char *ssid = "";
const char *password = "";

WiFiServer server(80);

void setup() {
myservo.attach(2);
pinMode(LED_BUILTIN, OUTPUT);//将LED引脚设置为输出模式
Serial.begin(115200);
Serial.println();
Serial.println("Configuring access point...");

// 配置wifi以及获取IP地址.
WiFi.softAP(ssid, password);
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
server.begin();

Serial.println("Server started");
}

void loop() {
WiFiClient client = server.available();   // listen for incoming clients

if (client) {                           // if you get a client,
    Serial.println("New Client.");         // print a message out the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
      char c = client.read();             // read a byte, then
      Serial.write(c);                  // print it out the serial monitor
      if (c == '\n') {                  // if the byte is a newline character

          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();

            // the content of the HTTP response follows the header:
            client.print("Click <a href=\"/H\">here</a> to turn ON the LED.<br>");
            client.print("Click <a href=\"/L\">here</a> to turn OFF the LED.<br>");

            // The HTTP response ends with another blank line:
            client.println();
            // break out of the while loop:
            break;
          } else {    // if you got a newline, then clear currentLine:
            currentLine = "";
          }
      } else if (c != '\r') {// if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
      }

      // Check to see if the client request was "GET /H" or "GET /L":
      if (currentLine.endsWith("GET /H")) {
          digitalWrite(LED_BUILTIN, HIGH);               // GET /H turns the LED on
         myservo.write(100);
         delay(500);
         myservo.write(60);
      }
      if (currentLine.endsWith("GET /L")) {
          digitalWrite(LED_BUILTIN, LOW);                // GET /L turns the LED off
         myservo.write(30);
         delay(500);
         myservo.write(60);
      }
      }
    }
    // close the connection:
    client.stop();
    Serial.println("Client Disconnected.");
}
}
2、手机app程序很简单,控件只使用“开关按钮”和“http客户端”。https://mc.dfrobot.com.cn/forum.php?mod=attachment&aid=MTM3MjM4fGU5MTQ5NzUyfDE2NDEyOTU3NzR8ODI3Nzg0fDMxMTI1Nw%3D%3D&noupdate=yes
代码:当开关状态发生改变时,判断开关是开是关,访问对应地址。
https://mc.dfrobot.com.cn/forum.php?mod=attachment&aid=MTM3MjM5fDA2Y2M1YWQ3fDE2NDEyOTU3NzR8ODI3Nzg0fDMxMTI1Nw%3D%3D&noupdate=yes
https://www.bilibili.com/video/BV1nD4y1F7ms?share_source=copy_web【组装硬件】
【演示视频】https://www.bilibili.com/video/BV1pq4y127w6?share_source=copy_web

白凡 发表于 2022-1-7 09:20:53

学到了!!!{:6_209:}
页: [1]
查看完整版本: 【智能开关】手机控灯(改造家用开关,不搞破坏)