Lab4

Dependencies:   EasyVR mbed

Revision:
0:0420a5989bff
--- /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;
+            }
+        }
+    }
+}