├── libref.pdf ├── image ├── bridge-0.jpg ├── bridge-1.jpg ├── check_br.jpg ├── load_0_1.jpg ├── recognize.jpg ├── settings.jpg ├── connection.jpg ├── control_led.jpg ├── multi-cmd-0.jpg ├── input_command.jpg ├── serial_monitor.jpg ├── sigtrain_0_on.jpg ├── sigtrain_1_off.jpg └── train_command.jpg ├── examples ├── vr_sample_check_baud_rate │ └── vr_sample_check_baud_rate.ino ├── vr_sample_control_led │ └── vr_sample_control_led.ino ├── vr_sample_multi_cmd │ └── vr_sample_multi_cmd.ino ├── vr_sample_bridge │ └── vr_sample_bridge.ino └── vr_sample_train │ └── vr_sample_train.ino ├── keywords.txt ├── VoiceRecognitionV3.h ├── README.md └── VoiceRecognitionV3.cpp /libref.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elechouse/VoiceRecognitionV3/HEAD/libref.pdf -------------------------------------------------------------------------------- /image/bridge-0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elechouse/VoiceRecognitionV3/HEAD/image/bridge-0.jpg -------------------------------------------------------------------------------- /image/bridge-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elechouse/VoiceRecognitionV3/HEAD/image/bridge-1.jpg -------------------------------------------------------------------------------- /image/check_br.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elechouse/VoiceRecognitionV3/HEAD/image/check_br.jpg -------------------------------------------------------------------------------- /image/load_0_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elechouse/VoiceRecognitionV3/HEAD/image/load_0_1.jpg -------------------------------------------------------------------------------- /image/recognize.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elechouse/VoiceRecognitionV3/HEAD/image/recognize.jpg -------------------------------------------------------------------------------- /image/settings.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elechouse/VoiceRecognitionV3/HEAD/image/settings.jpg -------------------------------------------------------------------------------- /image/connection.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elechouse/VoiceRecognitionV3/HEAD/image/connection.jpg -------------------------------------------------------------------------------- /image/control_led.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elechouse/VoiceRecognitionV3/HEAD/image/control_led.jpg -------------------------------------------------------------------------------- /image/multi-cmd-0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elechouse/VoiceRecognitionV3/HEAD/image/multi-cmd-0.jpg -------------------------------------------------------------------------------- /image/input_command.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elechouse/VoiceRecognitionV3/HEAD/image/input_command.jpg -------------------------------------------------------------------------------- /image/serial_monitor.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elechouse/VoiceRecognitionV3/HEAD/image/serial_monitor.jpg -------------------------------------------------------------------------------- /image/sigtrain_0_on.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elechouse/VoiceRecognitionV3/HEAD/image/sigtrain_0_on.jpg -------------------------------------------------------------------------------- /image/sigtrain_1_off.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elechouse/VoiceRecognitionV3/HEAD/image/sigtrain_1_off.jpg -------------------------------------------------------------------------------- /image/train_command.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elechouse/VoiceRecognitionV3/HEAD/image/train_command.jpg -------------------------------------------------------------------------------- /examples/vr_sample_check_baud_rate/vr_sample_check_baud_rate.ino: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file vr_sample_control_led.ino 4 | * @author JiapengLi 5 | * @brief This file provides a demostration on 6 | * checking the baud rate of VoiceRecognitionModule 7 | ****************************************************************************** 8 | * @note: 9 | * check baud rate 10 | ****************************************************************************** 11 | * @section HISTORY 12 | * 13 | * 2013/07/10 Initial version. 14 | */ 15 | #include 16 | #include "VoiceRecognitionV3.h" 17 | /** 18 | * Connection 19 | * Arduino VoiceRecognitionModule 20 | * 2 -------> TX 21 | * 3 -------> RX 22 | */ 23 | VR myVR(2,3); // 2:RX 3:TX, you can choose your favourite pins. 24 | 25 | int br[]={ 26 | 2400, 4800, 9600, 19200, 38400 27 | }; 28 | 29 | void setup(void) 30 | { 31 | /** initialize */ 32 | int i=0; 33 | Serial.begin(115200); 34 | Serial.println("Elechouse Voice Recognition V3 Module\r\nCheck Baud Rate sample"); 35 | for(i=0; i<5; i++){ 36 | myVR.begin(br[i]); 37 | if(myVR.clear() == 0){ 38 | Serial.print("Baud rate: "); 39 | Serial.println(br[i], DEC); 40 | break; 41 | } 42 | } 43 | if(i==5){ 44 | Serial.println("Check baud rate failed. \r\nPlease check the connection, and reset arduino"); 45 | } 46 | } 47 | 48 | void loop(void) 49 | { 50 | 51 | } 52 | 53 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For NRF905 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | VR KEYWORD3 10 | myVR KEYWORD1 11 | 12 | ####################################### 13 | # Methods and Functions (KEYWORD2) 14 | ####################################### 15 | setBaudRate KEYWORD2 16 | setIOMode KEYWORD2 17 | resetIO KEYWORD2 18 | setPulseWidth KEYWORD2 19 | setAutoLoad KEYWORD2 20 | disableAutoLoad KEYWORD2 21 | restoreSystemSettings KEYWORD2 22 | checkSystemSettings KEYWORD2 23 | recognize KEYWORD2 24 | train KEYWORD2 25 | trainWithSignature KEYWORD2 26 | load KEYWORD2 27 | clear KEYWORD2 28 | setSignature KEYWORD2 29 | deleteSignature KEYWORD2 30 | checkSignature KEYWORD2 31 | checkRecognizer KEYWORD2 32 | checkRecord KEYWORD2 33 | setGroupControl KEYWORD2 34 | checkGroupControl KEYWORD2 35 | setUserGroup KEYWORD2 36 | checkUserGroup KEYWORD2 37 | loadSystemGroup KEYWORD2 38 | loadUserGroup KEYWORD2 39 | 40 | test KEYWORD2 41 | 42 | ####################################### 43 | # Constants (LITERAL1) 44 | ####################################### 45 | 46 | PULSE LITERAL1 47 | TOGGLE LITERAL1 48 | SET LITERAL1 49 | CLEAR LITERAL1 50 | 51 | LEVEL0 LITERAL1 52 | LEVEL1 LITERAL1 53 | LEVEL2 LITERAL1 54 | LEVEL3 LITERAL1 55 | LEVEL4 LITERAL1 56 | LEVEL5 LITERAL1 57 | LEVEL6 LITERAL1 58 | LEVEL7 LITERAL1 59 | LEVEL8 LITERAL1 60 | LEVEL9 LITERAL1 61 | LEVEL10 LITERAL1 62 | LEVEL11 LITERAL1 63 | LEVEL12 LITERAL1 64 | LEVEL13 LITERAL1 65 | LEVEL14 LITERAL1 66 | LEVEL15 LITERAL1 67 | 68 | GROUP0 LITERAL1 69 | GROUP1 LITERAL1 70 | GROUP2 LITERAL1 71 | GROUP3 LITERAL1 72 | GROUP4 LITERAL1 73 | GROUP5 LITERAL1 74 | GROUP6 LITERAL1 75 | GROUP7 LITERAL1 76 | -------------------------------------------------------------------------------- /examples/vr_sample_control_led/vr_sample_control_led.ino: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file vr_sample_control_led.ino 4 | * @author JiapengLi 5 | * @brief This file provides a demostration on 6 | how to control led by using VoiceRecognitionModule 7 | ****************************************************************************** 8 | * @note: 9 | voice control led 10 | ****************************************************************************** 11 | * @section HISTORY 12 | 13 | 2013/06/13 Initial version. 14 | */ 15 | 16 | #include 17 | #include "VoiceRecognitionV3.h" 18 | 19 | /** 20 | Connection 21 | Arduino VoiceRecognitionModule 22 | 2 -------> TX 23 | 3 -------> RX 24 | */ 25 | VR myVR(2,3); // 2:RX 3:TX, you can choose your favourite pins. 26 | 27 | uint8_t records[7]; // save record 28 | uint8_t buf[64]; 29 | 30 | int led = 13; 31 | 32 | #define onRecord (0) 33 | #define offRecord (1) 34 | 35 | /** 36 | @brief Print signature, if the character is invisible, 37 | print hexible value instead. 38 | @param buf --> command length 39 | len --> number of parameters 40 | */ 41 | void printSignature(uint8_t *buf, int len) 42 | { 43 | int i; 44 | for(i=0; i0x19 && buf[i]<0x7F){ 46 | Serial.write(buf[i]); 47 | } 48 | else{ 49 | Serial.print("["); 50 | Serial.print(buf[i], HEX); 51 | Serial.print("]"); 52 | } 53 | } 54 | } 55 | 56 | /** 57 | @brief Print signature, if the character is invisible, 58 | print hexible value instead. 59 | @param buf --> VR module return value when voice is recognized. 60 | buf[0] --> Group mode(FF: None Group, 0x8n: User, 0x0n:System 61 | buf[1] --> number of record which is recognized. 62 | buf[2] --> Recognizer index(position) value of the recognized record. 63 | buf[3] --> Signature length 64 | buf[4]~buf[n] --> Signature 65 | */ 66 | void printVR(uint8_t *buf) 67 | { 68 | Serial.println("VR Index\tGroup\tRecordNum\tSignature"); 69 | 70 | Serial.print(buf[2], DEC); 71 | Serial.print("\t\t"); 72 | 73 | if(buf[0] == 0xFF){ 74 | Serial.print("NONE"); 75 | } 76 | else if(buf[0]&0x80){ 77 | Serial.print("UG "); 78 | Serial.print(buf[0]&(~0x80), DEC); 79 | } 80 | else{ 81 | Serial.print("SG "); 82 | Serial.print(buf[0], DEC); 83 | } 84 | Serial.print("\t"); 85 | 86 | Serial.print(buf[1], DEC); 87 | Serial.print("\t\t"); 88 | if(buf[3]>0){ 89 | printSignature(buf+4, buf[3]); 90 | } 91 | else{ 92 | Serial.print("NONE"); 93 | } 94 | Serial.println("\r\n"); 95 | } 96 | 97 | void setup() 98 | { 99 | /** initialize */ 100 | myVR.begin(9600); 101 | 102 | Serial.begin(115200); 103 | Serial.println("Elechouse Voice Recognition V3 Module\r\nControl LED sample"); 104 | 105 | pinMode(led, OUTPUT); 106 | 107 | if(myVR.clear() == 0){ 108 | Serial.println("Recognizer cleared."); 109 | }else{ 110 | Serial.println("Not find VoiceRecognitionModule."); 111 | Serial.println("Please check connection and restart Arduino."); 112 | while(1); 113 | } 114 | 115 | if(myVR.load((uint8_t)onRecord) >= 0){ 116 | Serial.println("onRecord loaded"); 117 | } 118 | 119 | if(myVR.load((uint8_t)offRecord) >= 0){ 120 | Serial.println("offRecord loaded"); 121 | } 122 | } 123 | 124 | void loop() 125 | { 126 | int ret; 127 | ret = myVR.recognize(buf, 50); 128 | if(ret>0){ 129 | switch(buf[1]){ 130 | case onRecord: 131 | /** turn on LED */ 132 | digitalWrite(led, HIGH); 133 | break; 134 | case offRecord: 135 | /** turn off LED*/ 136 | digitalWrite(led, LOW); 137 | break; 138 | default: 139 | Serial.println("Record function undefined"); 140 | break; 141 | } 142 | /** voice recognized */ 143 | printVR(buf); 144 | } 145 | } 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /examples/vr_sample_multi_cmd/vr_sample_multi_cmd.ino: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file vr_sample_multi_cmd.ino 4 | * @author JiapengLi 5 | * @brief This file provides a demostration on 6 | how to implement a multi voice command project (exceed 7 voice command) 7 | by using VoiceRecognitionModule 8 | ****************************************************************************** 9 | * @note: 10 | voice control led 11 | ****************************************************************************** 12 | * @section HISTORY 13 | 14 | 2013/06/13 Initial version. 15 | */ 16 | 17 | #include 18 | #include "VoiceRecognitionV3.h" 19 | 20 | /** 21 | Connection 22 | Arduino VoiceRecognitionModule 23 | 2 -------> TX 24 | 3 -------> RX 25 | */ 26 | VR myVR(2,3); // 2:RX 3:TX, you can choose your favourite pins. 27 | 28 | uint8_t record[7]; // save record 29 | uint8_t buf[64]; 30 | 31 | int led = 13; 32 | 33 | int group = 0; 34 | 35 | #define switchRecord (0) 36 | 37 | #define group0Record1 (1) 38 | #define group0Record2 (2) 39 | #define group0Record3 (3) 40 | #define group0Record4 (4) 41 | #define group0Record5 (5) 42 | #define group0Record6 (6) 43 | 44 | #define group1Record1 (7) 45 | #define group1Record2 (8) 46 | #define group1Record3 (9) 47 | #define group1Record4 (10) 48 | #define group1Record5 (11) 49 | #define group1Record6 (12) 50 | 51 | void setup() 52 | { 53 | /** initialize */ 54 | myVR.begin(9600); 55 | 56 | Serial.begin(115200); 57 | Serial.println("Elechouse Voice Recognition V3 Module\r\nMulti Commands sample"); 58 | 59 | pinMode(led, OUTPUT); 60 | 61 | if(myVR.clear() == 0){ 62 | Serial.println("Recognizer cleared."); 63 | }else{ 64 | Serial.println("Not find VoiceRecognitionModule."); 65 | Serial.println("Please check connection and restart Arduino."); 66 | while(1); 67 | } 68 | 69 | record[0] = switchRecord; 70 | record[1] = group0Record1; 71 | record[2] = group0Record2; 72 | record[3] = group0Record3; 73 | record[4] = group0Record4; 74 | record[5] = group0Record5; 75 | record[6] = group0Record6; 76 | group = 0; 77 | if(myVR.load(record, 7) >= 0){ 78 | printRecord(record, 7); 79 | Serial.println(F("loaded.")); 80 | } 81 | 82 | } 83 | 84 | void loop() 85 | { 86 | int ret; 87 | ret = myVR.recognize(buf, 50); 88 | if(ret>0){ 89 | switch(buf[1]){ 90 | case switchRecord: 91 | /** turn on LED */ 92 | if(digitalRead(led) == HIGH){ 93 | digitalWrite(led, LOW); 94 | }else{ 95 | digitalWrite(led, HIGH); 96 | } 97 | if(group == 0){ 98 | group = 1; 99 | myVR.clear(); 100 | record[0] = switchRecord; 101 | record[1] = group1Record1; 102 | record[2] = group1Record2; 103 | record[3] = group1Record3; 104 | record[4] = group1Record4; 105 | record[5] = group1Record5; 106 | record[6] = group1Record6; 107 | if(myVR.load(record, 7) >= 0){ 108 | printRecord(record, 7); 109 | Serial.println(F("loaded.")); 110 | } 111 | }else{ 112 | group = 0; 113 | myVR.clear(); 114 | record[0] = switchRecord; 115 | record[1] = group0Record1; 116 | record[2] = group0Record2; 117 | record[3] = group0Record3; 118 | record[4] = group0Record4; 119 | record[5] = group0Record5; 120 | record[6] = group0Record6; 121 | if(myVR.load(record, 7) >= 0){ 122 | printRecord(record, 7); 123 | Serial.println(F("loaded.")); 124 | } 125 | } 126 | break; 127 | default: 128 | break; 129 | } 130 | /** voice recognized */ 131 | printVR(buf); 132 | } 133 | } 134 | 135 | /** 136 | @brief Print signature, if the character is invisible, 137 | print hexible value instead. 138 | @param buf --> command length 139 | len --> number of parameters 140 | */ 141 | void printSignature(uint8_t *buf, int len) 142 | { 143 | int i; 144 | for(i=0; i0x19 && buf[i]<0x7F){ 146 | Serial.write(buf[i]); 147 | } 148 | else{ 149 | Serial.print("["); 150 | Serial.print(buf[i], HEX); 151 | Serial.print("]"); 152 | } 153 | } 154 | } 155 | 156 | /** 157 | @brief Print signature, if the character is invisible, 158 | print hexible value instead. 159 | @param buf --> VR module return value when voice is recognized. 160 | buf[0] --> Group mode(FF: None Group, 0x8n: User, 0x0n:System 161 | buf[1] --> number of record which is recognized. 162 | buf[2] --> Recognizer index(position) value of the recognized record. 163 | buf[3] --> Signature length 164 | buf[4]~buf[n] --> Signature 165 | */ 166 | void printVR(uint8_t *buf) 167 | { 168 | Serial.println("VR Index\tGroup\tRecordNum\tSignature"); 169 | 170 | Serial.print(buf[2], DEC); 171 | Serial.print("\t\t"); 172 | 173 | if(buf[0] == 0xFF){ 174 | Serial.print("NONE"); 175 | } 176 | else if(buf[0]&0x80){ 177 | Serial.print("UG "); 178 | Serial.print(buf[0]&(~0x80), DEC); 179 | } 180 | else{ 181 | Serial.print("SG "); 182 | Serial.print(buf[0], DEC); 183 | } 184 | Serial.print("\t"); 185 | 186 | Serial.print(buf[1], DEC); 187 | Serial.print("\t\t"); 188 | if(buf[3]>0){ 189 | printSignature(buf+4, buf[3]); 190 | } 191 | else{ 192 | Serial.print("NONE"); 193 | } 194 | // Serial.println("\r\n"); 195 | Serial.println(); 196 | } 197 | 198 | void printRecord(uint8_t *buf, uint8_t len) 199 | { 200 | Serial.print(F("Record: ")); 201 | for(int i=0; i
© COPYRIGHT 2013 ELECHOUSE
27 | ****************************************************************************** 28 | */ 29 | 30 | #if ARDUINO >= 100 31 | #include "Arduino.h" 32 | #else 33 | #include "WProgram.h" 34 | #endif 35 | 36 | #include "wiring_private.h" 37 | 38 | #include "SoftwareSerial.h" 39 | #include 40 | 41 | #define DEBUG 42 | 43 | #ifdef DEBUG 44 | #define DBGSTR(message) Serial.print(message) 45 | #define DBGBUF(buf, len) Serial.write(buf, len) 46 | #define DBGLN(message) Serial.println(message) 47 | #define DBGFMT(msg, fmt) Serial.print(msg, fmt) 48 | #define DBGCHAR(c) Serial.write(c) 49 | #else 50 | #define DBG(message) 51 | #endif // DEBUG 52 | 53 | #define VR_DEFAULT_TIMEOUT (1000) 54 | 55 | /***************************************************************************/ 56 | #define FRAME_HEAD (0xAA) 57 | #define FRAME_END (0x0A) 58 | 59 | /***************************************************************************/ 60 | #define FRAME_CMD_CHECK_SYSTEM (0x00) 61 | #define FRAME_CMD_CHECK_BSR (0x01) 62 | #define FRAME_CMD_CHECK_TRAIN (0x02) 63 | #define FRAME_CMD_CHECK_SIG (0x03) 64 | 65 | #define FRAME_CMD_RESET_DEFAULT (0x10) //reset configuration 66 | #define FRAME_CMD_SET_BR (0x11) //baud rate 67 | #define FRAME_CMD_SET_IOM (0x12) //IO mode 68 | #define FRAME_CMD_SET_PW (0x13) //pulse width 69 | #define FRAME_CMD_RESET_IO (0x14) // reset IO OUTPUT 70 | #define FRAME_CMD_SET_AL (0x15) // Auto load 71 | 72 | #define FRAME_CMD_TRAIN (0x20) 73 | #define FRAME_CMD_SIG_TRAIN (0x21) 74 | #define FRAME_CMD_SET_SIG (0x22) 75 | 76 | #define FRAME_CMD_LOAD (0x30) //Load N records 77 | #define FRAME_CMD_CLEAR (0x31) //Clear BSR buffer 78 | #define FRAME_CMD_GROUP (0x32) // 79 | #define FRAME_CMD_GROUP_SET (0x00) // 80 | #define FRAME_CMD_GROUP_SUGRP (0x01) // 81 | #define FRAME_CMD_GROUP_LSGRP (0x02) // 82 | #define FRAME_CMD_GROUP_LUGRP (0x03) // 83 | #define FRAME_CMD_GROUP_CUGRP (0x04) // 84 | 85 | #define FRAME_CMD_TEST (0xEE) 86 | #define FRAME_CMD_TEST_READ (0x01) 87 | #define FRAME_CMD_TEST_WRITE (0x00) 88 | 89 | 90 | #define FRAME_CMD_VR (0x0D) //Voice recognized 91 | #define FRAME_CMD_PROMPT (0x0A) 92 | #define FRAME_CMD_ERROR (0xFF) 93 | 94 | /***************************************************************************/ 95 | // #define FRAME_ERR_UDCMD (0x00) 96 | // #define FRAME_ERR_LEN (0x01) 97 | // #define FRAME_ERR_DATA (0x02) 98 | // #define FRAME_ERR_SUBCMD (0x03) 99 | 100 | // //#define FRAME_ERR_ 101 | // #define FRAME_STA_SUCCESS (0x00) 102 | // #define FRAME_STA_FAILED (0xFF) 103 | /***************************************************************************/ 104 | 105 | 106 | class VR : public SoftwareSerial{ 107 | public: 108 | VR(uint8_t receivePin, uint8_t transmitPin); 109 | 110 | static VR* getInstance() { 111 | return instance; 112 | } 113 | 114 | typedef enum{ 115 | PULSE = 0, 116 | TOGGLE = 1, 117 | SET = 2, 118 | CLEAR = 3 119 | }io_mode_t; 120 | 121 | typedef enum{ 122 | LEVEL0 = 0, 123 | LEVEL1, 124 | LEVEL2, 125 | LEVEL3, 126 | LEVEL4, 127 | LEVEL5, 128 | LEVEL6, 129 | LEVEL7, 130 | LEVEL8, 131 | LEVEL9, 132 | LEVEL10, 133 | LEVEL11, 134 | LEVEL12, 135 | LEVEL13, 136 | LEVEL14, 137 | LEVEL15, 138 | }pulse_width_level_t; 139 | 140 | typedef enum{ 141 | GROUP0 = 0, 142 | GROUP1, 143 | GROUP2, 144 | GROUP3, 145 | GROUP4, 146 | GROUP5, 147 | GROUP6, 148 | GROUP7, 149 | GROUP_ALL = 0xFF, 150 | }group_t; 151 | 152 | int setBaudRate(unsigned long br); 153 | int setIOMode(io_mode_t mode); 154 | int resetIO(uint8_t *ios=0, uint8_t len=1); 155 | int setPulseWidth(uint8_t level); 156 | int setAutoLoad(uint8_t *records=0, uint8_t len = 0); 157 | int disableAutoLoad(); 158 | int restoreSystemSettings(); 159 | int checkSystemSettings(uint8_t* buf); 160 | int recognize(uint8_t *buf, int timeout = VR_DEFAULT_TIMEOUT); 161 | int train(uint8_t *records, uint8_t len=1, uint8_t *buf = 0); 162 | int train(uint8_t record, uint8_t *buf = 0); 163 | int trainWithSignature(uint8_t record, const void *buf, uint8_t len=0, uint8_t *retbuf = 0); 164 | int load(uint8_t *records, uint8_t len=1, uint8_t *buf = 0); 165 | int load(uint8_t record, uint8_t *buf = 0); 166 | int clear(); 167 | int setSignature(uint8_t record, const void *buf=0, uint8_t len=0); 168 | int deleteSignature(uint8_t record); 169 | 170 | int checkSignature(uint8_t record, uint8_t *buf); 171 | int checkRecognizer(uint8_t *buf); 172 | int checkRecord(uint8_t *buf, uint8_t *records = 0, uint8_t len = 0); 173 | 174 | /** group control */ 175 | int setGroupControl(uint8_t ctrl); 176 | int checkGroupControl(); 177 | int setUserGroup(uint8_t grp, uint8_t *records, uint8_t len); 178 | int checkUserGroup(uint8_t grp, uint8_t *buf); 179 | int loadSystemGroup(uint8_t grp, uint8_t *buf=0); 180 | int loadUserGroup(uint8_t grp, uint8_t *buf=0); 181 | 182 | int test(uint8_t cmd, uint8_t *bsr); 183 | 184 | int writehex(uint8_t *buf, uint8_t len); 185 | 186 | /***************************************************************************/ 187 | /** low level */ 188 | int len(uint8_t *buf); 189 | int cmp(uint8_t *buf, uint8_t *bufcmp, int len ); 190 | void cpy(char *buf, char * pbuf); 191 | void sort(uint8_t *buf, int len); 192 | int cleanDup(uint8_t *des, uint8_t *buf, int len); 193 | void send_pkt(uint8_t *buf, uint8_t len); 194 | void send_pkt(uint8_t cmd, uint8_t *buf, uint8_t len); 195 | void send_pkt(uint8_t cmd, uint8_t subcmd, uint8_t *buf, uint8_t len); 196 | int receive(uint8_t *buf, int len, uint16_t timeout = VR_DEFAULT_TIMEOUT); 197 | int receive_pkt(uint8_t *buf, uint16_t timeout = VR_DEFAULT_TIMEOUT); 198 | /***************************************************************************/ 199 | private: 200 | static VR* instance; 201 | }; 202 | 203 | -------------------------------------------------------------------------------- /examples/vr_sample_bridge/vr_sample_bridge.ino: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file vr_sample_bridge.ino 4 | * @author JiapengLi 5 | * @brief This file provides a demostration on 6 | how to control led by using VoiceRecognitionModule 7 | ****************************************************************************** 8 | * @note: 9 | Use this sample to try the command of VoiceRecognition Module. 10 | Eg: 11 | 1. Enable Arduino Serial monitor "Send with newline" feture, Baud rate 115200. 12 | 2. Input "01" to "check recognizer", 13 | 3. input "31" to "clear recognizer", 14 | 4. input "30 00 02 04" to "load record 0, record 2, record 4" 15 | ****************************************************************************** 16 | * @section HISTORY 17 | 18 | 2013/06/17 Initial version. 19 | */ 20 | 21 | #include 22 | #include "VoiceRecognitionV3.h" 23 | 24 | /** 25 | Connection 26 | Arduino VoiceRecognitionModule 27 | 2 -------> TX 28 | 3 -------> RX 29 | */ 30 | VR myVR(2,3); // 2:RX 3:TX, you can choose your favourite pins. 31 | 32 | /***************************************************************************/ 33 | // command analyze part 34 | #define CMD_BUF_LEN 64+1 35 | uint8_t cmd[CMD_BUF_LEN]; 36 | uint8_t cmd_cnt; 37 | uint8_t *paraAddr; 38 | 39 | uint8_t buf[400]; 40 | uint8_t buflen[32]; 41 | 42 | void setup(void) 43 | { 44 | myVR.begin(9600); 45 | 46 | /** initialize */ 47 | Serial.begin(115200); 48 | Serial.println(F("Elechouse Voice Recognition V3 Module \"bridge\" sample.")); 49 | Serial.println(F("Eg:\r\n1. Enable Arduino Serial monitor \"Send with newline\" feture, Baud rate 115200.\r\n2. Input \"01\" to \"check recognizer\".\r\n3. input \"31\" to \"clear recognizer\"\r\n4. input \"30 00 02 04\" to \"load record 0, record 2, record 4\"")); 50 | } 51 | 52 | void loop(void) 53 | { 54 | int len, i, ret, index; 55 | 56 | /** receive Serial command */ 57 | len = receiveCMD(); 58 | if(len > 0){ 59 | printSeperator(); 60 | if(!checkCMD(len)){ 61 | ret = convertCMD(buf, len); 62 | if(ret>0){ 63 | Serial.print("> "); 64 | myVR.writehex(buf, ret); 65 | myVR.send_pkt(buf, ret); 66 | Serial.println(); 67 | }else{ 68 | /** received command is invalid */ 69 | /** display the receved command back */ 70 | Serial.write(cmd, len); 71 | Serial.println(F("Input is not in hexadecimal format.")); 72 | } 73 | }else{ 74 | /** received command is invalid */ 75 | /** display the receved command back */ 76 | Serial.print("> "); 77 | Serial.write(cmd, len); 78 | Serial.println(F("Input is not in hexadecimal format.")); 79 | 80 | } 81 | // printSeperator(); 82 | } 83 | 84 | /** recieve all packet a time */ 85 | len=0; 86 | index = 0; 87 | while(1){ 88 | ret = myVR.receive_pkt(buf+len, 50); 89 | if(ret>0){ 90 | len+=ret; 91 | buflen[index] = ret; 92 | index++; 93 | }else{ 94 | break; 95 | } 96 | } 97 | if(index > 0){ 98 | len = 0; 99 | for(i=0; i0){ 125 | start_millis = millis(); 126 | cmd[cmd_cnt] = ret; 127 | if(cmd[cmd_cnt] == '\n'){ 128 | len = cmd_cnt+1; 129 | cmd_cnt = 0; 130 | return len; 131 | } 132 | cmd_cnt++; 133 | if(cmd_cnt == CMD_BUF_LEN){ 134 | cmd_cnt = 0; 135 | return -1; 136 | } 137 | } 138 | 139 | if(millis() - start_millis > 100){ 140 | cmd_cnt = 0; 141 | return -1; 142 | } 143 | } 144 | } 145 | 146 | /** 147 | @brief Check command format. 148 | @param len --> command length 149 | @retval 0 --> command is valid 150 | -1 --> command is invalid 151 | */ 152 | int checkCMD(int len) 153 | { 154 | int i; 155 | for(i=0; i='0' && cmd[i] <= '9'){ 157 | 158 | }else if(cmd[i] >='a' && cmd[i] <= 'f'){ 159 | 160 | }else if(cmd[i] >='A' && cmd[i] <= 'Z'){ 161 | 162 | }else if(cmd[i] == '\t' || cmd[i] == ' ' || cmd[i] == '\r' || cmd[i] == '\n'){ 163 | 164 | }else{ 165 | return -1; 166 | } 167 | } 168 | return 0; 169 | } 170 | 171 | /** 172 | @brief Check the number of parameters in the command 173 | @param len --> command length 174 | @retval number of parameters 175 | */ 176 | int checkParaNum(int len) 177 | { 178 | int cnt=0, i; 179 | for(i=0; i command length 194 | paraIndex --> parameter index 195 | addr --> return value. position of the parameter 196 | @retval length of specified parameter 197 | */ 198 | int findPara(int len, int paraIndex, uint8_t **addr) 199 | { 200 | int cnt=0, i, paraLen; 201 | uint8_t dt; 202 | for(i=0; i='0' && str[i]<='9') || (str[i]>='A' && str[i]<='F') || (str[i]>='a' && str[i]<='f') ){ 231 | if(i==8){ 232 | ret = 0; 233 | break; 234 | } 235 | ret <<= 4; 236 | if(str[i]>='0' && str[i]<='9'){ 237 | ret += (str[i]-'0'); 238 | }else if(str[i]>='A' && str[i]<='F'){ 239 | ret += (str[i] - 'A' + 0x0A); 240 | }else if(str[i]>='a' && str[i]<='f'){ 241 | ret += (str[i] - 'a' + 0x0A); 242 | } 243 | i++; 244 | } 245 | 246 | return ret; 247 | } 248 | 249 | int convertCMD(uint8_t *des, int len) 250 | { 251 | int i, paraNum, paraLen; 252 | paraNum = checkParaNum(len); 253 | for(i=0; i2){ 256 | return -1; 257 | } 258 | des[i] = atoh(paraAddr); 259 | if(des[i] == 0){ 260 | if(*paraAddr != '0'){ 261 | return -1; 262 | } 263 | if(paraLen == 2 && *(paraAddr+1) != '0'){ 264 | return -1; 265 | } 266 | } 267 | } 268 | return paraNum; 269 | } 270 | 271 | /** 272 | @brief Print seperator. Print 80 '-'. 273 | */ 274 | void printSeperator() 275 | { 276 | for(int i=0; i<80; i++){ 277 | Serial.write('-'); 278 | } 279 | Serial.println(); 280 | } 281 | 282 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Voice Recognition V3 **(WIP)** 2 | [START]: #voice-recognition-v3-wip 3 | 4 | ## Feature 5 | - Recognize maximum 7 voice commands at same time 6 | - Store maximum 255 records of voice 7 | - Group control and external group select pin 8 | - Auto load records when power on 9 | - Signature function, help to make out voice record 10 | - LED indicate 11 | 12 | ## Introduce 13 | 14 | ## Terminology 15 | - **recognizer** -- core part of voice recognition module 16 | - **recognizer index** -- Each VoiceRecognitionModule support 7 voice command, recognizer has 7 region for each voice command, one index corresponds to one region 17 | - **train** -- let VoiceRecognitionModule record your voice command 18 | - **load** -- copy trained voice to recognizer of VoiceRecognitionModule 19 | - **record** -- the trained voice command store in flash, number from 0 to 79 20 | - **signature** -- alias for **record** 21 | - **group** -- help to manage records, each group 7 **records**. System group and user group are supported. 22 | 23 | ## Quick Start 24 | 25 | ### Prepare 26 | + [Voice Recognition V3][VRV3] module 27 | + [Arduino][Arduino] board ([UNO][UNO] recommended) 28 | + [Arduino Sensor Shield V07][SensorShieldV7] 29 | + [Arduino IDE][ArduinoIDE] 30 | + Voice Recognition V3 library([Download zip file][dzip]) 31 | + [Access Port][accessport] 32 | 33 | [idtrain]: #train 34 | ### Train 35 | 1. Connect your Voice Recognition V3 Module with Arduino, By Default: 36 | ![connection](./image/connection.jpg) 37 | 38 | 1. Download VoiceRecognitionV3 library.(download [zip][dzip] file or use `git clone https://github.com/elechouse/VoiceRecognitionV3.git` command) 39 | 1. When use zip format file, extract **VoiceRecognitionV3.zip** to `Arduino Sketch\libraries` folder, or if you use `git clone` command copy **VoiceRecognitionV3** to `Arduino Sketch\libraries` . 40 | 1. Open **vr\_sample\_train**(File -> Examples -> VoiceRecognitionV3 -> vr\_sample\_train) 41 | 1. Choose right Arduino board(Tool -> Board, UNO recommended), Choose right serial port. 42 | 1. Click **Upload** button, wait until Arduino is uploaded. 43 | 1. Open **Serial Monitor**. Set baud rate 115200, set send with **Newline** or **Both NL & CR**. 44 | ![sm](./image/serial_monitor.jpg) 45 | 46 | 1. Send command `settings`(case insensitive) to check Voice Recognition Module settings. Input `settings`, and hit `Enter` to send. 47 | ![input](./image/input_command.jpg) 48 | ![input](./image/settings.jpg) 49 | 50 | 1. Train Voice Recognition Module. Send `sigtrain 0 On` command to train record 0 with signature "On". When Serial Monitor prints "Speak now", you need speak your voice(can be any word, meaningful word recommended, may be 'On' here), and when Serial Monitor prints "Speak again", you need repeat your voice again. If these two voice are matched, Serial Monitor prints "Success", and "record 0" is trained, or if are not matched, repeat speaking until success. 51 | **When training, the two led on the Voice Recognition Module can benefit your training process. After send `train` command, the SYS_LED is blinking which remind you to be ready, then speak your voice as soon as the STATUS_LED lights on, the record finishes once when the STATUS_LED lights off. Then the SYS_LED is blinking again, these status repeated, when the training is successful, SYS_LED and STATUS_LED blink together, if training is failed SYS_LED and STATUS_LED blink together quickly.** 52 | ![sigtrain](./image/sigtrain_0_on.jpg) 53 | 54 | 1. Train another record. Send `sigtrain 1 Off` command to train record 1 with signature "Off". Choose your favorite words to train (it can be any word, meaningful word recommended, may be 'Off' here). 55 | ![sigtrain](./image/sigtrain_1_off.jpg) 56 | 57 | 1. Send `load 0 1` command to load voice. And say your word to see if the Voice Recognition Module can recognize your words. 58 | ![load](./image/load_0_1.jpg) 59 | 60 | If the voice is recognized, you can see. 61 | ![vr](./image/recognize.jpg) 62 | 1. Train finish. Train sample also support several other commands. 63 | ![cmd](./image/train_command.jpg) 64 | 65 | ### Application 66 | [controlled]: #control-led-sample 67 | #### Control LED Sample 68 | 1. Open **vr\_sample\_control\_led**(File -> Examples -> VoiceRecognitionV3 -> vr\_sample\_control\_led) 69 | 1. Choose right Arduino board(Tool -> Board, UNO recommended), Choose right serial port. 70 | 1. Click **Upload** button, wait until Arduino is uploaded. 71 | 1. Open **Serial Monitor**. Set baud rate 115200. 72 | 1. Say your trained voice to control the LED on Arduino UNO board. When record 0 is recognized, the led turns on. When record 1 is recognized, the led turns off. 73 | ![control_led](./image/control_led.jpg) 74 | 1. Control led finish. 75 | 76 | ## Examples 77 | ### vr\_sample\_train 78 | See [Train][idtrain] for more information. 79 | 80 | ### vr\_sample\_control\_led 81 | See [Control LED][controlled] for more information. 82 | 83 | ### vr\_sample\_bridge 84 | Use this sample to know the command of VoiceRecognition Module. Details about command, see [Protocol][Protocol] . You must do not input **Frame Head**, **Frame Length**, **Frame End**, only need input **Frame Command** and **Frame Data**. For example, Check Recognizer Command is "AA 02 01 0A" for all, here you only need input 01. 85 | 86 | Example: 87 | 88 | 1. Enable Arduino Serial monitor "Send with newline" feture, Baud rate 115200. 89 | 2. Input "01" to "check recognizer". 90 | 3. input "31" to "clear recognizer" 91 | 4. input "30 00 02 04" to "load record 0, record 2, record 4" 92 | 93 | ![bridge](./image/bridge-0.jpg) 94 | ![bridge](./image/bridge-1.jpg) 95 | 96 | ### vr\_sample\_multi\_cmd 97 | This sample shows how to use multi commands(Break 7 voice command limits),this sample use **RECORD 0** to switch between the 2 command 'groups'(not Voice Recognition Group Function), first group is made up of *record 0, 1, 2, 3, 4, 5, 6,** and second group is made up of **record 0, 7, 8, 9, 10, 11, 12** . 98 | 99 | ***Note: Before start this sample, you need train your Voice Recognition module first, and make sure that all records from 0 to 12 should be trained.*** 100 | 101 | ### vr\_sample\_check\_baud\_rate 102 | This sample is used to check the baud rate, when you forgot your custom settings. 103 | 104 | ![bridge](./image/check_br.jpg) 105 | 106 | 107 | [Protocol]: #protocol 108 | ## Protocol 109 | The simplest way to play the Voice Recognition V3 module is to use this VoiceRecognition Arduino library. But for many **hackers**, this is far from enough, so we supply this protocol by which user can communicate with the Voice Recognition V3 module. 110 | 111 | ### Base Format 112 | 113 | #### Control 114 | **| Head (0AAH) | Length| Command | Data | End (0AH) |** 115 | Length = L(Length + Command + Data) 116 | 117 | #### Return 118 | **| Head (0AAH) | Length| Command | Data | End (0AH) |** 119 | Length = L(Length + Command + Data) 120 | 121 | NOTE: Data area is different with different with commands. 122 | 123 | ### Code 124 | [index]: #code 125 | ***ALL CODE ARE IN HEXADECIMAL FORMAT*** 126 | 127 | --- 128 | ***FRAME CODE*** 129 | **AA** --> Frame Head 130 | **0A** --> Frame End 131 | 132 | --- 133 | ***CHECK*** 134 | **00** --> [Check System Settings][id00] 135 | **01** --> [Check Recognizer][id01] 136 | **02** --> [Check Record Train Status][id02] 137 | **03** --> [Check Signature of One Record][id03] 138 | 139 | --- 140 | ***SYSTEM SETTINGS*** 141 | **10** --> [Restore System Settings][id10] 142 | **11** --> [Set Baud Rate][id11] 143 | **12** --> [Set Output IO Mode][id12] 144 | **13** --> [Set Output IO Pulse Width][id13] 145 | **14** --> [Reset Output IO][id14] 146 | **15** --> [Set Power On Auto Load][id15] 147 | 148 | --- 149 | ***RECORD OPERATION*** 150 | **20** --> [Train One Record or Records][id20] 151 | **21** --> [Train One Record and Set Signature][id21] 152 | **22** --> [Set Signature for Record][id22] 153 | 154 | --- 155 | ***RECOGNIZER CONTROL*** 156 | **30** --> [Load a Record or Records to Recognizer][id30] 157 | **31** --> [Clear Recognizer][id31] 158 | **32** --> [Group Control][id32] 159 | 160 | --- 161 | ***THESE 3 COMMANDS ARE ONLY USED FOR RETURN MESSAGE*** 162 | **0A** --> [Prompt][id0a] 163 | **0D** --> [Voice Recognized][id0d] 164 | **FF** --> [Error][idff] 165 | 166 | ### Details 167 | 168 | [id00]: #check-system-settings-00 169 | #### Check System Settings (00) 170 | Use "Check System Settings" command to check current settings of Voice Recognition Module, include serial baud rate, output IO mode, output IO pulse width, auto load and group function. 171 | **Format:** 172 | | AA | 02 | 00 | 0A | 173 | **Return:** 174 | | AA | 08 | 00 | STA | BR | IOM | IOPW | AL | GRP | 0A | 175 | **STA** : Trained status (0-untrained 1-trained FF-record value out of range) 176 | **BR**: Baud rate (0,3-9600 1-2400 2-4800 4-19200 5-38400) 177 | **IOM**: Outpu IO Mode (0-Pulse 1-Toggle 2-Clear 3-Set) 178 | **IOPW**: Outpu IO Pulse Width(Pulse Mode) (1~15) 179 | **AL**: Power on auto load (0-disable 1-enable) 180 | **GRP**: Group control by external IO (0-disable 1-system group 2-user group) 181 | 182 | [Back to index][index] 183 | [id01]: #check-recognizer-01 184 | #### Check Recognizer (01) 185 | Use "Check Recognizer" command to check **recognizer** of Voice Recognition Module. 186 | **Format:** 187 | | AA | 02 | 01 | 0A | 188 | **Return:** 189 | | AA | 0D | 01 | RVN | VRI0 | VRI1 | VRI2 | VRI3 | VRI4 | VRI5 | VRI6 | RTN | VRMAP | GRPM | 0A | 190 | **RVN**: number of valid records in recognizer. (MAX 7) 191 | **VRIn**(n=0~6): Record which is in recognizer, n is recognizer index value 192 | **RTN**: number of total records in recognizer. 193 | **VRMAP**: valid record bit map for VRI0~VRI6. 194 | **GRPM**: group mode indicate. (FF-not in group mode 00~0A-system group 80~87-user group mode) 195 | 196 | [Back to index][index] 197 | [id02]: #check-record-train-status-02 198 | #### Check Record Train Status (02) 199 | Use "Check Record Train Status" command to check if the record is trained. 200 | **Format:** 201 | *Check all records* 202 | | AA | 03 | 02 | FF| 0A | 203 | *Check specified records* 204 | | AA | 03+n | 02 | R0 | ... | Rn | 0A | 205 | **Return:** 206 | | AA | 5+2*n | 02 | N | R0 | STA | ... | Rn | STA | 0A | 207 | **N**: number of trained records. 208 | **R0 ~ Rn**: record. 209 | **STA** : trained status (0-untrained 1-trained FF-record value out of range) 210 | 211 | 212 | [Back to index][index] 213 | [id03]: #check-signature-of-one-record-03 214 | #### Check Signature of One Record (03) 215 | Use this command to check the signature of one record. 216 | **Format:** 217 | | AA | 03 | 03 | Record | 0A | 218 | **Return:** 219 | | AA | 03 | 03 | Record | SIGLEN | SIGNATURE | 0A | 220 | **SIGLEN**: signature string length 221 | **SIGNATURE**: signature string 222 | 223 | [Back to index][index] 224 | [id10]: #restore-system-settings-10 225 | #### Restore System Settings (10) 226 | Use this command to restore settings of Voice Recognition Module to default. 227 | **Format:** 228 | | AA | 02 | 10 | 0A | 229 | **Return:** 230 | | AA | 03 | 10 | 00 | 0A | 231 | 232 | [Back to index][index] 233 | [id11]: #set-baud-rate-11 234 | #### Set Baud Rate (11) 235 | Use this command to set baud rate of Voice Recognition Module, effect after Voice Recognition Module is restarted. 236 | **Format:** 237 | | AA | 03 | 11 | BR | 0A | 238 | **Return:** 239 | | AA | 03 | 11 | 00 | 0A | 240 | **BR**: Serial baud rate.(0-9600 1-2400 2-4800 3-9600 4-19200 5-38400) 241 | 242 | [Back to index][index] 243 | [id12]: #set-output-io-mode-12 244 | #### Set Output IO Mode (12) 245 | Use this command to set output IO mode of Voice Recognition Module, take effect immediately after the instruction execution. 246 | **Format:** 247 | | AA | 03 | 12 | MODE | 0A | 248 | **Return:** 249 | | AA | 03 | 12 | 00 | 0A | 250 | **MODE**: Output IO mode.(0-pulse mode 1-Toggle 2-Set 3-Clear) 251 | 252 | [Back to index][index] 253 | [id13]: #set-output-io-pulse-width-13 254 | #### Set Output IO Pulse Width (13) 255 | Use this command to set output IO pulse width of Voice Recognition Module, take effect immediately after the instruction execution. Pulse width is used when output IO mode is **"Pulse"**. 256 | **Format:** 257 | | AA | 03 | 13 | LEVEL | 0A | 258 | **Return:** 259 | | AA | 03 | 13 | 00 | 0A | 260 | **LEVEL**: pulse width level. Details: 261 | 262 | - 00 10ms 263 | - 01 15ms 264 | - 02 20ms 265 | - 03 25ms 266 | - 04 30ms 267 | - 05 35ms 268 | - 06 40ms 269 | - 07 45ms 270 | - 08 50ms 271 | - 09 75ms 272 | - 0A 100ms 273 | - 0B 200ms 274 | - 0C 300ms 275 | - 0D 400ms 276 | - 0E 500ms 277 | - 0F 1s 278 | 279 | [Back to index][index] 280 | [id14]: #reset-output-io-14 281 | #### Reset Output IO (14) 282 | Use this command to reset output IO. This command can be used in output IO set/clear mode to generate a user-defined pulse. 283 | **Format:** 284 | | AA| 03 | 14 | FF | 0A | (reset all output io) 285 | | AA| 03+n | 14 | IO0 | ... | IOn | 0A | (reset output ios) 286 | **Return:** 287 | | AA | 03 | 14 | 00 | 0A | 288 | **IOn**: number of output io 289 | 290 | [Back to index][index] 291 | [id15]: #set-power-on-auto-load-15 292 | #### Set Power On Auto Load (15) 293 | Use this command to enable or disable "Power On Auto Load" function. 294 | **Format:** 295 | | AA| 03 | 15 | 00 | 0A | (disable auto load) 296 | | AA| 03+n | 15 | BITMAP | R0 | ... | Rn | 0A | (set auto load) 297 | **Return:** 298 | | AA| 04+n | 15 | 00 |BITMAP | R0 | ... | Rn | 0A | (set auto load) 299 | **BITMAP**: Record bitmap.( **0**-zero record, disable auto load **01**-one record **03**-two records **07**-three records **0F**-four records **1F**-five records **3F**-six record **7F**-seven records ) 300 | **R0~Rn**: Record 301 | 302 | [Back to index][index] 303 | [id20]: #train-one-record-or-records-20 304 | #### Train One Record or Records (20) 305 | Train records, can train several records one time. 306 | **Format:** 307 | | AA| 03+n | 20 | R0 | ... | Rn | 0A | 308 | **Return:** 309 | | AA| LEN | 0A | RECORD | PROMPT | 0A | 310 | | AA| 05+2*n | 20 | N | R0 | STA0 | ... | Rn | STAn | SIG | 0A | 311 | **SIG**: signature string 312 | **PROMPT**: prompt string 313 | **Rn**: Record 314 | **STA**: train result(0-Success 1-Timeout 2-Record value out of range) 315 | **N**: number of train success 316 | 317 | [Back to index][index] 318 | [id21]: #train-one-record-and-set-signature-21 319 | #### Train One Record and Set Signature (21) 320 | Train one record and set a signature for it, one record one time. 321 | **Format:** 322 | | AA| 03+SIGLEN | 21 | RECORD | SIG | 0A | (Set signature) 323 | **Return:** 324 | | AA| LEN | 0A | RECORD | PROMPT | 0A | (train prompt) 325 | | AA| 05+SIGLEN | 21 | N | RECORD | STA | SIG | 0A | 326 | **SIG**: signature string 327 | **PROMPT**: prompt string 328 | **STA**: train result(0-Success 1-Timeout 2-Record value out of range) 329 | **N**: number of train success 330 | 331 | [Back to index][index] 332 | [id22]: #set-signature-for-record-22 333 | #### Set Signature for Record (22) 334 | Set a signature for a record, one record one time. 335 | **Format:** 336 | | AA | 03+SIGLEN | 22 | RECORD | SIG | 0A | (Set signature) 337 | | AA | 03 | 22 | RECORD | 0A | (Delete signature) 338 | **Return:** 339 | | AA | 04+SIGLEN | 22 | 00 | RECORD | SIG | 0A | (Set signature return) 340 | | AA | 04 | 22 | 00 | RECORD | 0A | (Delete signature return) 341 | **SIG**: signature string 342 | **SIGLEN**: signature string length 343 | 344 | [Back to index][index] 345 | [id30]: #load-a-record-or-records-to-recognizer-30 346 | #### Load a Record or Records to Recognizer (30) 347 | Load records(1~7) to recognizer of Voice Recognition Module, after execution the Voice Recognition Module start to recognize immediately. 348 | **Format:** 349 | | AA| 2+n | 30 | R0 | ... | Rn | 0A | 350 | **Return:** 351 | | AA| 2+n | 30 | N | R0 | STA0 | ... | Rn | STAn | 0A | 352 | N: number of loading successfully 353 | R0~Rn: Record 354 | STA0~STAn: Load result.(**0**-Success **FF**-Record value out of range **FE**-Record untrained **FD**-Recognizer full **FC**-Record already in recognizer) 355 | 356 | 357 | [Back to index][index] 358 | [id31]: #clear-recognizer-31 359 | #### Clear Recognizer (31) 360 | Stop recognizing, and empty recognizer of Voice Recognition Module. 361 | **Format:** 362 | | AA | 02 | 31 | 0A | 363 | **Return:** 364 | | AA | 03 | 31 | 00 | 0A | 365 | 366 | [Back to index][index] 367 | [id32]: #group-control-32 368 | #### Group Control (32) 369 | ##### Group select 370 | Set group control mode(disable, system, user), if group control function is enabled(system or user), then voice recognition module is controlled by the external control IO. 371 | **Format:** 372 | | AA| 04 | 32 | 00 | MODE | 0A | 373 | **MODE**: new group control mode. (00-disable 01-system 02-user FF-check) 374 | **Return:** 375 | | AA| 03 | 32 | 00 | 0A | 376 | or 377 | | AA| 05 | 32 | 00 | FF | MODE | 0A | (check command return) 378 | 379 | ##### Set user group 380 | Set user group content(record). 381 | **Format:** 382 | | AA| 03 | 32 | 01 | UGRP | 0A | (Delete UGRP) 383 | | AA| LEN | 32 | 01 | UGRP | R0 | ... | Rn | 0A | (Set UGRP) 384 | **UGRP**: user group number 385 | **R0~Rn**: record index number (n=0,1,...,6) 386 | **Return:** 387 | | AA| 03 | 32 | 00 | 0A | (Success return) 388 | 389 | ##### Load system group 390 | Load system group to recognizer, this command would clear recognizer. 391 | **Format:** 392 | | AA| 04 | 32 | 02 | SGRP | 0A | 393 | **Return:** 394 | | AA| 04 | 32 | SGRP | VRI0 | VRI1 | VRI2 | VRI3 | VRI4 | VRI5 | VRI6 | RTN | VRMAP | GRPM | 0A | 395 | **SGRP**: System group number. 396 | **VRIn**(n=0~6): Record which is in recognizer, n is recognizer index value 397 | **RTN**: number of total records in recognizer. 398 | **VRMAP**: valid record bit map for VRI0~VRI6. 399 | **GRPM**: group mode indicate. (00~0A-system group) 400 | 401 | ##### Load user group 402 | Load user group to recognizer, this command would clear recognizer. 403 | **Format:** 404 | | AA| 04 | 32 | 03 | UGRP | 0A | 405 | **Return:** 406 | | AA| 04 | 32 | UGRP | VRI0 | VRI1 | VRI2 | VRI3 | VRI4 | VRI5 | VRI6 | RTN | VRMAP | GRPM | | 0A | 407 | **UGRP**: System group number. 408 | **VRIn**(n=0~6): Record which is in recognizer, n is recognizer index value 409 | **RTN**: number of total records in recognizer. 410 | **VRMAP**: valid record bit map for VRI0~VRI6. 411 | **GRPM**: group mode indicate. (00~0A-system group) 412 | ##### Check user group 413 | Check user group content. 414 | **Format:** 415 | | AA| 04 | 32 | 04 | 0A | (check all user group) 416 | or 417 | | AA| 04 | 32 | 04 | UGRP0| ... | UGRPn | 0A | (check user group) 418 | **Return:** 419 | | AA | 0A | 32 | UGRP | R0 | R1 | R2 | R3 | R4 | R5 | R6 | 0A | 420 | **UGRP**: User group number. 421 | **R0~R6**: Any record. 422 | 423 | [Back to index][index] 424 | [id0a]: #prompt-0a 425 | #### Prompt (0A) 426 | **Prompt** command is only used for Voice Recognition Module to return data when user train voice command. 427 | **Format:** 428 | NONE 429 | **Return:** 430 | | AA | 07 | 0A | RECORD | PROMPT | 0A | 431 | **RECORD**: record which is in training 432 | **PROMPT**: prompt string 433 | 434 | [Back to index][index] 435 | [id0d]: #voice-recognized-0d 436 | #### Voice Recognized (0D) 437 | **Voice Recognized** command is only used for Voice Recognition Module to return data when voice is recognized. 438 | **Format:** 439 | NONE 440 | **Return:** 441 | | AA | 07 | 0D | 00 | GRPM | R | RI | SIGLEN | SIG | 0A | 442 | **GRPM**: group mode indicate. (FF-not in group mode 00~0A-system group mode 80~87-user group mode) 443 | **R**: record which is recognized. 444 | **RI**: recognizer index value for recognized record. 445 | **SIGLEN**: signature length of the recognized record, 0 means on signature, on SIG area 446 | **SIG**: signature content 447 | 448 | [Back to index][index] 449 | [idff]: #error-ff 450 | #### Error (FF) 451 | Error command is only used for Voice Recognition Module to return error status. 452 | **Format:** 453 | NONE 454 | **Return:** 455 | | AA | 03 | FF | ECODE | 0A | 456 | 457 | **ECODE**: error code (FF-command undefined FE-command length error FD-data error FC-subcommand error FB-command usage error) 458 | 459 | [Back to index][index] 460 | 461 | ## Library Reference 462 | See `VoiceRecognitionV3.cpp` or [libref.pdf][libref] to get more information. 463 | 464 | ## Buy ## 465 | [![elechouse][EHICON]][EHLINK] 466 | 467 | 468 | 469 | [Top][START] 470 | 471 | [EHLINK]: http://www.elechouse.com 472 | 473 | [EHICON]: https://raw.github.com/elechouse/CarDriverShield/master/image/elechouse.png 474 | 475 | [accessport]: http://www.sudt.com/en/ap/ "AccessPort" 476 | 477 | [ArduinoIDE]: http://arduino.cc/en/main/software "Arduino IDE" 478 | 479 | [SensorShieldV7]: http://www.elechouse.com/elechouse/index.php?main_page=product_info&cPath=74&products_id=2211 480 | 481 | [UNO]: http://arduino.cc/en/Main/arduinoBoardUno 482 | 483 | [VRV3]: http://www.elechouse.com/elechouse/index.php?main_page=product_info&cPath=&products_id=2254 484 | 485 | [Arduino]: http://arduino.cc/en/ 486 | 487 | [dzip]: https://github.com/elechouse/VoiceRecognitionV3/archive/master.zip 488 | 489 | [libref]: https://github.com/elechouse/VoiceRecognitionV3/blob/master/libref.pdf?raw=true 490 | 491 | 492 | [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/elechouse/voicerecognitionv3/trend.png)](https://bitdeli.com/free "Bitdeli Badge") 493 | 494 | -------------------------------------------------------------------------------- /examples/vr_sample_train/vr_sample_train.ino: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file vr_sample_train.ino 4 | * @author JiapengLi 5 | * @brief This file provides a demostration on 6 | * how to train VoiceRecognitionModule to record your voice 7 | ****************************************************************************** 8 | * @note: 9 | * Use serial command to control VoiceRecognitionModule. ' 10 | * All commands are case insensitive. Default serial baud rate 115200. 11 | * 12 | * COMMAND FORMAT EXAMPLE Comment 13 | * 14 | * train train (r0) (r1)... train 0 2 45 Train records 15 | * load load (r0) (r1) ... load 0 51 2 3 Load records 16 | * clear clear clear remove all records in Recognizer 17 | * record record / record (r0) (r1)... record / record 0 79 Check record train status 18 | * vr vr vr Check recognizer status 19 | * getsig getsig (r) getsig 0 Get signature of record (r) 20 | * sigtrain sigtrain (r) (sig) sigtrain 0 ZERO Train one record(r) with signature(sig) 21 | * settings settings settings Check current system settings 22 | ****************************************************************************** 23 | * @section HISTORY 24 | * 25 | * 2013/06/13 Initial version. 26 | */ 27 | #include 28 | #include "VoiceRecognitionV3.h" 29 | 30 | /** 31 | * Connection 32 | * Arduino VoiceRecognitionModule 33 | * 2 -------> TX 34 | * 3 -------> RX 35 | */ 36 | VR myVR(2,3); // 2:RX 3:TX, you can choose your favourite pins. 37 | 38 | /***************************************************************************/ 39 | /** declare print functions */ 40 | void printSeperator(); 41 | void printSignature(uint8_t *buf, int len); 42 | void printVR(uint8_t *buf); 43 | void printLoad(uint8_t *buf, uint8_t len); 44 | void printTrain(uint8_t *buf, uint8_t len); 45 | void printCheckRecognizer(uint8_t *buf); 46 | void printUserGroup(uint8_t *buf, int len); 47 | void printCheckRecord(uint8_t *buf, int num); 48 | void printCheckRecordAll(uint8_t *buf, int num); 49 | void printSigTrain(uint8_t *buf, uint8_t len); 50 | void printSystemSettings(uint8_t *buf, int len); 51 | void printHelp(void); 52 | 53 | /***************************************************************************/ 54 | // command analyze part 55 | #define CMD_BUF_LEN 64+1 56 | #define CMD_NUM 10 57 | typedef int (*cmd_function_t)(int, int); 58 | uint8_t cmd[CMD_BUF_LEN]; 59 | uint8_t cmd_cnt; 60 | uint8_t *paraAddr; 61 | int receiveCMD(); 62 | int checkCMD(int len); 63 | int checkParaNum(int len); 64 | int findPara(int len, int paraNum, uint8_t **addr); 65 | int compareCMD(uint8_t *para1 , uint8_t *para2, int len); 66 | 67 | int cmdTrain(int len, int paraNum); 68 | int cmdLoad(int len, int paraNum); 69 | int cmdTest(int len, int paraNum); 70 | int cmdVR(int len, int paraNum); 71 | int cmdClear(int len, int paraNum); 72 | int cmdRecord(int len, int paraNum); 73 | int cmdSigTrain(int len, int paraNum); 74 | int cmdGetSig(int len, int paraNum); 75 | int cmdSettings(int len, int paraNum); 76 | int cmdHelp(int len, int paraNum); 77 | /** cmdList, cmdLen, cmdFunction has correspondence */ 78 | const char cmdList[CMD_NUM][10] = { // command list table 79 | { 80 | "train" } 81 | , 82 | { 83 | "load" } 84 | , 85 | { 86 | "clear" } 87 | , 88 | { 89 | "vr" } 90 | , 91 | { 92 | "record" } 93 | , 94 | { 95 | "sigtrain" } 96 | , 97 | { 98 | "getsig" } 99 | , 100 | { 101 | "Settings" } 102 | , 103 | { 104 | "test" } 105 | , 106 | { 107 | "help" } 108 | , 109 | }; 110 | const char cmdLen[CMD_NUM]= { // command length 111 | 5, // {"train"}, 112 | 4, // {"load"}, 113 | 5, // {"clear"}, 114 | 2, // {"vr"}, 115 | 6, // {"record"}, 116 | 8, // {"sigtrain"}, 117 | 6, // {"getsig"}, 118 | 8, // {"Settings"}, 119 | 4, // {"test"}, 120 | 4, // {"help"} 121 | }; 122 | cmd_function_t cmdFunction[CMD_NUM]={ // command handle fuction(function pointer table) 123 | cmdTrain, 124 | cmdLoad, 125 | cmdClear, 126 | cmdVR, 127 | cmdRecord, 128 | cmdSigTrain, 129 | cmdGetSig, 130 | cmdSettings, 131 | cmdTest, 132 | cmdHelp, 133 | }; 134 | 135 | /***************************************************************************/ 136 | /** temprory data */ 137 | uint8_t buf[255]; 138 | uint8_t records[7]; // save record 139 | 140 | void setup(void) 141 | { 142 | myVR.begin(9600); 143 | 144 | /** initialize */ 145 | Serial.begin(115200); 146 | Serial.println(F("Elechouse Voice Recognition V3 Module \"train\" sample.")); 147 | 148 | printSeperator(); 149 | Serial.println(F("Usage:")); 150 | printSeperator(); 151 | printHelp(); 152 | printSeperator(); 153 | cmd_cnt = 0; 154 | } 155 | 156 | void loop(void) 157 | { 158 | int len, paraNum, paraLen, i; 159 | 160 | /** receive Serial command */ 161 | len = receiveCMD(); 162 | if(len>0){ 163 | /** check if the received command is valid */ 164 | if(!checkCMD(len)){ 165 | 166 | /** check parameter number of the received command */ 167 | paraNum = checkParaNum(len); 168 | 169 | /** display the receved command back */ 170 | Serial.write(cmd, len); 171 | 172 | /** find the first parameter */ 173 | paraLen = findPara(len, 1, ¶Addr); 174 | 175 | /** compare the received command with command in the list */ 176 | for(i=0; i0){ 211 | /** voice recognized, print result */ 212 | printVR(buf); 213 | } 214 | } 215 | 216 | /** 217 | * @brief receive command from Serial. 218 | * @param NONE. 219 | * @retval command length, if no command receive return -1. 220 | */ 221 | int receiveCMD() 222 | { 223 | int ret; 224 | int len; 225 | unsigned long start_millis; 226 | start_millis = millis(); 227 | while(1){ 228 | ret = Serial.read(); 229 | if(ret>0){ 230 | start_millis = millis(); 231 | cmd[cmd_cnt] = ret; 232 | if(cmd[cmd_cnt] == '\n'){ 233 | len = cmd_cnt+1; 234 | cmd_cnt = 0; 235 | return len; 236 | } 237 | cmd_cnt++; 238 | if(cmd_cnt == CMD_BUF_LEN){ 239 | cmd_cnt = 0; 240 | return -1; 241 | } 242 | } 243 | 244 | if(millis() - start_millis > 100){ 245 | cmd_cnt = 0; 246 | return -1; 247 | } 248 | } 249 | } 250 | 251 | /** 252 | * @brief compare two commands, case insensitive. 253 | * @param para1 --> command buffer 1 254 | * para2 --> command buffer 2 255 | * len --> buffer length 256 | * @retval 0 --> equal 257 | * -1 --> unequal 258 | */ 259 | int compareCMD(uint8_t *para1 , uint8_t *para2, int len) 260 | { 261 | int i; 262 | uint8_t res; 263 | for(i=0; i command length 278 | * @retval 0 --> command is valid 279 | * -1 --> command is invalid 280 | */ 281 | int checkCMD(int len) 282 | { 283 | int i; 284 | for(i=0; i 0x1F && cmd[i] < 0x7F){ 286 | 287 | } 288 | else if(cmd[i] == '\t' || cmd[i] == ' ' || cmd[i] == '\r' || cmd[i] == '\n'){ 289 | 290 | } 291 | else{ 292 | return -1; 293 | } 294 | } 295 | return 0; 296 | } 297 | 298 | /** 299 | * @brief Check the number of parameters in the command 300 | * @param len --> command length 301 | * @retval number of parameters 302 | */ 303 | int checkParaNum(int len) 304 | { 305 | int cnt=0, i; 306 | for(i=0; i command length 321 | * paraIndex --> parameter index 322 | * addr --> return value. position of the parameter 323 | * @retval length of specified parameter 324 | */ 325 | int findPara(int len, int paraIndex, uint8_t **addr) 326 | { 327 | int cnt=0, i, paraLen; 328 | uint8_t dt; 329 | for(i=0; i command length 369 | * paraNum --> number of parameters 370 | * @retval 0 --> success 371 | * -1 --> Command format error 372 | */ 373 | int cmdTrain(int len, int paraNum) 374 | { 375 | int i, ret; 376 | if(paraNum < 2 || paraNum > 8 ){ 377 | return -1; 378 | } 379 | 380 | for(i=2; i<=paraNum; i++){ 381 | findPara(len, i, ¶Addr); 382 | records[i-2] = atoi((char *)paraAddr); 383 | if(records[i-2] == 0 && *paraAddr != '0'){ 384 | return -1; 385 | } 386 | } 387 | printSeperator(); 388 | ret = myVR.train(records, paraNum-1, buf); 389 | // ret = myVR.train(records, paraNum-1); 390 | if(ret >= 0){ 391 | printTrain(buf, ret); 392 | } 393 | else if(ret == -1){ 394 | Serial.println(F("Train failed.")); 395 | } 396 | else if(ret == -2){ 397 | Serial.println(F("Train Timeout.")); 398 | } 399 | printSeperator(); 400 | return 0; 401 | } 402 | 403 | /** 404 | * @brief Handle "load" command 405 | * @param len --> command length 406 | * paraNum --> number of parameters 407 | * @retval 0 --> success 408 | * -1 --> Command format error 409 | */ 410 | int cmdLoad(int len, int paraNum) 411 | { 412 | int i, ret; 413 | if(paraNum < 2 || paraNum > 8 ){ 414 | return -1; 415 | } 416 | 417 | for(i=2; i<=paraNum; i++){ 418 | findPara(len, i, ¶Addr); 419 | records[i-2] = atoi((char *)paraAddr); 420 | if(records[i-2] == 0 && *paraAddr != '0'){ 421 | return -1; 422 | } 423 | } 424 | // myVR.writehex(records, paraNum-1); 425 | ret = myVR.load(records, paraNum-1, buf); 426 | printSeperator(); 427 | if(ret >= 0){ 428 | printLoad(buf, ret); 429 | } 430 | else{ 431 | Serial.println(F("Load failed or timeout.")); 432 | } 433 | printSeperator(); 434 | return 0; 435 | } 436 | 437 | /** 438 | * @brief Handle "clear" command 439 | * @param len --> command length 440 | * paraNum --> number of parameters 441 | * @retval 0 --> success 442 | * -1 --> Command format error 443 | */ 444 | int cmdClear(int len, int paraNum) 445 | { 446 | if(paraNum != 1){ 447 | return -1; 448 | } 449 | if(myVR.clear() == 0){ 450 | printSeperator(); 451 | Serial.println(F("Recognizer cleared.")); 452 | printSeperator(); 453 | } 454 | else{ 455 | printSeperator(); 456 | Serial.println(F("Clear recognizer failed or timeout.")); 457 | printSeperator(); 458 | } 459 | return 0; 460 | } 461 | 462 | /** 463 | * @brief Handle "vr" command 464 | * @param len --> command length 465 | * paraNum --> number of parameters 466 | * @retval 0 --> success 467 | * -1 --> Command format error 468 | */ 469 | int cmdVR(int len, int paraNum) 470 | { 471 | int ret; 472 | if(paraNum != 1){ 473 | return -1; 474 | } 475 | ret = myVR.checkRecognizer(buf); 476 | if(ret<=0){ 477 | printSeperator(); 478 | Serial.println(F("Check recognizer failed or timeout.")); 479 | printSeperator(); 480 | return 0; 481 | } 482 | printSeperator(); 483 | printCheckRecognizer(buf); 484 | printSeperator(); 485 | return 0; 486 | } 487 | 488 | /** 489 | * @brief Handle "record" command 490 | * @param len --> command length 491 | * paraNum --> number of parameters 492 | * @retval 0 --> success 493 | * -1 --> Command format error 494 | */ 495 | int cmdRecord(int len, int paraNum) 496 | { 497 | int ret; 498 | if(paraNum == 1){ 499 | ret = myVR.checkRecord(buf); 500 | printSeperator(); 501 | if(ret>=0){ 502 | printCheckRecordAll(buf, ret); 503 | } 504 | else{ 505 | Serial.println(F("Check record failed or timeout.")); 506 | } 507 | printSeperator(); 508 | } 509 | else if(paraNum < 9){ 510 | for(int i=2; i<=paraNum; i++){ 511 | findPara(len, i, ¶Addr); 512 | records[i-2] = atoi((char *)paraAddr); 513 | if(records[i-2] == 0 && *paraAddr != '0'){ 514 | return -1; 515 | } 516 | } 517 | 518 | ret = myVR.checkRecord(buf, records, paraNum-1); // auto clean duplicate records 519 | printSeperator(); 520 | if(ret>=0){ 521 | printCheckRecord(buf, ret); 522 | } 523 | else{ 524 | Serial.println(F("Check record failed or timeout.")); 525 | } 526 | printSeperator(); 527 | } 528 | else{ 529 | return -1; 530 | } 531 | return 0; 532 | } 533 | 534 | /** 535 | * @brief Handle "sigtrain" command 536 | * @param len --> command length 537 | * paraNum --> number of parameters 538 | * @retval 0 --> success 539 | * -1 --> Command format error 540 | */ 541 | int cmdSigTrain(int len, int paraNum) 542 | { 543 | int ret, sig_len; 544 | uint8_t *lastAddr; 545 | if(paraNum < 2){ 546 | return -1; 547 | } 548 | 549 | findPara(len, 2, ¶Addr); 550 | records[0] = atoi((char *)paraAddr); 551 | if(records[0] == 0 && *paraAddr != '0'){ 552 | return -1; 553 | } 554 | 555 | findPara(len, 3, ¶Addr); 556 | sig_len = findPara(len, paraNum, &lastAddr); 557 | sig_len +=( (unsigned int)lastAddr - (unsigned int)paraAddr ); 558 | 559 | printSeperator(); 560 | ret = myVR.trainWithSignature(records[0], paraAddr, sig_len, buf); 561 | // ret = myVR.trainWithSignature(records, paraNum-1); 562 | if(ret >= 0){ 563 | printSigTrain(buf, ret); 564 | } 565 | else{ 566 | Serial.println(F("Train with signature failed or timeout.")); 567 | } 568 | printSeperator(); 569 | 570 | return 0; 571 | } 572 | 573 | /** 574 | * @brief Handle "getsig" command 575 | * @param len --> command length 576 | * paraNum --> number of parameters 577 | * @retval 0 --> success 578 | * -1 --> Command format error 579 | */ 580 | int cmdGetSig(int len, int paraNum) 581 | { 582 | int ret; 583 | if(paraNum != 2){ 584 | return -1; 585 | } 586 | 587 | findPara(len, 2, ¶Addr); 588 | records[0] = atoi((char *)paraAddr); 589 | if(records[0] == 0 && *paraAddr != '0'){ 590 | return -1; 591 | } 592 | 593 | ret = myVR.checkSignature(records[0], buf); 594 | 595 | printSeperator(); 596 | if(ret == 0){ 597 | Serial.println(F("Signature isn't set.")); 598 | } 599 | else if(ret > 0){ 600 | Serial.print(F("Signature:")); 601 | printSignature(buf, ret); 602 | Serial.println(); 603 | } 604 | else{ 605 | Serial.println(F("Get sig error or timeout.")); 606 | } 607 | printSeperator(); 608 | 609 | return 0; 610 | } 611 | 612 | /** 613 | * @brief Handle "test" command 614 | * @param len --> command length 615 | * paraNum --> number of parameters 616 | * @retval 0 --> success 617 | * -1 --> Command format error 618 | */ 619 | int cmdTest(int len, int paraNum) 620 | { 621 | printSeperator(); 622 | Serial.println(F("TEST is not supported.")); 623 | printSeperator(); 624 | return 0; 625 | } 626 | 627 | int cmdSettings(int len, int paraNum) 628 | { 629 | int ret; 630 | if(paraNum != 1){ 631 | return -1; 632 | } 633 | ret = myVR.checkSystemSettings(buf); 634 | if( ret > 0){ 635 | printSeperator(); 636 | printSystemSettings(buf, ret); 637 | printSeperator(); 638 | } 639 | else{ 640 | printSeperator(); 641 | Serial.println(F("Check system settings error or timeout")); 642 | printSeperator(); 643 | } 644 | return 0; 645 | } 646 | 647 | /*****************************************************************************/ 648 | /** 649 | * @brief Print signature, if the character is invisible, 650 | * print hexible value instead. 651 | * @param buf --> command length 652 | * len --> number of parameters 653 | */ 654 | void printSignature(uint8_t *buf, int len) 655 | { 656 | int i; 657 | for(i=0; i0x19 && buf[i]<0x7F){ 659 | Serial.write(buf[i]); 660 | } 661 | else{ 662 | Serial.print(F("[")); 663 | Serial.print(buf[i], HEX); 664 | Serial.print(F("]")); 665 | } 666 | } 667 | } 668 | 669 | /** 670 | * @brief Print signature, if the character is invisible, 671 | * print hexible value instead. 672 | * @param buf --> VR module return value when voice is recognized. 673 | * buf[0] --> Group mode(FF: None Group, 0x8n: User, 0x0n:System 674 | * buf[1] --> number of record which is recognized. 675 | * buf[2] --> Recognizer index(position) value of the recognized record. 676 | * buf[3] --> Signature length 677 | * buf[4]~buf[n] --> Signature 678 | */ 679 | void printVR(uint8_t *buf) 680 | { 681 | Serial.println(F("VR Index\tGroup\tRecordNum\tSignature")); 682 | 683 | Serial.print(buf[2], DEC); 684 | Serial.print(F("\t\t")); 685 | 686 | if(buf[0] == 0xFF){ 687 | Serial.print(F("NONE")); 688 | } 689 | else if(buf[0]&0x80){ 690 | Serial.print(F("UG ")); 691 | Serial.print(buf[0]&(~0x80), DEC); 692 | } 693 | else{ 694 | Serial.print(F("SG ")); 695 | Serial.print(buf[0], DEC); 696 | } 697 | Serial.print(F("\t")); 698 | 699 | Serial.print(buf[1], DEC); 700 | Serial.print(F("\t\t")); 701 | if(buf[3]>0){ 702 | printSignature(buf+4, buf[3]); 703 | } 704 | else{ 705 | Serial.print(F("NONE")); 706 | } 707 | Serial.println(F("\r\n")); 708 | } 709 | 710 | /** 711 | * @brief Print seperator. Print 80 '-'. 712 | */ 713 | void printSeperator() 714 | { 715 | for(int i=0; i<80; i++){ 716 | Serial.write('-'); 717 | } 718 | Serial.println(); 719 | } 720 | 721 | /** 722 | * @brief Print recoginizer status. 723 | * @param buf --> VR module return value when voice is recognized. 724 | * buf[0] --> Number of valid voice records in recognizer 725 | * buf[i+1] --> Record number.(0xFF: Not loaded(Nongroup mode), or not set (Group mode)) (i= 0, 1, ... 6) 726 | * buf[8] --> Number of all voice records in recognizer 727 | * buf[9] --> Valid records position indicate. 728 | * buf[10] --> Group mode indicate(FF: None Group, 0x8n: User, 0x0n:System) 729 | */ 730 | void printCheckRecognizer(uint8_t *buf) 731 | { 732 | Serial.print(F("All voice records in recognizer: ")); 733 | Serial.println(buf[8], DEC); 734 | Serial.print(F("Valid voice records in recognizer: ")); 735 | Serial.println(buf[0], DEC); 736 | if(buf[10] == 0xFF){ 737 | Serial.println(F("VR is not in group mode.")); 738 | } 739 | else if(buf[10]&0x80){ 740 | Serial.print(F("VR is in user group mode:")); 741 | Serial.println(buf[10]&0x7F, DEC); 742 | } 743 | else{ 744 | Serial.print(F("VR is in system group mode:")); 745 | Serial.println(buf[10], DEC); 746 | } 747 | Serial.println(F("VR Index\tRecord\t\tComment")); 748 | for(int i=0; i<7; i++){ 749 | Serial.print(i, DEC); 750 | Serial.print(F("\t\t")); 751 | if(buf[i+1] == 0xFF){ 752 | if(buf[10] == 0xFF){ 753 | Serial.print(F("Unloaded\tNONE")); 754 | } 755 | else{ 756 | Serial.print(F("Not Set\t\tNONE")); 757 | } 758 | } 759 | else{ 760 | Serial.print(buf[i+1], DEC); 761 | Serial.print(F("\t\t")); 762 | if(buf[9]&(1< Check record command return value 777 | * buf[0] --> Number of checked records 778 | * buf[2i+1] --> Record number. 779 | * buf[2i+2] --> Record train status. (00: untrained, 01: trained, FF: record value out of range) 780 | * (i = 0 ~ buf[0]-1 ) 781 | * num --> Number of trained records 782 | */ 783 | void printCheckRecord(uint8_t *buf, int num) 784 | { 785 | Serial.print(F("Check ")); 786 | Serial.print(buf[0], DEC); 787 | Serial.println(F(" records.")); 788 | 789 | Serial.print(num, DEC); 790 | if(num>1){ 791 | Serial.println(F(" records trained.")); 792 | } 793 | else{ 794 | Serial.println(F(" record trained.")); 795 | } 796 | 797 | for(int i=0; i\t")); 800 | switch(buf[i+2]){ 801 | case 0x01: 802 | Serial.print(F("Trained")); 803 | break; 804 | case 0x00: 805 | Serial.print(F("Untrained")); 806 | break; 807 | case 0xFF: 808 | Serial.print(F("Record value out of range")); 809 | break; 810 | default: 811 | Serial.print(F("Unknown Stauts")); 812 | break; 813 | } 814 | Serial.println(); 815 | } 816 | } 817 | 818 | /** 819 | * @brief Print record train status. 820 | * @param buf --> Check record command return value 821 | * buf[0] --> Number of checked records 822 | * buf[2i+1] --> Record number. 823 | * buf[2i+2] --> Record train status. (00: untrained, 01: trained, FF: record value out of range) 824 | * (i = 0 ~ buf[0]-1 ) 825 | * num --> Number of trained records 826 | */ 827 | void printCheckRecordAll(uint8_t *buf, int num) 828 | { 829 | Serial.print(F("Check 255")); 830 | Serial.println(F(" records.")); 831 | 832 | Serial.print(num, DEC); 833 | if(num>1){ 834 | Serial.println(F(" records trained.")); 835 | } 836 | else{ 837 | Serial.println(F(" record trained.")); 838 | } 839 | myVR.writehex(buf, 255); 840 | for(int i=0; i<255; i++){ 841 | if(buf[i] == 0xF0){ 842 | continue; 843 | } 844 | Serial.print(i, DEC); 845 | Serial.print(F("\t-->\t")); 846 | switch(buf[i]){ 847 | case 0x01: 848 | Serial.print(F("Trained")); 849 | break; 850 | case 0x00: 851 | Serial.print(F("Untrained")); 852 | break; 853 | case 0xFF: 854 | Serial.print(F("Record value out of range")); 855 | break; 856 | default: 857 | Serial.print(F("Unknown Stauts")); 858 | break; 859 | } 860 | Serial.println(); 861 | } 862 | } 863 | 864 | /** 865 | * @brief Print check user group result. 866 | * @param buf --> Check record command return value 867 | * buf[8i] --> group number. 868 | * buf[8i+1] --> group position 0 status. 869 | * buf[8i+2] --> group position 1 status. 870 | * ... ... 871 | * buf[8i+6] --> group position 5 status. 872 | * buf[8i+7] --> group position 6 status. 873 | * (i = 0 ~ len) 874 | * len --> number of checked groups 875 | */ 876 | void printUserGroup(uint8_t *buf, int len) 877 | { 878 | int i, j; 879 | Serial.println(F("Check User Group:")); 880 | for(i=0; i "load" command return value 899 | * buf[0] --> number of records which are load successfully. 900 | * buf[2i+1] --> record number 901 | * buf[2i+2] --> record load status. 902 | * 00 --> Loaded 903 | * FC --> Record already in recognizer 904 | * FD --> Recognizer full 905 | * FE --> Record untrained 906 | * FF --> Value out of range" 907 | * (i = 0 ~ (len-1)/2 ) 908 | * len --> length of buf 909 | */ 910 | void printLoad(uint8_t *buf, uint8_t len) 911 | { 912 | if(len == 0){ 913 | Serial.println(F("Load Successfully.")); 914 | return; 915 | } 916 | else{ 917 | Serial.print(F("Load success: ")); 918 | Serial.println(buf[0], DEC); 919 | } 920 | for(int i=0; i "train" command return value 950 | * buf[0] --> number of records which are trained successfully. 951 | * buf[2i+1] --> record number 952 | * buf[2i+2] --> record train status. 953 | * 00 --> Trained 954 | * FE --> Train Time Out 955 | * FF --> Value out of range" 956 | * (i = 0 ~ len-1 ) 957 | * len --> length of buf 958 | */ 959 | void printTrain(uint8_t *buf, uint8_t len) 960 | { 961 | if(len == 0){ 962 | Serial.println(F("Train Finish.")); 963 | return; 964 | } 965 | else{ 966 | Serial.print(F("Train success: ")); 967 | Serial.println(buf[0], DEC); 968 | } 969 | for(int i=0; i "sigtrain" command return value 994 | * buf[0] --> number of records which are trained successfully. 995 | * buf[1] --> record number 996 | * buf[2] --> record train status. 997 | * 00 --> Trained 998 | * F0 --> Trained, signature truncate 999 | * FE --> Train Time Out 1000 | * FF --> Value out of range" 1001 | * buf[3] ~ buf[len-1] --> Signature. 1002 | * len --> length of buf 1003 | */ 1004 | void printSigTrain(uint8_t *buf, uint8_t len) 1005 | { 1006 | if(len == 0){ 1007 | Serial.println(F("Train With Signature Finish.")); 1008 | return; 1009 | } 1010 | else{ 1011 | Serial.print(F("Success: ")); 1012 | Serial.println(buf[0], DEC); 1013 | } 1014 | Serial.print(F("Record ")); 1015 | Serial.print(buf[1], DEC); 1016 | Serial.print(F("\t")); 1017 | switch(buf[2]){ 1018 | case 0: 1019 | Serial.println(F("Trained")); 1020 | break; 1021 | case 0xF0: 1022 | Serial.println(F("Trained, signature truncate")); 1023 | break; 1024 | case 0xFE: 1025 | Serial.println(F("Train Time Out")); 1026 | break; 1027 | case 0xFF: 1028 | Serial.println(F("Value out of range")); 1029 | break; 1030 | default: 1031 | Serial.print(F("Unknown status ")); 1032 | Serial.println(buf[2], HEX); 1033 | break; 1034 | } 1035 | Serial.print(F("SIG: ")); 1036 | Serial.write(buf+3, len-3); 1037 | Serial.println(); 1038 | } 1039 | 1040 | /** 1041 | * @brief Print "settings" command return value. 1042 | * @param buf --> "settings" command return value 1043 | * buf[0] --> number of records which are trained successfully. 1044 | * buf[1] --> record number 1045 | * buf[2] --> record train status. 1046 | * 00 --> Trained 1047 | * F0 --> Trained, signature truncate 1048 | * FE --> Train Time Out 1049 | * FF --> Value out of range" 1050 | * buf[3] ~ buf[len-1] --> Signature. 1051 | * len --> length of buf 1052 | */ 1053 | 1054 | const unsigned int io_pw_tab[16]={ 1055 | 10, 15, 20, 25, 30, 35, 40, 45, 1056 | 50, 75, 100, 200, 300, 400, 500, 1000 1057 | }; 1058 | 1059 | void printSystemSettings(uint8_t *buf, int len) 1060 | { 1061 | 1062 | switch(buf[0]){ 1063 | case 0: 1064 | case 3: 1065 | Serial.println(F("Baud rate: 9600")); 1066 | break; 1067 | case 1: 1068 | Serial.println(F("Baud rate: 2400")); 1069 | break; 1070 | case 2: 1071 | Serial.println(F("Baud rate: 4800")); 1072 | break; 1073 | case 4: 1074 | Serial.println(F("Baud rate: 19200")); 1075 | break; 1076 | case 5: 1077 | Serial.println(F("Baud rate: 38400")); 1078 | break; 1079 | default: 1080 | Serial.println(F("Baud rate: UNKONOWN")); 1081 | break; 1082 | } 1083 | 1084 | switch(buf[1]){ 1085 | case 0: 1086 | case 0xFF: 1087 | Serial.println(F("Outpu IO Mode: Pulse")); 1088 | break; 1089 | case 1: 1090 | Serial.println(F("Outpu IO Mode: Toggle")); 1091 | break; 1092 | case 2: 1093 | Serial.println(F("Outpu IO Mode: Clear(When recognized) ")); 1094 | break; 1095 | case 3: 1096 | Serial.println(F("Outpu IO Mode: Set(When recognized)")); 1097 | break; 1098 | default: 1099 | Serial.println(F("Output IO Mode: UNKONOWN")); 1100 | break; 1101 | } 1102 | 1103 | if(buf[2] > 15){ 1104 | Serial.println(F("Pulse width: UNKONOWN")); 1105 | } 1106 | else{ 1107 | Serial.print(F("Pulse Width: ")); 1108 | Serial.print(io_pw_tab[buf[2]], DEC); 1109 | Serial.println(F("ms")); 1110 | } 1111 | 1112 | if(buf[3] == 0 || buf[3] == 0xFF){ 1113 | Serial.println(F("Auto Load: disable")); 1114 | } 1115 | else{ 1116 | Serial.println(F("Auto Load: enable")); 1117 | } 1118 | 1119 | switch(buf[4]){ 1120 | case 0: 1121 | case 0xFF: 1122 | Serial.println(F("Group control by external IO: disabled")); 1123 | break; 1124 | case 1: 1125 | Serial.println(F("Group control by external IO: system group selected")); 1126 | break; 1127 | case 2: 1128 | Serial.println(F("Group control by external IO: user group selected")); 1129 | break; 1130 | default: 1131 | Serial.println(F("Group control by external IO: UNKNOWN STATUS")); 1132 | break; 1133 | } 1134 | } 1135 | 1136 | void printHelp(void) 1137 | { 1138 | Serial.println(F("COMMAND FORMAT EXAMPLE Comment")); 1139 | printSeperator(); 1140 | // Serial.println(F("--------------------------------------------------------------------------------------------------------------")); 1141 | Serial.println(F("train train (r0) (r1)... train 0 2 45 Train records")); 1142 | Serial.println(F("load load (r0) (r1) ... load 0 51 2 3 Load records")); 1143 | Serial.println(F("clear clear clear remove all records in Recognizer")); 1144 | Serial.println(F("record record / record (r0) (r1)... record / record 0 79 Check record train status")); 1145 | Serial.println(F("vr vr vr Check recognizer status")); 1146 | Serial.println(F("getsig getsig (r) getsig 0 Get signature of record (r)")); 1147 | Serial.println(F("sigtrain sigtrain (r) (sig) sigtrain 0 ZERO Train one record(r) with signature(sig)")); 1148 | Serial.println(F("settings settings settings Check current system settings")); 1149 | Serial.println(F("help help help print this message")); 1150 | } 1151 | 1152 | -------------------------------------------------------------------------------- /VoiceRecognitionV3.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file VoiceRecognitionV2.cpp 4 | * @author Elechouse Team 5 | * @version V1.0 6 | * @date 2013-6-6 7 | * @brief This file provides all the VoiceRecognitionV2 firmware functions. 8 | ****************************************************************************** 9 | @note 10 | This driver is for elechouse Voice Recognition V2 Module(LINKS here) 11 | ****************************************************************************** 12 | * @section HISTORY 13 | 14 | V1.0 Initial version. 15 | 16 | ****************************************************************************** 17 | * @attention 18 | * 19 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 20 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 21 | * TIME. AS A RESULT, ELECHOUSE SHALL NOT BE HELD LIABLE FOR ANY 22 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 23 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 24 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 25 | * 26 | *

© COPYRIGHT 2013 ELECHOUSE

27 | ****************************************************************************** 28 | */ 29 | #include "VoiceRecognitionV3.h" 30 | #include 31 | 32 | VR* VR::instance; 33 | 34 | /** temp data buffer */ 35 | uint8_t vr_buf[32]; 36 | uint8_t hextab[17]="0123456789ABCDEF"; 37 | 38 | /** 39 | @brief VR class constructor. 40 | @param receivePin --> software serial RX 41 | transmitPin --> software serial TX 42 | */ 43 | VR::VR(uint8_t receivePin, uint8_t transmitPin) : SoftwareSerial(receivePin, transmitPin) 44 | { 45 | instance = this; 46 | SoftwareSerial::begin(38400); 47 | } 48 | 49 | /** 50 | @brief VR class constructor. 51 | @param buf --> return data . 52 | buf[0] --> Group mode(FF: None Group, 0x8n: User, 0x0n:System 53 | buf[1] --> number of record which is recognized. 54 | buf[2] --> Recognizer index(position) value of the recognized record. 55 | buf[3] --> Signature length 56 | buf[4]~buf[n] --> Signature 57 | timeout --> wait time for receiving packet. 58 | @retval length of valid data in buf. 0 means no data received. 59 | */ 60 | int VR :: recognize(uint8_t *buf, int timeout) 61 | { 62 | int ret, i; 63 | ret = receive_pkt(vr_buf, timeout); 64 | if(vr_buf[2] != FRAME_CMD_VR){ 65 | return -1; 66 | } 67 | if(ret > 0){ 68 | for(i = 0; i < (vr_buf[1] - 3); i++){ 69 | buf[i] = vr_buf[4+i]; 70 | } 71 | return i; 72 | } 73 | 74 | return 0; 75 | } 76 | 77 | /** 78 | @brief train records, at least one. 79 | @param records --> record data buffer pointer. 80 | len --> number of records. 81 | buf --> pointer of return value buffer, optional. 82 | buf[0] --> number of records which are trained successfully. 83 | buf[2i+1] --> record number 84 | buf[2i+2] --> record train status. 85 | 00 --> Trained 86 | FE --> Train Time Out 87 | FF --> Value out of range" 88 | (i = 0 ~ len-1 ) 89 | @retval '>0' --> length of valid data in buf. 90 | 0 --> success, and no data received. 91 | '<0' --> failed. 92 | -1 --> data format error. 93 | -2 --> train timeout. 94 | */ 95 | int VR :: train(uint8_t *records, uint8_t len, uint8_t *buf) 96 | { 97 | int ret; 98 | unsigned long start_millis; 99 | if(len == 0){ 100 | return -1; 101 | } 102 | 103 | send_pkt(FRAME_CMD_TRAIN, records, len); 104 | start_millis = millis(); 105 | while(1){ 106 | ret = receive_pkt(vr_buf); 107 | if(ret>0){ 108 | switch(vr_buf[2]){ 109 | case FRAME_CMD_PROMPT: 110 | DBGSTR("Record:\t"); 111 | DBGFMT(vr_buf[3], DEC); 112 | DBGSTR("\t"); 113 | DBGBUF(vr_buf+4, ret-4); 114 | break; 115 | case FRAME_CMD_TRAIN: 116 | if(buf != 0){ 117 | memcpy(buf, vr_buf+3, vr_buf[1]-2); 118 | return vr_buf[1]-2; 119 | } 120 | DBGSTR("Train finish.\r\nSuccess: \t"); 121 | DBGFMT(vr_buf[3], DEC); 122 | DBGSTR(" \r\n"); 123 | return 0; 124 | break; 125 | default: 126 | break; 127 | } 128 | start_millis = millis(); 129 | } 130 | if(millis()-start_millis > 8000){ 131 | return -2; 132 | } 133 | } 134 | return 0; 135 | } 136 | 137 | /** 138 | @brief train one record. 139 | @param records --> record data buffer pointer. 140 | len --> number of records. 141 | buf --> pointer of return value buffer, optional. 142 | buf[0] --> number of records which are trained successfully. 143 | buf[2i+1] --> record number 144 | buf[2i+2] --> record train status. 145 | 00 --> Trained 146 | FE --> Train Time Out 147 | FF --> Value out of range" 148 | (i = 0 ~ len-1 ) 149 | @retval '>0' --> length of valid data in buf. 150 | 0 --> success, and no data received. 151 | '<0' --> failed. 152 | -1 --> data format error. 153 | -2 --> train timeout. 154 | */ 155 | int VR :: train(uint8_t record, uint8_t *buf) 156 | { 157 | return train(&record, 1, buf); 158 | } 159 | 160 | /** 161 | @brief train record and set a signature(alias) for this record. 162 | @param record --> record value. 163 | buf --> signature string/data pointer. 164 | len --> lenght of buf. 165 | retbuf --> return data . 166 | retbuf[0] --> number of records which are trained successfully. 167 | retbuf[1] --> record number. 168 | retbuf[2] --> record train status. 169 | 00 --> Trained 170 | F0 --> Trained, signature truncate 171 | FE --> Train Time Out 172 | FF --> Value out of range" 173 | retbuf[3] ~ retbuf[retval-1] --> Signature.(retval means return value) 174 | @retval '>0' --> length of valid data in buf. 175 | 0 --> success, and no data received. 176 | '<0' --> failed. 177 | -1 --> data format error. 178 | -2 --> train with signature timeout. 179 | */ 180 | int VR :: trainWithSignature(uint8_t record, const void *buf, uint8_t len, uint8_t * retbuf) 181 | { 182 | int ret; 183 | unsigned long start_millis; 184 | if(len){ 185 | send_pkt(FRAME_CMD_SIG_TRAIN, record, (uint8_t *)buf, len); 186 | }else{ 187 | if(buf == 0){ 188 | return -1; 189 | } 190 | len = strlen((char *)buf); 191 | if(len>10){ 192 | return -1; 193 | } 194 | send_pkt(FRAME_CMD_SIG_TRAIN, record, (uint8_t *)buf, len); 195 | } 196 | 197 | start_millis = millis(); 198 | while(1){ 199 | ret = receive_pkt(vr_buf); 200 | if(ret>0){ 201 | switch(vr_buf[2]){ 202 | case FRAME_CMD_PROMPT: 203 | DBGSTR("Record:\t"); 204 | DBGFMT(vr_buf[3], DEC); 205 | DBGSTR("\t"); 206 | DBGBUF(vr_buf+4, ret-4); 207 | break; 208 | case FRAME_CMD_SIG_TRAIN: 209 | if(retbuf != 0){ 210 | memcpy(retbuf, vr_buf+3, vr_buf[1]-2); 211 | return vr_buf[1]-2; 212 | } 213 | 214 | DBGSTR("Train finish.\r\nSuccess: \t"); 215 | DBGFMT(vr_buf[3], DEC); 216 | DBGSTR(" \r\n"); 217 | writehex(vr_buf, vr_buf[1]+2); 218 | return 0; 219 | break; 220 | default: 221 | break; 222 | } 223 | start_millis = millis(); 224 | } 225 | if(millis()-start_millis > 8000){ 226 | return -2; 227 | } 228 | } 229 | return 0; 230 | } 231 | 232 | /** 233 | @brief Load records to recognizer. 234 | @param records --> record data buffer pointer. 235 | len --> number of records. 236 | buf --> pointer of return value buffer, optional. 237 | buf[0] --> number of records which are load successfully. 238 | buf[2i+1] --> record number 239 | buf[2i+2] --> record load status. 240 | 00 --> Loaded 241 | FC --> Record already in recognizer 242 | FD --> Recognizer full 243 | FE --> Record untrained 244 | FF --> Value out of range" 245 | (i = 0 ~ '(retval-1)/2' ) 246 | @retval '>0' --> length of valid data in buf. 247 | 0 --> success, buf=0, and no data returned. 248 | '<0' --> failed. 249 | */ 250 | int VR :: load(uint8_t *records, uint8_t len, uint8_t *buf) 251 | { 252 | uint8_t ret; 253 | send_pkt(FRAME_CMD_LOAD, records, len); 254 | ret = receive_pkt(vr_buf); 255 | if(ret<=0){ 256 | return -1; 257 | } 258 | if(vr_buf[2] != FRAME_CMD_LOAD){ 259 | return -1; 260 | } 261 | if(buf != 0){ 262 | memcpy(buf, vr_buf+3, vr_buf[1]-2); 263 | return vr_buf[1]-2; 264 | } 265 | return 0; 266 | } 267 | 268 | /** 269 | @brief Load one record to recognizer. 270 | @param record --> record value. 271 | buf --> pointer of return value buffer, optional. 272 | buf[0] --> number of records which are load successfully. 273 | buf[2i+1] --> record number 274 | buf[2i+2] --> record load status. 275 | 00 --> Loaded 276 | FC --> Record already in recognizer 277 | FD --> Recognizer full 278 | FE --> Record untrained 279 | FF --> Value out of range" 280 | (i = 0 ~ '(retval-1)/2' ) 281 | @retval '>0' --> length of valid data in buf. 282 | 0 --> success, buf=0, and no data returned. 283 | '<0' --> failed. 284 | */ 285 | int VR :: load(uint8_t record, uint8_t *buf) 286 | { 287 | uint8_t ret; 288 | send_pkt(FRAME_CMD_LOAD, &record, 1); 289 | ret = receive_pkt(vr_buf); 290 | if(ret<=0){ 291 | return -1; 292 | } 293 | if(vr_buf[2] != FRAME_CMD_LOAD){ 294 | return -1; 295 | } 296 | if(buf != 0){ 297 | memcpy(buf, vr_buf+3, vr_buf[1]-2); 298 | return vr_buf[1]-2; 299 | } 300 | return 0; 301 | } 302 | 303 | /** 304 | @brief set signature(alias) for a record. 305 | @param record --> record value. 306 | buf --> signature buffer. 307 | len --> length of buf. 308 | @retval 0 --> success, buf=0, and no data returned. 309 | '<0' --> failed. 310 | */ 311 | int VR :: setSignature(uint8_t record, const void *buf, uint8_t len) 312 | { 313 | int ret; 314 | 315 | if(len == 0 && buf == 0){ 316 | /** delete signature */ 317 | }else if(len == 0 && buf != 0){ 318 | if(buf == 0){ 319 | return -1; 320 | } 321 | len = strlen((char *)buf); 322 | if(len>10){ 323 | return -1; 324 | } 325 | }else if(len != 0 && buf != 0){ 326 | 327 | }else{ 328 | return -1; 329 | } 330 | send_pkt(FRAME_CMD_SET_SIG, record, (uint8_t *)buf, len); 331 | ret = receive_pkt(vr_buf); 332 | if(ret<=0){ 333 | return -1; 334 | } 335 | if(vr_buf[2] != FRAME_CMD_SET_SIG){ 336 | return -1; 337 | } 338 | return 0; 339 | } 340 | 341 | /** 342 | @brief delete signature(alias) of a record. 343 | @param record --> record value. 344 | @retval 0 --> success 345 | -1 --> failed 346 | */ 347 | int VR :: deleteSignature(uint8_t record) 348 | { 349 | return setSignature(record); 350 | } 351 | 352 | /** 353 | @brief check the signature(alias) of a record. 354 | @param record --> record value. 355 | buf --> signature, return value buffer. 356 | @retval '>0' --> length of valid data in buf. 357 | 0 --> success, buf=0, and no data returned. 358 | '<0' --> failed. 359 | */ 360 | int VR :: checkSignature(uint8_t record, uint8_t *buf) 361 | { 362 | int ret; 363 | if(record < 0){ 364 | return -1; 365 | } 366 | send_pkt(FRAME_CMD_CHECK_SIG, record, 0, 0); 367 | ret = receive_pkt(vr_buf); 368 | 369 | if(ret<=0){ 370 | return -1; 371 | } 372 | if(vr_buf[2] != FRAME_CMD_CHECK_SIG){ 373 | return -1; 374 | } 375 | 376 | if(vr_buf[4]>0){ 377 | memcpy(buf, vr_buf+5, vr_buf[4]); 378 | return vr_buf[4]; 379 | }else{ 380 | return 0; 381 | } 382 | } 383 | 384 | /** 385 | @brief clear recognizer. 386 | @retval 0 --> success 387 | -1 --> failed 388 | */ 389 | int VR :: clear() 390 | { 391 | int len; 392 | send_pkt(FRAME_CMD_CLEAR, 0, 0); 393 | len = receive_pkt(vr_buf); 394 | if(len<=0){ 395 | return -1; 396 | } 397 | 398 | if(vr_buf[2] != FRAME_CMD_CLEAR){ 399 | return -1; 400 | } 401 | //DBGLN("VR Module Cleared"); 402 | return 0; 403 | } 404 | 405 | /** 406 | @brief clear recognizer. 407 | @param buf --> return value buffer. 408 | buf[0] --> Number of valid voice records in recognizer 409 | buf[i+1] --> Record number.(0xFF: Not loaded(Nongroup mode), or not set (Group mode)) 410 | (i= 0, 1, ... 6) 411 | buf[8] --> Number of all voice records in recognizer 412 | buf[9] --> Valid records position indicate. 413 | buf[10] --> Group mode indicate(FF: None Group, 0x8n: User, 0x0n:System 414 | @retval '>0' --> success, length of data in buf 415 | -1 --> failed 416 | */ 417 | int VR :: checkRecognizer(uint8_t *buf) 418 | { 419 | int len; 420 | send_pkt(FRAME_CMD_CHECK_BSR, 0, 0); 421 | len = receive_pkt(vr_buf); 422 | if(len<=0){ 423 | return -1; 424 | } 425 | 426 | if(vr_buf[2] != FRAME_CMD_CHECK_BSR){ 427 | return -1; 428 | } 429 | 430 | if(vr_buf[1] != 0x0D){ 431 | return -1; 432 | } 433 | 434 | memcpy(buf, vr_buf+3, vr_buf[1]-2); 435 | 436 | return vr_buf[1]-2; 437 | } 438 | 439 | /** 440 | @brief check record train status. 441 | @param buf --> return value 442 | buf[0] --> Number of checked records 443 | buf[2i+1] --> Record number. 444 | buf[2i+2] --> Record train status. (00: untrained, 01: trained, FF: record value out of range) 445 | (i = 0 ~ buf[0]-1 ) 446 | @retval Number of trained records 447 | */ 448 | int VR :: checkRecord(uint8_t *buf, uint8_t *records, uint8_t len) 449 | { 450 | int ret; 451 | int cnt = 0; 452 | unsigned long start_millis; 453 | if(records == 0 && len==0){ 454 | memset(buf, 0xF0, 255); 455 | send_pkt(FRAME_CMD_CHECK_TRAIN, 0xFF, 0, 0); 456 | start_millis = millis(); 457 | while(1){ 458 | len = receive_pkt(vr_buf); 459 | if(len>0){ 460 | if(vr_buf[2] == FRAME_CMD_CHECK_TRAIN){ 461 | for(int i=0; i 500){ 475 | if(cnt>0){ 476 | buf[0] = cnt*5; 477 | return vr_buf[3]; 478 | } 479 | return -2; 480 | } 481 | 482 | } 483 | 484 | }else if(len>0){ 485 | ret = cleanDup(vr_buf, records, len); 486 | send_pkt(FRAME_CMD_CHECK_TRAIN, vr_buf, ret); 487 | ret = receive_pkt(vr_buf); 488 | if(ret>0){ 489 | if(vr_buf[2] == FRAME_CMD_CHECK_TRAIN){ 490 | memcpy(buf+1, vr_buf+4, vr_buf[1]-3); 491 | buf[0] = (vr_buf[1]-3)/2; 492 | return vr_buf[3]; 493 | }else{ 494 | return -3; 495 | } 496 | }else{ 497 | return -1; 498 | } 499 | }else{ 500 | return -1; 501 | } 502 | 503 | } 504 | 505 | /****************************************************************************/ 506 | /******************************* GROUP CONTROL ******************************/ 507 | /** 508 | @brief set group control by external IO function 509 | @param ctrl --> group control by external IO 510 | 0 --> disable group control by external IO 511 | 1 --> user group control by external IO 512 | 2 --> system group control by external IO 513 | @retval 0 --> success 514 | -1 --> failed 515 | */ 516 | int VR :: setGroupControl(uint8_t ctrl) 517 | { 518 | int ret; 519 | if(ctrl>2){ 520 | return -1; 521 | } 522 | 523 | send_pkt(FRAME_CMD_GROUP, FRAME_CMD_GROUP_SET, &ctrl, 1); 524 | ret = receive_pkt(vr_buf); 525 | if(ret<=0){ 526 | return -1; 527 | } 528 | 529 | if(vr_buf[2] != FRAME_CMD_GROUP){ 530 | return -1; 531 | } 532 | return 0; 533 | } 534 | 535 | /** 536 | @brief check group control by external IO function 537 | @param ctrl --> group control by external IO 538 | @retval 0 --> group control by external IO disabled 539 | 1 --> user group control by external IO status 540 | 2 --> system group control by external IO status 541 | -1 --> failed 542 | */ 543 | int VR :: checkGroupControl() 544 | { 545 | uint8_t cmd; 546 | int ret; 547 | cmd = 0xFF; 548 | send_pkt(FRAME_CMD_GROUP, FRAME_CMD_GROUP_SET, &cmd, 1); 549 | ret = receive_pkt(vr_buf); 550 | if(ret<=0){ 551 | return -1; 552 | } 553 | 554 | if(vr_buf[2] != FRAME_CMD_GROUP){ 555 | return -1; 556 | } 557 | ret = vr_buf[5]; 558 | if(ret == 0xFF){ 559 | ret = 0; 560 | } 561 | return ret; 562 | } 563 | 564 | /** 565 | @brief set user gruop content. 566 | @param grp --> user group number. 567 | records --> pointer of records buffer. 568 | len --> length of reocrds 569 | @retval 0 --> success 570 | -1 --> failed 571 | */ 572 | int VR :: setUserGroup(uint8_t grp, uint8_t *records, uint8_t len) 573 | { 574 | int ret; 575 | if(len == 0 || records == 0){ 576 | return -1; 577 | } 578 | if(grp >= 8){ 579 | return -1; 580 | } 581 | vr_buf[0] = grp; 582 | memcpy(vr_buf+1, records, len); 583 | send_pkt(FRAME_CMD_GROUP, FRAME_CMD_GROUP_SUGRP, vr_buf, len+1); 584 | ret = receive_pkt(vr_buf); 585 | if(ret<=0){ 586 | return -1; 587 | } 588 | if(vr_buf[2] != FRAME_CMD_GROUP){ 589 | return -1; 590 | } 591 | return 0; 592 | } 593 | 594 | /** 595 | @brief check user gruop content. 596 | @param grp --> user group number. 597 | buf --> return value 598 | buf[8i] --> group number. 599 | buf[8i+1] --> group position 0 status. 600 | buf[8i+2] --> group position 1 status. 601 | ... ... 602 | buf[8i+6] --> group position 5 status. 603 | buf[8i+7] --> group position 6 status. 604 | (i = 0 ~ @retval) 605 | @retval '>0' --> number of checked user group 606 | '<0' --> failed 607 | */ 608 | int VR :: checkUserGroup(uint8_t grp, uint8_t *buf) 609 | { 610 | int ret; 611 | int cnt = 0; 612 | unsigned long start_millis; 613 | 614 | if(grp == GROUP_ALL){ 615 | send_pkt(FRAME_CMD_GROUP, FRAME_CMD_GROUP_CUGRP, 0, 0); 616 | start_millis = millis(); 617 | while(1){ 618 | ret = receive_pkt(vr_buf); 619 | if(ret>0){ 620 | if(vr_buf[2] == FRAME_CMD_GROUP && vr_buf[1] == 10){ 621 | memcpy(buf+8*cnt, vr_buf+3, vr_buf[1]-2); 622 | cnt++; 623 | if(cnt == 8){ 624 | return cnt; 625 | } 626 | }else{ 627 | return -3; 628 | } 629 | start_millis = millis(); 630 | } 631 | 632 | if(millis()-start_millis > 500){ 633 | if(cnt>0){ 634 | return cnt; 635 | } 636 | return -2; 637 | } 638 | 639 | } 640 | }else if(grp <= GROUP7){ 641 | send_pkt(FRAME_CMD_GROUP, FRAME_CMD_GROUP_CUGRP, &grp, 1); 642 | ret = receive_pkt(vr_buf); 643 | if(ret>0){ 644 | if(vr_buf[2] == FRAME_CMD_GROUP && vr_buf[1] == 10){ 645 | memcpy(buf+8*cnt, vr_buf+3, vr_buf[1]-2); 646 | return 1; 647 | }else{ 648 | return -3; 649 | } 650 | }else{ 651 | return -2; 652 | } 653 | }else{ 654 | return -1; 655 | } 656 | } 657 | 658 | /** 659 | @brief load system gruop content to recognizer. 660 | @param grp --> syestem group number. 661 | buf --> return value. 662 | buf[0] --> Number of valid voice records in recognizer. 663 | buf[i+1] --> Record number.(0xFF: Not loaded(Nongroup mode), or not set (Group mode)) 664 | (i= 0, 1, ... 6) 665 | buf[8] --> Number of all voice records in recognizer 666 | buf[9] --> Valid records position indicate. 667 | buf[10] --> Group mode indicate(FF: None Group, 0x8n: User, 0x0n:System 668 | (i = 0 ~ @retval) 669 | @retval '>0' --> length of buf 670 | '<0' --> failed 671 | */ 672 | int VR :: loadSystemGroup(uint8_t grp, uint8_t *buf) 673 | { 674 | int ret; 675 | if(grp > 10){ 676 | return -1; 677 | } 678 | send_pkt(FRAME_CMD_GROUP, FRAME_CMD_GROUP_LSGRP, &grp, 1); 679 | ret = receive_pkt(vr_buf); 680 | 681 | if(ret <= 0){ 682 | return -1; 683 | } 684 | 685 | if(vr_buf[2] != FRAME_CMD_GROUP){ 686 | return -1; 687 | } 688 | 689 | if(buf != 0){ 690 | vr_buf[3] = 0; 691 | for(int i=0; i<8; i++){ 692 | if(vr_buf[12]&(1< user group number. 706 | buf --> return value. 707 | buf[0] --> Number of valid voice records in recognizer. 708 | buf[i+1] --> Record number.(0xFF: Not loaded(Nongroup mode), or not set (Group mode)) 709 | (i= 0, 1, ... 6) 710 | buf[8] --> Number of all voice records in recognizer 711 | buf[9] --> Valid records position indicate. 712 | buf[10] --> Group mode indicate(FF: None Group, 0x8n: User, 0x0n:System) 713 | (i = 0 ~ @retval) 714 | @retval '>0' --> length of buf 715 | '<0' --> failed 716 | */ 717 | int VR :: loadUserGroup(uint8_t grp, uint8_t *buf) 718 | { 719 | int ret; 720 | if(grp > GROUP7){ 721 | return -1; 722 | } 723 | send_pkt(FRAME_CMD_GROUP, FRAME_CMD_GROUP_LUGRP, &grp, 1); 724 | ret = receive_pkt(vr_buf); 725 | 726 | if(ret <= 0){ 727 | return -1; 728 | } 729 | 730 | if(vr_buf[2] != FRAME_CMD_GROUP){ 731 | return -1; 732 | } 733 | 734 | if(buf != 0){ 735 | vr_buf[3] = 0; 736 | for(int i=0; i<8; i++){ 737 | if(vr_buf[12]&(1< success 751 | -1 --> failed 752 | */ 753 | int VR :: restoreSystemSettings() 754 | { 755 | int len; 756 | send_pkt(FRAME_CMD_RESET_DEFAULT, 0, 0); 757 | len = receive_pkt(vr_buf); 758 | if(len<=0){ 759 | return -1; 760 | } 761 | 762 | if(vr_buf[2] != FRAME_CMD_RESET_DEFAULT){ 763 | return -1; 764 | } 765 | 766 | return 0; 767 | } 768 | 769 | /** 770 | @brief check system settings 771 | @param buf --> return value 772 | buf[0] --> baud rate. (0-9600 1-2400 2-4800 3-9600 4-19200 5-38400) 773 | buf[1] --> output io mode(0-pulse 1-toggle 2-clear 3-set) 774 | buf[2] --> pulse width level 775 | buf[3] --> auto load(0,0xFF-disable 1-enable) 776 | buf[4] --> Group control by external IO(0-disable 1-system group 2-user group) 777 | @retval '>0' --> buf length 778 | -1 --> failed 779 | */ 780 | int VR :: checkSystemSettings(uint8_t* buf) 781 | { 782 | int len; 783 | if(buf == 0){ 784 | return -1; 785 | } 786 | send_pkt(FRAME_CMD_CHECK_SYSTEM, 0, 0); 787 | len = receive_pkt(vr_buf); 788 | if(len<=0){ 789 | return -1; 790 | } 791 | 792 | if(vr_buf[2] != FRAME_CMD_CHECK_SYSTEM){ 793 | return -1; 794 | } 795 | 796 | memcpy(buf, vr_buf+4, vr_buf[1]-3); 797 | return vr_buf[1]-3; 798 | 799 | return 0; 800 | } 801 | 802 | /** 803 | @brief set module baud rate. 804 | @param br --> module baud rate.(0-9600 1-2400 2-4800 3-9600 4-19200 5-38400) 805 | @retval 0 --> success 806 | -1 --> failed 807 | */ 808 | int VR :: setBaudRate(unsigned long br) 809 | { 810 | uint8_t baud_rate; 811 | int ret; 812 | switch(br){ 813 | case 2400: 814 | baud_rate = 1; 815 | break; 816 | case 4800: 817 | baud_rate = 2; 818 | break; 819 | case 9600: 820 | baud_rate = 0; 821 | //baud_rate = 3; 822 | break; 823 | case 19200: 824 | baud_rate = 4; 825 | break; 826 | case 38400: 827 | baud_rate = 5; 828 | break; 829 | default: 830 | return -1; 831 | break; 832 | } 833 | 834 | send_pkt(FRAME_CMD_SET_BR, baud_rate, 0, 0); 835 | ret = receive_pkt(vr_buf); 836 | if(ret<=0){ 837 | return -1; 838 | } 839 | 840 | if(vr_buf[2] != FRAME_CMD_SET_BR){ 841 | return -1; 842 | } 843 | //DBGLN("VR Module Cleared"); 844 | return 0; 845 | 846 | } 847 | 848 | /** 849 | @brief set module output IO mode. 850 | @param mode --> module output IO mode.(must be PULSE, TOGGLE, SET, CLEAR) 851 | @retval 0 --> success 852 | -1 --> failed 853 | */ 854 | int VR :: setIOMode(io_mode_t mode) 855 | { 856 | if(mode > 3){ 857 | return -1; 858 | } 859 | int ret; 860 | 861 | send_pkt(FRAME_CMD_SET_IOM, mode, 0, 0); 862 | ret = receive_pkt(vr_buf); 863 | if(ret<=0){ 864 | return -1; 865 | } 866 | 867 | if(vr_buf[2] != FRAME_CMD_SET_IOM){ 868 | return -1; 869 | } 870 | return 0; 871 | } 872 | 873 | /** 874 | @brief resset module output IO. 875 | @param ios --> output IO buffer. 876 | len --> length of ios. 877 | @retval 0 --> success 878 | -1 --> failed 879 | */ 880 | int VR :: resetIO(uint8_t *ios, uint8_t len) 881 | { 882 | int ret; 883 | if(len == 1 && ios == 0){ 884 | send_pkt(FRAME_CMD_RESET_IO, 0xFF, 0, 0); 885 | }else if(len != 0 && ios != 0){ 886 | send_pkt(FRAME_CMD_RESET_IO, ios, len); 887 | }else{ 888 | return -1; 889 | } 890 | 891 | ret = receive_pkt(vr_buf); 892 | if(ret<=0){ 893 | return -1; 894 | } 895 | if(vr_buf[2] != FRAME_CMD_RESET_IO){ 896 | return -1; 897 | } 898 | return 0; 899 | } 900 | 901 | /** 902 | @brief set module pulse width(PULSE mode). 903 | @param level --> pulse width level.(LEVEL0~LEVEL15) 904 | len --> length of ios. 905 | @retval 0 --> success 906 | -1 --> failed 907 | */ 908 | int VR :: setPulseWidth(uint8_t level) 909 | { 910 | int ret; 911 | 912 | if(level > VR::LEVEL15){ 913 | return -1; 914 | } 915 | 916 | send_pkt(FRAME_CMD_SET_PW, level, 0, 0); 917 | ret = receive_pkt(vr_buf); 918 | if(ret<=0){ 919 | return -1; 920 | } 921 | 922 | if(vr_buf[2] != FRAME_CMD_SET_PW){ 923 | return -1; 924 | } 925 | return 0; 926 | } 927 | 928 | /** 929 | @brief set autoload. 930 | @param records --> record buffer. 931 | len --> records length. 932 | @retval 0 --> success 933 | -1 --> failed 934 | */ 935 | int VR :: setAutoLoad(uint8_t *records, uint8_t len) 936 | { 937 | int ret; 938 | uint8_t map; 939 | if(len == 0 && records == 0){ 940 | map = 0; 941 | }else if(len != 0 && records != 0){ 942 | map = 0; 943 | for(int i=0; i record buffer. 964 | len --> records length. 965 | @retval 0 --> success 966 | -1 --> failed 967 | */ 968 | int VR :: disableAutoLoad() 969 | { 970 | return setAutoLoad(); 971 | } 972 | 973 | int VR :: test(uint8_t cmd, uint8_t *bsr) 974 | { 975 | int len, i; 976 | unsigned long start_millis; 977 | switch(cmd){ 978 | case FRAME_CMD_TEST_READ: 979 | vr_buf[0] = FRAME_CMD_TEST_READ; 980 | send_pkt(FRAME_CMD_TEST, vr_buf, 1); 981 | start_millis = millis(); 982 | while(1){ 983 | len = receive_pkt(vr_buf); 984 | if(len>0){ 985 | switch(vr_buf[2]){ 986 | case FRAME_CMD_TEST: 987 | memcpy(bsr+vr_buf[3]*20, vr_buf+4, 20); 988 | if(vr_buf[3] == 9){ 989 | return 0; 990 | } 991 | break; 992 | default: 993 | DBGLN("TEST ERROR"); 994 | return -1; 995 | break; 996 | } 997 | start_millis = millis(); 998 | } 999 | if(millis()-start_millis > 4000){ 1000 | return -2; 1001 | } 1002 | } 1003 | break; 1004 | case FRAME_CMD_TEST_WRITE: 1005 | for(i=0; i<10; i++){ 1006 | vr_buf[0] = i; 1007 | memcpy(vr_buf+1, bsr+20*i, 20); 1008 | send_pkt(FRAME_CMD_TEST, FRAME_CMD_TEST_WRITE, vr_buf, 21); 1009 | start_millis = millis(); 1010 | while(1){ 1011 | len = receive_pkt(vr_buf); 1012 | if(len>0){ 1013 | if(vr_buf[2] == FRAME_CMD_TEST){ 1014 | break; 1015 | }else{ 1016 | DBGLN("TEST ERROR"); 1017 | return -1; 1018 | } 1019 | start_millis = millis(); 1020 | } 1021 | if(millis()-start_millis > 4000){ 1022 | return -2; 1023 | } 1024 | } 1025 | } 1026 | break; 1027 | default: 1028 | break; 1029 | } 1030 | return 0; 1031 | } 1032 | 1033 | /**flash operation function (strlen)*/ 1034 | int VR :: len(uint8_t *buf) 1035 | { 1036 | int i=0; 1037 | while(pgm_read_byte_near(buf++)){ 1038 | i++; 1039 | } 1040 | return i; 1041 | } 1042 | 1043 | /**flash operation function (strcmp)*/ 1044 | int VR :: cmp(uint8_t *buf, uint8_t *bufcmp, int len ) 1045 | { 1046 | int i; 1047 | for(i=0; i>4]); 1125 | DBGCHAR(hextab[(buf[i]&0x0F)]); 1126 | DBGCHAR(' '); 1127 | } 1128 | return len; 1129 | } 1130 | 1131 | /** 1132 | @brief send data packet in Voice Recognition module protocol format. 1133 | @param cmd --> command 1134 | subcmd --> subcommand 1135 | buf --> data area 1136 | len --> length of buf 1137 | */ 1138 | void VR :: send_pkt(uint8_t cmd, uint8_t subcmd, uint8_t *buf, uint8_t len) 1139 | { 1140 | while(available()){ 1141 | read();// replace flush(); 1142 | } 1143 | write(FRAME_HEAD); 1144 | write(len+3); 1145 | write(cmd); 1146 | write(subcmd); 1147 | write(buf, len); 1148 | write(FRAME_END); 1149 | } 1150 | 1151 | /** 1152 | @brief send data packet in Voice Recognition module protocol format. 1153 | @param cmd --> command 1154 | buf --> data area 1155 | len --> length of buf 1156 | */ 1157 | void VR :: send_pkt(uint8_t cmd, uint8_t *buf, uint8_t len) 1158 | { 1159 | while(available()){ 1160 | read();// replace flush(); 1161 | } 1162 | write(FRAME_HEAD); 1163 | write(len+2); 1164 | write(cmd); 1165 | write(buf, len); 1166 | write(FRAME_END); 1167 | } 1168 | 1169 | /** 1170 | @brief send data packet in Voice Recognition module protocol format. 1171 | @param buf --> data area 1172 | len --> length of buf 1173 | */ 1174 | void VR :: send_pkt(uint8_t *buf, uint8_t len) 1175 | { 1176 | while(available()){ 1177 | read();// replace flush(); 1178 | } 1179 | write(FRAME_HEAD); 1180 | write(len+1); 1181 | write(buf, len); 1182 | write(FRAME_END); 1183 | } 1184 | 1185 | /** 1186 | @brief receive a valid data packet in Voice Recognition module protocol format. 1187 | @param buf --> return value buffer. 1188 | timeout --> time of reveiving 1189 | @retval '>0' --> success, packet lenght(length of all data in buf) 1190 | '<0' --> failed 1191 | */ 1192 | int VR :: receive_pkt(uint8_t *buf, uint16_t timeout) 1193 | { 1194 | int ret; 1195 | ret = receive(buf, 2, timeout); 1196 | if(ret != 2){ 1197 | return -1; 1198 | } 1199 | if(buf[0] != FRAME_HEAD){ 1200 | return -2; 1201 | } 1202 | if(buf[1] < 2){ 1203 | return -3; 1204 | } 1205 | ret = receive(buf+2, buf[1], timeout); 1206 | if(buf[buf[1]+1] != FRAME_END){ 1207 | return -4; 1208 | } 1209 | 1210 | // DBGBUF(buf, buf[1]+2); 1211 | 1212 | return buf[1]+2; 1213 | } 1214 | 1215 | /** 1216 | @brief receive data . 1217 | @param buf --> return value buffer. 1218 | len --> length expect to receive. 1219 | timeout --> time of reveiving 1220 | @retval number of received bytes, 0 means no data received. 1221 | */ 1222 | int VR::receive(uint8_t *buf, int len, uint16_t timeout) 1223 | { 1224 | int read_bytes = 0; 1225 | int ret; 1226 | unsigned long start_millis; 1227 | 1228 | while (read_bytes < len) { 1229 | start_millis = millis(); 1230 | do { 1231 | ret = read(); 1232 | if (ret >= 0) { 1233 | break; 1234 | } 1235 | } while( (millis()- start_millis ) < timeout); 1236 | 1237 | if (ret < 0) { 1238 | return read_bytes; 1239 | } 1240 | buf[read_bytes] = (char)ret; 1241 | read_bytes++; 1242 | } 1243 | 1244 | return read_bytes; 1245 | } 1246 | --------------------------------------------------------------------------------