Skip to content

Instantly share code, notes, and snippets.

@pH14
Created December 16, 2013 18:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pH14/7991541 to your computer and use it in GitHub Desktop.
Save pH14/7991541 to your computer and use it in GitHub Desktop.
/**
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