nRF24L01, encoder, pca9685, pid
Dependencies: mbed QEI-1 LibPN532 nRF24L01P xiugai
Revision 7:6f8157c58241, committed 2019-11-07
- Comitter:
- brainliang
- Date:
- Thu Nov 07 06:31:09 2019 +0000
- Parent:
- 6:7db9b13ece76
- Commit message:
- V5
Changed in this revision
diff -r 7db9b13ece76 -r 6f8157c58241 LibPN532.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LibPN532.lib Thu Nov 07 06:31:09 2019 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/zhangyx/code/LibPN532/#685e0bf1409d
diff -r 7db9b13ece76 -r 6f8157c58241 SYN6288.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SYN6288.h Thu Nov 07 06:31:09 2019 +0000 @@ -0,0 +1,45 @@ +#include <string> +typedef bool boolean; +typedef std::string String; + +void voice_play(String value_, Serial* ser) { + const char* value = value_.c_str(); + int size = strlen(value); + int data_length = 1+2+1+1+size; + int* data = (int*)malloc(sizeof(int)*(data_length+1)); + + int start = 0xfd; + int length = size + 3; + int length_h = length / 256; + int length_l = length % 256; + int command = 0x01; + int param = 0x01; + + data[0] = start; + data[1] = length_h; + data[2] = length_l; + data[3] = command; + data[4] = param; + + for (int i=5; i<5+size; i++) { + data[i] = value[i-5]; + } + + // calculate check bit + int check_bit = data[0]; + for (int i=1; i<data_length; i++) { + check_bit ^= data[i]; + } + data[data_length] = check_bit; + + for (int i=0; i<=data_length; i++) { + ser->putc(data[i]); + } + + free(data); + + //int recv = ser->getc(); + //PC.printf("%c", recv); + //int done = ser->getc(); + //PC.printf("%c", done); +} \ No newline at end of file
diff -r 7db9b13ece76 -r 6f8157c58241 esp8266.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/esp8266.cpp Thu Nov 07 06:31:09 2019 +0000 @@ -0,0 +1,236 @@ +/*************************************************************** +功能 : ESP8266物联车接口函数 +作者 : 马晓健 +邮箱 : jeasinema[at]gmail[dot]com +声明 : +本程序仅供学习与交流使用,如需他用,须联系作者 +本程序可以随意更改,但须保留本信息页 +All rights reserved +2017.6.16 +***************************************************************/ + +#include "esp8266.h" + +#include <cstdarg> +#include <cstring> +#include <stdint.h> +#include "mbed.h" + +//extern Serial ser2usb; + +static int ser_baud = 9600; + +//定义了一个调试的宏,C语言语法 +#define ESP_CMD(format, ...) do{\ + char cmdbuf[128], *p;\ + ser2esp8266.printf("\r"); \ + sprintf(cmdbuf, format "\r", ##__VA_ARGS__);\ + for(p=cmdbuf;*p;p++){\ + ser2esp8266.putc(*p);\ + wait(0.02);\ + }\ + wait(0.3);\ +}while(0) + + + +void Esp8266::gotResponse(char *token, char *param) +{ + if(*token<'a' || *token>'z') return; +// ser2usb.printf("gotResponse %s %s\r\n", token, param); + if(strcmp(token, "connected") == 0) + mqtt_start = true; + else if(strcmp(token, "control") == 0){ + if(!control_cmd){ + strncpy(control_buf, param, sizeof(control_buf)); + control_cmd = true; + } + } + else if(strcmp(token, "wifi") == 0){ + if(*param == '5') + network_start = true; + } +} + +bool Esp8266::get_control_cmd(char* actuator, char* value) +{ + if(!control_cmd) + return false; + + char* plus = strchr(control_buf, '+'); + if(!plus){ + control_cmd = false; + return false; + } + *plus = '\0'; + strcpy(actuator, control_buf); + strcpy(value, plus+1); + control_cmd = false; + return true; +} + +// 接收 esp8266 侧数据的回调函数, 每次仅接收一个8位字符 +// 数据格式约定: #token+data +void Esp8266::esp8266_rxCallback() { + char in = ser2esp8266.getc(); +// ser2usb.putc(in); + enum{STATE_WAIT, STATE_TOKEN, STATE_PARAM}; + static uint8_t state = STATE_WAIT; + static int tokenLen, paramLen; + switch(state){ + case STATE_WAIT: + if(in == '#'){ + tokenLen = 0; + state = STATE_TOKEN; + } + break; + case STATE_TOKEN: + if(in == '+' || in == '\r' || in == '\n'){ + esp_tokenBuf[tokenLen] = '\0'; + if(in == '+'){ + paramLen = 0; + state = STATE_PARAM; + }else{ + gotResponse(esp_tokenBuf, NULL); + //memcpy(esp_token, esp_tokenBuf, tokenLen); + //esp_token[tokenLen] = '\0'; + esp_buf_ready = true; + state = STATE_WAIT; + } + }else if(tokenLen+1 < sizeof(esp_tokenBuf)){ + esp_tokenBuf[tokenLen++] = in; + } + break; + case STATE_PARAM: + if(in == '\r' || in == '\n'){ + esp_paramBuf[paramLen] = '\0'; + gotResponse(esp_tokenBuf, esp_paramBuf); + //memcpy(esp_token, esp_tokenBuf, tokenLen); + //memcpy(esp_param, esp_paramBuf, paramLen); + //esp_token[tokenLen] = '\0'; + //esp_param[paramLen] = '\0'; + //ser2usb.putc('?'); + esp_buf_ready = true; + state = STATE_WAIT; + }else if(paramLen+1 < sizeof(esp_paramBuf)){ + esp_paramBuf[paramLen++] = in; + } + break; + } +} + + +Esp8266::Esp8266(PinName TX, PinName RX, const char *wifi_ssid, const char *wifi_passwd) //定义类的函数 + : network_start(false), mqtt_start(false), control_cmd(false), esp_buf_ready(false), ser2esp8266(TX, RX) +{ + // serial to esp8266 init + ser2esp8266.baud(ser_baud); + ser2esp8266.attach(callback(this,&Esp8266::esp8266_rxCallback), Serial::RxIrq); + //if (mode == 0) { // client mode + this->reset(); + this->connect_wifi(wifi_ssid, wifi_passwd); + while(!is_connected()){ + wait(0.5); + } + this->weblogin(); + //} else { + // + //} +} + +bool Esp8266::reset() { //定义类的函数 + ESP_CMD("node.restart()"); + wait(2); // 延迟2s + return true; +} + +bool Esp8266::connect_wifi(const char *wifi_ssid, const char *wifi_passwd) { //定义类的函数 + ESP_CMD("wifi.setmode(wifi.STATION)"); + ESP_CMD("wifi.sta.config([[%s]],[[%s]])", wifi_ssid, wifi_passwd); + wait(2); + // set auto autoconnect + ESP_CMD("wifi.sta.autoconnect(1)"); + return true; +} + +bool Esp8266::is_connected() +{ + ESP_CMD("print('\\035wifi+'..wifi.sta.status())"); + wait(0.4); + return network_start; +} + +bool Esp8266::weblogin() { //定义类的函数 + // not implemented yet + return true; +} + +void Esp8266::buildCapability(char *out, const char* infoList[][2]) +{ + out[0] = '\0'; + for (int i = 0; infoList[i][0]; ++i) + { + strcat(out, infoList[i][0]); + strcat(out, ","); + strcat(out, infoList[i][1]); + strcat(out, "\\n"); + } +} + +bool Esp8266::connect_mqtt_broker(char *ip, const char *node_name, const char* sensors[][2], const char* actuator[][2]) { //定义类的函数 + + ESP_CMD("node_name = '%s'", node_name); + ESP_CMD("m = mqtt.Client('i_' .. node.chipid(), 120)"); + ESP_CMD("m:connect(\"%s\",1883,0,function(conn)print (\"\\035connected\"); end)", ip); + + do{ + wait(0.5); + }while(!mqtt_start); + + ESP_CMD("m:on(\"message\", function(conn, topic, data)"); + ESP_CMD("if topic:find(\"^/control/\") then"); + ESP_CMD("local tok = topic:match(\"^/control/.+/(.+)\")"); + ESP_CMD("if tok then print(\"\\035control+\"..tok..\"+\"..data) end"); + ESP_CMD("end"); + ESP_CMD("end)"); + + ESP_CMD("m:publish('/events/'..node_name..'/online','',1,0)"); + wait(0.1); + + char * capabilities = new char[512]; + + if(sensors){ + buildCapability(capabilities, sensors); + ESP_CMD("m:publish('/capability/'..node_name..'/values','%s',1,1)", capabilities); + wait(0.1); + } + if(actuator){ + buildCapability(capabilities, actuator); + ESP_CMD("m:publish('/capability/'..node_name..'/control','%s',1,1)", capabilities); + wait(0.1); + for (int i = 0; actuator[i][0]; ++i) + subscribe_control(actuator[i][0]); + } + + delete[ ] capabilities; + + return true; +} + +bool Esp8266::publish_value(const char *topic, const char *data) { //定义类的函数 + //if (mqtt_start) { + ESP_CMD("m:publish('/values/'..node_name..'/%s',\"%s\",0,0)", topic, data); + wait(0.1); + //} + return true; +} + +bool Esp8266::subscribe_control(const char *topic, const char *data) { //定义类的函数 + //if (mqtt_start) { + ESP_CMD("m:subscribe('/control/'..node_name..'/%s', 0)", topic); + wait(0.1); + //} + + // ESP_CMD("m:unsubscribe(\"%s\")", topic); + return true; +} \ No newline at end of file
diff -r 7db9b13ece76 -r 6f8157c58241 esp8266.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/esp8266.h Thu Nov 07 06:31:09 2019 +0000 @@ -0,0 +1,34 @@ + +#include "mbed.h" + +class Esp8266 { //声明一个类 + volatile bool network_start; + volatile bool mqtt_start; + volatile bool control_cmd; + char esp_tokenBuf[32], esp_paramBuf[32]; // recv from esp8266 + char control_buf[32]; + bool esp_buf_ready; + Serial ser2esp8266; + +protected: + void esp8266_rxCallback(); + void gotResponse(char *token, char *param); + void buildCapability(char *out, const char* infoList[][2]); +public: + Esp8266(PinName TX, PinName RX, const char *wifi_ssid, const char *wifi_passwd); + + // 通用 + bool reset(); + + // 连接模式 + bool connect_wifi(const char *wifi_ssid, const char *wifi_passwd); + bool weblogin(); + bool connect_mqtt_broker(char *ip, const char *node_name, const char* sensors[][2], const char* actuator[][2]); + bool is_connected(); + + bool publish_value(const char *topic, const char *data); + bool subscribe_control(const char *topic, const char *data = NULL); + bool is_control_available(void) { return control_cmd; } + bool get_control_cmd(char* actuator, char* value); + // 热点模式 +}; \ No newline at end of file
diff -r 7db9b13ece76 -r 6f8157c58241 main.cpp --- a/main.cpp Sun Nov 03 08:26:46 2019 +0000 +++ b/main.cpp Thu Nov 07 06:31:09 2019 +0000 @@ -4,82 +4,20 @@ #include <string> typedef bool boolean; typedef std::string String; -#include "QEI.h" -#include "converters.h" - -int Position; -float Error; -int Output; -float Error_Last; -float P; -float Error_int; -float I; -float Error_diff; -float D; - -QEI qei_PA_0(PA_0,PA_1,NC,13,QEI::X4_ENCODING); -Serial Serial_2(PA_2,PA_3); -PwmOut myServoPB_0(PB_0); -PwmOut myServoPB_1(PB_1); -Ticker tick241376; +#include "SYN6288.h" -void PID_Caculation() { -Error = 0 - Position; -Error_diff = Error - Error_Last; -Error_Last = Error; -Error_int = Error_int + Error; -if (Error_int > 100) { -Error_int = 100; -} else if (Error_int < -100) { -Error_int = -100; -} -if (Error > -10 && Error < 10) { -Output = 0; -} else { -Output = P * Error + (I * Error_int + D * Error_diff); -} -if (Output > 100) { -Output = 100; -} else if (Output < -100) { -Output = -100; -} -} +String str; -void Set_speed() { -if (Output >= 0) { -myServoPB_0.period_ms(20); -myServoPB_0.pulsewidth_us((200 * Output)); -myServoPB_1.period_ms(20); -myServoPB_1.pulsewidth_us(0); -} else if (Output < 0) { -myServoPB_0.period_ms(20); -myServoPB_0.pulsewidth_us(0); -myServoPB_1.period_ms(20); -myServoPB_1.pulsewidth_us((-200 * Output)); -} -} - -void tick241376_handle() { -Position = Position + qei_PA_0.getPulses(); -qei_PA_0.reset(); -Serial_2.printf("%d\n",_p(Position)); -PID_Caculation(); -Set_speed(); -} - +Serial syn6288_Serial_2(PA_2,PA_3); int main() { -Serial_2.baud(9600); - -tick241376.attach(&tick241376_handle,0.05); -Position = 0; -qei_PA_0.reset(); -P = 1; -I = 0; -D = 1; -while (true) { +for (int count = 0; count < 100; count++) { +str = "\xc4\xe3\xba\xc3"; +str += String("\xca\xc0\xbd\xe7"); +voice_play(str,&syn6288_Serial_2); +wait_ms(2000); } } \ No newline at end of file