新建文本文档

点灯科技+esp8266+四路继电器+dht11湿温度计

最近迷上了esp8266,看一一些大佬的代码,组合成了一个四路继电器联合点灯科技,小爱语音,上传湿温度数据

软件

Arduino ide 可直接百度官网下载 如何配置有很多教程 此处不赘述了

代码

#define BLINKER_WIFI               //支持wifi
#define BLINKER_ESP_SMARTCONFIG    //Smartconfig或者手机微信扫码自动配网,代码配网请注释此条
#define BLINKER_MIOT_MULTI_OUTLET  //支持多路插座,最多4个插孔
#define BLINKER_PRINT Serial       //串口协议库
#define BLINKER_WITHOUT_SSL        //blinker默认使用加密方式进行远程通信,但通信加密会消耗大量的RAM,如果您对通信安全性无要求
//可以添加宏BLINKER_WITHOUT_SSL用以获得更多可用RAM,BLINKER_WITHOUT_SSL目前仅可用于ESP8266,其他设备的RAM足以进行加密通信
//#define BLINKER_WIFI_SUBDEVICE

#include <Blinker.h>               //使用第三方Blinker库
#include <EEPROM.h>

//接入DHT11 库
#include <dht11.h>
dht11 DHT;
#define DHT11_PIN 15  //制定DHT11数据引脚


char auth[] = "e5621a7be632";      //Blinker APP(连接小爱同学必须阿里云服务器)中获取到的Secret Key(密钥)
//代码配网用这段
//char ssid[] = "Your WIFI SSID";        //自己wifi名称
//char pswd[] = "********";        //自己wifi密码

//定义继电器信号
#define Relay_1 2         //定义继电器1信号接入GPIO2.低电平触发
#define Relay_2 0         //定义继电器2信号接入GPIO0 低电平触发
#define Relay_3 4         //定义继电器3信号接入GPIO4 高电平触发
#define Relay_4 5         //定义继电器4信号接入GPIO5 高电平触发


bool flag; //继电器是否写入标志位
bool relay1; //记录继电器状态
bool relay2;
bool relay3;
bool relay4;

unsigned long lastUpdateTime = 0; //记录上次更新数据时间
const unsigned long updateInterval = 600000; // 每10分钟保存一次数据(300秒)
String relay_status;
String save_status;

void save_or_check_config() {
  relay_status = String(digitalRead(Relay_1)) + String(digitalRead(Relay_2)) + String(digitalRead(Relay_3)) + String(digitalRead(Relay_4));
  if (save_status) {
    if (relay_status == save_status) {//不需要保存到缓存中
      BLINKER_LOG("check config sucess, status code 1");
      return;
    }
  }
  EEPROM.begin(4008);
  flag = EEPROM.read(4000);
  if (flag == 1) {
    relay1 = EEPROM.read(4001 );
    relay2 = EEPROM.read(4002 );
    relay3 = EEPROM.read(4003 );
    relay4 = EEPROM.read(4004 );
    save_status = String(relay1) + String(relay2) + String(relay3) + String(relay4);
    if (relay_status == save_status) {//不需要保存到缓存中
      BLINKER_LOG("check config sucess, status code 2");
      return;
    }
  }
  EEPROM.write(4000, 1);
  EEPROM.write(4001, digitalRead(Relay_1));
  EEPROM.write(4002, digitalRead(Relay_2));
  EEPROM.write(4003, digitalRead(Relay_3));
  EEPROM.write(4004, digitalRead(Relay_4));
  EEPROM.end();
  BLINKER_LOG("save config sucess");
  save_status = relay_status;
}


void load_config() {
  EEPROM.begin(4008);
  flag = EEPROM.read(4000);
  if (flag == 1) {
    relay1 = EEPROM.read(4001 );
    relay2 = EEPROM.read(4002 );
    relay3 = EEPROM.read(4003 );
    relay4 = EEPROM.read(4004 );
    digitalWrite(Relay_1, relay1);
    digitalWrite(Relay_2, relay2);
    digitalWrite(Relay_3, relay3);
    digitalWrite(Relay_4, relay4);
    BLINKER_LOG("\nload config sucess\t");
  } else {
    BLINKER_LOG("\nload config failed\t");
  }
  EEPROM.end();
}
// 新建Blinker软件组件对象
BlinkerButton Button("MainSwitch");     //组件对象,要和APP组件中的“数据键名”一致,总开关
BlinkerButton Button1("Switch1");       //组件对象,要和APP组件中的“数据键名”一致,开关1
BlinkerButton Button2("Switch2");       //组件对象,要和APP组件中的“数据键名”一致,开关2
BlinkerButton Button3("Switch3");       //组件对象,要和APP组件中的“数据键名”一致,开关3
BlinkerButton Button4("Switch4");       //组件对象,要和APP组件中的“数据键名”一致,开关4
BlinkerButton Button5("Refresh");       //APP端按钮状态刷新

//新建Blinker软件组件数据条
BlinkerNumber HUMI("humi");  //湿度
BlinkerNumber TEMP("temp"); //温度
float humi_read = 0, temp_read = 0; //定义温湿度变量存储数据

//定义插座状态,用于小爱同学状态反馈
bool oState[5] = { false };
#define OUTLET_ALL   0  //所有插孔
#define OUTLET_NO_1  1  //插座插孔一
#define OUTLET_NO_2  2  //插座插孔二
#define OUTLET_NO_3  3  //插座插孔三
#define OUTLET_NO_4  4  //插座插孔四



//反馈继电器状态函数
void RelayState(int num)
{
  switch (num)
  {
    case 1:   //插座插孔一状态
      if (digitalRead(Relay_1) == LOW)
      {
        Button1.color("#FFFF00");   //设置app按键是纯黄色,16进制颜色码
        Button1.text("插座1开");          //设置app按键注释“开”
        Button1.print("on");
        oState[1] = true;
      }
      else if (digitalRead(Relay_1 == HIGH))
      {
        Button1.color("#808080");   //设置app按键是灰色,16进制颜色码
        Button1.text("插座1关");          //设置app按键注释“关”
        Button1.print("off");
        oState[1] = false;
      }
      break;
    case  2:
      if (digitalRead(Relay_2) == LOW)
      {
        Button2.color("#FFFF00");   //设置app按键是纯黄色,16进制颜色码
        Button2.text("插座2开");          //设置app按键注释“开”
        Button2.print("on");
        oState[2] = true;
      }
      else if (digitalRead(Relay_2 == HIGH))
      {
        Button2.color("#808080");   //设置app按键是灰色,16进制颜色码
        Button2.text("插座2关");          //设置app按键注释“关”
        Button2.print("off");
        oState[2] = false;
      }
      break;
    case  3:
      if (digitalRead(Relay_3) == HIGH)
      {
        Button3.color("#FFFF00");   //设置app按键是纯黄色,16进制颜色码
        Button3.text("插座3开");          //设置app按键注释“开”
        Button3.print("on");
        oState[3] = true;
      }
      else if (digitalRead(Relay_3 == LOW))
      {
        Button3.color("#808080");   //设置app按键是灰色,16进制颜色码
        Button3.text("插座3关");          //设置app按键注释“关”
        Button3.print("off");
        oState[3] = false;
      }
      break;
    case  4:
      if (digitalRead(Relay_4) == HIGH)
      {
        Button4.color("#FFFF00");   //设置app按键是纯黄色,16进制颜色码
        Button4.text("插座4开");          //设置app按键注释“开”
        Button4.print("on");
        oState[4] = true;
      }
      else if (digitalRead(Relay_4 == LOW))
      {
        Button4.color("#808080");   //设置app按键是灰色,16进制颜色码
        Button4.text("插座4关");          //设置app按键注释“关”
        Button4.print("off");
        oState[4] = false;
      }
      break;
    default:
      break;
  }
}



//小爱同学控制插座多个插孔
void ctrl_multi_outlet(uint8_t num, uint8_t io_level)
{
  switch (num)
  {
    case 0:  //所有插孔
      digitalWrite(Relay_1, io_level);//控制继电器1
      digitalWrite(Relay_2, io_level);//控制继电器2
      digitalWrite(Relay_3, !io_level);//控制继电器3
      digitalWrite(Relay_4, !io_level);//控制继电器4
      break;
    case 1:  //插座插孔一
      digitalWrite(Relay_1, io_level);//控制继电器1
      break;
    case 2:  //插座插孔二
      digitalWrite(Relay_2, io_level);//控制继电器2
      break;
    case 3:  //插座插孔三
      digitalWrite(Relay_3, !io_level);//控制继电器3
      break;
    case 4:  //插座插孔四
      digitalWrite(Relay_4, !io_level);//控制继电器4
      break;
    default:
      break;
  }
}

//小爱电源类回调,例如:“打开插座”、“打开插座插孔一”、“打开插座插孔二”
void miotPowerState(const String & state, uint8_t num)
{
  BLINKER_LOG("need set outlet: ", num, ", power state: ", state);

  if (state == BLINKER_CMD_ON)
  {
    ctrl_multi_outlet(num, LOW);//打开继电器,num表示是多少路(继电器低电平出发)
    BlinkerMIOT.powerState("on", num);
    BlinkerMIOT.print();
    RelayState(num);

    oState[num] = true;
  }
  else if (state == BLINKER_CMD_OFF)
  {
    ctrl_multi_outlet(num, HIGH);//关闭继电器,num表示是多少路

    BlinkerMIOT.powerState("off", num);
    BlinkerMIOT.print();
    RelayState(num);

    oState[num] = false;
  }
}

//小爱设备查询的回调函数,查询设备状态,例如:“插座插孔一状态”
void miotQuery(int32_t queryCode, uint8_t num)
{
  BLINKER_LOG("插孔", num, "状态", ",codes:", queryCode);

  switch (num)
  {
    case 0 :
      BLINKER_LOG("状态:");
      BlinkerMIOT.powerState(oState[1] ? "on" : "off");
      BlinkerMIOT.powerState(oState[2] ? "on" : "off");
      BlinkerMIOT.powerState(oState[3] ? "on" : "off");
      BlinkerMIOT.powerState(oState[4] ? "on" : "off");
      BlinkerMIOT.print();
      break;
    case 1 :
      BLINKER_LOG("插孔1状态:");
      BlinkerMIOT.powerState(oState[1] ? "on" : "off");
      BlinkerMIOT.print();
      break;
    case 2 :
      BLINKER_LOG("插孔2状态:");
      BlinkerMIOT.powerState(oState[2] ? "on" : "off");
      BlinkerMIOT.print();
      break;
    case 3 :
      BLINKER_LOG("插孔3状态:");
      BlinkerMIOT.powerState(oState[3] ? "on" : "off");
      BlinkerMIOT.print();
      break;
    case 4 :
      BLINKER_LOG("插孔4状态:");
      BlinkerMIOT.powerState(oState[4] ? "on" : "off");
      BlinkerMIOT.print();
      break;
    default :
      BlinkerMIOT.powerState(oState[1] ? "on" : "off");
      BlinkerMIOT.powerState(oState[2] ? "on" : "off");
      BlinkerMIOT.powerState(oState[3] ? "on" : "off");
      BlinkerMIOT.powerState(oState[4] ? "on" : "off");
      BlinkerMIOT.print();
      break;
  }
}

// 在APP控制,按下MainSwitch按键即会执行该函数
void button_callback(const String & state)
{
  BLINKER_LOG("操作了MainSwitch: ", state);//APP中的Monitor控件打印的信息
  if (state == "on")
  {
    ctrl_multi_outlet(OUTLET_ALL, LOW);//打开继电器--所有
    // 反馈继电器状态
    Button.color("#FFFF00");   //设置app按键是纯黄色,16进制颜色码
    Button.text("开");          //设置app按键注释“开”
    Button.print("on");
  } else if (state == "off")
  {
    ctrl_multi_outlet(OUTLET_ALL, HIGH);//关闭继电器--所有
    // 反馈继电器状态
    Button.color("#808080");   //设置app按键是纯黄色,16进制颜色码
    Button.text("关");          //设置app按键注释“开”
    Button.print("off");
  }
}

// 在APP控制,按下Switch1按键即会执行该函数--第1路开关
void button1_callback(const String & state)
{
  BLINKER_LOG("get button state: ", state);//APP中的Monitor控件打印的信息
  if (state == "on")
  {
    ctrl_multi_outlet(OUTLET_NO_1, LOW);//打开继电器--第1路
    // 反馈继电器1状态
    RelayState(1);    //调用继电器反馈程序
  } else if (state == "off")
  {
    ctrl_multi_outlet(OUTLET_NO_1, HIGH);//关闭继电器--第1路
    // 反馈继电器状态
    RelayState(1);    //调用继电器反馈程序
  }
}

// 在APP控制,按下Switch2按键即会执行该函数--第2路开关
void button2_callback(const String & state)
{
  BLINKER_LOG("get button state: ", state);//APP中的Monitor控件打印的信息
  if (state == "on")
  {
    ctrl_multi_outlet(OUTLET_NO_2, LOW);//打开继电器--第2路
    // 反馈继电器状态
    RelayState(2);    //调用继电器反馈程序
  } else if (state == "off")
  {
    ctrl_multi_outlet(OUTLET_NO_2, HIGH);//关闭继电器--第2路
    // 反馈继电器状态
    RelayState(2);    //调用继电器反馈程序
  }
}

// 在APP控制,按下Switch3按键即会执行该函数--第3路开关
void button3_callback(const String & state)
{
  BLINKER_LOG("get button state: ", state);//APP中的Monitor控件打印的信息
  if (state == "on")
  {
    ctrl_multi_outlet(OUTLET_NO_3, LOW);//打开继电器--第3路
    // 反馈继电器状态
    RelayState(3);    //调用继电器反馈程序
  } else if (state == "off")
  {
    ctrl_multi_outlet(OUTLET_NO_3, HIGH);//关闭继电器--第3路
    // 反馈继电器状态
    RelayState(3);    //调用继电器反馈程序
  }
}

// 在APP控制,按下Switch4按键即会执行该函数--第4路开关
void button4_callback(const String & state)
{
  BLINKER_LOG("get button state: ", state);//APP中的Monitor控件打印的信息
  if (state == "on")
  {
    ctrl_multi_outlet(OUTLET_NO_4, LOW);//打开继电器--第4路
    // 反馈继电器状态
    RelayState(4);    //调用继电器反馈程序
  } else if (state == "off")
  {
    ctrl_multi_outlet(OUTLET_NO_4, HIGH);//关闭继电器--第4路
    // 反馈继电器状态
    RelayState(4);    //调用继电器反馈程序
  }
}

//APP端状态手动刷新按钮
void button5_callback(const String & state)
{
  for (int i = 0; i < 5; i++)
  {
    RelayState(i);
  }
}


void getdht11() {

}
//心跳包刷新状态
void heartbeat()
{
  for (int i = 0; i < 5; i++)
  {
    RelayState(i);
  }
  int chk;
  chk = DHT.read(DHT11_PIN);    // READ DATA
  switch (chk) {
    case DHTLIB_OK:
      BLINKER_LOG("OK,\t");
      break;
    case DHTLIB_ERROR_CHECKSUM:
      BLINKER_LOG("Checksum error,\t");
      break;
    case DHTLIB_ERROR_TIMEOUT:
      BLINKER_LOG("Time out error,\t");
      break;
    default:
      BLINKER_LOG("Unknown error,\t");
      break;
  }
  BLINKER_LOG("humidity", DHT.humidity);
  BLINKER_LOG("temperature", DHT.temperature);
  if (chk == DHTLIB_OK) {
    temp_read = DHT.temperature;
    humi_read = DHT.humidity;
  } else {
    BLINKER_LOG("get humidity,temperature failed");
  }
  //反馈温度数据
  HUMI.print(humi_read);
  //设置ui组件图标和颜色
  HUMI.icon("fas fa-humidity");
  HUMI.color("#fddb10");

  //反馈湿度数据
  TEMP.print(temp_read);
  TEMP.icon("fas fa-thermometer-half");
  HUMI.color("#fddb01");
}


void dataStorage()
{
  Blinker.dataStorage("temp", temp_read);
  Blinker.dataStorage("humi", humi_read);
}


void setup()
{
  // 初始化串口,用于调试,后期可删除
  Serial.begin(115200);
  BLINKER_DEBUG.stream(Serial);
  BLINKER_DEBUG.debugAll();

  // 初始化有继电器的IO
  pinMode(Relay_1, OUTPUT);
  pinMode(Relay_2, OUTPUT);
  pinMode(Relay_3, OUTPUT);
  pinMode(Relay_4, OUTPUT);
  //初始化继电器初始状态
  digitalWrite(Relay_1, HIGH);       //继电器为低电平触发,初始化为HIGH
  digitalWrite(Relay_2, HIGH);
  digitalWrite(Relay_3, LOW);
  digitalWrite(Relay_4, LOW);
  load_config();//从EEEprom读取数据,调整继电器状态为断电前状态

  //初始化blinker
  Blinker.begin(auth);              //手机配网用这段
  //Blinker.begin(auth, ssid, pswd);//代码配网用这段
  Button.attach(button_callback);   //绑定按键回调
  Button1.attach(button1_callback); //绑定按键回调
  Button2.attach(button2_callback); //绑定按键回调
  Button3.attach(button3_callback); //绑定按键回调
  Button4.attach(button4_callback); //绑定按键回调
  Button5.attach(button5_callback);

  //小爱同学注册回调
  BlinkerMIOT.attachPowerState(miotPowerState); //注册小爱电源回调
  BlinkerMIOT.attachQuery(miotQuery);           //小爱设备查询的回调函数

  //心跳包,初始化
  Blinker.attachHeartbeat(heartbeat);           //app定时向设备发送心跳包, 设备收到心跳包后会返回设备当前状态
  Blinker.attachDataStorage(dataStorage);
}

void loop()
{
  Blinker.run();
  if ((millis() - lastUpdateTime > updateInterval)) {
    save_or_check_config();
    lastUpdateTime = millis();
  }
}

由于点灯科技diy设备同时只能支持一种设备类型,我就选择了设备类型为四路插座,小爱同学可以控制四路插座,然后接入了dnt11,通过app的图表控件可以查看dht11上传的是温度数据.

配网

配网可用微信关注安信可公众号 右下角配网,

或者通过点灯科技app开发者工具配网

点灯app温湿度曲线图配置

曲线图 增加一个 图表 控件,图表 控件名称无所谓,数据键名1为temp 文本:温度 数据键名2为humi 文本:湿度 即可

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 Linux 系统中新建文本文档可以使用命令行或图形界面。 命令行方法: 1. 打开终端。 2. 使用 "touch" 命令新建文件,格式为 "touch 文件名" 。 图形界面方法: 1. 打开文件管理器。 2. 在需要新建文本文档文件夹中点击右键。 3. 选择 "新建" -> "文本文档"。 ### 回答2: 在Linux系统中,有多种方法可以创建新的文本文档。 1. 使用命令行:可以使用touch命令创建一个空的文本文件。在终端中输入以下命令: touch filename.txt 其中filename.txt为你想要创建的文件名。 2. 使用文本编辑器:Linux系统中有许多文本编辑器可供选择,如nano、vim、emacs等。你可以使用其中任意一个编辑器来创建并编辑文本文件。在终端中输入以下命令来打开一个文本编辑器: nano filename.txt 其中filename.txt为你想要创建的文件名。在编辑器界面中,你可以输入文本内容并保存文件。 3. 使用图形界面文件管理器:如果你使用的是带有图形界面的Linux发行版(如Ubuntu、Fedora等),你可以通过文件管理器创建新的文本文件。在文件管理器中找到你想要创建文件的位置,右键点击空白处,选择新建文档(或者类似的选项),然后选择文本文件选项即可。输入文件名并保存,即可创建新的文本文档。 无论你选择使用命令行或者图形界面的方法来创建文本文档,都可以根据自己的需求和喜好来选择最适合自己的方式。 ### 回答3: 在Linux系统中,我们可以通过命令行来新建文本文档。 1. 打开终端:可以使用快捷键Ctrl + Alt + T来打开终端。 2. 进入到你想要新建文本文档的目录:使用cd命令,例如:cd /home/user/Desktop。 3. 使用touch命令来新建文本文档:输入touch 文件名.txt(文件名可以根据需要自行命名),然后按下回车键。 4. 现在,你已经成功地新建了一个文本文档。你可以使用命令ls来查看当前目录下的文件,你会看到你新建文本文档。 另外,如果你想在终端中直接编辑文本内容,可以使用类似于vi或nano这样的编辑器。例如,你可以在终端中输入nano 文件名.txt,然后按下回车键来使用nano编辑器来新建并编辑文本文档的内容。编辑完成后,按下Ctrl + X来保存并退出编辑器。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值