自从租房之后,生活环境发生了很大的变化。其实大部分的变化我尚且还算满意,但每当晚上躺在床上玩手机的时候,当困意袭来时,心里总是非常郁闷:我在这边,灯的开关在床的那边。没办法,只得再度下床关灯,再摸黑爬上床 —— 此时睡意早已消失(大哭
于是,我想到了关灯神器 —— 远程操控开关关灯。
方案设计#
因为只是想做一个解放双手的小玩具,自然没有打算做的非常复杂。鉴于家里的开关设计(如下图),只需要一个可以通电左右摇摆的舵机即可,给予一定的电信号,就物理控制开关上下拨动
方案很简单,只需要一块单片机和一个舵机就可以,考虑到拨动开关所需的强度,如果开关很硬可以考虑提供额外的电源供电来保持舵机输出功率。好在家里的开关还算听话(勉强刚刚好,鬼知道我调整了多少次角度和高度),这次就不额外添加配件了。
参考 B 站的诸多 "关灯神器"视频, 这里单片机选用了 esp8266,类似下图
舵机则是使用了sg90
:
总成本不到 20 元...
(Ps: 网上淘宝现成的开关神器换个马甲,多装个模块就能卖百来块... 可见其中的利润空间,咱们理工男可不能被这种骗了钱去~)
剩下就是控制方案
常见的必然是手机 app 控制,这里必须借助第三方提供,自己写 app 也不是不可以,主要是不想徒增学习成本(说白了还是懒😂),连接方法有蓝牙、WiFi,这里可以看自己的开发板需求。
具体实现#
既然搞定了方案,接下来进行实践环节!
硬件实现#
硬件方面很简单,注意看卖家给的引脚图不要插错即可。
注意观察,如果发现线序不对,可能需要自己拆下舵机的线材固定器更改线序。运气很好,我买的不需要,就直接插上连 PC 就行了
软件实现#
这里需要用到软件和安装包如下
- 8266 开发板的配置包
- 开发板开发软件
- blink 电灯科技第三方应用的适配库文件
- COM 串口驱动
安装 arduino#
首先安装 arduino,直接无脑 next 即可
安装完成后打开 arduino,界面如图:
导入 ESP8266 配置包#
首先打开 Arduino IDE 菜单 > 文件 > 首选项,在 附加开发板管理器网址 输入框中,填入以下网址:https://www.arduino.cn/package_esp8266com_index.json
然后点击文件夹中的配置包:
导入配置。
安装三方库文件#
添加库中添加blinker-library-0.3.80210803.zip
配置开发板#
接下来新建文件 -> 保存一下 -> 如下图配置开发板信息
如果没有8266
开发选项,如下图,搜索8266
,安装上图对应module
接下来就是编写代码,这边已经提供好了一个模板
#define BLINKER_WIFI
#define BLINKER_MIOT_LIGHT
#include <Blinker.h>
#include <Servo.h>
Servo myservo;//定义舵机
char auth[] = "xxxxxxxx"; //点灯Key
char ssid[] = "SELF-WIFI"; //wifi名称
char pswd[] = "password"; //wifi密码
// 新建组件对象,注意这里的名称要和电灯科技app里保持一致
BlinkerButton Button1("test");
int counter = 0;
//注意如果接入小爱同学,其监听的就是这个电源事件
void miotPowerState(const String & state)//电源类操作
{
BLINKER_LOG("need set power state: ", state);
if (state == BLINKER_CMD_ON) {
myservo.write(150);//收到“on”的指令后舵机旋转150度
BlinkerMIOT.powerState("on");
BlinkerMIOT.print();//反馈状态
delay(1000);//延时1秒
myservo.write(90);//舵机归零,回到垂直状态
}
else if (state == BLINKER_CMD_OFF) {
myservo.write(30); //舵机偏转30°
BlinkerMIOT.powerState("off");
BlinkerMIOT.print();
delay(1000);
myservo.write(90);
}
}
// 按下按键即会执行该函数
void button1_callback(const String & state)
{
BLINKER_LOG("get button state: ", state);
if (state=="on")
{
myservo.write(170);//收到“on”的指令后舵机旋转150
delay(1000);//延时
myservo.write(90);//舵机归零垂直
} else if(state=="press"||state=="tap")
{
myservo.write(10);//长按开关按键后舵机旋转10
delay(1000);//延时
myservo.write(90);//舵机归零垂直(90度)
}
}
// 如果未绑定的组件被触发,则会执行其中内容
void dataRead(const String & data)
{
BLINKER_LOG("Blinker readString: ", data);
counter++;
}
void setup()
{
// 初始化串口
Serial.begin(115200);
BLINKER_DEBUG.stream(Serial);
// 初始化舵机
myservo.attach(2);//舵机的IO口,nodemcu的D4口
myservo.write(90);//上电时舵机归零垂直
BlinkerMIOT.attachPowerState(miotPowerState);
// 初始化blinker
Blinker.begin(auth, ssid, pswd);
Blinker.attachData(dataRead);
Button1.attach(button1_callback);
}
void loop() {
BLINKER_LOG("Blinked running...");
Blinker.run();
}
接下来,只需要点击左上角编译通过就完成了。
如果编译没有问题,接下来就需要将程序上传到开发板上。首先注意下图端口,经过之前安装 com 端口驱动,理论上这边端口可以正常显示
如果不能,查看设备管理器看是否端口正常显示。
安装 APP#
还记得代码里的key
吗?接下来就是下载电灯科技 APP 并申请key
一般应用市场都有,如果没有的话可以去官网下.
注册设备#
下载并注册点灯科技账号之后,在右上角加号 -> 独立设备 -> 网络接入
一般推荐阿里云 接入,但是我目前的版本只能接入点灯科技服务,实测无论是控制还是接入小爱同学都没有影响,这里就看大家选择。
完成设备注册后如上图所示,这时你会获取一个key
,填入代码中即可。
开发界面#
这里大家就可以按照代码中发信指引自己制作开关界面。我这边在网上找到一份简单的界面配置文件
{¨config¨{¨headerColor¨¨transparent¨¨headerStyle¨¨dark¨¨background¨{¨img¨¨assets/img/headerbg.jpg¨¨isFull¨«}}¨dashboard¨|{¨type¨¨btn¨¨ico¨¨fad fa-lightbulb-on¨¨mode¨Ê¨t0¨¨开灯¨¨t1¨¨文本2¨¨bg¨Ì¨cols¨Í¨rows¨Í¨key¨¨test¨´x´Ë´y´Ì¨speech¨|÷¨cus¨¨on¨¨lstyle¨Ë¨clr¨¨#076EEF¨}{ßAßBßC¨fad fa-lightbulb¨ßEÉßF¨关灯¨ßHßIßJÌßKÍßLÍßMßN´x´Ë´y´ÑßO|÷ßRËßSßT}{ßA¨deb¨ßEÉßJÉßKÑßLÌßM¨debug¨´x´É´y´¤D}÷¨actions¨|¦¨cmd¨¦¨switch¨‡¨text¨‡ßQ¨打开?name¨¨off¨¨关闭?name¨—÷¨triggers¨|{¨source¨ßa¨source_zh¨¨开关状态¨¨state¨|ßQßd÷¨state_zh¨|¨打开¨¨关闭¨÷}÷}
将这份文件导入到配置信息即可。(上面的乱码是真的(汗))
导入后配置如下:
接下来就可以自己操控查看配置情况了。
接入小爱同学#
接入小爱同学其实很简单,就看第三方服务方提不提供支持
米家 -> 接入其他设备 -> 点灯科技 -> 同步配置即可
设备安装#
这一步在实际操作中反倒是最难的,因为每个人情况不同,按钮的强度也不一样,我一开始还是非常担心舵机的功率可能不足以拨动开关的。实际上确实在尝试了很多角度之后总是无法成功实现。
曾经尝试过给舵机扇叶进行延长增大接触面积,但是这些方案最终没有一个很好的实现。最后我尝试回归起点,通过垫高舵机,使得扇叶和开关产生一定的间隔,这样在扇叶旋转的时候,会有一个惯性辅助用力。接着使用纸板和 502 将舵机固定,并用透明胶在外层进行二次辅助固定,最终总算实现了开关的正常拨动(虽然有的时候还是不太灵敏)
最终实现图如下:
效果#
这里给出一个链接