esp8266引脚图
界面配置
- #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足以进行加密通信
-
- #include <Blinker.h> //使用第三方Blinker库
- #include <Servo.h> //舵机库
- #include <OneWire.h> //使用温度的库
- #include <DallasTemperature.h> //使用温度的库
- char auth[] = "128679da61a7";//ed9c736dca2f
- char ssid[] = "TP-LINK_鲁";
- char pswd[] = "13198852106";
- /*char ssid[] = "l";
- char pswd[] = "12345678";*/
- #define Servo_pin 13 //定义舵机连接引脚D7
- //定义温度传感器信号
- #define ONE_WIRE_BUS 2 // DS18B20 DQ接ESP8266引脚D4(GPIO2)
- #define hot 14 //控制加热棒继电器接ESP8266引脚D5(GPIO14) 和 void setup()中的pinMode(hot,OUTPUT);配合
- OneWire oneWire(ONE_WIRE_BUS);
- DallasTemperature sensors(&oneWire);
- //定义水质传感器信号
- #define TdsSensorPin A0 //TDS水质传感器A接ESP8266引脚A0
- #define VREF 5.0 // analog reference voltage(Volt) of the ADC
- #define SCOUNT 30 // sum of sample point
- int analogBuffer[SCOUNT]; // store the analog value in the array, read from ADC
- int analogBufferTemp[SCOUNT];
- int analogBufferIndex = 0, copyIndex = 0;
-
- float averageVoltage = 0, tdsValue = 0, tdsValue_MAX = 300 , tempe = 25 ,tempe_MAX = 28;//
- //int lock = 0;
- double temp,data;
-
- //定义继电器信号
- #define Relay_1 0 //定义继电器1信号接入GPIO5,D3
- #define Relay_2 4 //定义继电器2信号接入GPIO4,D2
- #define Relay_3 16 //定义继电器3信号接入GPIO0,D0
- #define Relay_4 12 //定义继电器4信号接入GPIO12,D6
- //定义水位传感器信号
- #define Grove_Water_Sensor 5 // S接ESP8266引脚D1(GPIO5)
- #define Water 15 //继电器IN接ESP8266引脚D8(GPIO15)控制水泵开关
- // 新建Blinker软件组件对象
- BlinkerButton Button("MainSwitch"); //组件对象,要和APP组件中的“数据键名”一致,总开关
- BlinkerButton Button1("btn-1"); //组件对象,要和APP组件中的“数据键名”一致,开关1
- BlinkerButton Button2("btn-2"); //组件对象,要和APP组件中的“数据键名”一致,开关2
- BlinkerButton Button3("btn-3"); //组件对象,要和APP组件中的“数据键名”一致,开关3
- BlinkerButton Button4("btn-4"); //组件对象,要和APP组件中的“数据键名”一致,开关4
- BlinkerButton Button5("Refresh"); //APP端按钮状态刷新
- BlinkerNumber TEMP("tempe"); //定义温度 数据键名
- BlinkerNumber DEMP("data"); //定义水位 数据键名
- BlinkerNumber WATER("tdsValue"); //定义水质 数据键名
- BlinkerText WATERSTATUS("waterStatus");//定义水位 文本键名
- BlinkerText HOT("hot"); //定义加热棒 文本键名
- BlinkerText TDS("tds"); //定义水质 文本键名
- //定义插座状态,用于小爱同学状态反馈
- 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 //插座插孔四
- //喂食量
- Servo servo;
- int feedamount = 300;
- int feed_EA = 1;
- BlinkerSlider Slider1("ran-feedamount"); //喂食量滑块(通过延时时间控制出食量)
- void Slider1_feedamount(int32_t amount)
- {
- feedamount = amount >= 1000 ? 1000 : amount <= 1 ? 1
- : amount;
- Slider1.print(feedamount);
- BLINKER_LOG("feedamount:", feedamount);
- }
- BlinkerButton Button6("btn-handfeed"); //喂食
- void Button6_callback(const String &state)
- {
- BLINKER_LOG("get button state: ", state);
- if (state == BLINKER_CMD_BUTTON_TAP && feed_EA)
- {
- feed_EA = 1;
- BLINKER_LOG("get feedamount: ", feedamount);
- feed_cat();
- Blinker.vibrate(1000); //震动1s
- Button6.color("#0000FF");
- Button6.text("出料完成");
- Button6.print();
- feed_EA = 1;
- }
- }
- void feed_cat() //喂食出料
- {
- // playmusic();
- servo.write(0);
- Button6.color("#FFA500");
- Button6.text("出料中");
- Button6.print();
- Blinker.delay(50);
- Blinker.delay(feedamount * 10);
- servo.write(90);
- }
- //反馈继电器状态函数
- void RelayState(int num)
- {
- switch(num)
- {
- case 1: //插座插孔一状态
- if(digitalRead(Relay_1)==LOW)
- {
- Button1.color("#808080"); //设置app按键是灰色,16进制颜色码
- Button1.text("关灯"); //设置app按键注释“关”
- Button1.print("off");
- oState[1] = false;
- }
- else if(digitalRead(Relay_1==HIGH))
- {
- Button1.color("#FFA500"); //设置app按键是橙色,16进制颜色码https://www.w3school.com.cn/tags/html_ref_colornames.asp
- Button1.text("开灯"); //设置app按键注释“开”
- Button1.print("on");
- oState[1] = true;
- }
- break;
- case 2:
- if(digitalRead(Relay_2)==LOW /*|| digitalRead(Water) == HIGH*/)
- {
- //lock = 1;
- Button2.color("#808080"); //设置app按键是灰色,16进制颜色码
- Button2.text("注水关"); //设置app按键注释“关”
- Button2.print("off");
- oState[2] = false;
- }
- else if(digitalRead(Relay_2==HIGH) /*|| digitalRead(Water) == LOW*/)
- {
- //lock = 0;
- Button2.color("#FFA500"); //设置app按键是橙色,16进制颜色码
- Button2.text("注水开"); //设置app按键注释“开”
- Button2.print("on");
- oState[2] = true;
- }
- break;
- case 3:
- if(digitalRead(Relay_3)==LOW)
- {
- Button3.color("#808080"); //设置app按键是灰色,16进制颜色码
- Button3.text("排水关"); //设置app按键注释“关”
- Button3.print("off");
- oState[3] = false;
- }
- else if(digitalRead(Relay_3==HIGH))
- {
- Button3.color("#FFA500"); //设置app按键是橙色,16进制颜色码
- Button3.text("排水开"); //设置app按键注释“开”
- Button3.print("on");
- oState[3] = true;
- }
- break;
- case 4:
- if(digitalRead(Relay_4)==LOW)
- {
- Button4.color("#808080"); //设置app按键是灰色,16进制颜色码
- Button4.text("加热棒关"); //设置app按键注释“关”
- Button4.print("off");
- oState[4] = false;
- }
- else if(digitalRead(Relay_4==HIGH))
- {
- Button4.color("#FFA500"); //设置app按键是橙色,16进制颜色码
- Button4.text("加热棒开"); //设置app按键注释“开”
- Button4.print("on");
- oState[4] = true;
- }
- break;
- default:
- 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("#FFA500"); //设置app按键是橙色,16进制颜色码
- Button.text("开"); //设置app按键注释“开”
- Button.icon("fal fa-power-on");
- Button.print("on");
- Blinker.vibrate(); //开启继电器时反馈,让手机震动
- } else if(state=="off")
- {
- ctrl_multi_outlet(OUTLET_ALL, HIGH);//关闭继电器--所有
- // 反馈继电器状态
- Button.color("#808080"); //设置app按键是橙色,16进制颜色码
- Button.text("关"); //设置app按键注释“开”
- Button.icon("fal fa-power-off");
- 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,HIGH );//打开继电器--第1路
- // 反馈继电器状态
- RelayState(1); //调用继电器反馈程序
- } else if(state=="off")
- {
- ctrl_multi_outlet(OUTLET_NO_1, LOW);//关闭继电器--第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,HIGH );//打开继电器--第2路
- // 反馈继电器状态
- RelayState(2); //调用继电器反馈程序
- } else if(state=="off")
- {
- ctrl_multi_outlet(OUTLET_NO_2,LOW );//关闭继电器--第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, HIGH);//打开继电器--第3路
- // 反馈继电器状态
- RelayState(3); //调用继电器反馈程序
- } else if(state=="off")
- {
- ctrl_multi_outlet(OUTLET_NO_3, LOW);//关闭继电器--第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, HIGH);//打开继电器--第4路
- // 反馈继电器状态
- RelayState(4); //调用继电器反馈程序
- } else if(state=="off")
- {
- ctrl_multi_outlet(OUTLET_NO_4, LOW);//关闭继电器--第4路
- // 反馈继电器状态
- RelayState(4); //调用继电器反馈程序
- }
- }
- //APP端状态手动刷新按钮
- void button5_callback(const String & state)
- {
- for(int i=0;i<5;i++)
- {
- RelayState(i);
- }
- }
- //小爱同学控制插座多个插孔
- 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;
- }
- }
- //心跳包刷新状态
- void heartbeat()
- {
- for(int i=0;i<5;i++)
- {
- RelayState(i);
- }
- TEMP.print(tempe); //给blinkerapp回传温度数据
- WATER.print(tdsValue); //给blinkerapp回传水质数据
- DEMP.print(data); //给blinkerapp回传水位数据
- }
- //显示图表
- void dataRead(const String & data)
- {
- BLINKER_LOG("Blinker readString: ", data);
- uint32_t BlinkerTime = millis();
- Blinker.vibrate();
- Blinker.print("millis", BlinkerTime);
- digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
- }
- void dataStorage()
- {
- Blinker.dataStorage("tempe",tempe); //app显示图表温度
- Blinker.dataStorage("tdsValue",tdsValue); //app显示图表水质
- Blinker.dataStorage("data",data); //app显示图表水位
- }//图表 https://blog.csdn.net/weixin_64583141/article/details/125903980
-
- void setup()
- {
- // 初始化串口,用于调试,后期可删除
- Serial.begin(115200);
- BLINKER_DEBUG.stream(Serial);
- BLINKER_DEBUG.debugAll();
- servo.attach(13);//舵机接口D7
- servo.write(90);//360度舵机静止
- Slider1.attach(Slider1_feedamount);
- Button6.attach(Button6_callback);
-
- // 初始化有继电器的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, HIGH);
- digitalWrite(Relay_4, HIGH);
-
- //初始化blinker
- // Blinker.begin(auth); //手机配网用这段
-
- Blinker.attachData(dataRead); //图表数据获取
- Blinker.attachDataStorage(dataStorage);
-
- 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定时向设备发送心跳包, 设备收到心跳包后会返回设备当前状态
-
- sensors.begin();
- pinMode(TdsSensorPin, INPUT);
- pinMode(hot,OUTPUT);
- pinMode(Grove_Water_Sensor, INPUT); // The Water Sensor is an Input
- pinMode(Water, OUTPUT); // The LED is an Output加热棒继电器打开
- }
-
- void loop()
- {
-
- Blinker.run();
- //获取水位cm
- temp=(long)analogRead(5);//传感器连接引脚gpio5,D1
- //根据最大值时候的模拟值计算出当前实际值
- //data=(temp/650)*4;//最高4cm
- //data=(temp/650)*20;//最高31.48cm
- data=(temp/650)*10;//最高15.74cm
- Serial.print("the depth is:");
- Serial.print(data);
- Serial.println("cm");
- DEMP.print(data);
- //获取水质
- static unsigned long analogSampleTimepoint = millis();
- if (millis() - analogSampleTimepoint > 40U) //every 40 milliseconds,read the analog value from the ADC
- {
- analogSampleTimepoint = millis();
- analogBuffer[analogBufferIndex] = analogRead(TdsSensorPin); //read the analog value and store into the buffer
- analogBufferIndex++;
- if (analogBufferIndex == SCOUNT)
- analogBufferIndex = 0;
- }
- static unsigned long printTimepoint = millis();
- if (millis() - printTimepoint > 800U)
- {
- printTimepoint = millis();
- for (copyIndex = 0; copyIndex < SCOUNT; copyIndex++)
- analogBufferTemp[copyIndex] = analogBuffer[copyIndex];
- averageVoltage = getMedianNum(analogBufferTemp, SCOUNT) * (float)VREF / 1024.0; // read the analog value more stable by the median filtering algorithm, and convert to voltage value
- float compensationCoefficient = 1.0 + 0.02 * (tempe - 25.0); //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));
- float compensationVolatge = averageVoltage / compensationCoefficient; //temperature compensation
- tdsValue = (133.42 * compensationVolatge * compensationVolatge * compensationVolatge - 255.86 * compensationVolatge * compensationVolatge + 857.39 * compensationVolatge) * 0.5; //convert voltage value to tds value
- if(tdsValue < tdsValue_MAX){
- //digitalWrite(hot,HIGH);
- TDS.print("鱼缸水质硬度正常");
- }else{
- //digitalWrite(hot,LOW);
- TDS.color("#FF0000"); //设置app按键是纯红色,16进制颜色码
- TDS.print("鱼缸水质偏高");
- Blinker.vibrate(1000); //鱼缸水质偏高时反馈,让手机震动
- }
- Serial.print("voltage:");
- Serial.print(averageVoltage,2);
- Serial.print("V ");
- Serial.print("TDS Value:");
- Serial.print(tdsValue, 0);
- Serial.println("ppm");
- WATER.print(tdsValue);
- }
- getTemperature();
- //Blinker.delay(500);
- getWaterHight();
- }
- //获取水位
- void getWaterHight(){
- /* if(lock == 0){
- Serial.println("按钮已经关闭了");
- if( digitalRead(Grove_Water_Sensor) == HIGH) {
- digitalWrite(Water,LOW);
- WATERSTATUS.print("鱼缸水位正常,注水泵已关闭");
- }else {
- WATERSTATUS.color("#FF0000"); //设置app按键是纯红色,16进制颜色码
- digitalWrite(Water,HIGH);
- WATERSTATUS.print("鱼缸水位低,注水泵已打开");
- }
- }else{
- Serial.println("按钮已经开启 自动模式失效");
- }*/
- if( digitalRead(Grove_Water_Sensor) == HIGH) {
- digitalWrite(Water,LOW);
- WATERSTATUS.print("鱼缸水位正常,注水泵已关闭");
- }else {
- WATERSTATUS.color("#FF0000"); //设置app按键是纯红色,16进制颜色码
- digitalWrite(Water,HIGH);
- WATERSTATUS.print("鱼缸水位低,注水泵已打开");
- }
- }
- //获取温度并赋值
- void getTemperature(){
- sensors.requestTemperatures(); // 发送命令获取温度
- //Serial.print("temperature: ");
- tempe= (float)sensors.getTempCByIndex(0);
- if(tempe < tempe_MAX){
- HOT.color("#FF0000"); //设置app按键是纯红色,16进制颜色码
- digitalWrite(hot,HIGH);
- HOT.print("鱼缸水温低于28℃,加热棒已打开");
- }else{
- digitalWrite(hot,LOW);
- HOT.print("鱼缸水温正常,加热棒已关闭");
- }
- Serial.print("the temperature is:");
- Serial.print(tempe);
- Serial.println(" ℃");
- TEMP.print(tempe);
- }
- int getMedianNum(int bArray[], int iFilterLen)
- {
- int bTab[iFilterLen];
- for (byte i = 0; i < iFilterLen; i++)
- bTab[i] = bArray[i];
- int i, j, bTemp;
- for (j = 0; j < iFilterLen - 1; j++)
- {
- for (i = 0; i < iFilterLen - j - 1; i++)
- {
- if (bTab[i] > bTab[i + 1])
- {
- bTemp = bTab[i];
- bTab[i] = bTab[i + 1];
- bTab[i + 1] = bTemp;
- }
- }
- }
- if ((iFilterLen & 1) > 0)
- bTemp = bTab[(iFilterLen - 1) / 2];
- else
- bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;
- return bTemp;
- }
复制代码
|