sads

Dependencies:   mbed

Fork of smart_drawer by Xiaoyuan Yu

Committer:
plao
Date:
Mon Jul 23 06:22:33 2018 +0000
Revision:
1:4ffc39e81583
dfs

Who changed what in which revision?

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