发作品签到
专业版

电动翻转插座

工程标签

2.5k
0
0
2

简介

智能电动翻转插座,不但可以通过插座上的按键控制插座翻转,而且可以通过WIFI连接巴法云服务器进行远程控制,当接入巴法云后,可以通过米家进行与小爱智能音箱连接,实现语音控制

简介:智能电动翻转插座,不但可以通过插座上的按键控制插座翻转,而且可以通过WIFI连接巴法云服务器进行远程控制,当接入巴法云后,可以通过米家进行与小爱智能音箱连接,实现语音控制
星火计划2023

开源协议

GPL 3.0

(未经作者授权,禁止转载)
创建时间:2023-06-29 19:36:54更新时间:2024-02-21 08:51:20

描述

电动翻转插座

随着我们身边充电设备的逐渐增多,如手机,平板,手表,耳机,鼠标,键盘,台灯,电子烟,游戏手柄,笔记本电脑等等。插座的使用率变得逐渐增多,插孔数量变得越来越多,随着插孔数量的变多,插座的体积也在逐渐增大,美观和便携上就变得尤为笨重麻烦。于是我在想能不能设计一款非常方便,且智能的插座,来满足生活的需要,考虑到我的这些电子设备大部分都是在桌面上使用,那么如果将桌面与插座相结合,做成隐藏式的岂不是非常漂亮,想到这里我打开了某宝,果然在上面找到了相匹配的插座,居然可以通过翻转进行隐藏在桌子下面,但是这个价格实在是贵的吓人最便宜的居然要700多,作为一个电子爱好者,这个钱是万万不能花的,于是乎我有了一个大胆的想法“自己做”。

由于我并不知道插座的内部结构是什么样的,所以只能凭借自己的一点经验进行遐想:翻转功能:用舵机搞定;插座:可以购买网上现成的PDU移位插座进行拼装;在加几路USB接口,用来充手表,游戏手柄;当然手机的快充功能也还是要有的;于是我把最终插座的功能确定了下来:四路五孔插座用于满足一些家用电器的需要;两个USB充电接口,两个TYPE-C充电接口,一路TYPE-c下载接口(后面会将作用),当然无线充电功能是必须要有的。

所有的硬件我都会一一详细的列举出来,如图1

3D打印件

序号

名称

数量

翻转外仓-1

1

翻转外仓-2

1

翻转内仓-1

1

翻转内仓-2

1

线缆压块

1

桌子固定块

1

翻转内仓-3

1

序号

名称

数量

舵机MG995-180

1

轴承 6805(内径:25 外径:37 厚度7

1

一位五孔插座(嵌入卡式)

4

舵机配套连杆

1

 

5米电源线

1

 

电源适配器220VDC24V8A

1

 

1

 

第一步:将所有3D打印零件全部打印好,把7号“轴承”放入1号“翻转外仓-1”的圆孔中,如图2所示

 

2

 

第二步:将3号“翻转插座内仓-1”凸出的一段插入7号“轴承”内部,如图3,安装完成后如图4所示。

 

   

            

              3                                          4

第三步:将6号“舵机”与5号“翻转内仓-2”安装在一起,并使用螺丝固定,如图5所示

 

5

第四步: 3号“翻转内仓-1”开口一侧的螺丝孔进行热熔螺母M1.6*3*2.5如图6所示:

 

 

 

            

    6                                         7

第五步:将装配好的5号“翻转内仓-2”与3号“翻转内仓-1”固定在一起,如图7所示:

第六步:将PCB-USB板与无线充电线圈安装在3号“翻转内仓-1”的内部,并使用螺丝固定如图8所示:

 

   

 

8                                            9

第七步:将PCB上的四条黑线与USB板连接的排线,以及无线充电线圈的排线全部引出如图9所示(PCB板详细说明如下:)

 

第八步:把电路板固定到11号“翻转内仓-3”,并将四根火线引到四个插座孔,如图10所示:

   

10                                                        11

第九步: 准备两条导线作为五孔插座的(零线,地线)并进行剥皮分割,如图11

第十步: 将插座与黑色导线进行连接固定(黑色接入插座的L端子),如图12所示

 

 12                                                                        13

第十一步: 将准备好的两组导线和黑色(火线)一样穿过孔洞并联在一起,分别接入插座的N端子,与底线端子,如图13所示(靠近轴承方向的第一个插座可以暂时不接,因为下一步要接电源线)

第十二步: 准备一条电源线(1.5)如图14,并穿过轴承孔洞如图15,分别将N零线与地线接到第一个插座的端子上,如图16

        

14                                                           16                                          15

第十三步: 经电源线的火线焊接在电路板上,同时如果在DC24那里焊接了DC端子母座,需要先将电源线拔出后,插入电源适配器端子,在插入电源线,否则适配器端子头太大了,进不去轴承孔洞,如果没有焊接,可以将电源适配器赠送的导线焊接在PCB上引出,如图16所示

 

16                                             17

第十四步: PCBUSB板的连接导线一一连接,不要忘了连接舵机与无线充电线圈,并将两个按键的导线也引出来如图17所示

第十五步: 11号“翻转内仓-3”与PCB板固定如图18并与3号“翻转内仓-1”进行安装固定如图19所示

     

18                                                                  19

第十六步:将按键的导线从侧面引出穿过按键孔洞如图20,并焊接按键如图21所示

   

       20                                                       21

第十七步:将按键固定在凹槽内,并将导线在凹槽内理顺如图22,在下方两个螺丝孔安装两个M3的热熔螺母,并将9号“线缆压块”安装在侧面,如图23所示

 

        22                                         23

第十八步: 2号“翻转外仓-2”安装在舵机的一侧如图24,将8号“舵机配套连杆”安装在凹槽内,并用螺丝固定如图所示25,并在底部安装M3热熔螺母。

 

     24                                        25

到这里整个电动翻转插座就彻底组装完了。

 

接下来是是软件程序部分:

#include 

#include 

 

#define server_ip "bemfa.com"  //巴法云服务器地址默认即可

#define server_port "8344"  //服务器端口号

 

#define wifi_name "*******"  //自己家的WIFI名称

#define wifi_password "*****"//自己家的WIFI密码

String UID = "*******";   //用户私钥  注册一个云服务器,本次程序使用的云服务器为巴法云巴法科技&巴法云-巴法设备云-巴法物联网云平台 (bemfa.com)

           

//主题名字

String TOPIC1 = "1fzcz006"; //翻转控制

String TOPIC2 = "2fzcz006"; //1号继电器控制

String TOPIC3 = "3fzcz006"; //2号继电器控制

 

const int KEY = 2;          //定义一个按键控制舵机旋转

const int JiDianQi1 = 14;

const int JiDianQi2 = 12;

 

Servo myservo;

 

#define MAX_PACKETSIZE 512 //最大字节数

#define KEEPALIVEATIME 60*1000 //设置心跳值60s

 

WiFiClient TCPclient;   //tcp客户端相关初始化,默认即可

String TcpClient_Buff = "";  //初始化字符串,用于接受服务器发送的数据

unsigned int TcpClient_BuffIndex = 0;

unsigned long TcpClient_preTick = 0;

unsigned long preHeartTick = 0;        //心跳

unsigned long preTCPStartTick = 0;     //连接

bool preTCPConnected = false;

 

void doWiFiTick();

void startSTA();

 

void doTCPClientTick();

void startTCPClient();

void sendtoTCPServer(String p);

 

int servoState = HIGH;     //舵机当前状态

int buttonState ;         //按钮当前状态

int lastButtonState = LOW;//上一次按钮的状态

bool servoTurnedOn = false;

 

int pos = 0;

unsigned long lastDebounceTime = 0;

unsigned long debounceDelay = 50;

int angle;

int val=180;

int val1=0;

 

/*

  *发送数据到TCP服务器

 */

void sendtoTCPServer(String p){

  if (!TCPclient.connected()) 

  {

    Serial.println("Client is not readly");//客户端未读取

    return;

  }

  TCPclient.print(p);

  preHeartTick = millis();//心跳计时开始,需要每隔60秒发送一次数据

}

 

/*

  *初始化和服务器建立连接

*/

void startTCPClient(){

  if(TCPclient.connect(server_ip, atoi(server_port))){

    Serial.print("\nConnected to server:");

    Serial.printf("%s:%d\r\n",server_ip,atoi(server_port));

   

    String tcpTemp="";  //初始化字符串

    tcpTemp = "cmd=1&uid="+UID+"&topic="+TOPIC1+","+TOPIC2+","+TOPIC3+"\r\n"; //构建订阅指令

    sendtoTCPServer(tcpTemp); //发送订阅指令

    tcpTemp="";//清空

    /*

     //如果需要订阅多个主题,可发送  cmd=1&uid=xxxxxxxxxxxxxxxxxxxxxxx&topic=xxx1,xxx2,xxx3,xxx4\r\n

    教程:https://bbs.bemfa.com/64

     */

   

    preTCPConnected = true;

    TCPclient.setNoDelay(true);

  }

  else{

    Serial.print("Failed connected to server:");

    Serial.println(server_ip);

    TCPclient.stop();

    preTCPConnected = false;

  }

  preTCPStartTick = millis();

}

 

//检查数据发送心跳

void doTCPClientTick(){

  int but;

  //检查是否断开,断开后重连

  if(WiFi.status() != WL_CONNECTED) return;

  if (!TCPclient.connected()) {//断开重连

  if(preTCPConnected == true){

    preTCPConnected = false;

    preTCPStartTick = millis();

    Serial.println();

    Serial.println("TCP Client disconnected.");

    TCPclient.stop();

  }

  else if(millis() - preTCPStartTick > 1*1000)//重新连接

    startTCPClient();

  }

  else

  {

    if (TCPclient.available()) {//收数据

      char c =TCPclient.read();

      TcpClient_Buff +=c;

      TcpClient_BuffIndex++;

      TcpClient_preTick = millis();

     

      if(TcpClient_BuffIndex>=MAX_PACKETSIZE - 1){

        TcpClient_BuffIndex = MAX_PACKETSIZE-2;

        TcpClient_preTick = TcpClient_preTick - 200;

      }

 

    }

    if(millis() - preHeartTick >= KEEPALIVEATIME){//保持心跳

      preHeartTick = millis();

      Serial.println("--Keep alive:");

      sendtoTCPServer("ping\r\n"); //发送心跳,指令需\r\n结尾,详见接入文档介绍

    }

  }

  if((TcpClient_Buff.length() >= 1) && (millis() - TcpClient_preTick>=200))

  {

    TCPclient.flush();

    Serial.print("Rev string: ");

    TcpClient_Buff.trim(); //去掉首位空格

    Serial.println(TcpClient_Buff); //打印接收到的消息

    String getTopic = "";

    String getMsg = "";

    if(TcpClient_Buff.length() > 15){//注意TcpClient_Buff只是个字符串,在上面开头做了初始化 String TcpClient_Buff = "";

          //此时会收到推送的指令,指令大概为 cmd=2&uid=xxx&topic=light002&msg=off

          int topicIndex = TcpClient_Buff.indexOf("&topic=")+7; //c语言字符串查找,查找&topic=位置,并移动7位,不懂的可百度c语言字符串查找

          int msgIndex = TcpClient_Buff.indexOf("&msg=");//c语言字符串查找,查找&msg=位置

          getTopic = TcpClient_Buff.substring(topicIndex,msgIndex);//c语言字符串截取,截取到topic,不懂的可百度c语言字符串截取

          getMsg = TcpClient_Buff.substring(msgIndex+5);//c语言字符串截取,截取到消息

          Serial.print("topic:------");

          Serial.println(getTopic); //打印截取到的主题值

          Serial.print("msg:--------");

          Serial.println(getMsg);   //打印截取到的消息值

   }

   

     if(getTopic == TOPIC1){//当翻转功能触发

       if(getMsg == "on"){  

             servoTurnedOn = true;

             myservo.write(180);

             Serial.println("翻转");

             

        }else if(getMsg == "off"){

           servoTurnedOn = false;

           myservo.write(0);

           Serial.println("转回");

           

       }

 

     }else if(getTopic == TOPIC2){ //当一号继电器触发

 

       if(getMsg == "on"){

        digitalWrite(JiDianQi1, HIGH);

        Serial.println("继电器1开");

       }else if(getMsg == "off"){

        digitalWrite(JiDianQi1, LOW);

        Serial.println("继电器1关");

       }

 

     }else if(getTopic == TOPIC3){ //当二号继电器触发

       if(getMsg == "on"){

        digitalWrite(JiDianQi2, HIGH);

        Serial.println("继电器2开");

       }else if(getMsg == "off"){

        digitalWrite(JiDianQi2, LOW);

        Serial.println("继电器2关");

       }

     }

     TcpClient_Buff="";

     TcpClient_BuffIndex = 0;

  }

}

 

void startSTA(){

  WiFi.disconnect();

  WiFi.mode(WIFI_STA);

  WiFi.begin(wifi_name, wifi_password);

}

 

//WiFiTick  检查是否需要初始化wifi,检查是否wifi连接上,若连接成功启动TCP Client

void doWiFiTick(){

  static bool startSTAFlag = false;// 启动STA模式

  static bool taskStarted = false; //任务已启动

  static uint32_t lastWiFiCheckTick = 0;//最后WiFi检查滴答声

 

  if (!startSTAFlag) {

    startSTAFlag = true;

    startSTA();

  }

 

  //未连接1s重连

  if ( WiFi.status() != WL_CONNECTED ) {

    if (millis() - lastWiFiCheckTick > 1000) {

      lastWiFiCheckTick = millis();

    }

  }

  //连接成功建立

  else {

    if (taskStarted == false) {

      taskStarted = true;

      Serial.print("\r\nGet IP Address: ");

      Serial.println(WiFi.localIP());

      startTCPClient();

    }

  }

}

 

void setup() {

  Serial.begin(115200);

  pinMode(KEY, INPUT_PULLUP);

  pinMode(JiDianQi1, OUTPUT);

  pinMode(JiDianQi2, OUTPUT);

 

  digitalWrite(JiDianQi1, LOW);

  digitalWrite(JiDianQi2, LOW);

 

  myservo.attach(13,500,2450);

  myservo.write(0);

 

}

 

void KEY_1(){

  int reading = digitalRead(KEY);

 

  if(reading != lastButtonState){//这次读取的状态,与上次不相等,说明按钮发生了变化

    lastDebounceTime = millis();//当前变换幅值时间

  }

 

  if((millis() - lastDebounceTime) > debounceDelay){

    if(reading != buttonState){

      buttonState = reading;

 

      if(buttonState == HIGH){

       // servoState = !servoState;

        servoTurnedOn = !servoTurnedOn;

      }

    }

  }

    if (servoTurnedOn){

      myservo.write(0);

    }else{

      myservo.write(180);

    }

  /*if (servoState == HIGH){

        myservo.write(0);  

   }

   if(servoState == LOW){

       myservo.write(180);

    }*/

    lastButtonState = reading;

}

 

void loop() {

 

  doWiFiTick();

  doTCPClientTick();

  KEY_1();

}

 

 

这个程序非常简单,用户只需要修改这几项:

#define wifi_name "*******"  //自己家的WIFI名称

#define wifi_password "*****"//自己家的WIFI密码

String UID = "*******";   //用户私钥  注册一个云服务器,本次程序使用的云服务器为巴法云巴法科技&巴法云-巴法设备云-巴法物联网云平台 (bemfa.com)

将自己注册好的的账号私钥复制到程序String UID = "*******";

修改完成后,进入巴法云,创建主题如图27所示

27

 

注意:

私钥表示:在程序中的String UID = "*******";   //用户私钥

巴法云中的新建主题表示:String TOPIC1 = "1fzcz006"; //翻转控制

String TOPIC2 = "2fzcz006"; //1号继电器控制

String TOPIC3 = "3fzcz006"; //2号继电器控制

三个设备要和程序中的命名,一一对应;

第二步: 安装巴法云APP,图28安装并登录好后,开关设备中就会显示刚刚创建的三个主题如图29所示;(可以去官网下载,也可以扫描二维码)

            图28

 

                                         

 图29                                                         30                                     31

第三步: 打开APP测试一下,翻转插座有没有反应,如果可以正常使用进入“米家APP”进行关联同步设备,打开米家APP,点击“我的”找到“连接其他平台”如图30,点击“添加”这里我已经添加好了,搜索或找到“巴法云”进行添加,添加完成之后,就可以使用小爱音响控制啦!

32

说明:在这个插座上我做了一些,长远考虑的设计;

比如:1. 因为我经常出差,我把ESP8266下载接口引出来,方便以后升级程序,

2. 我在插座上预留了两个按键,其中一共是控制插座翻转,另一个可以根据需要自定义,本来计划控制卧式里的照明灯的,但是时间不够了,我又要上班了。

 

设计图

未生成预览图,请在编辑器重新保存一次

BOM

暂无BOM

附件

序号文件名称下载次数
1
Electric-flip-socket.ino
6
2
2024-1-31-电动翻转插座-装配体1.SLDASM
7
3
202402211356.mp4
65
克隆工程
添加到专辑
0
0
分享
侵权投诉

工程成员

评论

全部评论(1)
按时间排序|按热度排序
粉丝0|获赞0
相关工程
暂无相关工程

底部导航