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