diff --git a/arc_design_contest/2019/NCTU_Voice_Control_Car/README.md b/arc_design_contest/2019/NCTU_Voice_Control_Car/README.md new file mode 100644 index 00000000..52a4e49f --- /dev/null +++ b/arc_design_contest/2019/NCTU_Voice_Control_Car/README.md @@ -0,0 +1,125 @@ +# Voice Control Meal Delivery Car +This is a car make for Meal Delivery, which can go through the route that been set by voice control or by direct coding. And include two ultra-sonic distance sensor to detect whether the car has been blocked, at the same time keep updating the information about the car to the cloud, and can be seen by the kitchen or the cook. Most of the proses will be calculated on IOTDK. + +* [Introduction](#introduction) + * [Function](#function) + * [System Architecture](#system-architecture) + * [Control Method](#control-method) +* [Hardware and Software Setup](#hardware-and-software-setup) + * [Required Hardware](#required-hardware) + * [Required Software](#required-software) + * [Hardware Connection](#hardware-connection) +* [User Manual](#user-manual) + * [Before Running This Application](#before-running-this-application) + * [Run This Application](#run-this-application) + +## Introduction +**Voice Control Meal Delivery** + +### Function + +- **Set the route that the car can deliver meals to the right table number** +- **Voice control** (To only control the car or set the route step by step with voice.) +- **Cloud management** (The meal provider can know every car's states through online cloud) +- **Front Detection** (There are two distance detecter to stop the car from accidentally crash into something) +- **Controller based**(Through improving the Controller we can make the car move more smoothly and precisely) + +![all-sys][0] + +### System Architecture + +![system_architecture][1] +![system_architecture_2][7] +**Timer interrupt** +![code-interr][8] + +### Control Method + +![controlleri][2] + +## Hardware and Software Setup +### Required Hardware +- 1 [ARC IoT Development Kit(IOTDK)][30] +- 2 Li-ion Battery 18650 3.7v +- 1 Li-ion Battery Box with MD line(for protect board) +- 1 2S 10A 18650 Lithium Battery Protection Board +- 1 XL6009 Boost Buck DC Adjustable Step Up Down Converter +- 1 L298N DC Motor Driver Dual H Bridge +- 1 SPH0645LM4H I2S Microphone +- 2 Motor with Hall Sensor +- 2 HC-SR04 Ultrasonic Distance Rangefinder +- 1 NodeMCU ESP8266 Lua WiFi Internet Development Board +- WiFi Hotspot(SSID:**Prophet**, Password:**1mProphet**, WPA/WPA2 encypted) +- PC to write the code onto the board + +This is the car been assambled +![whole_car][10] + +![whole_car_2][11] + +### Required Software +- embarc_osp +- ARC Gnu IDE +- digilent.adept + +### Hardware Connection +Connect the IOTDK through micor USB to write the code. +And the wires connection is down below. +![hardware_connect][12] +![power][13] + +## User Manual +### Before Running This Application +You have to download thw embarc_ops and install the IDE and Driver, and download the code from the github,but because the voice recognition model is from **Cyberon** so you have to get licence from it. + +And set up the environment by follow the [guide][31]. +To use NodeMCU, you have to set up the arduino IDE according to your NodeMCU WiFi board version. + +And download the **wifi** folder for NodeMCU WiFi module. + +### Run This Application + +Under Win10, put **src/voice** folder in the embarc_osp(from the synopsys or the [link][31]) open powershell at the voice folder, + +(path: `embarc_osp/voice`): + + make BOARD=iotdk TOOLCHAIN=gnu run +![screenshot_powershell][14] + +And you can see some recognition result with putty through serial port. + +![putty][15] + + + + + +[0]: ./doc/pic/all.png "all-sys" +[1]: ./doc/pic/code_structure.png "system_architecture" +[2]: ./doc/pic/controller.png "controller" +[3]: ./doc/screenshots/wearable_node.jpg "wearable_node" +[4]: ./doc/screenshots/wifi_connected_info.PNG "wifi_connected_info" +[5]: ./doc/screenshots/lwm2m_started_info.PNG "lwm2m_started_info" +[6]: ./doc/screenshots/lamp_work_info.PNG "lamp_work_info" +[7]: ./doc/pic/code_struction_2.png "system_architecture_2" +[8]: ./doc/pic/code-interr.png "code-interr" +[9]: ./doc/pic/controller.png "controller" +[10]: ./doc/pic/whole_car.png "whole_car" +[11]: ./doc/pic/whole_car_2.png "whole_car_2" +[12]: ./doc/pic/hardware_connect.png "hardware_connect" +[13]: ./doc/pic/power.png "power" +[14]: ./doc/pic/powershell.PNG "screenshot_powershell" +[15]: ./doc/pic/putty.PNG "putty" + + +[30]: https://embarc.org/embarc_osp/doc/build/html/board/iotdk.html "v" +[31]: https://embarc.org/embarc_osp/doc/build/html/getting_started/getting_started.html +[32]: https://www.invensense.com/products/motion-tracking/6-axis/mpu-6050/ "Acceleration sensor(MPU6050)" +[33]: http://www.electronics-lab.com/max30102/ "Heartrate sensor(MAX30102)" +[34]: https://developer.mbed.org/components/MLX90614-I2C-Infrared-Thermometer/ "Temperature sensor(MLX90614)" +[35]: https://github.com/XiangcaiHuang/ibaby.git "iBaby Smarthome Gateway" +[36]: https://github.com/XiangcaiHuang/ibaby.git "iBaby Freeboard UI" +[37]: http://www.openmobilealliance.org/release/LightweightM2M/V1_0_1-20170704-A/OMA-TS-LightweightM2M-V1_0_1-20170704-A.pdf "LwM2M Protocol" +[38]: http://www.openmobilealliance.org/wp/OMNA/LwM2M/LwM2MRegistry.html#omalabel "LwM2M Object and Resource" +[39]: http://www.freertos.org/a00106.html "FreeRTOS API" +[40]: http://embarc.org/embarc_osp/doc/embARC_Document/html/page_example.html " embARC Example User Guide" diff --git a/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/all.png b/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/all.png new file mode 100644 index 00000000..a36af735 Binary files /dev/null and b/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/all.png differ diff --git a/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/code-interr.png b/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/code-interr.png new file mode 100644 index 00000000..db014433 Binary files /dev/null and b/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/code-interr.png differ diff --git a/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/code_struction_2.png b/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/code_struction_2.png new file mode 100644 index 00000000..9ef72fac Binary files /dev/null and b/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/code_struction_2.png differ diff --git a/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/code_structure.png b/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/code_structure.png new file mode 100644 index 00000000..b8c385db Binary files /dev/null and b/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/code_structure.png differ diff --git a/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/controller.png b/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/controller.png new file mode 100644 index 00000000..9ab60ccc Binary files /dev/null and b/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/controller.png differ diff --git a/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/hardware_connect.png b/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/hardware_connect.png new file mode 100644 index 00000000..9dc39480 Binary files /dev/null and b/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/hardware_connect.png differ diff --git a/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/power.png b/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/power.png new file mode 100644 index 00000000..73b673ce Binary files /dev/null and b/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/power.png differ diff --git a/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/powershell.PNG b/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/powershell.PNG new file mode 100644 index 00000000..7c4c38ec Binary files /dev/null and b/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/powershell.PNG differ diff --git a/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/putty.PNG b/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/putty.PNG new file mode 100644 index 00000000..b5811f1a Binary files /dev/null and b/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/putty.PNG differ diff --git a/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/whole_car.png b/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/whole_car.png new file mode 100644 index 00000000..c62165ff Binary files /dev/null and b/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/whole_car.png differ diff --git a/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/whole_car_2.png b/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/whole_car_2.png new file mode 100644 index 00000000..c7878d15 Binary files /dev/null and b/arc_design_contest/2019/NCTU_Voice_Control_Car/doc/pic/whole_car_2.png differ diff --git a/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/CYBExtRej.mod b/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/CYBExtRej.mod new file mode 100644 index 00000000..ce77ecfb Binary files /dev/null and b/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/CYBExtRej.mod differ diff --git a/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/CYBase.mod b/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/CYBase.mod new file mode 100644 index 00000000..8fdfb3e0 Binary files /dev/null and b/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/CYBase.mod differ diff --git a/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/Group_1.mod b/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/Group_1.mod new file mode 100644 index 00000000..16b95aae Binary files /dev/null and b/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/Group_1.mod differ diff --git a/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/Group_1.txt b/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/Group_1.txt new file mode 100644 index 00000000..8326a216 Binary files /dev/null and b/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/Group_1.txt differ diff --git a/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/Group_2.mod b/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/Group_2.mod new file mode 100644 index 00000000..752ce192 Binary files /dev/null and b/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/Group_2.mod differ diff --git a/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/Group_2.txt b/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/Group_2.txt new file mode 100644 index 00000000..81d2d347 Binary files /dev/null and b/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/Group_2.txt differ diff --git a/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/Spotter_IC.c b/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/Spotter_IC.c new file mode 100644 index 00000000..0794b6e4 --- /dev/null +++ b/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/Spotter_IC.c @@ -0,0 +1,181 @@ +#include +#include + +#include +#include "CSpotterSDK.h" +#include "conf.h" + +#define DISABLE_MALLOC +#if defined DEBUG + #define LOG(args...) {printf(args); putchar('\n');} +#else + #define LOG(args...) +#endif + + +#ifdef DISABLE_MALLOC +#define k_nMemSize (20 * 256* sizeof(int)) //Memory alloc size for CSpotter. Modify it, if need. +#endif + +#define k_nStateSize (19* sizeof(int)) +#define k_nMaxTime 300 +#define k_nFrameSize 160//256 + +#define k_nMaxGroupSize 5 +#define k_nLevel2TimeOut (5*16000) //interval of level 2 recognize time. After time out, it would back to level 1 + +typedef struct +{ + HANDLE hCSpotter; + int groupId; + int cmdId; + BYTE lpbyState[k_nStateSize] ; + #ifndef DISABLE_MALLOC + BYTE *lpbyMemPool; + #else + #pragma message "Spotter.c: use fixed memory size" + BYTE lpbyMemPool[k_nMemSize]; + #endif +int groupList[k_nMaxGroupSize+1]; +int level2RemainTime; +}Spotter; + +static Spotter gSpotter= {0}; +void Spotter_Release(void); +int Spotter_Init2(BYTE *lpbyCYBase, BYTE **lppbyModel, void* lpbyRejModel){ + int n; + int nGroups, nCmds; + int err; + if (gSpotter.hCSpotter!= 0){ + Spotter_Release(); + } + + for(nGroups= 0, nCmds= 0; nGroups<= k_nMaxGroupSize; nGroups++){ + if(lppbyModel[nGroups]== 0) break; + nCmds+= CSpotter_GetNumWord(lppbyModel[nGroups]); + gSpotter.groupList[nGroups]= nCmds; + } +// LOG("cmd num: %d\n", nCmds); + gSpotter.groupList[nGroups]= INT_MAX; + // Check the memory usage + n = CSpotter_GetMemoryUsage_MultiWithExtRejModel(lpbyCYBase , lppbyModel , nGroups, k_nMaxTime, lpbyRejModel); +#ifndef DISABLE_MALLOC + gSpotter.lpbyMemPool= malloc(n); + if( gSpotter.lpbyMemPool== 0 ) { +#else + if( n > k_nMemSize ) { +#endif + LOG("CSpotter init fail: memory need %d\n", n); + return -2; + } + + gSpotter.hCSpotter = CSpotter_Init_MultiWithExtRejModel(lpbyCYBase , lppbyModel , nGroups, k_nMaxTime, (BYTE*)lpbyRejModel, (BYTE*)gSpotter.lpbyMemPool , n , gSpotter.lpbyState , k_nStateSize , &err ) ; + if( err != CSPOTTER_SUCCESS ) { +#ifndef DISABLE_MALLOC + free(gSpotter.lpbyMemPool); + gSpotter.lpbyMemPool= 0; +#endif + LOG("CSpotter init fail:error code is %d\n", err); + return err; + } + gSpotter.level2RemainTime= 0; + return CSPOTTER_SUCCESS; +} + +int Spotter_Init(BYTE *lpbyCYBase, BYTE *lppbyModel[]){ + return Spotter_Init2(lpbyCYBase, lppbyModel, 0); +} + +static void calResult(void){ + int cmd= CSpotter_GetResult(gSpotter.hCSpotter); + int i; + for(i= 0; ; i++){ + if(cmd< gSpotter.groupList[i]) { + gSpotter.groupId= i; + if(i> 0){ + gSpotter.cmdId= cmd- gSpotter.groupList[i- 1]; + }else{ + gSpotter.cmdId= cmd; + } + return; + } + } +} + +LED_MODE led; +int Spotter_AddSample(SHORT *lpsSample, INT nNumSample){ + int nRet= CSpotter_AddSample(gSpotter.hCSpotter, lpsSample, nNumSample); + if(nRet== CSPOTTER_SUCCESS){ + calResult(); + if(gSpotter.groupId== 0){ + gSpotter.level2RemainTime= k_nLevel2TimeOut; //goto level 2 + led = LED_LIGHT; + //printf("ledd\n",led ); + LOG("trigger, jump to level 2"); + }else if(gSpotter.level2RemainTime<= 0){ + nRet= CSPOTTER_ERR_NeedMoreSample; //false alarm + LOG("ignore cmd"); + }else{ + gSpotter.level2RemainTime= 0; //detect level 2 cmd, back to level 1 + led = LED_DARK_TASK; + set_work_status_EXE_CMD(); + LOG("detect cmd"); + } + }else if(gSpotter.level2RemainTime> 0){ + gSpotter.level2RemainTime-= nNumSample; + if(gSpotter.level2RemainTime<= 0){ + printf("timoutttttttttttttt\n" ); + led = LED_DARK; + LOG("time out"); + } + } + + return nRet; +} + + +int Spotter_GetResultId(void){ + return gSpotter.cmdId; +} + +int Spotter_GetResultGroupId(void){ + return gSpotter.groupId; +} + +void Spotter_Reset(void){ + CSpotter_Reset(gSpotter.hCSpotter); +} + +void Spotter_Release(void){ + if(!gSpotter.hCSpotter) return; + CSpotter_Release(gSpotter.hCSpotter); + gSpotter.hCSpotter= 0; +#ifndef DISABLE_MALLOC + free(gSpotter.lpbyMemPool); + gSpotter.lpbyMemPool= 0; +#endif +} + +const char* Spotter_GetVersion(void){ + return CSpotter_GetVersion(); +} + +int Spotter_VAD_Enable(int isEnabled){ +#if SUPPORT_VAD + return CSpotter_VAD_Enable(gSpotter.hCSpotter , isEnabled); +#else + return -1; +#endif +} + +int Spotter_VAD_SetMinEnergyThreshd(int nThreshold){ +#if SUPPORT_VAD + return CSpotter_VAD_SetMinEnergyThreshd(gSpotter.hCSpotter , nThreshold); +#else + return -1; +#endif +} + +HANDLE Spotter_GetHandle(){ + return gSpotter.hCSpotter; +} diff --git a/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/libCSpotter_IC.version b/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/libCSpotter_IC.version new file mode 100644 index 00000000..a437428a --- /dev/null +++ b/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/libCSpotter_IC.version @@ -0,0 +1,6 @@ +version: 6.4.5.0.20190823(trial)(synopsys_limited) +-------------------------------------- +-mcpu=em4_fpuda -mlittle-endian -mcode-density -mdiv-rem -mswap -mnorm -mmpy-option=6 -mbarrel-shifter -mfpu=fpuda_all +-------------------------------------- +target: arc-elf32 +gcc_version: '8.2.1 20180814 (ARCompact/ARCv2 ISA elf32 toolchain 2018.09) ' diff --git a/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/main.c b/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/main.c new file mode 100644 index 00000000..2df05f25 --- /dev/null +++ b/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/main.c @@ -0,0 +1,654 @@ +#include +#include +#include +#include "Spotter_IC.h" +#include "recorder.h" +#include "mpu9250.h" +#include "embARC.h" +#include "embARC_debug.h" +#include "conf.h" + +//全域變數 +LED_MODE led = LED_DARK; +static DEV_GPIO_PTR gpio_moter,gpio_led,pwm; +static MOV_DRECT mov_dir; + +static uint32_t switchway = 0; +static uint32_t timepwmcount = 0; +static uint32_t timempucount=0; +static int gpID,cmdID; +static uint32_t in1,in2,in3,in4; +static int Enc1=0,Enc2=0; +MPU9250_DATA mpu9250_data = { 0 }; +/**/ +static int Rtarget_Enc; +static int Ltarget_Enc; +/**/ +static int Loutput=1; +static int Routput=1; +/**/ +static float yal=0; +float TargetDeg=0; +/**/ +int Turn_out=0; +int MAX_PWM=100; +int mapflag=0,recodering_flag=0,TurnAro_flag=0; +VOICE_CMD map1[10]={CMD_GO_FRONT,CMD_TURN_LEFT_DEG_90,CMD_TURN_LEFT_DEG_90,CMD_TURN_RIGHT_DEG_90,CMD_TURN_RIGHT_DEG_90}; +VOICE_CMD map0[10]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}; +static int Enc1Count=0,Enc2Count=0,preEnc1=0,preEnc2=0; +static WorkStatus work_st = RECON_VOICE;//reconition +int Blocked=0; + +static void GPIO_INIT(); +static void TIMER_INIT(); +static void prr(int); +static void moterPWM(void *ptr); +static MPU9250_DEFINE(mpu9250_sensor, MPU9250_IIC_ID, MPU9250_IIC_ADDRESS); +static void right_rotation(int dir,int pwm_1); +static void left_rotation(int dir,int pwm_2); +static void check_Enc(); +static void Turn(int ); +static void PRINT_WK_ST(); + +void Map_Inverter(VOICE_CMD*,int); + +static int doRecognize(); +void mpu9250(float*); +#include "CYBase.mod.h" +#include "Group_1.mod.h" +#include "Group_2.mod.h" + +int main(int argc, char **argv){ + //float yal; + gpio_moter=gpio_get_dev(IOTDK_MOTER_ID); + gpio_led=gpio_get_dev(IOTDK_LED_ID); + GPIO_INIT(); + mpu9250_sensor_init(mpu9250_sensor); + //timer1 + TIMER_INIT(); + + int nRet; + + printf("CSpotter version: %s\r\n", Spotter_GetVersion()); + + nRet= Spotter_Init2((void*)pCYBase_mod, (const void*[]){pGroup_1_mod, pGroup_2_mod, 0}, 0); + if(nRet!= 0){ + goto Exit; + } + + while(1){ + if(work_st==RECON_VOICE){ + Spotter_Reset(); + doRecognize(); + } + else if( work_st == EXE_CMD){ + mpu9250(&yal); + if(preEnc1==Enc1){ + Enc1Count++; + } + else{ + preEnc1=Enc1; + Enc1Count=0; + } + if(preEnc2==Enc2){ + Enc2Count++; + } + else{ + preEnc2=Enc2; + Enc2Count=0; + } + if(Blocked){ + Enc2Count=0; + Enc1Count=0; + } + if( Enc1Count > 100 && Enc2Count > 100 ){ + + if(recodering_flag){ + mapflag++; + } + if(TurnAro_flag==1){ + mov_dir = MOV_TURN_LEFT_90; + TargetDeg = yal + DEG_90; + TurnAro_flag++; + }else if(TurnAro_flag==2){ + mov_dir = MOV_TURN_LEFT_90; + TargetDeg = yal + DEG_90; + TurnAro_flag=0; + } + else if(TurnAro_flag==0){ + mov_dir=MOV_STOP; + work_st=RECON_VOICE; + } + Enc2Count=0; + Enc1Count=0; + } + + } + else if( work_st == BACK2HOME){ + mpu9250(&yal); + //EMBARC_PRINTF("MP_F %d mov %d\n",mapflag,map1[mapflag]); + if(preEnc1==Enc1){ + Enc1Count++; + } + else{ + preEnc1=Enc1; + Enc1Count=0; + } + + if(preEnc2==Enc2){ + Enc2Count++; + } + else{ + preEnc2=Enc2; + Enc2Count=0; + } + if(Blocked){ + Enc2Count=0; + Enc1Count=0; + } + + if( Enc1Count > 100 && Enc2Count > 100 ){ + if(TurnAro_flag==1){ + mov_dir = MOV_TURN_LEFT_90; + TargetDeg = yal + DEG_90; + TurnAro_flag++; + } + else if(TurnAro_flag==2){ + mov_dir = MOV_TURN_LEFT_90; + TargetDeg = yal + DEG_90; + TurnAro_flag=0; + } + else{ + switch(map1[mapflag]){ + case CMD_TURN_RIGHT_DEG_45: + break; + case CMD_TURN_RIGHT_DEG_90: + //mpu9250(&yal); + mov_dir = MOV_TURN_RIGHT_90; + TargetDeg = yal - DEG_90; + break; + case CMD_TURN_LEFT_DEG_45: + break; + case CMD_TURN_LEFT_DEG_90: + //mpu9250(&yal); + mov_dir = MOV_TURN_LEFT_90; + TargetDeg = yal + DEG_90; + break; + case CMD_STOP: + mov_dir = MOV_STOP; + break; + case CMD_GO_FRONT: + mov_dir = MOV_GO_FRONT; + Ltarget_Enc = Enc2+1000; + Rtarget_Enc = Enc1+1000; + break; + case CMD_TURN_AROUND: + //mpu9250(&yal); + TurnAro_flag=1; + break; + case -1: + default: + mov_dir=MOV_STOP; + work_st=RECON_VOICE; + mapflag=0; + break; + } + mapflag++; + } + Enc2Count=0; + Enc1Count=0; + + } + } + else if(work_st == RECORD_MAP){ + recodering_flag=1; + mapflag=0; + //EMBARC_PRINTF("MP_F %d\n",recodering_flag); + mov_dir=MOV_STOP; + work_st=RECON_VOICE; + } + + //EMBARC_PRINTF("Routput= %d taskfin= %d targetEnc = %d NowEnc = %d \n",Routput,finish_task,Rtarget_Enc,Enc1); + //EMBARC_PRINTF("Lout= %d Enc2= %d\r\n",Loutput,Enc2); + //EMBARC_PRINTF("DDD\n"); + //PRINT_WK_ST(); + //EMBARC_PRINTF_FlOAT("Tar",TargetDeg); + //EMBARC_PRINTF_FlOAT("yal",yal); + + + } + printf("Done\r\n"); +Exit: + Spotter_Release(); + exit(0); + return 0; +} + + +static void moterPWM(void *ptr){ + timer_int_clear(TIMER_1); + switch(mov_dir){ + case MOV_STOP: + //EMBARC_PRINTF("way %d\r\n",mov_dir); + break; + case MOV_GO_FRONT://前; + right_rotation(0,Routput); + left_rotation(0,Loutput); + break; + case MOV_TURN_LEFT_90://左 + Turn(DIR_LEFT); + break; + case MOV_TURN_RIGHT_90://右 + Turn(DIR_RIGHT); + break; + case MOV_TURN_AROUND: + //Turn(DIR_LEFT); + break; + default: + break; + } + + gpio_led->gpio_read(&Blocked, 1 << IOTDK_LED_1); + + if (timepwmcount == 250||Blocked){ + gpio_moter->gpio_write(0<< IOTDK_PWM_1_0, 1 << IOTDK_PWM_1_0); + gpio_moter->gpio_write(0<< IOTDK_PWM_1_1, 1 << IOTDK_PWM_1_1); + gpio_moter->gpio_write(0<< IOTDK_PWM_2_0, 1 << IOTDK_PWM_2_0); + gpio_moter->gpio_write(0<< IOTDK_PWM_2_1, 1 << IOTDK_PWM_2_1); + timepwmcount = 0; + } + + switch(led){ + case 0: + gpio_led->gpio_write(0<< IOTDK_LED_0, 1 <gpio_write(1<< IOTDK_LED_0, 1 <gpio_write(0<< IOTDK_LED_0, 1 <gpio_read(&in4, 1 << IOTDK_ENC_2_1); + gpio_moter->gpio_read(&in2, 1 << IOTDK_ENC_1_1); + if(!in1){ + gpio_moter->gpio_read(&in1, 1 << IOTDK_ENC_1_0); + if(in1) + if(in2) + Enc1++; + else + Enc1--; + } + else + { + gpio_moter->gpio_read(&in1, 1 << IOTDK_ENC_1_0); + } + + if(!in3){ + gpio_moter->gpio_read(&in3, 1 << IOTDK_ENC_2_0); + if(in3) + if(in4) + Enc2++; + else + Enc2--; + + } + else{ + gpio_moter->gpio_read(&in3, 1 << IOTDK_ENC_2_0); + } + check_Enc(); + timepwmcount++; + +} +static int doRecognize(){ + int nRet; + nRet= Recorder_Init(); + int16_t *pData; + if(nRet!= 0){ + printf("record init fail: %d\r\n", nRet); + return 1; + } + Spotter_Reset(); + Recorder_Start(); + while(work_st==RECON_VOICE){ + + //EMBARC_PRINTF("[1]= %d [2]= %d \r\n",Enc1,Enc2); + //EMBARC_PRINTF("mov_dir is %d\r\n",mov_dir); + pData= Recorder_GetBuffer(); + if(pData== 0) continue; + + nRet= Spotter_AddSample(pData, Recorder_GetBufferSize()); + if(nRet== CSPOTTER_SUCCESS){ + gpID=Spotter_GetResultGroupId(); + cmdID=Spotter_GetResultId(); + printf("CSpotter detect result gpID=%d cmdID=%d\n", gpID, cmdID); + if(gpID){ + switch(cmdID){ + case CMD_TURN_RIGHT_DEG_45: + + break; + case CMD_TURN_RIGHT_DEG_90: + //mpu9250(&yal); + if(recodering_flag) + map1[mapflag]=CMD_TURN_RIGHT_DEG_90; + mov_dir = MOV_TURN_RIGHT_90; + TargetDeg = yal - DEG_90; + break; + case CMD_TURN_LEFT_DEG_45: + break; + case CMD_TURN_LEFT_DEG_90: + //mpu9250(&yal); + if(recodering_flag) + map1[mapflag]=CMD_TURN_LEFT_DEG_90; + mov_dir = MOV_TURN_LEFT_90; + TargetDeg = yal + DEG_90; + break; + case CMD_BACK2HOME: + recodering_flag=0; + work_st = BACK2HOME; + TurnAro_flag=1; + Map_Inverter(map1,mapflag); + mapflag=0; + break; + case CMD_STOP: + mov_dir = MOV_STOP; + break; + case CMD_GO_FRONT: + if(recodering_flag) + map1[mapflag]=CMD_GO_FRONT; + mov_dir = MOV_GO_FRONT; + Ltarget_Enc = Enc2+1000; + Rtarget_Enc = Enc1+1000; + break; + case CMD_TURN_AROUND: + //mpu9250(&yal); + if(recodering_flag) + map1[mapflag]=CMD_TURN_AROUND; + mov_dir = MOV_TURN_AROUND; + TurnAro_flag=1; + break; + case CMD_START_RECORD: + work_st = RECORD_MAP; + break; + + } + } + }else if(nRet!= CSPOTTER_ERR_NeedMoreSample){ + printf("recognize fail: %d\n" , nRet); + break; + } + Recorder_NextBuffer(); + } + Recorder_Stop(); + Recorder_Release(); + return nRet; +} +void GPIO_INIT(){ + gpio_moter->gpio_open((1 << IOTDK_PWM_1_0)); + gpio_moter->gpio_open((1 << IOTDK_PWM_1_1)); + gpio_moter->gpio_open((1 << IOTDK_PWM_2_0)); + gpio_moter->gpio_open((1 << IOTDK_PWM_2_1)); + gpio_moter->gpio_open((1 << IOTDK_ENC_1_0)); + gpio_moter->gpio_open((1 << IOTDK_ENC_1_1)); + gpio_moter->gpio_open((1 << IOTDK_ENC_2_0)); + gpio_moter->gpio_open((1 << IOTDK_ENC_2_1)); + gpio_moter->gpio_control(GPIO_CMD_SET_BIT_DIR_OUTPUT, (void *)(1 << IOTDK_PWM_1_0)); + gpio_moter->gpio_control(GPIO_CMD_SET_BIT_DIR_OUTPUT, (void *)(1 << IOTDK_PWM_1_1)); + gpio_moter->gpio_control(GPIO_CMD_SET_BIT_DIR_OUTPUT, (void *)(1 << IOTDK_PWM_2_0)); + gpio_moter->gpio_control(GPIO_CMD_SET_BIT_DIR_OUTPUT, (void *)(1 << IOTDK_PWM_2_1)); + //gpio_moter->gpio_control(GPIO_CMD_ENA_BIT_INT, (void *)(1 << IOTDK_Enc_1_0)); + gpio_moter->gpio_control(GPIO_CMD_SET_BIT_DIR_INPUT, (void *)(1 << IOTDK_ENC_1_0)); + gpio_moter->gpio_control(GPIO_CMD_SET_BIT_DIR_INPUT, (void *)(1 << IOTDK_ENC_1_1)); + gpio_moter->gpio_control(GPIO_CMD_SET_BIT_DIR_INPUT, (void *)(1 << IOTDK_ENC_2_0)); + gpio_moter->gpio_control(GPIO_CMD_SET_BIT_DIR_INPUT, (void *)(1 << IOTDK_ENC_2_1)); + + + //gpio_moter->gpio_control(GPIO_CMD_SET_BIT_ISR, enen ); + //gpio_moter->gpio_control(GPIO_CMD_GET_BIT_INT_CFG, enenen ); + //print_CPIO_CFG_INFO(); + //int_handler_install(INTNO_TIMER1,moterPWM); + + gpio_led->gpio_open((1 << IOTDK_LED_0)); + gpio_led->gpio_open((1 << IOTDK_LED_1)); + gpio_led->gpio_open((1 << IOTDK_LED_2)); + gpio_led->gpio_open((1 << IOTDK_LED_3)); + gpio_led->gpio_control(GPIO_CMD_SET_BIT_DIR_OUTPUT, (void *)(1 << IOTDK_LED_0)); + gpio_led->gpio_control(GPIO_CMD_SET_BIT_DIR_INPUT, (void *)(1 << IOTDK_LED_1)); + gpio_led->gpio_control(GPIO_CMD_SET_BIT_DIR_OUTPUT, (void *)(1 << IOTDK_LED_2)); + gpio_led->gpio_control(GPIO_CMD_SET_BIT_DIR_OUTPUT, (void *)(1 << IOTDK_LED_3)); + //gpio_led->gpio_write(1<< IOTDK_LED_3, 1 << IOTDK_LED_3); + + //gpio_led->gpio_open((1 << 1)); + //gpio_led->gpio_control(GPIO_CMD_SET_BIT_DIR_INPUT, (void *)(1 << 1)); +} +void TIMER_INIT() +{ + if (timer_present(TIMER_1)) + { + EMBARC_PRINTF("timer 1 is present\n"); + timer_stop(TIMER_1); // Stop it first since it might be enabled before + int_handler_install(INTNO_TIMER1,moterPWM); + int_pri_set(INTNO_TIMER1, INT_PRI_MIN); + int_enable(INTNO_TIMER1); + timer_start(TIMER_1, TIMER_CTRL_IE, 0.0001 * BOARD_CPU_CLOCK); + } + else + { + EMBARC_PRINTF("timer 1 is not present\r\n"); + } +} +void prr(int val){ + EMBARC_PRINTF("%d%d%d%d%d%d%d%d%d\r\n",val,val,val,val,val,val,val,val,val,val); +} +void mpu9250(float* yal){ + mpu9250_sensor_read(mpu9250_sensor, &mpu9250_data); +#ifdef MPU9250_USE_DMP + char datay[10]; + sprintf(datay, "%06.1f", mpu9250_data.yaw); + + *yal=strtof(datay,datay+0x0A); + + //EMBARC_PRINTF("dmp: pitch=%s, roll=%s, yaw=%s, \r\n", datap, datar, datay); + //EMBARC_PRINTF_FlOAT("yal",*yal); + + //board_delay_ms(100, 1); + //EMBARC_PRINTF("\x1b[2k\x1b\x45"); + + +#else + EMBARC_PRINTF("accel x=%5d, y=%5d, z=%5d \r\n", mpu9250_data.accel_x, mpu9250_data.accel_y, mpu9250_data.accel_z); + EMBARC_PRINTF("gpro x=%5d, y=%5d, z=%5d \r\n", mpu9250_data.gyro_x, mpu9250_data.gyro_y, mpu9250_data.gyro_z); + EMBARC_PRINTF("mag x=%5d, y=%5d, z=%5d \r\n", mpu9250_data.mag_x, mpu9250_data.mag_y, mpu9250_data.mag_z); + board_delay_ms(100, 1); + EMBARC_PRINTF("\x1b[2k\x1b\x45"); + EMBARC_PRINTF("\x1b[2k\x1b\x45"); + EMBARC_PRINTF("\x1b[2k\x1b\x45"); +#endif +} + +void EMBARC_PRINTF_FlOAT(char* str,float x) +{ + int b = 10*(x); + if(b/10 == 0) + EMBARC_PRINTF("%s = %c0.%d\r\n",str,(b>0)? ' ':'-',( b>0 )? b%10 : -b%10); + else + EMBARC_PRINTF("%s = %d.%d\r\n",str,(int)x,( b>0 )? b%10 : -b%10); +} +void PRINT_WK_ST() +{ + if (work_st == EXE_CMD ) + EMBARC_PRINTF("wk_st %d \r\n",work_st); + else if (work_st == RECON_VOICE) + EMBARC_PRINTF("wk_st2 %d \r\n",work_st); +} +int Straight_Controler(){ + + +} +//int Straight_Controler(){ + + +//} +void right_rotation(int dir,int pwm_1){ + //cEMBARC_PRINTF("IOTDK_PWM_1_0 is running\r\n"); + if (pwm_1>MAX_PWM){ + pwm_1=MAX_PWM; + } + else if(pwm_1<-MAX_PWM) + pwm_1=-MAX_PWM; + if(pwm_1>0){ + if(dir==0){ + //EMBARC_PRINTF("I\r\n"); + if(timepwmcount == 200-pwm_1){ + gpio_moter->gpio_write(0<< IOTDK_PWM_1_1, 1 << IOTDK_PWM_1_1); + gpio_moter->gpio_write(1<< IOTDK_PWM_1_0, 1 << IOTDK_PWM_1_0); + //EMBARC_PRINTF("pwm1= %d\r\n",pwm_1); + } + } + else if(dir==1){ + if(timepwmcount == 200-pwm_1){ + gpio_moter->gpio_write(0<< IOTDK_PWM_1_0, 1 << IOTDK_PWM_1_0); + gpio_moter->gpio_write(1<< IOTDK_PWM_1_1, 1 << IOTDK_PWM_1_1); + } + } +} +else if(pwm_1<0){ + pwm_1=-pwm_1; + if(dir==0){ + if(timepwmcount == (200-pwm_1)){ + gpio_moter->gpio_write(0<< IOTDK_PWM_1_0, 1 << IOTDK_PWM_1_0); + gpio_moter->gpio_write(1<< IOTDK_PWM_1_1, 1 << IOTDK_PWM_1_1); + //EMBARC_PRINTF("pwm1= %d\r\n",pwm_1); + } + } + else if(dir==1){ + if(timepwmcount == 200-pwm_1){ + gpio_moter->gpio_write(0<< IOTDK_PWM_1_1, 1 << IOTDK_PWM_1_1); + gpio_moter->gpio_write(1<< IOTDK_PWM_1_0, 1 << IOTDK_PWM_1_0); + } + } +} +} + +void left_rotation(int dir,int pwm_2){ + if (pwm_2>MAX_PWM){ + pwm_2=MAX_PWM; + } + else if(pwm_2<-MAX_PWM) + pwm_2=-MAX_PWM; + //EMBARC_PRINTF("pwm2= %d\r\n",pwm_2); + if(pwm_2>0){ + if(dir==0){ + if(timepwmcount == 200-pwm_2){ + gpio_moter->gpio_write(0<< IOTDK_PWM_2_1, 1 << IOTDK_PWM_2_1); + gpio_moter->gpio_write(1<< IOTDK_PWM_2_0, 1 << IOTDK_PWM_2_0); + + } + } + else if(dir==1){ + if(timepwmcount == 200-pwm_2){ + gpio_moter->gpio_write(0<< IOTDK_PWM_2_0, 1 << IOTDK_PWM_2_0); + gpio_moter->gpio_write(1<< IOTDK_PWM_2_1, 1 << IOTDK_PWM_2_1); + } + } + } + else if(pwm_2<0){ + pwm_2=-pwm_2; + if(dir==0){ + if(timepwmcount == 200-pwm_2){ + gpio_moter->gpio_write(0<< IOTDK_PWM_2_0, 1 << IOTDK_PWM_2_0); + gpio_moter->gpio_write(1<< IOTDK_PWM_2_1, 1 << IOTDK_PWM_2_1); + //EMBARC_PRINTF("pwm2= %d\r\n",pwm_2); + } + } + else if(dir==1){ + if(timepwmcount == 200-pwm_2){ + gpio_moter->gpio_write(0<< IOTDK_PWM_2_1, 1 << IOTDK_PWM_2_1); + gpio_moter->gpio_write(1<< IOTDK_PWM_2_0, 1 << IOTDK_PWM_2_0); + } + } + } +} +void check_Enc(){ + int P=3; + int Rerr=( Enc1 - Rtarget_Enc ); + int Lerr=( Enc2 - Ltarget_Enc ); + int Rout = - Rerr * P; + int Lout = - Lerr * P; + if( Rout < 20 && Rout > -20 ){ + Routput=0; + } + else{ + Routput=Rout; + } + + if(Lout<20&&Lout>-20){ + Loutput=0; + } + else{ + Loutput=Lout; + } +} + +void set_work_status_EXE_CMD() +{ + work_st = EXE_CMD; +} +void Turn(int dir){ + int p=3; + //EMBARC_PRINTF("Turn_out= %d",Turn_out); + if( dir == DIR_LEFT ){ + if(TargetDeg>180){ + if(yal<0) + TargetDeg=TargetDeg-360 ; + else + Turn_out = -p * ( yal - TargetDeg ); + } + Turn_out = -p * ( yal - TargetDeg ); + if( Turn_out < 20 && Turn_out > -20 ){ + Turn_out = 0; + } + //EMBARC_PRINTF("Turn_out= %d",Turn_out); + right_rotation(0,Turn_out); + left_rotation(1,Turn_out); + } + else if( dir == DIR_RIGHT ){ + if(TargetDeg<-180){ + if(yal>0) + TargetDeg=TargetDeg+360 ; + else + Turn_out = -p * ( yal - TargetDeg ); + } + Turn_out = -p * ( yal - TargetDeg ); + if( Turn_out < 20 && Turn_out > -20 ){ + Turn_out = 0; + } + right_rotation(0,Turn_out); + left_rotation(1,Turn_out); + } + +} +void Map_Inverter(VOICE_CMD* map,int size){ + int flag=0; + VOICE_CMD temp; + size=size-1; + while(flag<=size){ + if(map1[flag]==CMD_TURN_RIGHT_DEG_90) + map1[flag]=CMD_TURN_LEFT_DEG_90; + else if(map1[flag]==CMD_TURN_LEFT_DEG_90) + map1[flag]=CMD_TURN_RIGHT_DEG_90; + flag++; + } + flag=0; + while(flag<=size/2){ + temp=map1[size-flag]; + map1[size-flag]=map1[flag]; + map1[flag]=temp; + flag++; + //EMBARC_PRINTF("map = %d %d %d",map1[0],map1[1],map1[2]); + } + + +} \ No newline at end of file diff --git a/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/makefile b/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/makefile new file mode 100644 index 00000000..c90e7375 --- /dev/null +++ b/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/makefile @@ -0,0 +1,25 @@ +# Application name +APPL ?= CSpotter_IC +BOARD = iotdk +EXT_DEV_LIST += sensor/imu/mpu9250 +# +# root dir of embARC +# +EMBARC_ROOT = ../ + +MID_SEL = common + +# application source dirs +APPL_CSRC_DIR = . +APPL_ASMSRC_DIR = . + +# application include dirs +APPL_INC_DIR = . + +APPL_LIBS= libCSpotter_IC.a +# include current project makefile +COMMON_COMPILE_PREREQUISITES += makefile + +### Options above must be added before include options.mk ### +# include key embARC build system makefile +include $(EMBARC_ROOT)/options/options.mk \ No newline at end of file diff --git a/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/recorder.c b/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/recorder.c new file mode 100644 index 00000000..90b780ca --- /dev/null +++ b/arc_design_contest/2019/NCTU_Voice_Control_Car/src/voice/recorder.c @@ -0,0 +1,114 @@ +#include +#include +#include +#include +#include "embARC.h" +#include "dw_i2s.h" + +#define BUFFER_SIZE 160 +#define NUM_OF_BUFFER 3 + +static int16_t gDevBuffer[BUFFER_SIZE* 2]; +static DEV_BUFFER gDEV_BUFFER; + +static int16_t gBuffer[NUM_OF_BUFFER][BUFFER_SIZE]; + +static int gWrite=0; +static int gRead= 0; +static int gIsRunnning= 0; +static int gIsOverflow= 0; + +static DEV_I2S_PTR gDevice; + +/* +此範例程式使用Adafruit SPH0645LM4H I2S 麥克風 +CSpotter 語音音量最大介於5000 ~ 20000 之間的辨識效果最佳。 +聲音過小或爆音都會造成較差的辨識效果 +*/ +#define BIAS 1700 +#define GAIN 8 +static int16_t normalize(int16_t sample){ + int32_t v= (((int32_t)sample) + BIAS)* GAIN; + if(v> SHRT_MAX) return SHRT_MAX; + if(v< SHRT_MIN) return SHRT_MIN; + return (int16_t)v; +} + +static void callback_on_record_data(uint32_t count){ + int i; + int16_t *buffer; + if(!gIsRunnning) return; + if(!gIsOverflow&& gWrite- gRead>= NUM_OF_BUFFER){ + gIsOverflow= 1; + gWrite= gRead+ 1; + printf("record buffer overflow\r\n"); + }else if(gWrite> 10000&& gRead== gWrite){ + gRead= gWrite= 0; + } + buffer= gBuffer[gWrite%NUM_OF_BUFFER]; + for(i= 0; i< BUFFER_SIZE; i++){ + buffer[i]= normalize(gDevBuffer[i*2]); + } + gWrite++; + dw_i2s_control(gDevice, I2S_CMD_SET_RXINT_BUF,&gDEV_BUFFER); + } + + static void callback_on_record_error(uint32_t error){ + printf("record fail\r\n"); + } + +int Recorder_Init(){ + int nRet; + DW_I2S_CONFIG *i2s_config_ptr; + gDevice= i2s_get_dev(DW_I2S_1_ID); + if(gDevice== 0) return 1; + i2s_config_ptr = (DW_I2S_CONFIG *)(gDevice->i2s_info.i2s_config); +// i2s_config_ptr->data_res[0] = I2S_AUD_DATA_32B; + i2s_rx_clk_div(1538/(32*2)); //for sample rate 16000 + DEV_BUFFER_INIT(&gDEV_BUFFER, gDevBuffer, BUFFER_SIZE*2); + nRet= dw_i2s_open(gDevice, DEV_MASTER_MODE, I2S_DEVICE_RECEIVER); + if(nRet!= E_OK){ + printf("open record fail: %d\r\n", nRet); + } + dw_i2s_control(gDevice, I2S_CMD_ENA_DEV, 0); + dw_i2s_control(gDevice, I2S_CMD_MST_SET_CLK, (void*)1); + dw_i2s_control(gDevice, I2S_CMD_SET_RXCHDT_BUF, (void*)0x0080000); //receive 8 sample frame each time, so BUFFER_SIZE should be multiple of 8 + dw_i2s_control(gDevice, I2S_CMD_SET_RXCB, callback_on_record_data); + dw_i2s_control(gDevice, I2S_CMD_SET_ERRCB, callback_on_record_error); + dw_i2s_control(gDevice, I2S_CMD_SET_RXINT_BUF,&gDEV_BUFFER); + return 0; +} + +int16_t* Recorder_GetBuffer(){ + if(gRead>= gWrite) return 0; + return gBuffer[gRead%NUM_OF_BUFFER]; +} + +int Recorder_NextBuffer(){ + if(gRead>= gWrite) return 0; + gRead++; + return 1; +} + +int Recorder_GetBufferSize(){ + return BUFFER_SIZE; +} + +int Recorder_Start(){ + gRead= gWrite= 0; + gIsRunnning= 1; + dw_i2s_control(gDevice, I2S_CMD_SET_RXINT, (void*)1); + return 0; +} + +void Recorder_Stop(){ + gIsRunnning= 0; + dw_i2s_control(gDevice, I2S_CMD_SET_RXINT, (void*)0); +} + + + +void Recorder_Release(){ + Recorder_Stop(); + dw_i2s_control(gDevice, I2S_CMD_MST_SET_CLK, (void*)0); +} diff --git a/arc_design_contest/2019/NCTU_Voice_Control_Car/src/wifi/wifi.ino b/arc_design_contest/2019/NCTU_Voice_Control_Car/src/wifi/wifi.ino new file mode 100644 index 00000000..9d6d3381 --- /dev/null +++ b/arc_design_contest/2019/NCTU_Voice_Control_Car/src/wifi/wifi.ino @@ -0,0 +1,150 @@ +#include +#include + +const char* ssid = "Prophet"; +const char* password = "1mProphet"; +const char* mqttServer = "broker.hivemq.com"; // MQTT伺服器位址 +const char* mqttUserName = "Prophet_Car"; // 使用者名稱,隨意設定。 +const char* mqttPwd = "12345679"; // MQTT密碼 +const char* clientID = "Prophet"; // 用戶端ID,隨意設定。 +const char* topic = "/AGiLBERSPBCcqU"; + +unsigned long prevMillis = 0; // 暫存經過時間(毫秒) +const long interval = 1000; // 上傳資料的間隔時間,20秒。 +String msgStr = ""; // 暫存MQTT訊息字串 +String Direction=""; +String Car_Front=""; +String Available=""; +long duration, cm; +long duration2, cm2; + + + + +int temp; // 暫存溫度 +int hum; // 暫存濕度 +int DP5; +int DP6; +int DP7; + + +WiFiClient espClient; +PubSubClient client(espClient); +//dht11 DHT11; + +void setup_wifi() { + delay(10); + pinMode(D0, INPUT); + pinMode(D1, INPUT); + pinMode(D2, OUTPUT); + pinMode(D3, INPUT); + pinMode(D4, OUTPUT); + pinMode(D5, INPUT); + pinMode(D6, OUTPUT); + + WiFi.begin(ssid, password); + + while (WiFi.status() != WL_CONNECTED) { + delay(5000); + Serial.print("."); + } + + Serial.println(""); + Serial.println("WiFi connected"); +} + +void reconnect() { + while (!client.connected()) { + if (client.connect(clientID, mqttUserName, mqttPwd)) { + Serial.println("MQTT connected"); + } else { + Serial.print("failed, rc="); + Serial.print(client.state()); + Serial.println(" try again in 5 seconds"); + delay(5000); // 等5秒之後再重試 + } + } +} + +void setup() { + Serial.begin(9600); + setup_wifi(); + client.setServer(mqttServer, 1883); +} + +void loop() { + if (!client.connected()) { + reconnect(); + } + client.loop(); + digitalWrite(D4, LOW); + delayMicroseconds(5); + digitalWrite(D4, HIGH); // 給 Trig 高電位,持續 10微秒 + delayMicroseconds(10); + digitalWrite(D4, LOW); + duration = pulseIn(D3, HIGH); // 收到高電位時的時間 + cm = (duration/2) / 29.1; + + digitalWrite(D6, LOW); + delayMicroseconds(5); + digitalWrite(D6, HIGH); + delayMicroseconds(10); + digitalWrite(D6, LOW); + duration2 = pulseIn(D5, HIGH); + cm2 = (duration2/2) / 29.1; + Serial.print(cm2); + Serial.println("cm2"); + + //Car_Front + if(cm<20||cm2<20){ + Car_Front="Block"; + digitalWrite(D2, HIGH); + } + else{ + Car_Front="Clean"; + digitalWrite(D2, LOW); + } + + + // 等待20秒 + if (millis() - prevMillis > interval) { + prevMillis = millis(); + DP5=digitalRead(D0); + DP6=digitalRead(D1); + DP7=digitalRead(D2); + //Direction + if(DP5) + Direction="Dining Out"; + else + Direction="Finish"; + //Available + if(DP6){ + Available="Waiting Commd"; + } + else + Available="Useing"; + + + // // 讀取DHT11的溫濕度資料 +// int chk = DHT11.read(DHT11PIN); + // if (chk == 0) { + // temp = DHT11.temperature; + // hum = DHT11.humidity; + temp++; + hum++; + + + // 組合MQTT訊息;field1填入溫度、field2填入濕度 + msgStr=msgStr+" Direction "+Direction+" Car_Front "+Car_Front+" Available "+Available; + + // 宣告字元陣列 + byte arrSize = msgStr.length() + 1; + char msg[arrSize]; + + Serial.print("Publish message: "); + Serial.println(msgStr); + msgStr.toCharArray(msg, arrSize); // 把String字串轉換成字元陣列格式 + client.publish(topic, msg); // 發布MQTT主題與訊息 + msgStr = ""; + } +}