Created
December 16, 2013 18:07
-
-
Save pH14/7991541 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
EasyVR Tester | |
Dump contents of attached EasyVR module | |
and exercise it with playback and recognition. | |
Serial monitor can be used to send a few basic commands: | |
'c' - cycles through available command groups | |
'b' - cycles through built-in word sets | |
's123.' - play back sound 123 if available (or beep) | |
With EasyVR Shield, the green LED is ON while the module | |
is listening (using pin IO1 of EasyVR). | |
Successful recognition is acknowledged with a beep. | |
Details are displayed on the serial monitor window. | |
** | |
Example code for the EasyVR library v1.0 | |
Written in 2011 by RoboTech srl for VeeaR <http:://www.veear.eu> | |
To the extent possible under law, the author(s) have dedicated all | |
copyright and related and neighboring rights to this software to the | |
public domain worldwide. This software is distributed without any warranty. | |
You should have received a copy of the CC0 Public Domain Dedication | |
along with this software. | |
If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. | |
*/ | |
#if defined(ARDUINO) && ARDUINO >= 100 | |
#include "Arduino.h" | |
#include "SoftwareSerial.h" | |
SoftwareSerial port(12,13); | |
#else // Arduino 0022 - use modified NewSoftSerial | |
#include "WProgram.h" | |
#include "NewSoftSerial.h" | |
NewSoftSerial port(12,13); | |
#endif | |
#include "EasyVR.h" | |
static const int8_t IDLE_STATE = 0; //looking for commands in group 0 | |
static const int8_t LISTENING_STATE = 1; //looking for commands in group 1 | |
static const int NURSE_CALL = 0; //in listening state, nurse call is 0 | |
static const int AIDE_CALL = 1; | |
static const int STOP_LISTENING = 2; | |
static const int TIMEOUT_TIME = 8; // in seconds | |
static const int FAILED_ATTEMPTS_LIMIT = 5; | |
static const int16_t NOW_LISTENING_AUDIO = 3; | |
static const int16_t CALLING_AIDE_AUDIO = 1; | |
EasyVR easyvr(port); | |
int NURSE_CALL_PIN = 3; | |
int LED_POS_PIN = 10; | |
int LED_NEG_PIN = 11; | |
int failed_listen_attempts = 0; | |
int8_t set = 0; | |
int8_t state = 0; | |
uint32_t mask = 0; | |
uint8_t train = 0; | |
char name[32]; | |
bool useCommands = true; | |
EasyVRBridge bridge; | |
void setup() | |
{ | |
// bridge mode? | |
if (bridge.check()) | |
{ | |
cli(); | |
bridge.loop(0, 1, 12, 13); | |
} | |
// run normally | |
Serial.begin(9600); | |
port.begin(9600); | |
if (!easyvr.detect()) | |
{ | |
Serial.println("EasyVR not detected!!"); | |
for (;;); | |
} | |
easyvr.setPinOutput(EasyVR::IO1, LOW); | |
Serial.println("EasyVR detected!"); | |
easyvr.setTimeout(TIMEOUT_TIME); | |
easyvr.setLanguage(EasyVR::ENGLISH); | |
// Set threshold for detection rate. Change this if | |
// there are too many false positives / too many | |
// missed words | |
easyvr.setLevel(EasyVR::HARDEST); | |
int16_t count = 0; | |
Serial.print("Sound table: "); | |
if (easyvr.dumpSoundTable(name, count)) | |
{ | |
Serial.println(name); | |
Serial.print("Sound entries: "); | |
Serial.println(count); | |
} | |
else | |
Serial.println("n/a"); | |
if (easyvr.getGroupMask(mask)) | |
{ | |
uint32_t msk = mask; | |
for (state = 0; state <= EasyVR::PASSWORD; ++state, msk >>= 1) | |
{ | |
if (!(msk & 1)) continue; | |
if (state == EasyVR::TRIGGER) | |
Serial.print("Trigger: "); | |
else if (state == EasyVR::PASSWORD) | |
Serial.print("Password: "); | |
else | |
{ | |
Serial.print("state "); | |
Serial.print(state); | |
Serial.print(": "); | |
} | |
count = easyvr.getCommandCount(state); | |
Serial.println(count); | |
for (int8_t idx = 0; idx < count; ++idx) | |
{ | |
if (easyvr.dumpCommand(state, idx, name, train)) | |
{ | |
Serial.print(idx); | |
Serial.print(" = "); | |
Serial.print(name); | |
Serial.print(", Trained "); | |
Serial.print(train, DEC); | |
if (!easyvr.isConflict()) | |
Serial.println(" times, OK"); | |
else | |
{ | |
int8_t confl = easyvr.getWord(); | |
if (confl >= 0) | |
Serial.print(" times, Similar to Word "); | |
else | |
{ | |
confl = easyvr.getCommand(); | |
Serial.print(" times, Similar to Command "); | |
} | |
Serial.println(confl); | |
} | |
} | |
} | |
} | |
} | |
state = 0; | |
mask |= 1; // force to use trigger | |
useCommands = (mask != 1); | |
pinMode(NURSE_CALL_PIN, OUTPUT); | |
pinMode(LED_POS_PIN, OUTPUT); | |
pinMode(LED_NEG_PIN, OUTPUT); | |
digitalWrite(NURSE_CALL_PIN, LOW); | |
digitalWrite(LED_POS_PIN, LOW); | |
digitalWrite(LED_NEG_PIN, LOW); | |
} | |
const char* ws0[] = | |
{ | |
"ROBOT", | |
}; | |
const char* ws1[] = | |
{ | |
"ACTION", | |
"MOVE", | |
"TURN", | |
"RUN", | |
"LOOK", | |
"ATTACK", | |
"STOP", | |
"HELLO", | |
}; | |
const char* ws2[] = | |
{ | |
"LEFT", | |
"RIGHT", | |
"UP", | |
"DOWN", | |
"FORWARD", | |
"BACKWARD", | |
}; | |
const char* ws3[] = | |
{ | |
"ZERO", | |
"ONE", | |
"TWO", | |
"THREE", | |
"FOUR", | |
"FIVE", | |
"SIX", | |
"SEVEN", | |
"EIGHT", | |
"NINE", | |
"TEN", | |
}; | |
const char** ws[] = { ws0, ws1, ws2, ws3 }; | |
bool checkMonitorInput() | |
{ | |
if (Serial.available() <= 0) | |
return false; | |
// check console commands | |
int16_t rx = Serial.read(); | |
if (rx == 'b') | |
{ | |
useCommands = false; | |
set++; | |
if (set > 3) | |
set = 0; | |
} | |
if (rx == 'c') | |
{ | |
useCommands = true; | |
do | |
{ | |
state++; | |
if (state > EasyVR::PASSWORD) | |
state = 0; | |
} while (!((mask >> state) & 1)); | |
} | |
if (rx == 's') | |
{ | |
int16_t num = 0; | |
delay(5); | |
while ((rx = Serial.read()) >= 0) | |
{ | |
if (isdigit(rx)) | |
num = num * 10 + (rx - '0'); | |
else | |
break; | |
delay(5); | |
} | |
if (rx == '.') | |
{ | |
easyvr.stop(); | |
easyvr.playSound(num, EasyVR::VOL_DOUBLE); | |
} | |
} | |
if (rx >= 0) | |
{ | |
easyvr.stop(); | |
Serial.flush(); | |
return true; | |
} | |
return false; | |
} | |
void performAction(int8_t state, int action_id) { | |
Serial.print("Executing command: "); | |
// Actually do something useful! | |
if (state == IDLE_STATE) { | |
} else if (state == LISTENING_STATE) { | |
switch(action_id) { | |
case NURSE_CALL: | |
Serial.print("calling nurse."); | |
digitalWrite(NURSE_CALL_PIN, HIGH); | |
digitalWrite(LED_POS_PIN, HIGH); | |
digitalWrite(LED_NEG_PIN, LOW); | |
delay(500); | |
digitalWrite(NURSE_CALL_PIN, LOW); | |
digitalWrite(LED_POS_PIN, LOW); | |
delay(300); | |
digitalWrite(LED_POS_PIN, HIGH); | |
delay(100); | |
digitalWrite(LED_POS_PIN, LOW); | |
delay(300); | |
digitalWrite(LED_POS_PIN, HIGH); | |
delay(100); | |
digitalWrite(LED_POS_PIN, LOW); | |
delay(300); | |
digitalWrite(LED_POS_PIN, HIGH); | |
delay(100); | |
digitalWrite(LED_POS_PIN, LOW); | |
// Light + sound indicators | |
easyvr.playSound(CALLING_AIDE_AUDIO, EasyVR::VOL_FULL); | |
break; | |
case AIDE_CALL: | |
Serial.print("calling aide."); | |
digitalWrite(NURSE_CALL_PIN, HIGH); | |
digitalWrite(LED_POS_PIN, HIGH); | |
digitalWrite(LED_NEG_PIN, LOW); | |
delay(500); | |
digitalWrite(NURSE_CALL_PIN, LOW); | |
digitalWrite(LED_POS_PIN, LOW); | |
delay(300); | |
digitalWrite(LED_POS_PIN, HIGH); | |
delay(100); | |
digitalWrite(LED_POS_PIN, LOW); | |
delay(300); | |
digitalWrite(LED_POS_PIN, HIGH); | |
delay(100); | |
digitalWrite(LED_POS_PIN, LOW); | |
delay(300); | |
digitalWrite(LED_POS_PIN, HIGH); | |
delay(100); | |
digitalWrite(LED_POS_PIN, LOW); | |
// Light + sound indicators | |
easyvr.playSound(CALLING_AIDE_AUDIO, EasyVR::VOL_FULL); | |
break; | |
case STOP_LISTENING: | |
Serial.print("told to stop listening..."); | |
break; | |
default: | |
; | |
} | |
} | |
Serial.println(); | |
} | |
void updateState(int8_t *state, int reset) { | |
if (reset > 0) { | |
Serial.println("Resetting to Idle after timeout."); | |
*state = IDLE_STATE; | |
digitalWrite(LED_POS_PIN, LOW); | |
digitalWrite(LED_NEG_PIN, LOW); | |
return; | |
} | |
if (*state == IDLE_STATE) { | |
Serial.println("Transitioning from Idle to Listening."); | |
*state = LISTENING_STATE; | |
failed_listen_attempts = FAILED_ATTEMPTS_LIMIT; | |
digitalWrite(LED_POS_PIN, LOW); | |
digitalWrite(LED_NEG_PIN, HIGH); | |
easyvr.playSound(NOW_LISTENING_AUDIO, EasyVR::VOL_FULL); | |
return; | |
} | |
if (*state == LISTENING_STATE) { | |
Serial.println("Transitioning from Listening to Idle."); | |
*state = IDLE_STATE; | |
digitalWrite(LED_POS_PIN, LOW); | |
digitalWrite(LED_NEG_PIN, LOW); | |
return; | |
} | |
} | |
void loop() | |
{ | |
checkMonitorInput(); | |
easyvr.setPinOutput(EasyVR::IO1, HIGH); // LED on (listening) | |
switch(state) { | |
case IDLE_STATE: | |
Serial.println("Idling... listening for \"Start\""); | |
break; | |
case LISTENING_STATE: | |
Serial.println("Activated. Listening for command."); | |
break; | |
default: | |
Serial.println("I don't know what state I am in."); | |
} | |
easyvr.recognizeCommand(state); | |
// Check Arduino monitor for input | |
// (useful for debugging) | |
do { | |
if (checkMonitorInput()) return; | |
} | |
while (!easyvr.hasFinished()); | |
easyvr.setPinOutput(EasyVR::IO1, LOW); // LED off | |
int16_t command = easyvr.getCommand(); | |
// >= 0 if we recognized a command | |
if (command >= 0) { | |
/* Recognize a command and do useful things */ | |
if (easyvr.dumpCommand(state, command, name, train)) { | |
Serial.print("Command: "); | |
Serial.print(" = "); | |
Serial.println(name); | |
} else { | |
Serial.println("Unable to dump last command."); | |
} | |
performAction(state, command); | |
if (command == STOP_LISTENING) { | |
updateState(&state, 1); | |
} else { | |
updateState(&state, -1); | |
} | |
} else { | |
/* Errors or timeouts */ | |
if (easyvr.isTimeout()) { | |
Serial.println("Timed out, try again..."); | |
// reset state to Idle after a timeout | |
// not after an error | |
updateState(&state, 1); | |
} | |
int16_t err = easyvr.getError(); | |
if (err >= 0) { | |
// We'll try several times to get a detection once | |
// we're listening. Determined by the FAILED_LISTEN_LIMIT | |
if (--failed_listen_attempts == 0) { | |
updateState(&state, 1); | |
} | |
Serial.print("Failed, will try "); | |
Serial.print(failed_listen_attempts); | |
Serial.print(" more times.\n"); | |
Serial.print("Error "); | |
Serial.println(err, HEX); | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment