虎年第一次推送 | esp8266搭建轻量智能家居平台

云中志

共 7986字,需浏览 16分钟

 · 2022-02-11

今天的内容其实是在农历春节前就完成的,但是由于临近放假那几天稍微有点忙,春节放假期间只想好好休息,所以也就没发出来。今天是我复工的第一天,把它发出来算是2022年内容创作的开始和起点,新的一年,我要不断提升自己,努力创作出更多内容,同时也希望能够真正帮到各位小伙伴,好了下面让我们开始今天的正文:

前言

截止到今天,我已经居家办公一个月多,期间小台灯突然就坏了,更不幸的是,在修台灯的时候,烙铁还坏了,由于疫情影响,物流也停了,所以买是没法买的,于是我决定用之前把玩过几次的esp8266翻出来,让它发挥下真正的价值,于是经过昨天一天的捣鼓,我的智能家居管理平台完美诞生,虽然它现在就只能控制小台灯,但是它确确实实解决我关灯难的问题(这么冷的天,睡前还要取关灯,想想都觉得冷),下面我就来分享下我的小成果。

轻量智能家居管理平台

硬件部分

本次项目示例需要用到三个硬件:esp8266开发板、继电器装置和一个LED灯。这里的LED灯可以换成任何设备,因为抛开LED灯,剩下的设备其实起的作用就是一个开关。

esp8266

关于8266这款硬件,这里就不赘述了,之前我也分享过一些小demo,感兴趣的小伙伴可以去看下:

这款开发板的价格很亲民,10块钱就可以拿下,关键是可玩性还是很高的:

首先确保本地环境没有问题,驱动安装正常:

继电器

继电器是很早之前就到手了,就是这种双路光耦继电器,价格¥3.5,其中NO表示常开,NC表示常闭,COM就是公共端子。从这个图片上可以很清楚地看到我用的是常开,所以在后面的代码中我在一开始要把LED引脚设置成HEIGH,否则LED从一开始就是亮的,感兴趣的小伙伴可以自己试下,当然你也可以直接用NC端,这样就不存在这个问题了:

另外,从继电器上给出的参数可以看出,这个继电器其实可以支持到10A 250V的功率,说明用在普通家用电器上也是可以的。这里我就接了一个3.7V的小台灯,确实有点大材小用了。

被控制对象

这里就是一个功率特别小的台灯,就是通过8266和继电器来实现远程控制,后面会有视频演示哦。

代码部分

arduino

先是arduino部分,这块的代码很简单,也没有复杂的逻辑,主要是基于c++的硬件操作。

首先打开我们的arduino IDE,然后安装依赖库

今天的项目主要涉及websocket的一些功能,所以我们安装ArduinoWebsockets这个包就行了,这个包的作用就是让我们的8266能够构建一个简易的websocket服务器,能够处理一些简单的请求即可,我本地安装的是0.5.2

另外我们还需要ESP8266WiFi的相关依赖,这个库就是8266的核心库,其中wifi配网需要用到:

由于,我还有加了OLED,加这个小屏幕的作用主要是为了方便查看8266ip,同时能够通过它调试代码,类似于日志控制台,所以还需要通过添加它的库,也就是上面图中的SSD1306库。

以上工作完成后,我们开始编写arduino代码:

#include <ArduinoWebsockets.h>
#include <ESP8266WiFi.h>
#include <SPI.h>; // 加载SPI库
#include <Wire.h>; // 加载Wire库
#include <Adafruit_GFX.h>; // 加载Adafruit_GFX库
#include <Adafruit_SSD1306.h>; // 加载Adafruit_SSD1306库

// 定义 OLED屏幕的分辨率
Adafruit_SSD1306 display = Adafruit_SSD1306(12864, &Wire);

// WiFi parameters
const char* ssid = "wifi名称";
const char* password = "wifi密码";
String ip = "";
int LED=16;//GPIO16--D0

using namespace websockets;

WebsocketsServer server;
void setup() {
  Serial.begin(115200);
  // 设置OLED的I2C地址
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); 
  // 清空屏幕
  display.clearDisplay(); 
  // 设置字体大小
  display.setTextSize(1); 
  // 设置字体颜色
  display.setTextColor(SSD1306_WHITE); 
  // 设置开始显示文字的坐标
  display.setCursor(00); 
  // Connect to wifi
  WiFi.begin(ssid, password);

  // Wait some time to connect to wifi
  for (int i = 0; i < 15 && WiFi.status() != WL_CONNECTED; i++) {
    Serial.print(".");
    delay(1000);
  }
  ip = WiFi.localIP().toString();
  // 输出的字符
  display.println("IP: " + ip); 
   // 输出的字符
  display.println("webSocket Server");
  // 使更改的显示生效
  display.display(); 

  // 创建websocket服务器
  server.listen(80);
  //设置对应引脚为输出模式
  pinMode(LED, OUTPUT);
  digitalWrite(LED, HIGH);
}

void loop() {
  display.clearDisplay(); // 清空屏幕
  display.setCursor(00); // 设置开始显示文字的坐标
  auto client = server.accept();
  if (client.available()) {
    auto msg = client.readBlocking();
    // return echo
    client.send("Echo: " + msg.data());

    // close the connection
    client.close();
    String ipInfo = "IP: " + ip;
    // 将ip信息输出到屏幕上
    printText(ipInfo);

    String data = msg.data();
    int status =digitalRead(LED);   
    if(data.equals("taggleLed")) {
      if (status == LOW) {
        digitalWrite(LED,HIGH);
        printText("ligth close!");
      } else {
         digitalWrite(LED,LOW); 
         printText("ligth open!");
      }      
    }
    
    printText("message: " + data); // 输出的字符
  }

  delay(1000);
}

// 向屏幕输出字符串
void printText(String text) {
    display.setTextSize(1); // 设置字体大小
    display.setTextColor(SSD1306_WHITE); // 设置字体颜色
    display.println(text); // 输出的字符
    // 使更改的显示生效
    display.display();
  }

代码虽然看着很长,很复杂,其实内部逻辑很简单:

  • 首先是配网,这块需要指定wifi名称和密码;
  • 配网完成后,会在小屏幕上显示8266ip地址;
  • 接着会启动websocket服务,端口用的是80;
  • 然后就是LED的相关操作:这里我们把LED(也就是台灯)的引脚(这里用的是GPIO16,对应8266D0针脚)设置为输出模式,同时将引脚电平设置为高电平(HIGH)。

注意: 因为我用到的是继电器的常开端,所以我设置为HEIGH,如果你用的是常闭端,你可以设置为低电平LOW,这块前面在继电器部分也说过了。

关于8266的详细引脚图可以参考下面这个图:

loop代码中,我们监听客户端的wesocket请求,如果请求内容为taggleLed,我们就去获取LED引脚的电平,根据LED引脚的电平值设置它新的电平值:

如果电平为高电平(关闭状态,仅在当前示例中),则将引脚电平设置为LOW,即开灯操作,否则将电平设置为高电平,也就是关灯操作。

至此我们arduino部分的代码就完成了,下面看下接线图:

图画的太累了,效果貌似还不怎么好,后面找找合适的软件,不过参照图上的连线是没有问题的。

后端部分

最开始想的是前端发送http请求,然后后端再调用arduinowebsocket服务,后来才想起来,前端可以直接通过js发送websocket请求,于是项目就变成了一个纯前端项目,但是为了让手机端也能够访问,于是我就索性把它变成一个后端项目,虽然只有一个页面,页面效果如下(就是找素材有点费时间,关于后端部分我已经分享过了,也就是我年前分享的python项目):

这块最核心的代码就主要是js发送websocket请求部分:

function taggleCmd({

 var ws = new WebSocket("ws://192.168.0.101:80");
    //申请一个WebSocket对象,参数是服务端地址,同http协议使用http://开头一样,WebSocket协议的u   rl使用ws://开头,另外安全的WebSocket协议使用wss://开头
    ws.onopen = function(){
      //当WebSocket创建成功时,触发onopen事件
       console.log("open");
      ws.send("taggleLed"); //将消息发送到服务端
    }
    ws.onmessage = function(e){
  //当客户端收到服务端发来的消息时,触发onmessage事件,参数e.data包含server传递过来的数据
  console.log(e.data);
    }
    ws.onclose = function(e){
      //当客户端收到服务端发送的关闭连接请求时,触发onclose事件
      console.log("close");
    }
    ws.onerror = function(e){
      //如果出现连接、处理、接收、发送数据失败的时候触发onerror事件
      console.log(error);
    }

}

也就是点击对应的按钮时,调用taggleCmd方法发送taggleLed消息即可,这样arduino在收到响应的请求时就可以触发相应的操作。

这里配置的192.168.0.101:80,就是我们8266ipwebsocket的服务端口,下面我们通过一个视频来看下操作效果:

为了便于运行和编辑,后端我用的是pythonflask框架,目前只有一个页面,后续考虑增加设备管理(增删改查)、操作注册等页面。

另外,这里再放上一个webscoket客户端的python脚本,方便各位小伙伴测试:

from websocket import create_connection

ws = create_connection("ws://192.168.0.101:80")
print("Sending 'Hello, World'...")
ws.send("taggleLed")
print("Sent")
print("Receiving...")
result = ws.recv()
print("Received '%s'" % result)
ws.close()

结语

本次这个项目,比预想的要简单很多,反而前端页面成了最耗时间的操作,但从实际达成的效果来说,我还是很满意的,毕竟现在躺在床上就可以关灯开灯,它不香吗?

单个esp826610个数据引脚,也就是说它可以控制10个用电设备,从这一点上说,一个esp8266开发板就可以满足我们大部分家电的控制需求,价格简直不要太友好。

当然今天我们算是提供了一种家庭智能设备控制的一种解决方案,有了这套解决方案的加持,我们不仅可以实现手机端、pc端对设备的控制,还可以实现设备的定时启停,甚至是根据日出日落进行相关这样的复制控制操作,这里的esp8266+继电器充当的只是执行器,而真正的智能是外部的逻辑运算。

- END -


浏览 82
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报