So I am using an EasyVR 3+ shield which works perfectly. I am also using the Adafruit Music Maker with amplifier shield and that works perfectly too. I've even stacked them and I can get one or the other to work perfectly but not both at the same time.
A bit of an introduction - I am building Wheatley from Portal 2. I want to use voice commands like "say hello" and he will go "hello!" etc with various different prompts. At the moment I am just testing relatively basic code to ensure it does what I want it to do. Later I will add servos and lights into the code too (which I have tested and also work very well). My problem is, I think that the EasyVR and the Music Maker shields are sharing some pins or something? I can only run one. Can you please review my code and advise? I am using an Arduino Uno.
This code is not really mine, it's a combination of the exported code from the EasyVR software and the Simple Music Player from the VS1053 library example. I've just frankenstein'd it together. I'm not a great coder and so this sort of stuff doesn't really come naturally to me. I expect I am going to get in trouble for not starting with something simpler!! That's just not how I learn unfortunately.
#include "Arduino.h"
#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SdFat.h>
#if !defined(SERIAL_PORT_MONITOR)
#error "Arduino version not supported. Please update your IDE to the latest version."
#endif
#define SHIELD_RESET -1 // VS1053 reset pin (unused!)
#define SHIELD_CS 7 // VS1053 chip select pin (output)
#define SHIELD_DCS 6 // VS1053 Data/command select pin (output)
// These are common pins between breakout and shield
#define CARDCS 4 // Card chip select pin
// DREQ should be an Int pin, see http://arduino.cc/en/Reference/attachInterrupt
#define DREQ 3 // VS1053 Data request, ideally an Interrupt pin
Adafruit_VS1053_FilePlayer musicPlayer =
// create breakout-example object!
//Adafruit_VS1053_FilePlayer(BREAKOUT_RESET, BREAKOUT_CS, BREAKOUT_DCS, DREQ, CARDCS);
// create shield-example object!
Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);
#if defined(__SAMD21G18A__)
// Shield Jumper on HW (for Zero, use Programming Port)
#define port SERIAL_PORT_HARDWARE
#define pcSerial SERIAL_PORT_MONITOR
#elif defined(SERIAL_PORT_USBVIRTUAL)
// Shield Jumper on HW (for Leonardo and Due, use Native Port)
#define port SERIAL_PORT_HARDWARE
#define pcSerial SERIAL_PORT_USBVIRTUAL
#else
// Shield Jumper on SW (using pins 12/13 or 8/9 as RX/TX)
#include "SoftwareSerial.h"
SoftwareSerial port(12, 13);
#define pcSerial SERIAL_PORT_MONITOR
#endif
#include "EasyVR.h"
EasyVR easyvr(port);
//Groups and Commands
enum Groups
{
GROUP_0 = 0,
GROUP_1 = 1,
};
enum Group0
{
G0_WHEATLEY = 0,
};
enum Group1
{
G1_SAY_HELLO = 0,
G1_TELL_STORY = 1,
G1_YOURE_A_MORON = 2,
G1_BE_QUIET = 3,
G1_CLOSE_EYE = 4,
};
//Grammars and Words
enum Wordsets
{
SET_1 = -1,
SET_2 = -2,
SET_3 = -3,
};
enum Wordset1
{
S1_ACTION = 0,
S1_MOVE = 1,
S1_TURN = 2,
S1_RUN = 3,
S1_LOOK = 4,
S1_ATTACK = 5,
S1_STOP = 6,
S1_HELLO = 7,
};
enum Wordset2
{
S2_LEFT = 0,
S2_RIGHT = 1,
S2_UP = 2,
S2_DOWN = 3,
S2_FORWARD = 4,
S2_BACKWARD = 5,
};
enum Wordset3
{
S3_ZERO = 0,
S3_ONE = 1,
S3_TWO = 2,
S3_THREE = 3,
S3_FOUR = 4,
S3_FIVE = 5,
S3_SIX = 6,
S3_SEVEN = 7,
S3_EIGHT = 8,
S3_NINE = 9,
S3_TEN = 10,
};
// use negative group for wordsets
int8_t group, idx;
void setup()
{
musicPlayer.begin();
SD.begin(CARDCS);
musicPlayer.setVolume(10,10);
musicPlayer.playFullFile("/MORON001.wav");
// setup PC serial port
pcSerial.begin(9600);
bridge:
// bridge mode?
int mode = easyvr.bridgeRequested(pcSerial);
switch (mode)
{
case EasyVR::BRIDGE_NONE:
// setup EasyVR serial port
port.begin(9600);
// run normally
pcSerial.println(F("Bridge not requested, run normally"));
pcSerial.println(F("---"));
break;
case EasyVR::BRIDGE_NORMAL:
// setup EasyVR serial port (low speed)
port.begin(9600);
// soft-connect the two serial ports (PC and EasyVR)
easyvr.bridgeLoop(pcSerial);
// resume normally if aborted
pcSerial.println(F("Bridge connection aborted"));
pcSerial.println(F("---"));
break;
case EasyVR::BRIDGE_BOOT:
// setup EasyVR serial port (high speed)
port.begin(115200);
pcSerial.end();
pcSerial.begin(115200);
// soft-connect the two serial ports (PC and EasyVR)
easyvr.bridgeLoop(pcSerial);
// resume normally if aborted
pcSerial.println(F("Bridge connection aborted"));
pcSerial.println(F("---"));
break;
}
// initialize EasyVR
while (!easyvr.detect())
{
pcSerial.println(F("EasyVR not detected!"));
for (int i = 0; i < 10; ++i)
{
if (pcSerial.read() == '?')
goto bridge;
delay(100);
}
}
pcSerial.print(F("EasyVR detected, version "));
pcSerial.print(easyvr.getID());
if (easyvr.getID() < EasyVR::EASYVR3)
easyvr.setPinOutput(EasyVR::IO1, LOW); // Shield 2.0 LED off
if (easyvr.getID() < EasyVR::EASYVR)
pcSerial.print(F(" = VRbot module"));
else if (easyvr.getID() < EasyVR::EASYVR2)
pcSerial.print(F(" = EasyVR module"));
else if (easyvr.getID() < EasyVR::EASYVR3)
pcSerial.print(F(" = EasyVR 2 module"));
else
pcSerial.print(F(" = EasyVR 3 module"));
pcSerial.print(F(", FW Rev."));
pcSerial.println(easyvr.getID() & 7);
easyvr.setDelay(0); // speed-up replies
easyvr.setTimeout(5);
easyvr.setLanguage(0); //<-- same language set on EasyVR Commander when code was generated
group = EasyVR::TRIGGER; //<-- start group (customize)
}
void loop()
{
if (easyvr.getID() < EasyVR::EASYVR3)
easyvr.setPinOutput(EasyVR::IO1, HIGH); // LED on (listening)
if (group < 0) // SI wordset/grammar
{
pcSerial.print("Say a word in Wordset ");
pcSerial.println(-group);
easyvr.recognizeWord(-group);
}
else // SD group
{
pcSerial.print("Say a command in Group ");
pcSerial.println(group);
easyvr.recognizeCommand(group);
}
do
{
// allows Commander to request bridge on Zero (may interfere with user protocol)
if (pcSerial.read() == '?')
{
setup();
return;
}
// <<-- can do some processing here, while the module is busy
}
while (!easyvr.hasFinished());
if (easyvr.getID() < EasyVR::EASYVR3)
easyvr.setPinOutput(EasyVR::IO1, LOW); // LED off
idx = easyvr.getWord();
if (idx == 0 && group == EasyVR::TRIGGER)
{
// beep
easyvr.playSound(0, EasyVR::VOL_FULL);
// print debug message
pcSerial.println("Word: ROBOT");
// write your action code here
// group = GROUP_X\SET_X; <-- jump to another group or wordset
return;
}
else if (idx >= 0)
{
// beep
easyvr.playSound(0, EasyVR::VOL_FULL);
// print debug message
uint8_t flags = 0, num = 0;
char name[32];
pcSerial.print("Word: ");
pcSerial.print(idx);
if (easyvr.dumpGrammar(-group, flags, num))
{
for (uint8_t pos = 0; pos < num; ++pos)
{
if (!easyvr.getNextWordLabel(name))
break;
if (pos != idx)
continue;
pcSerial.print(F(" = "));
pcSerial.println(name);
break;
}
}
// perform some action
action();
return;
}
idx = easyvr.getCommand();
if (idx >= 0)
{
// beep
easyvr.playSound(0, EasyVR::VOL_FULL);
// print debug message
uint8_t train = 0;
char name[32];
pcSerial.print("Command: ");
pcSerial.print(idx);
if (easyvr.dumpCommand(group, idx, name, train))
{
pcSerial.print(" = ");
pcSerial.println(name);
}
else
pcSerial.println();
// perform some action
action();
}
else // errors or timeout
{
if (easyvr.isTimeout())
pcSerial.println("Timed out, try again...");
int16_t err = easyvr.getError();
if (err >= 0)
{
pcSerial.print("Error ");
pcSerial.println(err, HEX);
}
}
}
void action()
{
switch (group)
{
case GROUP_0:
switch (idx)
{
case G0_WHEATLEY:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
}
break;
case GROUP_1:
switch (idx)
{
case G1_SAY_HELLO:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case G1_TELL_STORY:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case G1_YOURE_A_MORON:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case G1_BE_QUIET:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case G1_CLOSE_EYE:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
}
break;
case SET_1:
switch (idx)
{
case S1_ACTION:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case S1_MOVE:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case S1_TURN:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case S1_RUN:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case S1_LOOK:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case S1_ATTACK:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case S1_STOP:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case S1_HELLO:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
}
break;
case SET_2:
switch (idx)
{
case S2_LEFT:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case S2_RIGHT:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case S2_UP:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case S2_DOWN:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case S2_FORWARD:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case S2_BACKWARD:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
}
break;
case SET_3:
switch (idx)
{
case S3_ZERO:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case S3_ONE:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case S3_TWO:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case S3_THREE:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case S3_FOUR:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case S3_FIVE:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case S3_SIX:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case S3_SEVEN:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case S3_EIGHT:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case S3_NINE:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
case S3_TEN:
// write your action code here
// group = GROUP_X\SET_X; <-- or jump to another group or wordset for composite commands
break;
}
break;
}
}