Chad Miller
/
Lab4
Lab4
Diff: main.cpp
- Revision:
- 0:0420a5989bff
diff -r 000000000000 -r 0420a5989bff main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Oct 19 14:40:32 2015 +0000 @@ -0,0 +1,271 @@ +/* + * Documentation: + * http://www.zagrosrobotics.com/files/easyvr-user-manual-30.pdf + */ + +#include "easyvr.h" + +#define BUF_SIZE 32 +#define NUM_NOTES 8 + +EasyVR easyVR( p28, p27 ); +Serial term( USBTX, USBRX ); +PwmOut speaker( p21 ); +InterruptIn hold_button( p8 ); + +// C major scale starting at C4 +char *note_table[] = { "C4", "D4", "E4", "F4", "G4", "A4", "B4", "C5" }; +float freq_table[] = { 261.63, 293.66, 329.63, 349.23, 392.0, 440.0, 493.88, 523.25 }; + +char note_buffer[BUF_SIZE]; +short note_buffer_pos = 0; +bool do_read = false; + +void print_error( int error ) +{ + switch( error ) + { + case ERR_DATACOL_TOO_NOISY: + term.printf( "Too noisy, try again\r\n" ); + break; + case ERR_DATACOL_TOO_SOFT: + term.printf( "Spoke too softly, try again\r\n" ); + break; + case ERR_DATACOL_TOO_LOUD: + term.printf( "Spoke too loudly, try again\r\n" ); + break; + case ERR_DATACOL_TOO_SOON: + term.printf( "Spoke too soon, try again\r\n" ); + break; + case ERR_DATACOL_TOO_CHOPPY: + term.printf( "Too complex, try again\r\n" ); + break; + case ERR_RECOG_FAIL: + term.printf( "Recognition failed, try again\r\n" ); + break; + case ERR_RECOG_LOW_CONF: + term.printf( "Recognition result status: doubtful, try again\r\n" ); + break; + case ERR_RECOG_MID_CONF: + term.printf( "Recognition result status: maybe, try again\r\n" ); + break; + case ERR_RECOG_BAD_TEMPLATE: + term.printf( "Invalid command stored in memory\r\n" ); + break; + case ERR_RECOG_DURATION: + term.printf( "Bad duration patterns\r\n" ); + break; + case ERR_SYNTH_BAD_VERSION: + term.printf( "Bad release number in speech file\r\n" ); + break; + case ERR_SYNTH_BAD_MSG: + term.printf( "Bad data in speech file\r\n" ); + break; + case ERR_NOT_A_WORD: + term.printf( "Spoken word is not in vocabulary\r\n" ); + break; + default: + break; + } +} + +void add_command( int index ) +{ + char command_num = i2a( index ); + char note = note_table[index][0]; + char scale = (char)( note_table[index][1] + 17 ); + + char err; + + easyVR.send( CMD_GROUP_SD ); + easyVR.send( i2a( 1 ) ); + easyVR.send( command_num ); + + if( ( err = easyVR.receive() ) != STS_SUCCESS ) + term.printf( "(in add_command( %s ) line %d) Error %c\r\n", note_table[index], __LINE__, err ); + + easyVR.send( CMD_NAME_SD ); + easyVR.send( i2a( 1 ) ); + easyVR.send( command_num ); + easyVR.send( i2a( 3 ) ); + easyVR.send( note ); + easyVR.send( '^' ); + easyVR.send( scale ); + + if( ( err = easyVR.receive() ) != STS_SUCCESS ) + term.printf( "(in add_command( %s ) line %d) Error %c\r\n", note_table[index], __LINE__, err ); +} + +char train_command( int index ) +{ + char command_num = i2a( index ); + char note = note_table[index][0]; + char scale = (char)( note_table[index][1] + 17 ); + + term.printf( "Please say: %s\r\n", note_table[index] ); + + easyVR.send( CMD_TRAIN_SD ); + easyVR.send( i2a( 1 ) ); + easyVR.send( command_num ); + + char recv, err, retval; + + switch( ( recv = easyVR.receive() ) ) + { + case STS_SUCCESS: + term.printf( "Successfully trained command %c^%c\r\n", note, scale ); + retval = recv; + break; + case STS_RESULT: + easyVR.send( ARG_ACK ); + err = a2i( easyVR.receive() ); + term.printf( "Successfully trained command %c^%c, but similar to SD command %d\r\n", note, scale, err ); + retval = STS_SUCCESS; + break; + case STS_SIMILAR: + easyVR.send( ARG_ACK ); + err = a2i( easyVR.receive() ); + term.printf( "Successfully trained command %c^%c, but similar to SI command %d\r\n", note, scale, err ); + retval = STS_SUCCESS; + break; + case STS_TIMEOUT: + term.printf( "Timed out trying to train %c^%c!\r\n", note, scale ); + retval = recv; + break; + case STS_ERROR: + easyVR.send( ARG_ACK ); + err = a2i( easyVR.receive() ) * 16; + easyVR.send( ARG_ACK ); + err += a2i( easyVR.receive() ); + print_error( err ); + retval = err; + break; + default: + term.printf( "(in train_command( %s ) line %d) Error %c\r\n", note_table[index], __LINE__, recv ); + retval = recv; + break; + } + + return retval; +} + +void enable_read() +{ + do_read = true; +} + +void play_buffer() +{ + do_read = false; + easyVR.send( CMD_BREAK ); + + for( int i = 0; i < note_buffer_pos; i++ ) + { + speaker.period( 1.0 / freq_table[note_buffer[i]] ); + speaker = 0.25; + wait( 0.5 ); + } + + speaker = 0; + note_buffer_pos = 0; +} + +int main( void ) +{ + term.baud( 19200 ); + + easyVR.wakeup(); + easyVR.setup( 0, 3 ); + + char err; + + easyVR.baud( 9600 ); + easyVR.send( CMD_BAUDRATE ); + easyVR.send( i2a( 12 ) ); + + if( ( err = easyVR.receive() ) != STS_SUCCESS ) + term.printf( "(in main() line %d) Error: %c\r\n", __LINE__, err ); + + easyVR.send( CMD_LEVEL ); + easyVR.send( i2a( 1 ) ); + + if( ( err = easyVR.receive() ) != STS_SUCCESS ) + term.printf( "(in main() line %d) Error: %c\r\n", __LINE__, err ); + + /* + int result; + + for( int i = 0; i < NUM_NOTES; i++ ) + { + add_command( i ); + + do + { + result = train_command( i ); + wait( 0.5 ); + } while( result != STS_SUCCESS ); + } + */ + + hold_button.rise( enable_read ); + hold_button.fall( play_buffer ); + + char note, recv; + + while( 1 ) + { + while( do_read ) + { + term.printf( "Ready!\r\n" ); + + easyVR.send( CMD_RECOG_SI ); + easyVR.send( i2a( 3 ) ); + + switch( ( recv = easyVR.receive() ) ) + { + case STS_SIMILAR: + easyVR.send( ARG_ACK ); + note = a2i( easyVR.receive() ); + + if( note < NUM_NOTES ) + { + term.printf( "Heard: %s\r\n", note_table[note] ); + + if( note_buffer_pos < BUF_SIZE ) + { + note_buffer[note_buffer_pos] = note; + note_buffer_pos++; + } + else + term.printf( "Buffer full\r\n" ); + } + else + term.printf( "Heard SI command %d\r\n", note ); + + break; + /* + case STS_SIMILAR: + easyVR.send( ARG_ACK ); + err = a2i( easyVR.receive() ); + term.printf( "Heard similar to SI command %d\r\n", err ); + break; + */ + case STS_TIMEOUT: + term.printf( "Timed out\r\n" ); + break; + case STS_ERROR: + easyVR.send( ARG_ACK ); + err = a2i( easyVR.receive() ) * 16; + easyVR.send( ARG_ACK ); + err += a2i( easyVR.receive() ); + print_error( err ); + break; + default: + if( recv != STS_INTERR ) + term.printf( "(in main() line %d) Error %c\r\n", __LINE__, recv ); + + break; + } + } + } +}