Kuo Yiching

Dependencies:   mbed

Fork of iot_example by YX ZHANG

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?

UserRevisionLine numberNew 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 }