ddd

Dependencies:   a4998ss mbed

Fork of whouse by Keegan Hu

Committer:
glintligo
Date:
Sun Jun 03 10:18:11 2018 +0000
Revision:
4:d66b6f331b74
ddd

Who changed what in which revision?

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