小车 走

Dependencies:   mbed

Committer:
xmwmx
Date:
Sat Aug 04 04:17:02 2018 +0000
Revision:
2:4a9ba34cd90a
Parent:
0:5d8b03e224fd
?????

Who changed what in which revision?

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