nRF24L01, encoder, pca9685, pid

Dependencies:   mbed QEI-1 LibPN532 nRF24L01P xiugai

Committer:
brainliang
Date:
Wed Oct 30 10:59:58 2019 +0000
Revision:
5:fdacb4ef6709
encoder PID PCA9685 esp8266

Who changed what in which revision?

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