功能 : ESP8266物联车接口函数 作者 : 马晓健 邮箱 : jeasinema@gmail.com 声明 : 本程序仅供学习与交流使用,如需他用,须联系作者 本程序可以随意更改,但须保留本信息页 All rights reserved 2017.6.16

Dependents:   Ex_esp8266 Example_for_learning_easy

Committer:
Dennis_Yu
Date:
Fri Sep 07 13:02:03 2018 +0000
Revision:
0:36956da27f53
Child:
1:08113511c9ab
first commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Dennis_Yu 0:36956da27f53 1 /***************************************************************
Dennis_Yu 0:36956da27f53 2 功能 : ESP8266物联车接口函数
Dennis_Yu 0:36956da27f53 3 作者 : 马晓健
Dennis_Yu 0:36956da27f53 4 邮箱 : jeasinema[at]gmail[dot]com
Dennis_Yu 0:36956da27f53 5 声明 :
Dennis_Yu 0:36956da27f53 6 本程序仅供学习与交流使用,如需他用,须联系作者
Dennis_Yu 0:36956da27f53 7 本程序可以随意更改,但须保留本信息页
Dennis_Yu 0:36956da27f53 8 All rights reserved
Dennis_Yu 0:36956da27f53 9 2017.6.16
Dennis_Yu 0:36956da27f53 10 ***************************************************************/
Dennis_Yu 0:36956da27f53 11
Dennis_Yu 0:36956da27f53 12 #include "esp8266.h"
Dennis_Yu 0:36956da27f53 13
Dennis_Yu 0:36956da27f53 14 #include <cstdarg>
Dennis_Yu 0:36956da27f53 15 #include <cstring>
Dennis_Yu 0:36956da27f53 16 #include <stdint.h>
Dennis_Yu 0:36956da27f53 17 #include "mbed.h"
Dennis_Yu 0:36956da27f53 18
Dennis_Yu 0:36956da27f53 19 extern Serial ser2usb;
Dennis_Yu 0:36956da27f53 20
Dennis_Yu 0:36956da27f53 21 static int ser_baud = 9600;
Dennis_Yu 0:36956da27f53 22
Dennis_Yu 0:36956da27f53 23 //定义了一个调试的宏,C语言语法
Dennis_Yu 0:36956da27f53 24 #define ESP_CMD(format, ...) do{\
Dennis_Yu 0:36956da27f53 25 char cmdbuf[128], *p;\
Dennis_Yu 0:36956da27f53 26 ser2esp8266.printf("\r"); \
Dennis_Yu 0:36956da27f53 27 sprintf(cmdbuf, format "\r", ##__VA_ARGS__);\
Dennis_Yu 0:36956da27f53 28 for(p=cmdbuf;*p;p++){\
Dennis_Yu 0:36956da27f53 29 ser2esp8266.putc(*p);\
Dennis_Yu 0:36956da27f53 30 wait(0.02);\
Dennis_Yu 0:36956da27f53 31 }\
Dennis_Yu 0:36956da27f53 32 wait(0.3);\
Dennis_Yu 0:36956da27f53 33 }while(0)
Dennis_Yu 0:36956da27f53 34
Dennis_Yu 0:36956da27f53 35
Dennis_Yu 0:36956da27f53 36
Dennis_Yu 0:36956da27f53 37 void Esp8266::gotResponse(char *token, char *param)
Dennis_Yu 0:36956da27f53 38 {
Dennis_Yu 0:36956da27f53 39 if(*token<'a' || *token>'z') return;
Dennis_Yu 0:36956da27f53 40 ser2usb.printf("gotResponse %s %s\r\n", token, param);
Dennis_Yu 0:36956da27f53 41 if(strcmp(token, "connected") == 0)
Dennis_Yu 0:36956da27f53 42 mqtt_start = true;
Dennis_Yu 0:36956da27f53 43 else if(strcmp(token, "control") == 0){
Dennis_Yu 0:36956da27f53 44 if(!control_cmd){
Dennis_Yu 0:36956da27f53 45 strncpy(control_buf, param, sizeof(control_buf));
Dennis_Yu 0:36956da27f53 46 control_cmd = true;
Dennis_Yu 0:36956da27f53 47 }
Dennis_Yu 0:36956da27f53 48 }
Dennis_Yu 0:36956da27f53 49 else if(strcmp(token, "wifi") == 0){
Dennis_Yu 0:36956da27f53 50 if(*param == '5')
Dennis_Yu 0:36956da27f53 51 network_start = true;
Dennis_Yu 0:36956da27f53 52 }
Dennis_Yu 0:36956da27f53 53 }
Dennis_Yu 0:36956da27f53 54
Dennis_Yu 0:36956da27f53 55 bool Esp8266::get_control_cmd(char* actuator, char* value)
Dennis_Yu 0:36956da27f53 56 {
Dennis_Yu 0:36956da27f53 57 if(!control_cmd)
Dennis_Yu 0:36956da27f53 58 return false;
Dennis_Yu 0:36956da27f53 59
Dennis_Yu 0:36956da27f53 60 char* plus = strchr(control_buf, '+');
Dennis_Yu 0:36956da27f53 61 if(!plus){
Dennis_Yu 0:36956da27f53 62 control_cmd = false;
Dennis_Yu 0:36956da27f53 63 return false;
Dennis_Yu 0:36956da27f53 64 }
Dennis_Yu 0:36956da27f53 65 *plus = '\0';
Dennis_Yu 0:36956da27f53 66 strcpy(actuator, control_buf);
Dennis_Yu 0:36956da27f53 67 strcpy(value, plus+1);
Dennis_Yu 0:36956da27f53 68 control_cmd = false;
Dennis_Yu 0:36956da27f53 69 return true;
Dennis_Yu 0:36956da27f53 70 }
Dennis_Yu 0:36956da27f53 71
Dennis_Yu 0:36956da27f53 72 // 接收 esp8266 侧数据的回调函数, 每次仅接收一个8位字符
Dennis_Yu 0:36956da27f53 73 // 数据格式约定: #token+data
Dennis_Yu 0:36956da27f53 74 void Esp8266::esp8266_rxCallback() {
Dennis_Yu 0:36956da27f53 75 char in = ser2esp8266.getc();
Dennis_Yu 0:36956da27f53 76 // ser2usb.putc(in);
Dennis_Yu 0:36956da27f53 77 enum{STATE_WAIT, STATE_TOKEN, STATE_PARAM};
Dennis_Yu 0:36956da27f53 78 static uint8_t state = STATE_WAIT;
Dennis_Yu 0:36956da27f53 79 static int tokenLen, paramLen;
Dennis_Yu 0:36956da27f53 80 switch(state){
Dennis_Yu 0:36956da27f53 81 case STATE_WAIT:
Dennis_Yu 0:36956da27f53 82 if(in == '#'){
Dennis_Yu 0:36956da27f53 83 tokenLen = 0;
Dennis_Yu 0:36956da27f53 84 state = STATE_TOKEN;
Dennis_Yu 0:36956da27f53 85 }
Dennis_Yu 0:36956da27f53 86 break;
Dennis_Yu 0:36956da27f53 87 case STATE_TOKEN:
Dennis_Yu 0:36956da27f53 88 if(in == '+' || in == '\r' || in == '\n'){
Dennis_Yu 0:36956da27f53 89 esp_tokenBuf[tokenLen] = '\0';
Dennis_Yu 0:36956da27f53 90 if(in == '+'){
Dennis_Yu 0:36956da27f53 91 paramLen = 0;
Dennis_Yu 0:36956da27f53 92 state = STATE_PARAM;
Dennis_Yu 0:36956da27f53 93 }else{
Dennis_Yu 0:36956da27f53 94 gotResponse(esp_tokenBuf, NULL);
Dennis_Yu 0:36956da27f53 95 //memcpy(esp_token, esp_tokenBuf, tokenLen);
Dennis_Yu 0:36956da27f53 96 //esp_token[tokenLen] = '\0';
Dennis_Yu 0:36956da27f53 97 esp_buf_ready = true;
Dennis_Yu 0:36956da27f53 98 state = STATE_WAIT;
Dennis_Yu 0:36956da27f53 99 }
Dennis_Yu 0:36956da27f53 100 }else if(tokenLen+1 < sizeof(esp_tokenBuf)){
Dennis_Yu 0:36956da27f53 101 esp_tokenBuf[tokenLen++] = in;
Dennis_Yu 0:36956da27f53 102 }
Dennis_Yu 0:36956da27f53 103 break;
Dennis_Yu 0:36956da27f53 104 case STATE_PARAM:
Dennis_Yu 0:36956da27f53 105 if(in == '\r' || in == '\n'){
Dennis_Yu 0:36956da27f53 106 esp_paramBuf[paramLen] = '\0';
Dennis_Yu 0:36956da27f53 107 gotResponse(esp_tokenBuf, esp_paramBuf);
Dennis_Yu 0:36956da27f53 108 //memcpy(esp_token, esp_tokenBuf, tokenLen);
Dennis_Yu 0:36956da27f53 109 //memcpy(esp_param, esp_paramBuf, paramLen);
Dennis_Yu 0:36956da27f53 110 //esp_token[tokenLen] = '\0';
Dennis_Yu 0:36956da27f53 111 //esp_param[paramLen] = '\0';
Dennis_Yu 0:36956da27f53 112 //ser2usb.putc('?');
Dennis_Yu 0:36956da27f53 113 esp_buf_ready = true;
Dennis_Yu 0:36956da27f53 114 state = STATE_WAIT;
Dennis_Yu 0:36956da27f53 115 }else if(paramLen+1 < sizeof(esp_paramBuf)){
Dennis_Yu 0:36956da27f53 116 esp_paramBuf[paramLen++] = in;
Dennis_Yu 0:36956da27f53 117 }
Dennis_Yu 0:36956da27f53 118 break;
Dennis_Yu 0:36956da27f53 119 }
Dennis_Yu 0:36956da27f53 120 }
Dennis_Yu 0:36956da27f53 121
Dennis_Yu 0:36956da27f53 122
Dennis_Yu 0:36956da27f53 123 Esp8266::Esp8266(PinName TX, PinName RX, const char *wifi_ssid, const char *wifi_passwd) //定义类的函数
Dennis_Yu 0:36956da27f53 124 : network_start(false), mqtt_start(false), control_cmd(false), esp_buf_ready(false), ser2esp8266(TX, RX)
Dennis_Yu 0:36956da27f53 125 {
Dennis_Yu 0:36956da27f53 126 // serial to esp8266 init
Dennis_Yu 0:36956da27f53 127 ser2esp8266.baud(ser_baud);
Dennis_Yu 0:36956da27f53 128 ser2esp8266.attach(callback(this,&Esp8266::esp8266_rxCallback), Serial::RxIrq);
Dennis_Yu 0:36956da27f53 129 //if (mode == 0) { // client mode
Dennis_Yu 0:36956da27f53 130 this->reset();
Dennis_Yu 0:36956da27f53 131 this->connect_wifi(wifi_ssid, wifi_passwd);
Dennis_Yu 0:36956da27f53 132 while(!is_connected()){
Dennis_Yu 0:36956da27f53 133 wait(0.5);
Dennis_Yu 0:36956da27f53 134 }
Dennis_Yu 0:36956da27f53 135 this->weblogin();
Dennis_Yu 0:36956da27f53 136 //} else {
Dennis_Yu 0:36956da27f53 137 //
Dennis_Yu 0:36956da27f53 138 //}
Dennis_Yu 0:36956da27f53 139 }
Dennis_Yu 0:36956da27f53 140
Dennis_Yu 0:36956da27f53 141 bool Esp8266::reset() { //定义类的函数
Dennis_Yu 0:36956da27f53 142 ESP_CMD("node.restart()");
Dennis_Yu 0:36956da27f53 143 wait(2); // 延迟2s
Dennis_Yu 0:36956da27f53 144 return true;
Dennis_Yu 0:36956da27f53 145 }
Dennis_Yu 0:36956da27f53 146
Dennis_Yu 0:36956da27f53 147 bool Esp8266::connect_wifi(const char *wifi_ssid, const char *wifi_passwd) { //定义类的函数
Dennis_Yu 0:36956da27f53 148 ESP_CMD("wifi.setmode(wifi.STATION)");
Dennis_Yu 0:36956da27f53 149 ESP_CMD("wifi.sta.config([[%s]],[[%s]])", wifi_ssid, wifi_passwd);
Dennis_Yu 0:36956da27f53 150 wait(2);
Dennis_Yu 0:36956da27f53 151 // set auto autoconnect
Dennis_Yu 0:36956da27f53 152 ESP_CMD("wifi.sta.autoconnect(1)");
Dennis_Yu 0:36956da27f53 153 return true;
Dennis_Yu 0:36956da27f53 154 }
Dennis_Yu 0:36956da27f53 155
Dennis_Yu 0:36956da27f53 156 bool Esp8266::is_connected()
Dennis_Yu 0:36956da27f53 157 {
Dennis_Yu 0:36956da27f53 158 ESP_CMD("print('\\035wifi+'..wifi.sta.status())");
Dennis_Yu 0:36956da27f53 159 wait(0.4);
Dennis_Yu 0:36956da27f53 160 return network_start;
Dennis_Yu 0:36956da27f53 161 }
Dennis_Yu 0:36956da27f53 162
Dennis_Yu 0:36956da27f53 163 bool Esp8266::weblogin() { //定义类的函数
Dennis_Yu 0:36956da27f53 164 // not implemented yet
Dennis_Yu 0:36956da27f53 165 return true;
Dennis_Yu 0:36956da27f53 166 }
Dennis_Yu 0:36956da27f53 167
Dennis_Yu 0:36956da27f53 168 void Esp8266::buildCapability(char *out, const char* infoList[][2])
Dennis_Yu 0:36956da27f53 169 {
Dennis_Yu 0:36956da27f53 170 out[0] = '\0';
Dennis_Yu 0:36956da27f53 171 for (int i = 0; infoList[i][0]; ++i)
Dennis_Yu 0:36956da27f53 172 {
Dennis_Yu 0:36956da27f53 173 strcat(out, infoList[i][0]);
Dennis_Yu 0:36956da27f53 174 strcat(out, ",");
Dennis_Yu 0:36956da27f53 175 strcat(out, infoList[i][1]);
Dennis_Yu 0:36956da27f53 176 strcat(out, "\\n");
Dennis_Yu 0:36956da27f53 177 }
Dennis_Yu 0:36956da27f53 178 }
Dennis_Yu 0:36956da27f53 179
Dennis_Yu 0:36956da27f53 180 bool Esp8266::connect_mqtt_broker(char *ip, const char *node_name, const char* sensors[][2], const char* actuator[][2]) { //定义类的函数
Dennis_Yu 0:36956da27f53 181
Dennis_Yu 0:36956da27f53 182 ESP_CMD("node_name = '%s'", node_name);
Dennis_Yu 0:36956da27f53 183 ESP_CMD("m = mqtt.Client('i_' .. node.chipid(), 120)");
Dennis_Yu 0:36956da27f53 184 ESP_CMD("m:connect(\"%s\",1883,0,function(conn)print (\"\\035connected\"); end)", ip);
Dennis_Yu 0:36956da27f53 185
Dennis_Yu 0:36956da27f53 186 do{
Dennis_Yu 0:36956da27f53 187 wait(0.5);
Dennis_Yu 0:36956da27f53 188 }while(!mqtt_start);
Dennis_Yu 0:36956da27f53 189
Dennis_Yu 0:36956da27f53 190 ESP_CMD("m:on(\"message\", function(conn, topic, data)");
Dennis_Yu 0:36956da27f53 191 ESP_CMD("if topic:find(\"^/control/\") then");
Dennis_Yu 0:36956da27f53 192 ESP_CMD("local tok = topic:match(\"^/control/.+/(.+)\")");
Dennis_Yu 0:36956da27f53 193 ESP_CMD("if tok then print(\"\\035control+\"..tok..\"+\"..data) end");
Dennis_Yu 0:36956da27f53 194 ESP_CMD("end");
Dennis_Yu 0:36956da27f53 195 ESP_CMD("end)");
Dennis_Yu 0:36956da27f53 196
Dennis_Yu 0:36956da27f53 197 ESP_CMD("m:publish('/events/'..node_name..'/online','',1,0)");
Dennis_Yu 0:36956da27f53 198 wait(0.1);
Dennis_Yu 0:36956da27f53 199
Dennis_Yu 0:36956da27f53 200 char * capabilities = new char[512];
Dennis_Yu 0:36956da27f53 201
Dennis_Yu 0:36956da27f53 202 if(sensors){
Dennis_Yu 0:36956da27f53 203 buildCapability(capabilities, sensors);
Dennis_Yu 0:36956da27f53 204 ESP_CMD("m:publish('/capability/'..node_name..'/values','%s',1,1)", capabilities);
Dennis_Yu 0:36956da27f53 205 wait(0.1);
Dennis_Yu 0:36956da27f53 206 }
Dennis_Yu 0:36956da27f53 207 if(actuator){
Dennis_Yu 0:36956da27f53 208 buildCapability(capabilities, actuator);
Dennis_Yu 0:36956da27f53 209 ESP_CMD("m:publish('/capability/'..node_name..'/control','%s',1,1)", capabilities);
Dennis_Yu 0:36956da27f53 210 wait(0.1);
Dennis_Yu 0:36956da27f53 211 for (int i = 0; actuator[i][0]; ++i)
Dennis_Yu 0:36956da27f53 212 subscribe_control(actuator[i][0]);
Dennis_Yu 0:36956da27f53 213 }
Dennis_Yu 0:36956da27f53 214
Dennis_Yu 0:36956da27f53 215 delete[ ] capabilities;
Dennis_Yu 0:36956da27f53 216
Dennis_Yu 0:36956da27f53 217 return true;
Dennis_Yu 0:36956da27f53 218 }
Dennis_Yu 0:36956da27f53 219
Dennis_Yu 0:36956da27f53 220 bool Esp8266::publish_value(const char *topic, const char *data) { //定义类的函数
Dennis_Yu 0:36956da27f53 221 //if (mqtt_start) {
Dennis_Yu 0:36956da27f53 222 ESP_CMD("m:publish('/values/'..node_name..'/%s',\"%s\",0,0)", topic, data);//
Dennis_Yu 0:36956da27f53 223 wait(0.1);
Dennis_Yu 0:36956da27f53 224 //}
Dennis_Yu 0:36956da27f53 225 return true;
Dennis_Yu 0:36956da27f53 226 }
Dennis_Yu 0:36956da27f53 227
Dennis_Yu 0:36956da27f53 228 bool Esp8266::subscribe_control(const char *topic, const char *data) { //定义类的函数
Dennis_Yu 0:36956da27f53 229 //if (mqtt_start) {
Dennis_Yu 0:36956da27f53 230 ESP_CMD("m:subscribe('/control/'..node_name..'/%s', 0)", topic);
Dennis_Yu 0:36956da27f53 231 wait(0.1);
Dennis_Yu 0:36956da27f53 232 //}
Dennis_Yu 0:36956da27f53 233
Dennis_Yu 0:36956da27f53 234 // ESP_CMD("m:unsubscribe(\"%s\")", topic);
Dennis_Yu 0:36956da27f53 235 return true;
Dennis_Yu 0:36956da27f53 236 }