一、 介绍
本项目要实现的是一个通过手机APP控制寝室灯开关的辅助工具。
项目框图如下图所示。
实现原理
- 手机和本模块都接入同一个wifi网络,手机端发送命令,本模块执行相应的命令。
二、硬件设计
2.1 主控
ESP8266串口WIFI ESP-12F
ESP8266-12F是ESP8266-12的增强版。
2.2 原理图设计 2.2.1 控制板 本项目实际上只需要一个GPIO口来控制舵机即可。 将其他的引脚引入是为了后续可能扩展其他功能使用。 2.2.2 电源板 ESP12F模组3.3v供电,舵机5v供电。 使用了一片AMS1117-3.3v和一片AMS1117-5v芯片,实现12v至3.3v和5v的转换。 ( 由于寝室开关座子附近有一个插座,所以就直接找了一个输入220v输出12v点的电源线,作为电源板的输入电源 ) 2.3 PCB设计 2.3.1 控制板PCB
需要注意ESP12F模组天线部分的布局,与周围的PCB要有大于5mm的间距。 2.3.2 电源板PCB 三、软件设计 3.1 控制程序
开发环境使用的是Arduino IDE。 要实现的功能有两大块 - #include <ESP8266WiFi.h>
- #include <WiFiUdp.h>
- typedef unsigned char u8;
- typedef unsigned short u16;
- typedef unsigned int u32;
- /*********************** 舵机相关 ************************/
- // 连接舵机的引脚
- #define STEER_PIN 13
- typedef enum SWITCH_STATE{
- SWITCH_ON,
- SWITCH_OFF
- }SWITCH_STATE;
- typedef struct SWITCH_CONTROL{
- u16 switch_on;
- u16 switch_off;
- SWITCH_STATE switch_state;
- }SWITCH_CONTROL;
- void Steer_Init_PWM(){
- pinMode(STEER_PIN,OUTPUT);
- }
- /**
- * 根据pwm高电平时间(us)控制舵机
- */
- void Steer_SetAngle_PWM(u16 pwm) {
- u8 index = 0;
- // 控制舵机转动
- for(index = 0;index<10;index++){
- digitalWrite(STEER_PIN,HIGH);
- delayMicroseconds(pwm);
- digitalWrite(STEER_PIN,LOW);
- delayMicroseconds(20000 - pwm);
- }
- }
- SWITCH_CONTROL switch_contrl = {
- .switch_on = 2300,
- .switch_off = 1400,
- .switch_state = SWITCH_OFF
- };
- void Change_Switch_State( u8 switch_state ) {
- if( switch_state == SWITCH_ON){
- Steer_SetAngle_PWM(switch_contrl.switch_on);
- switch_contrl.switch_state = SWITCH_ON;
- }else if(switch_state == SWITCH_OFF){
- Steer_SetAngle_PWM(switch_contrl.switch_off);
- switch_contrl.switch_state = SWITCH_OFF;
- }else{
-
- }
- }
- /*******************************************************/
- /*********************** WIFI相关 ***********************/
- typedef enum WIFI_STATE{
- WIFI_OK,
- WIFI_ERROR,
- UDP_OK,
- UDP_ERROR
- }WIFI_STATE;
- typedef enum USER_CMD {
- CMD_ERROR,
- CMD_SWITCH_ON,
- CMD_SWITCH_OFF
- }USER_CMD;
- #define UDP_PORT 6666
- #define BUF_LEN 20
- const char* ssid = "xxxxx"; //wifi name
- const char* passwd = "xxxxx";//wifi passwd
- // buf
- unsigned char udp_buf[BUF_LEN] = {0};
- WiFiUDP Udp;
- u8 WIFI_Init(const char* wifi_ssid, const char* wifi_passwd){
- u8 counter = 0;
- WiFi.begin(wifi_ssid, wifi_passwd);
- while (WiFi.status() != WL_CONNECTED) {
- counter++;
- delay(500);
- //10秒后如果还是连接不上,就判定为连接超时
- if (counter > 20) return WIFI_ERROR;
- }
- return WIFI_OK;
- }
- u8 UDP_Init(u16 port) {
- if(Udp.begin(port)){ //启动Udp监听服务
- return UDP_OK;
- }else {
- return UDP_ERROR;
- }
- }
- u8 Get_UDP_Packet(unsigned char * buf,u8 buf_len){
- int packetSize = Udp.parsePacket();//获得解析包
- if(Udp.available()){
- return Udp.read(buf, buf_len);
- }else{
- return 0;
- }
- }
- /**
- * 定义报文格式
- * 1B 1B
- * 0xff cmd
- * 开关灯的cmd: 0x00:关灯 0x01:开灯
- */
- u8 Parse_UDP_Packet(unsigned char * data,u8 data_len){
- if( data[0] != 0xff ) return CMD_ERROR;
- if( data[1] == 0x00 ) return CMD_SWITCH_OFF;
- else if( data[1] == 0x01 ) return CMD_SWITCH_ON;
- else return CMD_ERROR;
- }
- void Execute_Cmd(u8 cmd){
- switch( cmd ) {
- case CMD_SWITCH_ON:
- Change_Switch_State(SWITCH_ON);
- break;
- case CMD_SWITCH_OFF:
- Change_Switch_State(SWITCH_OFF);
- break;
- default:
- break;
- }
- }
- /*******************************************************/
- void setup() {
- Serial.begin(9600); // 波特率9600
- Steer_Init_PWM();
- if(WIFI_Init(ssid,passwd) == WIFI_OK) {
- Serial.println(WiFi.localIP()); // 打印ip地址
- if( UDP_Init(UDP_PORT) ) {
- Serial.printf("UDP监听端口:%d\r\n",UDP_PORT);
- }else{
- Serial.println("UDP Init Failed");
- }
- }else{
- Serial.println("WIFI Init Failed");
- }
- }
- void loop() {
- u8 datalen = Get_UDP_Packet(udp_buf,BUF_LEN);
- if( datalen == 0 ) return ;
- u8 user_cmd = Parse_UDP_Packet(udp_buf,datalen);
- if( user_cmd == CMD_ERROR ) return;
- Execute_Cmd(user_cmd);
- }
复制代码3.2 手机APP程序
使用Flutter开发手机APP,实现遥控灯的开关。 界面设计较为简单,只有两个功能按键,分别对应灯的开与关。 四、外壳设计
五、结果展示 将辅助工具与灯座进行固定,使用的是纳米胶。( 直接粘在灯座上,不要粘在墙上-->直接导致墙皮脱落) ( 这里使用了一块黑色的废PCB板的原因,这个开关座子是一个双开开关,控制两个灯,粘上了一块板子将一个双开开关合成一个整体 )
六、附件 1. 控制板制板文件 |