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