Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of iot_example by
esp8266.cpp@8:cd472721e8a8, 2017-12-20 (annotated)
- Committer:
- jasonkuo52
- Date:
- Wed Dec 20 08:46:09 2017 +0000
- Revision:
- 8:cd472721e8a8
- Parent:
- 7:49a823b5a935
Kuo Yiching
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)); |
jasonkuo52 | 8:cd472721e8a8 | 55 | ser2usb.printf("%s\r\n", control_buf); |
jasonkuo52 | 8:cd472721e8a8 | 56 | |
zyx | 3:06080fa094a0 | 57 | control_cmd = true; |
zyx | 3:06080fa094a0 | 58 | } |
zyx | 3:06080fa094a0 | 59 | } |
zhangyx | 2:b10925c474fc | 60 | else if(strcmp(token, "wifi") == 0){ |
zhangyx | 2:b10925c474fc | 61 | if(*param == '5') |
zhangyx | 2:b10925c474fc | 62 | network_start = true; |
zhangyx | 2:b10925c474fc | 63 | } |
zhangyx | 2:b10925c474fc | 64 | } |
brainliang | 0:63af4719467f | 65 | |
zyx | 3:06080fa094a0 | 66 | bool Esp8266::get_control_cmd(char* actuator, char* value) |
zyx | 3:06080fa094a0 | 67 | { |
jasonkuo52 | 8:cd472721e8a8 | 68 | |
zyx | 3:06080fa094a0 | 69 | if(!control_cmd) |
zyx | 3:06080fa094a0 | 70 | return false; |
jasonkuo52 | 8:cd472721e8a8 | 71 | |
zyx | 3:06080fa094a0 | 72 | char* plus = strchr(control_buf, '+'); |
zyx | 3:06080fa094a0 | 73 | if(!plus){ |
zyx | 3:06080fa094a0 | 74 | control_cmd = false; |
zyx | 3:06080fa094a0 | 75 | return false; |
zyx | 3:06080fa094a0 | 76 | } |
zyx | 3:06080fa094a0 | 77 | *plus = '\0'; |
zyx | 3:06080fa094a0 | 78 | strcpy(actuator, control_buf); |
zyx | 3:06080fa094a0 | 79 | strcpy(value, plus+1); |
zyx | 3:06080fa094a0 | 80 | control_cmd = false; |
zyx | 3:06080fa094a0 | 81 | return true; |
zyx | 3:06080fa094a0 | 82 | } |
zyx | 3:06080fa094a0 | 83 | |
brainliang | 0:63af4719467f | 84 | // 接收 esp8266 侧数据的回调函数, 每次仅接收一个8位字符 |
brainliang | 0:63af4719467f | 85 | // 数据格式约定: #token+data |
zhangyx | 1:3b487c4813a2 | 86 | void Esp8266::esp8266_rxCallback() { |
brainliang | 0:63af4719467f | 87 | char in = ser2esp8266.getc(); |
brainliang | 0:63af4719467f | 88 | enum{STATE_WAIT, STATE_TOKEN, STATE_PARAM}; |
brainliang | 0:63af4719467f | 89 | static uint8_t state = STATE_WAIT; |
brainliang | 0:63af4719467f | 90 | static int tokenLen, paramLen; |
brainliang | 0:63af4719467f | 91 | switch(state){ |
brainliang | 0:63af4719467f | 92 | case STATE_WAIT: |
brainliang | 0:63af4719467f | 93 | if(in == '#'){ |
brainliang | 0:63af4719467f | 94 | tokenLen = 0; |
brainliang | 0:63af4719467f | 95 | state = STATE_TOKEN; |
brainliang | 0:63af4719467f | 96 | } |
brainliang | 0:63af4719467f | 97 | break; |
brainliang | 0:63af4719467f | 98 | case STATE_TOKEN: |
brainliang | 0:63af4719467f | 99 | if(in == '+' || in == '\r' || in == '\n'){ |
brainliang | 0:63af4719467f | 100 | esp_tokenBuf[tokenLen] = '\0'; |
brainliang | 0:63af4719467f | 101 | if(in == '+'){ |
brainliang | 0:63af4719467f | 102 | paramLen = 0; |
brainliang | 0:63af4719467f | 103 | state = STATE_PARAM; |
brainliang | 0:63af4719467f | 104 | }else{ |
zhangyx | 2:b10925c474fc | 105 | gotResponse(esp_tokenBuf, NULL); |
brainliang | 0:63af4719467f | 106 | //memcpy(esp_token, esp_tokenBuf, tokenLen); |
brainliang | 0:63af4719467f | 107 | //esp_token[tokenLen] = '\0'; |
brainliang | 0:63af4719467f | 108 | esp_buf_ready = true; |
brainliang | 0:63af4719467f | 109 | state = STATE_WAIT; |
brainliang | 0:63af4719467f | 110 | } |
brainliang | 0:63af4719467f | 111 | }else if(tokenLen+1 < sizeof(esp_tokenBuf)){ |
brainliang | 0:63af4719467f | 112 | esp_tokenBuf[tokenLen++] = in; |
brainliang | 0:63af4719467f | 113 | } |
brainliang | 0:63af4719467f | 114 | break; |
brainliang | 0:63af4719467f | 115 | case STATE_PARAM: |
brainliang | 0:63af4719467f | 116 | if(in == '\r' || in == '\n'){ |
brainliang | 0:63af4719467f | 117 | esp_paramBuf[paramLen] = '\0'; |
zhangyx | 2:b10925c474fc | 118 | gotResponse(esp_tokenBuf, esp_paramBuf); |
brainliang | 0:63af4719467f | 119 | //memcpy(esp_token, esp_tokenBuf, tokenLen); |
brainliang | 0:63af4719467f | 120 | //memcpy(esp_param, esp_paramBuf, paramLen); |
brainliang | 0:63af4719467f | 121 | //esp_token[tokenLen] = '\0'; |
brainliang | 0:63af4719467f | 122 | //esp_param[paramLen] = '\0'; |
brainliang | 0:63af4719467f | 123 | //ser2usb.putc('?'); |
brainliang | 0:63af4719467f | 124 | esp_buf_ready = true; |
brainliang | 0:63af4719467f | 125 | state = STATE_WAIT; |
brainliang | 0:63af4719467f | 126 | }else if(paramLen+1 < sizeof(esp_paramBuf)){ |
brainliang | 0:63af4719467f | 127 | esp_paramBuf[paramLen++] = in; |
brainliang | 0:63af4719467f | 128 | } |
brainliang | 0:63af4719467f | 129 | break; |
brainliang | 0:63af4719467f | 130 | } |
brainliang | 0:63af4719467f | 131 | } |
brainliang | 0:63af4719467f | 132 | |
brainliang | 0:63af4719467f | 133 | |
zhangyx | 1:3b487c4813a2 | 134 | Esp8266::Esp8266(PinName TX, PinName RX, const char *wifi_ssid, const char *wifi_passwd) //定义类的函数 |
zyx | 3:06080fa094a0 | 135 | : network_start(false), mqtt_start(false), control_cmd(false), esp_buf_ready(false), ser2esp8266(TX, RX) |
brainliang | 0:63af4719467f | 136 | { |
brainliang | 0:63af4719467f | 137 | // serial to esp8266 init |
brainliang | 0:63af4719467f | 138 | ser2esp8266.baud(ser_baud); |
zhangyx | 2:b10925c474fc | 139 | ser2esp8266.attach(callback(this,&Esp8266::esp8266_rxCallback), Serial::RxIrq); |
zhangyx | 1:3b487c4813a2 | 140 | //if (mode == 0) { // client mode |
brainliang | 0:63af4719467f | 141 | this->reset(); |
zhangyx | 1:3b487c4813a2 | 142 | this->connect_wifi(wifi_ssid, wifi_passwd); |
zhangyx | 2:b10925c474fc | 143 | while(!is_connected()){ |
zhangyx | 2:b10925c474fc | 144 | wait(0.5); |
zhangyx | 2:b10925c474fc | 145 | } |
brainliang | 0:63af4719467f | 146 | this->weblogin(); |
zhangyx | 1:3b487c4813a2 | 147 | //} else { |
zhangyx | 1:3b487c4813a2 | 148 | // |
zhangyx | 1:3b487c4813a2 | 149 | //} |
brainliang | 0:63af4719467f | 150 | } |
brainliang | 0:63af4719467f | 151 | |
brainliang | 0:63af4719467f | 152 | bool Esp8266::reset() { //定义类的函数 |
brainliang | 0:63af4719467f | 153 | ESP_CMD("node.restart()"); |
brainliang | 0:63af4719467f | 154 | wait(2); // 延迟2s |
brainliang | 0:63af4719467f | 155 | return true; |
brainliang | 0:63af4719467f | 156 | } |
brainliang | 0:63af4719467f | 157 | |
zhangyx | 1:3b487c4813a2 | 158 | bool Esp8266::connect_wifi(const char *wifi_ssid, const char *wifi_passwd) { //定义类的函数 |
brainliang | 0:63af4719467f | 159 | ESP_CMD("wifi.setmode(wifi.STATION)"); |
brainliang | 0:63af4719467f | 160 | ESP_CMD("wifi.sta.config([[%s]],[[%s]])", wifi_ssid, wifi_passwd); |
brainliang | 0:63af4719467f | 161 | wait(2); |
brainliang | 0:63af4719467f | 162 | // set auto autoconnect |
brainliang | 0:63af4719467f | 163 | ESP_CMD("wifi.sta.autoconnect(1)"); |
zhangyx | 2:b10925c474fc | 164 | return true; |
zhangyx | 2:b10925c474fc | 165 | } |
zhangyx | 2:b10925c474fc | 166 | |
zhangyx | 2:b10925c474fc | 167 | bool Esp8266::is_connected() |
zhangyx | 2:b10925c474fc | 168 | { |
brainliang | 0:63af4719467f | 169 | ESP_CMD("print('\\035wifi+'..wifi.sta.status())"); |
zhangyx | 2:b10925c474fc | 170 | wait(0.4); |
zhangyx | 2:b10925c474fc | 171 | return network_start; |
brainliang | 0:63af4719467f | 172 | } |
brainliang | 0:63af4719467f | 173 | |
brainliang | 0:63af4719467f | 174 | bool Esp8266::weblogin() { //定义类的函数 |
brainliang | 0:63af4719467f | 175 | // not implemented yet |
brainliang | 0:63af4719467f | 176 | return true; |
brainliang | 0:63af4719467f | 177 | } |
brainliang | 0:63af4719467f | 178 | |
zyx | 3:06080fa094a0 | 179 | void Esp8266::buildCapability(char *out, const char* infoList[][2]) |
zyx | 3:06080fa094a0 | 180 | { |
zyx | 3:06080fa094a0 | 181 | out[0] = '\0'; |
zyx | 3:06080fa094a0 | 182 | for (int i = 0; infoList[i][0]; ++i) |
zyx | 3:06080fa094a0 | 183 | { |
zyx | 3:06080fa094a0 | 184 | strcat(out, infoList[i][0]); |
zyx | 3:06080fa094a0 | 185 | strcat(out, ","); |
zyx | 3:06080fa094a0 | 186 | strcat(out, infoList[i][1]); |
zyx | 3:06080fa094a0 | 187 | strcat(out, "\\n"); |
zyx | 3:06080fa094a0 | 188 | } |
zyx | 3:06080fa094a0 | 189 | } |
zyx | 3:06080fa094a0 | 190 | |
zyx | 3:06080fa094a0 | 191 | bool Esp8266::connect_mqtt_broker(char *ip, const char* sensors[][2], const char* actuator[][2]) { //定义类的函数 |
zyx | 3:06080fa094a0 | 192 | |
brainliang | 0:63af4719467f | 193 | ESP_CMD("m = mqtt.Client('i_' .. node.chipid(), 120)"); |
zhangyx | 2:b10925c474fc | 194 | ESP_CMD("m:connect(\"%s\",1883,0,function(conn)print (\"\\035connected\"); end)", ip); |
zhangyx | 2:b10925c474fc | 195 | |
zhangyx | 2:b10925c474fc | 196 | do{ |
zhangyx | 2:b10925c474fc | 197 | wait(0.5); |
zhangyx | 2:b10925c474fc | 198 | }while(!mqtt_start); |
zyx | 3:06080fa094a0 | 199 | |
zyx | 3:06080fa094a0 | 200 | ESP_CMD("m:on(\"message\", function(conn, topic, data)"); |
zyx | 3:06080fa094a0 | 201 | ESP_CMD("if topic:find(\"^/control/\") then"); |
zyx | 3:06080fa094a0 | 202 | ESP_CMD("local tok = topic:match(\"^/control/.+/(.+)\")"); |
zhangyx | 7:49a823b5a935 | 203 | ESP_CMD("if tok then print(\"\\035control+\"..tok..\"+\"..data) end"); |
zyx | 3:06080fa094a0 | 204 | ESP_CMD("end"); |
zyx | 3:06080fa094a0 | 205 | ESP_CMD("end)"); |
zyx | 3:06080fa094a0 | 206 | |
zyx | 3:06080fa094a0 | 207 | ESP_CMD("m:publish('/events/i_'..node.chipid()..'/online','',1,0)"); |
zyx | 3:06080fa094a0 | 208 | wait(0.1); |
zyx | 3:06080fa094a0 | 209 | |
zyx | 3:06080fa094a0 | 210 | char * capabilities = new char[512]; |
zyx | 3:06080fa094a0 | 211 | |
zyx | 3:06080fa094a0 | 212 | if(sensors){ |
zyx | 3:06080fa094a0 | 213 | buildCapability(capabilities, sensors); |
zyx | 3:06080fa094a0 | 214 | ESP_CMD("m:publish('/capability/i_'..node.chipid()..'/values','%s',1,1)", capabilities); |
zyx | 3:06080fa094a0 | 215 | wait(0.1); |
zyx | 3:06080fa094a0 | 216 | } |
zyx | 3:06080fa094a0 | 217 | if(actuator){ |
zyx | 3:06080fa094a0 | 218 | buildCapability(capabilities, actuator); |
zyx | 3:06080fa094a0 | 219 | ESP_CMD("m:publish('/capability/i_'..node.chipid()..'/control','%s',1,1)", capabilities); |
zyx | 3:06080fa094a0 | 220 | wait(0.1); |
zyx | 3:06080fa094a0 | 221 | for (int i = 0; actuator[i][0]; ++i) |
zyx | 3:06080fa094a0 | 222 | subscribe_control(actuator[i][0]); |
zyx | 3:06080fa094a0 | 223 | } |
zyx | 3:06080fa094a0 | 224 | |
zyx | 3:06080fa094a0 | 225 | delete[ ] capabilities; |
zyx | 3:06080fa094a0 | 226 | |
brainliang | 0:63af4719467f | 227 | return true; |
brainliang | 0:63af4719467f | 228 | } |
brainliang | 0:63af4719467f | 229 | |
zyx | 3:06080fa094a0 | 230 | bool Esp8266::publish_value(const char *topic, const char *data) { //定义类的函数 |
brainliang | 0:63af4719467f | 231 | //if (mqtt_start) { |
zyx | 3:06080fa094a0 | 232 | ESP_CMD("m:publish('/values/i_'..node.chipid()..'/%s',\"%s\",0,1)", topic, data); |
zyx | 3:06080fa094a0 | 233 | wait(0.1); |
brainliang | 0:63af4719467f | 234 | //} |
brainliang | 0:63af4719467f | 235 | return true; |
brainliang | 0:63af4719467f | 236 | } |
brainliang | 0:63af4719467f | 237 | |
zyx | 3:06080fa094a0 | 238 | bool Esp8266::subscribe_control(const char *topic, const char *data) { //定义类的函数 |
brainliang | 0:63af4719467f | 239 | //if (mqtt_start) { |
zyx | 3:06080fa094a0 | 240 | ESP_CMD("m:subscribe('/control/i_'..node.chipid()..'/%s', 0)", topic); |
brainliang | 0:63af4719467f | 241 | wait(0.1); |
brainliang | 0:63af4719467f | 242 | //} |
brainliang | 0:63af4719467f | 243 | |
zyx | 3:06080fa094a0 | 244 | // ESP_CMD("m:unsubscribe(\"%s\")", topic); |
brainliang | 0:63af4719467f | 245 | return true; |
brainliang | 0:63af4719467f | 246 | } |