斐讯插排TC1改造,基于ESP8266和阿里云IOT

最近买了一个63块钱斐讯插排TC1,本来是有远程控制的,由于斐讯倒闭了所以只能当普通排插用。不过远程控制这点小功能可难不倒专业IT码农:),于是直接开干。

拆开外包装的样子,做工真心不错:

开拆,首先拆掉底部的两颗螺丝:


接着用平口螺丝刀翘途中沿线位置把所有底部卡口都撬开就可以开盖了:

先瞧瞧原来的主控

拆掉主控,技术还要多练,掉了一个焊盘

引脚定义,参考贴子
https://www.amobbs.com/thread-5715200-1-1.html

焊上排线

排线的另一端,自己人肉打了标 :)

刚好手上有现成的nodemcu板子,接上

再接上一个温湿度传感器,功能多多益善

装回外壳,由于nodemcu体积有点大,只能这样放在外面了,幸好盖上盖子啥也看不到

网页端控制软件,aliyun IoT Studio拖拽出来的。云端能正常控制,温湿度也正常显示。到此搞定

下面是源代码:

阿里云端的配置,网上教程超级多,我就不一一介绍了。

建好一个产品,然后添加一个设备。在产品里面配置好“自定义功能”这些就是到时候nodemcu和控制端里面要用的字段:

设备详情页面,里面的ProductKey, DeviceName,DeviceSecret在esp8266代码里面需要用到

阿里云账号的区域,在代码里面要用到REGION_ID。我是上海地区的代码就填cn-shanghai

Password生成小工具是阿里云提供的,用于计算MQTT_PASSWD,或者根据规则自己算也可以。timestamp默认全用1234567890就可以

ESP8266代码,直接在Arduino里面写的,目标板子选nodemcu即可。两个###之间的是需要根据各自阿里云配置修改的地方

#include <ESP8266WiFi.h>
/* 依赖 PubSubClient 2.4.0 */
#include <PubSubClient.h>
/* 依赖 ArduinoJson 5.13.4 */
#include <ArduinoJson.h>

#include <DHT.h>


/* 连接您的WIFI SSID和密码 */
#define WIFI_SSID         "###你的wifi名称###"
#define WIFI_PASSWD       "###你的wifi名称###"

/* 设备证书信息*/
#define PRODUCT_KEY       "###你的阿里云PRODUCT_KEY###"
#define DEVICE_NAME       "###你的阿里云DEVICE_NAME###"
#define DEVICE_SECRET     "###你的阿里云DEVICE_SECRET###"
#define REGION_ID         "###你的阿里云REGION_ID###"

/* 线上环境域名和端口号,不需要改 */
#define MQTT_SERVER       PRODUCT_KEY ".iot-as-mqtt." REGION_ID ".aliyuncs.com"
#define MQTT_PORT         1883
#define MQTT_USRNAME      DEVICE_NAME "&" PRODUCT_KEY

#define CLIENT_ID         "###你的阿里云DEVICE_NAME###|securemode=3,timestamp=1234567890,signmethod=hmacsha1|"
// 请使用以上说明中的加密工具或参见MQTT-TCP连接通信文档加密生成password。
// 加密明文是参数和对应的值(clientId${deviceName}deviceName${deviceName}productKey${productKey}timestamp1234567890)按字典顺序拼接
// 密钥是设备的DeviceSecret
#define MQTT_PASSWD       "###根据Password生成小工具算出来的密码,或者自己根据定义算出来的密码###"

#define ALINK_BODY_FORMAT         "{"id":"123","version":"1.0","method":"thing.event.property.post","params":%s}"
#define ALINK_TOPIC_PROP_POST     "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post"

int LightSwitch = 0;
int LightSwitch1 = 0;   
int LightSwitch2 = 0;   
int CurtainSwitch = 0;   
int CurtainSwitch1 = 0;   
int CurtainSwitch2 = 0;

#define LightSwitchPin 5  //D1
#define LightSwitch1Pin 4  //D2
#define LightSwitch2Pin 15 //D8
#define CurtainSwitchPin 13  //D7
#define CurtainSwitch1Pin 14  //D5
#define CurtainSwitch2Pin 12  //D6

#define DHTPIN 10 //SD3

unsigned long lastMs = 0;
WiFiClient espClient;
PubSubClient  client(espClient);
DHT dht(DHTPIN, DHT11,15);

bool refreshStatus = false;

void callback(char *topic, byte *payload, unsigned int length)
{
    Serial.print("Message arrived [");
    Serial.print(topic);
    Serial.print("] ");
    payload[length] = '\0';
    Serial.println((char *)payload);
    DynamicJsonBuffer jsonBuffer;
    JsonObject& root = jsonBuffer.parseObject((char *)payload);
    if (!root.success())
    {
      Serial.print("parseObject(");
      Serial.print((char *)payload);
      Serial.println(") failed");
    }
    else
    {
      //###下面json里面的字段需要根据你产品定义里面的功能字段做修改###
      JsonObject& params = root["params"];
      if(params.containsKey("LightSwitch"))
      {
        LightSwitch = params["LightSwitch"];
        Serial.print("LightSwitch: ");
        Serial.print(LightSwitch);
      }
      if(params.containsKey("LightSwitch1"))
      {
        LightSwitch1 = params["LightSwitch1"];
        Serial.print("LightSwitch1: ");
        Serial.print(LightSwitch1);
      }
      if(params.containsKey("LightSwitch2"))
      {
        LightSwitch2 = params["LightSwitch2"];
        Serial.print("LightSwitch2: ");
        Serial.print(LightSwitch2);
      }
      if(params.containsKey("CurtainSwitch"))
      {
        CurtainSwitch = params["CurtainSwitch"];
        Serial.print("CurtainSwitch: ");
        Serial.print(CurtainSwitch);
      }
      if(params.containsKey("CurtainSwitch1"))
      {
        CurtainSwitch1 = params["CurtainSwitch1"];
        Serial.print("CurtainSwitch1: ");
        Serial.print(CurtainSwitch1);
      }
      if(params.containsKey("CurtainSwitch2"))
      {
        CurtainSwitch2 = params["CurtainSwitch2"];
        Serial.print("CurtainSwitch2: ");
        Serial.print(CurtainSwitch2);
      }
    }
    refreshStatus = true;
}


void wifiInit()
{
    WiFi.mode(WIFI_STA);
    WiFi.begin(WIFI_SSID, WIFI_PASSWD);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(1000);
        Serial.println("WiFi not Connect");
    }

    Serial.println("Connected to AP");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());

    
Serial.print("espClient [");


    client.setServer(MQTT_SERVER, MQTT_PORT);   /* 连接WiFi之后,连接MQTT服务器 */
    client.setCallback(callback);
}


void mqttCheckConnect()
{
    while (!client.connected())
    {
        Serial.println("Connecting to MQTT Server ...");
        if (client.connect(CLIENT_ID, MQTT_USRNAME, MQTT_PASSWD))

        {

            Serial.println("MQTT Connected!");

        }
        else
        {
            Serial.print("MQTT Connect err:");
            Serial.println(client.state());
            delay(5000);
        }
    }
}


void mqttIntervalPost()
{
    float h = dht.readHumidity();
    float t = dht.readTemperature();
    if (isnan(h) || isnan(t)) {
      Serial.println("Failed to read from DHT sensor!");
      return;
    }
    
    char param[128];
    char jsonBuf[256];
    //###下面json里面的字段需要根据你产品定义里面的功能字段做修改###
    sprintf(param, 
          "{"Temperature":%f,"Humidity":%f,"LightSwitch":%d,"LightSwitch1":%d,"LightSwitch2":%d,"CurtainSwitch":%d,"CurtainSwitch1":%d,"CurtainSwitch2":%d}"
          ,t
          ,h
          ,LightSwitch
          ,LightSwitch1
          ,LightSwitch2
          ,CurtainSwitch
          ,CurtainSwitch1
          ,CurtainSwitch2);
    sprintf(jsonBuf, ALINK_BODY_FORMAT, param);
    Serial.println(jsonBuf);
    boolean d = client.publish(ALINK_TOPIC_PROP_POST, jsonBuf);
    Serial.print("publish:0 失败;1成功");
    Serial.println(d);
}


void setup() 
{
    pinMode(LED_BUILTIN, OUTPUT);     // Initialize the LED_BUILTIN pin as an output   
    pinMode(LightSwitchPin, OUTPUT);
    pinMode(LightSwitch1Pin, OUTPUT);
    pinMode(LightSwitch2Pin, OUTPUT);
    pinMode(CurtainSwitchPin, OUTPUT);
    pinMode(CurtainSwitch1Pin, OUTPUT);
    pinMode(CurtainSwitch2Pin, OUTPUT);
                

    /* initialize serial for debugging */
    Serial.begin(115200);
    Serial.println("Demo Start");

    wifiInit();
    dht.begin();
}


// the loop function runs over and over again forever
void loop()
{
    //IO输出
    if(LightSwitch)
    {
      digitalWrite(LightSwitchPin, HIGH);
    }
    else
    {
      digitalWrite(LightSwitchPin, LOW);
    }
    if(LightSwitch1)
    {
      digitalWrite(LightSwitch1Pin, HIGH);
    }
    else
    {
      digitalWrite(LightSwitch1Pin, LOW);
    }
    if(LightSwitch2)
    {
      digitalWrite(LightSwitch2Pin, HIGH);
    }
    else
    {
      digitalWrite(LightSwitch2Pin, LOW);
    }
    if(CurtainSwitch)
    {
      digitalWrite(CurtainSwitchPin, HIGH);
    }
    else
    {
      digitalWrite(CurtainSwitchPin, LOW);
    }
    if(CurtainSwitch1)
    {
      digitalWrite(CurtainSwitch1Pin, HIGH);
    }
    else
    {
      digitalWrite(CurtainSwitch1Pin, LOW);
    }
    if(CurtainSwitch2)
    {
      digitalWrite(CurtainSwitch2Pin, HIGH);
    }
    else
    {
      digitalWrite(CurtainSwitch2Pin, LOW);
    }
    //提交数据
    if ((millis() - lastMs >= 60000) || refreshStatus)
    {
        refreshStatus = false;
        lastMs = millis();
        mqttCheckConnect(); 
        /* 上报消息心跳周期 */
        mqttIntervalPost();
    }
    client.loop();
    Serial.println("Loop!");
    digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
    delay(1000);                       // wait for a second
    digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
    delay(1000);                       // wait for a second
}

串口日志

15:50:37.598 -> Loop!
15:50:39.578 -> Loop!
15:50:41.602 -> Loop!
15:50:43.584 -> Loop!
15:50:45.596 -> Loop!
15:50:47.598 -> Loop!
15:50:49.608 -> Connecting to MQTT Server ...
15:50:49.678 -> MQTT Connected!
15:50:49.713 -> {"id":"123","version":"1.0","method":"thing.event.property.post","params":{"Temperature":31.000000,"Humidity":13.000000,"LightSwitch":0,"LightSwitch1":0,"LightSwitch2":0,"CurtainSwitch":0,"CurtainSwitch1":0,"CurtainSwitch2":0}}
15:50:49.713 -> publish:0 失败;1成功1
15:50:49.713 -> Loop!
15:50:51.705 -> Loop!
15:50:53.710 -> Loop!
15:50:55.714 -> Loop!
15:50:57.686 -> Loop!
15:50:59.693 -> Loop!
15:51:01.722 -> Message arrived [/sys/a1myZkJoTPx/esp8266_01/thing/service/property/set] {"method":"thing.service.property.set","id":"944037471","params":{"LightSwitch1":1},"version":"1.0.0"}
15:51:01.722 -> LightSwitch1: 1Loop!
15:51:03.757 -> {"id":"123","version":"1.0","method":"thing.event.property.post","params":{"Temperature":32.000000,"Humidity":13.000000,"LightSwitch":0,"LightSwitch1":1,"LightSwitch2":0,"CurtainSwitch":0,"CurtainSwitch1":0,"CurtainSwitch2":0}}
15:51:03.757 -> publish:0 失败;1成功1
15:51:03.757 -> Loop!
15:51:05.766 -> Loop!
15:51:07.753 -> Message arrived [/sys/a1myZkJoTPx/esp8266_01/thing/service/property/set] {"method":"thing.service.property.set","id":"944038010","params":{"LightSwitch1":0},"version":"1.0.0"}
15:51:07.753 -> LightSwitch1: 0Loop!
15:51:09.805 -> {"id":"123","version":"1.0","method":"thing.event.property.post","params":{"Temperature":32.000000,"Humidity":13.000000,"LightSwitch":0,"LightSwitch1":0,"LightSwitch2":0,"CurtainSwitch":0,"CurtainSwitch1":0,"CurtainSwitch2":0}}
15:51:09.805 -> publish:0 失败;1成功1
15:51:09.805 -> Loop!
15:51:11.797 -> Loop!
15:51:13.815 -> Message arrived [/sys/a1myZkJoTPx/esp8266_01/thing/service/property/set] {"method":"thing.service.property.set","id":"944038559","params":{"LightSwitch":1},"version":"1.0.0"}
15:51:13.815 -> LightSwitch: 1Loop!
15:51:15.862 -> {"id":"123","version":"1.0","method":"thing.event.property.post","params":{"Temperature":32.000000,"Humidity":13.000000,"LightSwitch":1,"LightSwitch1":0,"LightSwitch2":0,"CurtainSwitch":0,"CurtainSwitch1":0,"CurtainSwitch2":0}}
15:51:15.862 -> publish:0 失败;1成功1
15:51:15.862 -> Loop!
15:51:17.850 -> Loop!
15:51:19.872 -> Message arrived [/sys/a1myZkJoTPx/esp8266_01/thing/service/property/set] {"method":"thing.service.property.set","id":"944039031","params":{"LightSwitch":0},"version":"1.0.0"}
15:51:19.872 -> LightSwitch: 0Loop!
15:51:21.906 -> {"id":"123","version":"1.0","method":"thing.event.property.post","params":{"Temperature":32.000000,"Humidity":13.000000,"LightSwitch":0,"LightSwitch1":0,"LightSwitch2":0,"CurtainSwitch":0,"CurtainSwitch1":0,"CurtainSwitch2":0}}
15:51:21.906 -> publish:0 失败;1成功1
15:51:21.906 -> Loop!
15:51:23.892 -> Loop!
15:51:25.898 -> Loop!
15:51:27.905 -> Message arrived [/sys/a1myZkJoTPx/esp8266_01/thing/service/property/set] {"method":"thing.service.property.set","id":"944039692","params":{"CurtainSwitch1":1},"version":"1.0.0"}
15:51:27.905 -> CurtainSwitch1: 1Loop!
15:51:29.952 -> {"id":"123","version":"1.0","method":"thing.event.property.post","params":{"Temperature":32.000000,"Humidity":13.000000,"LightSwitch":0,"LightSwitch1":0,"LightSwitch2":0,"CurtainSwitch":0,"CurtainSwitch1":1,"CurtainSwitch2":0}}
15:51:29.952 -> publish:0 失败;1成功1
15:51:29.952 -> Loop!
15:51:31.940 -> Loop!
15:51:33.940 -> Loop!
15:51:35.948 -> Loop!
15:51:37.958 -> Loop!
15:51:39.943 -> Loop!
15:51:41.942 -> Loop!
发表在 单片机, 文章 | 标签为 , , , | 留下评论

群晖SurveillanceStation连接萤石C6Tc摄像头

继续阅读

发表在 文章 | 留下评论

【雕刻机】制作雕刻机控制箱

继续阅读

发表在 作品, 雕刻机 | 标签为 , | 留下评论

【算法练习题】纸牌游戏——小猫钓鱼

继续阅读

发表在 文章, 算法 | 留下评论

【算法练习题】排序合集

继续阅读

发表在 文章, 算法 | 留下评论

【算法练习题】求解数组最大差值

继续阅读

发表在 文章, 算法 | 留下评论

【C#】Visual Studio 常用快捷键

继续阅读

发表在 文章 | 留下评论

【C#】通过调用minitab自动化生成报表

继续阅读

发表在 .NET, 文章 | 留下评论

【C#】ASCII和十六进制码转换小工具ASCII2Hex

继续阅读

发表在 作品, 应用程序 | 留下评论

【SharePoint】基于SPServices获取list中文件夹列表及列表中文件

继续阅读

发表在 SharePoint, 文章 | 留下评论