Shop OBEX P1 Docs P2 Docs Learn Events
EasyVR Question - Page 2 — Parallax Forums

EasyVR Question

2»

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-10-22 14:55
    NWCCTV wrote: »
    So to make sure I somewhat knew what I was doing I added White to the mix.(Although with my resistors it is closer to Pink) but it worked, White comes up in the Menu and when it turns on the correct color shows on the PST. I am going to try my luck at making a Servo move now. I am thinking I can use "move" that is in wordset 1. Is that correct or am I off base here?

    It's good to hear you added white on your own. I almost added white to the example but I thought I'd leave it out as a tempting addition others could make.
    I generally use a higher resistor value on the red cathode than the blue and green cathode when using a RGB LED.

    You can use any word you like to control a servo. I think "move" or "turn" are good choices. Depending on what your servo is connected to, "attack" might be a good option? (I'm thinking of erco's flame thrower.)

    As the code it written now, the program waits for a direction word after hearing "move".
    LISTEN_FOR_WORDSET_1:
          case adjustedIndex
            ACTION_WS1:
              nextMode := LISTEN_FOR_WORDSET_3 ' This can be any set or group you want
              nextAction := ACTION_NEXT 
              wordset3DigitRemaining := 3
              wordset3Total := 0
              Debug.Str(string(13, "Action command received."))
              Debug.Str(string(13, "Waiting for action number to execute."))
    [COLOR=#ff0000]        MOVE_WS1:[/COLOR]
    [COLOR=#ff0000]          nextMode := LISTEN_FOR_WORDSET_2 ' This can be any set or group you want[/COLOR]
    [COLOR=#ff0000]          Debug.Str(string(13, "Move command received."))[/COLOR]
    [COLOR=#ff0000]          Debug.Str(string(13, "Waiting for direction to move."))[/COLOR]
    

    "nextMode" holds the next group or wordset to listen for next time. In this example wordset 2 was selected. Wordset 2 has a list of directions.

    When a word from wordset 2 is heard, the program checks both the new word (as "adjustedIndex") and the checks the previous word ("previousIndex") to know which action to take.

    For example, lets say after you said the word "move" you then say "right". In this case, this section of code would be active.
    RIGHT_WS2:
              Debug.Str(string(13, "Right command received."))
              case previousIndex
                MOVE_WS1:
                  nextMode := LISTEN_FOR_WORDSET_3 [COLOR=#ff0000] ' since the previousIndex was "MOVE_WS1" this code will be executed.[/COLOR]
                  nextAction := MOVE_RIGHT_NEXT  
                  wordset3DigitRemaining := 3 [COLOR=#ff0000]' when this value reaches zero, the "nextAction" will be executed.[/COLOR]
                  wordset3Total := 0       [COLOR=#ff0000] ' This value will be added to as number words (from wordset 3) are spoken)[/COLOR]
                  Debug.Str(string(13, "Waiting for amount to move right."))
    

    As it is now, the "move" command requires multiple (four) additional words before an action is taken. For example, a valid command is: "move", "right", "one", "eight", "zero".

    Now lets assume the words "move", "right", "one", "eight", "zero" have been spoken. As each number is spoken the value of wordset3Total is multipllied by 10 with the new number just spoken added to the value.
    LISTEN_FOR_WORDSET_3:
          wordset3Total := (10 * wordset3Total) + adjustedIndex
          Debug.Str(string(13, "command index = "))
          Debug.Dec(adjustedIndex)
          Debug.Str(string(13, "wordset3Total = "))
          Debug.Dec(wordset3Total)
          Debug.Str(string(13, "wordset3DigitRemaining = "))
          Debug.Dec(--wordset3DigitRemaining)
    

    You can see the value of wordset3DigitRemaining is decremented with each number spoken.

    When the last number is spokent wordset3DigitRemaining will equal zero which triggers this portion of code.
    if wordset3DigitRemaining == 0
        TakeAction(adjustedIndex)
        if nextMode == LISTEN_FOR_WORDSET_3
          nextMode := LISTEN_FOR_WORDSET_0
    

    The "TakeAction" method is the method which executes the various actions required by the program.

    In the second section of code I posted here, you can see the line:
    nextAction := MOVE_RIGHT_NEXT
    

    Now that "wordset3DigitRemaining" equals zero, this action is triggered. In the "TakeAction" method we find this under "MOVE_RIGHT_NEXT":
    MOVE_RIGHT_NEXT
    :      Debug.Str(string(13, "Received command to move right "))
          Debug.Dec(wordset3Total)
          Debug.Str(string(" units"))
          Debug.Str(string(13, "Add method to move appropriate amount. "))
          nextAction := NO_NEXT_ACTION
    

    You can try to make the servo changes you want. If you don't get the changes you want to work, let me know, and I'll show you how to make the change (don't wait very long before asking for help). I think once you have an example of how to change the wordset part of the code, you'll be able to make the changes on your own on the future.

    I'm always glad to hear about someone else using code I've written. It makes me feel like the time I spent writing the code was even more productive than when it only benefited myself.

    I'm not completely satisfied with the structure of the current program. I thing there should be a better way of accomplishing some of the tasks but I haven't figured out what these techniques are.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2013-10-22 15:05
    When I say "Left" after the Move command, it comes up wanting a number from zero to 9. Sometimes the Servo moves on zero, others it moves on 3 or 4. I have to leave shortly but will follow your instructions shortly. I am currently just using the PropBoe Servo Object and placing set.Servo(14,200) on the Move, Left command.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-10-22 15:10
    NWCCTV wrote: »
    When I say "Left" after the Move command, it comes up wanting a number from zero to 9. Sometimes the Servo moves on zero, others it moves on 3 or 4. I have to leave shortly but will follow your instructions shortly. I am currently just using the PropBoe Servo Object and placing set.Servo(14,200) on the Move, Left command.

    Could you cut and paste the bit of code you're changing and also explain what you'd like the servo to do with what commands.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2013-10-22 15:17
    MOVE_LEFT_NEXT:
    Debug.Str(string(13, "Received command to move left "))
    Debug.Dec(wordset3Total)
    Debug.Str(string(" units"))
    Debug.Str(string(13, "Add method to move appropriate amount. "))
    servo.Set(14,500)
    nextAction := NO_NEXT_ACTION
    

    This is all I have done thus far. For now I just want to get one Servo moving correctly. Once I have that figures out I should be able to tackle it on my own.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-10-22 15:32
    NWCCTV wrote: »
    This is all I have done thus far. For now I just want to get one Servo moving correctly. Once I have that figures out I should be able to tackle it on my own.

    One possible problem is you're setting the servo to 500. You ought to try 1000. 500 is out of range for most servos.

    The standard (if you can call it that) servo driver uses microseconds. So a centered servo would be set to "1500". Full clockwise is normally 1000us and full counter clockwise is 2000us.

    The program will still want three digits. I'll show you how to change that. I'll also show you how to add a new action to the TakeAction menu. I think the program will flow much better if you keep all the actions at least routed through the "TakeAction" menu.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-10-22 15:44
    I think "move" is a logical word to use to control a servo. I also think "left"and "right" make sense. I'll show how to add "right" and I'll leave "left" to you. I do wonder about adding some option which requires a number so I can show you an example of how to change the code that way too.

    What if the word "up" took either an microsecond value or an angle value? Would that be useful? (Hint, say yes.)

    You could then use "move", "up", "one", "five", "one", "zero", "ten" to set the servo at position 1510 (just off of its center position). I used the word "ten" to indicate the end of the number input. This way the numbers wouldn't need to all have the same number of digits (as the current code requires). What do you think? (Hint, "that would be great" is a good reply.)



    I've got some life stuff to take care of but I should have time to work on this either this evening or tomorrow morning.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2013-10-22 16:43
    OK, Yes!!! Any how, my Servos are CR. I was following the PropBOE Center Servo demo and I think 0 was off so I just used 500 to test. No rush on working on it. This is one of those "add on" things but since it just arrived last week I wanted to get somewhat of a grip on it. I understand about life coming up. I will be busy from tomorrow all through next week.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2013-10-22 16:48
    1000 worked fine after speaking 3 consecutive numbers.

    Except, what do I use to overwrite the EEPROM? I accidentally hit F11 instead of F10 so now it is loaded in EEPROM.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2013-10-22 17:32
    I think you are correct in that it would be easiest to leave all of the Servo commands under the TakeAction column. I am going to toy around to see if I can get it to work without having to use zero, one, eight, etc. to get movement. For what I will be using those types of commands for if I say Move and then Left, I just want to go left and not have to say the numbers. Could get real ugly like that if I was in a hurry to go left or right!!!
  • NWCCTVNWCCTV Posts: 3,629
    edited 2013-10-22 18:13
    So what is the purpose of the Wordset3digit setting? I changed the 0 to a 3 and my Servos on Pin 14 and 15 turn after I say Left, which is what I want. However, I would like to eliminate this altogether unless it is needed for something else.
    if wordset3DigitRemaining == 3
    TakeAction(adjustedIndex)
    if nextMode == LISTEN_FOR_WORDSET_3
    nextMode := LISTEN_FOR_WORDSET_0
    

    EDIT: Well, Not sure why but doing that made the LED commands no longer work. Back to the drawing board.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-10-22 18:40
    Andy, Did you see the this?

    If you want one send me a PM quick. There are only two left.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-10-22 21:16
    NWCCTV wrote: »
    OK, Yes!!! Any how, my Servos are CR. I was following the PropBOE Center Servo demo and I think 0 was off so I just used 500 to test.

    I'm not familiar with the that demo. It sounds like they were using a speed parameter rather than a pulse length. Which servo object are planning on using? I usually use Servo32v9.
    NWCCTV wrote: »
    . . . Except, what do I use to overwrite the EEPROM? I accidentally hit F11 instead of F10 so now it is loaded in EEPROM.
    I usually use F11 when loading a program. I'm not sure what your question is? In order for a program to load after the Propeller has been turned off, it needs to be stored in EEPROM.
    NWCCTV wrote: »
    I think you are correct in that it would be easiest to leave all of the Servo commands under the TakeAction column. I am going to toy around to see if I can get it to work without having to use zero, one, eight, etc. to get movement. For what I will be using those types of commands for if I say Move and then Left, I just want to go left and not have to say the numbers. Could get real ugly like that if I was in a hurry to go left or right!!!

    I like the idea of having an action list all located in one method, but I don't like the way I use the "Wordset3digit" to indicate when to move to the "TakeAction" method. It was just a way to tell the program how many digits to wait to receive before taking action. I think I should have some sort of action type variable to indicate how many and what type of parameters the action requires.
    NWCCTV wrote: »
    So what is the purpose of the Wordset3digit setting? I changed the 0 to a 3 and my Servos on Pin 14 and 15 turn after I say Left, which is what I want. However, I would like to eliminate this altogether unless it is needed for something else.
    if wordset3DigitRemaining == 3
    TakeAction(adjustedIndex)
    if nextMode == LISTEN_FOR_WORDSET_3
    nextMode := LISTEN_FOR_WORDSET_0
    

    EDIT: Well, Not sure why but doing that made the LED commands no longer work. Back to the drawing board.

    As you've seen, this doesn't work.

    Instead of changing the code where you did, change it here:
    RIGHT_WS2:
              Debug.Str(string(13, "Right command received."))
              case previousIndex
                MOVE_WS1:
    [COLOR=#ff0000]              nextMode := LISTEN_FOR_WORDSET_1 '3 ' This will needs to be changed *[/COLOR]
                  nextAction := MOVE_RIGHT_NEXT  
    [COLOR=#ff0000]              wordset3DigitRemaining := 0 ' 3 Change this to zero[/COLOR]
    [COLOR=#ff0000]              'wordset3Total := 0 ' This line is no longer needed. (though it could be used to set servo position)[/COLOR]
                 [COLOR=#ff0000] 'Debug.Str(string(13, "Waiting for amount to move right."))
                  ' this debug statement isn't needed anymore either.[/COLOR]
    

    The "nextMode" variable should be set to whichever group or wordset you want to be active once the servo has moved.

    There are a couple of different ways to move the action taken to the TakeAction method. I'm not sure which is the best approach right now. I'll work on this and let you know what I changed.

    This program reminds me a lot of my touchscreen programs. With a touchscreen there are many possible branches a program can take. I felt like I came up with a nice and clean way of keeping track of the various menus and actions in my touchscreen programs. I'm tempted to use a similar technique with the EasyVR. While the techniques I use in my touchscreen programs, makes changing the menus and actions relatively easy, the code itself is kind of hard to follow.

    I don't think I've come up with the best way of keeping track of branches and actions with this EasyVR program. I'm pretty sure I'll be making some major changes to it sometime.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-10-25 12:33
    I originally started make a note next to each section of code I changed but it soon became clear I was changing more code than keeping.

    I don't think it will be hard to add your "white" command back into the program.

    There are fewer places in the code that will need to be changed in order to add a new word now.

    The main change required is to add the word in the appropriate location of the DAT section.
    group1                  byte "LED", 0[WORDSET_LABEL_SIZE - 3]                        byte "other", 0[WORDSET_LABEL_SIZE - 5]
                  
    group2                  byte "red", 0[WORDSET_LABEL_SIZE - 3]
                            byte "yellow", 0[WORDSET_LABEL_SIZE - 6]
                            byte "green", 0[WORDSET_LABEL_SIZE - 5]
                            byte "blue", 0[WORDSET_LABEL_SIZE - 4]
                            byte "violet", 0[WORDSET_LABEL_SIZE - 6]
                            byte "off", 0[WORDSET_LABEL_SIZE - 3]
                            byte "exit", 0[WORDSET_LABEL_SIZE - 4]
        
    group3
    group4
    group5
    group6
    group7
    group8
    group9
    group10
    group11
    group12
    group13
    group14
    group15
    password
    
    
    noWord                  byte "no word", 0[WORDSET_LABEL_SIZE - 7]
    

    The program now automatically computes the group size based on the number of words in the group.

    I think I've fixed all the menu choices and I've added an option to check the words listed in the DAT section against those programmed in the EasyVR module.
    For now it just checks each word in the DAT section for a corresponding word in the saved to the module. It doesn't find words saved to the module unless there is also a word listed in the DAT section.

    The code had been greatly simplified. I've moved all the communication to and from the module to dedicated methods.

    I'm not completely happy with the code yet, but it's getting closer to a "done" state.

    One addition that's really useful is the errors are now identified. The program will pass along messages about words being spoken too softly etc.

    Edit: I just found a couple errors in code I'll upload a corrected version soon.
    Edit: Here's almost the same version. I just deleted a few unused constants.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-10-25 13:25
    I made a couple small changes to the code. The newest version (for now) is in post #44.

    There's not really a simple way to add new words to the program. Hopefully the examples provide will help anyone wanting to change the code.

    I haven't tested any of the servo code (with a servo). I added "move", "right". And "move", "up". The move up command requires a number to be spoken. In this case the number can be a variable number of digits. Once the last digit is spoken the word "ten" is spoken to indicate you've finished entering the number.

    The "action" and "run" commands both require a single digit number be spoken to indicate which action or which program to "run".

    Most of the commands no longer require numeric input.

    As usual, feel free to ask questions.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2013-10-25 16:50
    @Duane Degn, It is probably going to be a week or more before I get back to this. I start a fairly large job tommorrow that will take me through next week. Been busy this week also. I hate it when my real job gets in the way of my hobby!!!!! But, the bills still come in. I will let you know how it goes once I try it out.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-10-25 19:00
    Not a problem here Andy.

    It's been fun working on this. I've been meaning to do some of this stuff from the last three and a half years (since the SayIt was deal of the day).
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-11-02 15:02
    As I work on my robot remote, I've decided I'd like to add a feature to my EasyVR program. I'd like to program to compare the list of commands in the program to the list of commands stored in the EasyVR's memory (it already kind of does this). If there's a command listed in the program which isn't listed in the EasyVR, I'd like the program to load the command text to the EasyVR and then train the EVR without the need of hooking it up to a PC. I'd also like to include the option of retraining a word in case the EVR doesn't recognize one of the SD words as often as it should.

    I added some pictures comparing the EasyVR to the SayIt in my robot remote thread. I glad Parallax has switched to selling the EasyVR instead of selling the SayIt. I think the EasyVR is easier to install in devices than the SayIt was. I really like how the mic on the EVR can be installed a few inches from the PCB.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2014-02-02 19:32
    I think xainnasir is spamming...
    I certainly agree.
  • crazyrobotgirlcrazyrobotgirl Posts: 32
    edited 2014-04-11 07:29
    Is anyone having problems with the easy vr beeping to let you know its waiting for the next command? I m using the code in post #44. To turn on an LED. I have successfully trained my words in the Easy Vr Commander, and I am able to test it in the sound table in the Commander. My easy vr is working, but however when I say LED there is no beep or noise to let me know to say the next command. So I am continuously saying the next command hoping to get it in the right time frame. I am able to get the LED to turn on after constantly saying the next command. With out that beep to let you know the easy vr is ready it takes out all the fun. Any advice anyone?
  • banjobanjo Posts: 447
    edited 2014-09-01 12:10
    A newbie question:
    Can I connect EasyVR to my Propeller Activity Board when it's docked to the dev board? I'd like to avoid docking and undocking it frequently as the pins might take some damage.
    Or how do you do to test something through your PC before trying it on a board (PAB or similar)?
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-09-01 12:29
    banjo wrote: »
    Can I connect EasyVR to my Propeller Activity Board when it's docked to the dev board?

    I don't see a way to access the tx and rx pins while the EasyVR is docked. I think the development board is only used when using the EasyVR with a PC.
    banjo wrote: »
    Or how do you do to test something through your PC before trying it on a board (PAB or similar)?

    The GUI program on the PC makes it easier to test the various functions of the EasyVR. IMO, it's easier to set the speaker dependent (SD) words with the GUI. I'm pretty sure everything done with the GUI can be done with a microcontroller but it's just a bit more cumbersome with the microcontroller.

    The EasyVR doesn't make any decisions for you. Your microcontroller has to do all the decision making. Your program has to tell the EasyVR's when to change word sets, it wont do this on its own.

    I like to think of the EasyVR as a verbal touchscreen. The word sets are like the active menu displayed on the screen with the words within the word set acting like buttons on the touchscreen. When using a touchscreen, the microcontroller has to tell the screen what to display (which buttons are active) just like the microcontroller also has to tell the EasyVR which word set to use.
  • banjobanjo Posts: 447
    edited 2014-09-01 12:46
    Thanks Duane for the clarifications!
Sign In or Register to comment.