generating functional code Sayit Module and Parallax Digital I/O Board
not sure if I'll start this with all the needed info if you have questions or comments all are welcome.
I have a Board of Education(BOE)with a BS2.In the app mod header I have the Sayit module.It works fine using the sample code to control a Boe bot.
Im trying to use the Sayit module to control a Parallax DIOB.When I create my own words in the Sayit GUI and generate code I get stuck with where to go from there.Im using 4 groups of words.It should Idealy work like this I say COMPUTER,(pick a room)KITCHEN,(what to activate/deactivate)LIGHTS,ON or OFF.
When I generate code it looks quite different from the given example.Which is how Im stuck.I see the area that says insert code here.Im not sure what i want to put there.
Ive edited the example code to switch between relays on different commands and it will work(with the wrong commands for my project ie.Robot,TURN,LEFT and relay 1 turns on for a second and off as coded.
So any help getting my generated code to work right would be great.Thanks
Here is the edited demo code that works with the wrong verble commands.I say for example COMPUTER,MOVE,LEFT and relay 3 lights up for a second and goes off.
I have a Board of Education(BOE)with a BS2.In the app mod header I have the Sayit module.It works fine using the sample code to control a Boe bot.
Im trying to use the Sayit module to control a Parallax DIOB.When I create my own words in the Sayit GUI and generate code I get stuck with where to go from there.Im using 4 groups of words.It should Idealy work like this I say COMPUTER,(pick a room)KITCHEN,(what to activate/deactivate)LIGHTS,ON or OFF.
When I generate code it looks quite different from the given example.Which is how Im stuck.I see the area that says insert code here.Im not sure what i want to put there.
Ive edited the example code to switch between relays on different commands and it will work(with the wrong commands for my project ie.Robot,TURN,LEFT and relay 1 turns on for a second and off as coded.
So any help getting my generated code to work right would be great.Thanks
' {$STAMP BS2}
' {$PBASIC 2.5}
' COM Parameters
COM_RX PIN 0 ' rx pin
COM_TX PIN 2 ' tx pin
COM_SPEED CON 84 ' baud 9600
COM_10MS CON 10 ' 10ms unit
' Protocol Command
CMD_BREAK CON "b" ' abort recog or ping
CMD_SLEEP CON "s" ' go to power down
CMD_KNOB CON "k" ' set si knob <1>
CMD_LEVEL CON "v" ' set sd level <1>
CMD_LANGUAGE CON "l" ' set si language <1>
CMD_TIMEOUT CON "o" ' set timeout <1>
CMD_RECOG_SI CON "i" ' do si recog from ws <1>
CMD_RECOG_SD CON "d" ' do sd recog at group <1> (0 = trigger mixed si/sd)
' Protocol Status
STS_AWAKEN CON "w" ' back from power down mode
STS_ERROR CON "e" ' signal error code <1-2>
STS_INVALID CON "v" ' invalid command or argument
STS_TIMEOUT CON "t" ' timeout expired
STS_INTERR CON "i" ' back from aborted recognition (see 'break')
STS_SUCCESS CON "o" ' no errors status
STS_RESULT CON "r" ' recognised sd command <1> - training similar to sd <1>
STS_SIMILAR CON "s" ' recognised si <1> (in mixed si/sd) - training similar to si <1>
' Protocol arguments are in the range 0x40 (-1) TO 0x60 (+31) inclusive
ARG_MIN CON 64 ' 0x40
ARG_MAX CON 96 ' 0x60
ARG_ZERO CON 65 ' 0x41
ARG_ACK CON 32 ' 0x20 'TO READ more status arguments
'Groups and Commands
GROUP_0 CON 0 '(Command count: 1)
G0_COMPUTER CON 0
GROUP_1 CON 1 '(Command count: 4)
G1_KITCHEN CON 0
G1_LIVINGROOM CON 1
G1_MASTERBEDROOM CON 2
G1_OFFICE CON 3
GROUP_2 CON 2 '(Command count: 1)
G2_LIGHTS CON 0
GROUP_3 CON 3 '(Command count: 2)
G3_ON CON 0
G3_OFF CON 1
RES_ERROR CON 255
RES_TIMEOUT CON 254
RES_COMMFAIL CON 253
RES_BUILTIN CON 32
'Robot Constant
VRLED PIN 4
'Global Variable
VRA VAR Byte
VRA1 VAR Byte
VRGROUP VAR Byte
VRCOMMAND VAR Byte
' Main Start
INPUT COM_RX
HIGH COM_TX
Restart:
LOW VRLED
VRGROUP = 0
DEBUG CR, "Setting up VRbot... "
'Wake up or stop recognition
GOSUB VR_Wakeup
DEBUG "awake... "
'Set SI Language
VRA1 = 0
GOSUB VR_SetLanguage
DEBUG "language ", DEC VRA1, "... "
'Set 5 seconds timeout
VRA1 = 5
GOSUB VR_SetTimeout
DEBUG "timeout ", DEC VRA1, "... "
DEBUG CR, "VRbot ready!"
VR_Loop:
DEBUG CR, "VRbot in group ", DEC VRGROUP, " waiting for command... "
LOW VRLED
PAUSE 150
IF VRGROUP > 0 THEN HIGH VRLED
VRA1 = VRGROUP
GOSUB VR_RecognizeSD
'-- handle errors or timeout
IF VRA1 = RES_ERROR THEN
DEBUG "error"
'try again in the same group
GOTO VR_Loop
ENDIF
IF VRA1 = RES_TIMEOUT THEN
DEBUG "timed out"
VRGROUP = 0 ' back to trigger
GOTO VR_Loop
ENDIF
IF VRA1 = RES_COMMFAIL THEN
DEBUG "comm failed"
'resync and try again
GOSUB VR_Wakeup
GOTO VR_Loop
ENDIF
'-- got a command
VRCOMMAND = VRA1
IF VRCOMMAND <= RES_BUILTIN THEN GOSUB VR_Action
GOTO VR_Loop
VR_Action:
DEBUG "got ", DEC VRCOMMAND
SELECT VRGROUP
CASE GROUP_0
SELECT VRCOMMAND
CASE G0_COMPUTER
PAUSE 0 '-- write your code here
ENDSELECT
CASE GROUP_1
SELECT VRCOMMAND
CASE G1_KITCHEN
PAUSE 0 '-- write your code here
CASE G1_LIVINGROOM
PAUSE 0 '-- write your code here
CASE G1_MASTERBEDROOM
PAUSE 0 '-- write your code here
CASE G1_OFFICE
PAUSE 0 '-- write your code here
ENDSELECT
CASE GROUP_2
SELECT VRCOMMAND
CASE G2_LIGHTS
PAUSE 0 '-- write your code here
ENDSELECT
CASE GROUP_3
SELECT VRCOMMAND
CASE G3_ON
PAUSE 0 '-- write your code here
CASE G3_OFF
PAUSE 0 '-- write your code here
ENDSELECT
ENDSELECT
RETURN
'=== VR Routines ===
' Wake up:
VR_Wakeup:
TOGGLE VRLED
VRA = CMD_BREAK
SEROUT COM_TX, COM_SPEED, [VRA]
SERIN COM_RX, COM_SPEED, 100*COM_10MS, VR_Wakeup, [VRA]
IF (VRA <> STS_SUCCESS) THEN GOTO VR_Wakeup
LOW VRLED
RETURN
' Inputs:
' VRA1 = language index (0 = english, ...)
VR_SetLanguage:
VRA = CMD_LANGUAGE
SEROUT COM_TX, COM_SPEED, [VRA]
VRA1 = VRA1 + ARG_ZERO
SEROUT COM_TX, COM_SPEED, [VRA1]
SERIN COM_RX, COM_SPEED, 20*COM_10MS, VR_CommFailed, [VRA]
VRA1 = VRA1 - ARG_ZERO
'IF (VRA <> STS_SUCCESS) THEN GOTO VR_Wakeup
RETURN
' Inputs:
' VRA1 = timeout (in ms, 0=forever, 255=default)
VR_SetTimeout:
VRA = CMD_TIMEOUT
SEROUT COM_TX, COM_SPEED, [VRA]
VRA1 = VRA1 + ARG_ZERO
SEROUT COM_TX, COM_SPEED, [VRA1]
SERIN COM_RX, COM_SPEED, 20*COM_10MS, VR_CommFailed, [VRA]
VRA1 = VRA1 - ARG_ZERO
'IF (VRA <> STS_SUCCESS) THEN GOTO VR_Wakeup
RETURN
' Inputs:
' VRA1 = SI knob (0=loosest, 2=normal, 4=tightest)
VR_SetKnob:
VRA = CMD_KNOB
SEROUT COM_TX, COM_SPEED, [VRA]
VRA1 = VRA1 + ARG_ZERO
SEROUT COM_TX, COM_SPEED, [VRA1]
SERIN COM_RX, COM_SPEED, 20*COM_10MS, VR_CommFailed, [VRA]
VRA1 = VRA1 - ARG_ZERO
'IF (VRA <> STS_SUCCESS) THEN GOTO VR_Wakeup
RETURN
' Inputs:
' VRA1 = SD level (1=easy, 2=default, 5=hard)
VR_SetLevel:
VRA = CMD_LEVEL
SEROUT COM_TX, COM_SPEED, [VRA]
VRA1 = VRA1 + ARG_ZERO
SEROUT COM_TX, COM_SPEED, [VRA1]
SERIN COM_RX, COM_SPEED, 20*COM_10MS, VR_CommFailed, [VRA]
VRA1 = VRA1 - ARG_ZERO
'IF (VRA <> STS_SUCCESS) THEN GOTO VR_Wakeup
RETURN
' Inputs:
' VRA1 = wordset (0=trigger)
' Ouputs:
' VRA1 = result (0-31=word, 32..=builtin, 253=comm err, 254=timeout, 255=error)
VR_RecognizeSI:
VRA = CMD_RECOG_SI
GOTO VR_Recognize0
VR_RecognizeSD:
VRA = CMD_RECOG_SD
VR_Recognize0:
SEROUT COM_TX, COM_SPEED, [VRA]
' send Group/WS
VRA1 = VRA1 + ARG_ZERO
SEROUT COM_TX, COM_SPEED, [VRA1]
' wait for answer
SERIN COM_RX, COM_SPEED, 600*COM_10MS, VR_CommFailed, [VRA]
IF VRA = STS_RESULT THEN
' send ack
VRA = ARG_ACK
SEROUT COM_TX, COM_SPEED, [VRA]
' wait for recognised command code
SERIN COM_RX, COM_SPEED, 20*COM_10MS, VR_CommFailed, [VRA1]
VRA1 = VRA1 - ARG_ZERO
ELSEIF VRA = STS_SIMILAR THEN
' send ack
VRA = ARG_ACK
SEROUT COM_TX, COM_SPEED, [VRA]
' wait for recognised command code
SERIN COM_RX, COM_SPEED, 20*COM_10MS, VR_CommFailed, [VRA1]
VRA1 = VRA1 - ARG_ZERO + RES_BUILTIN
ELSEIF VRA = STS_TIMEOUT THEN
VRA1 = RES_TIMEOUT
ELSE
VRA1 = RES_ERROR
ENDIF
RETURN
VR_CommFailed:
VRA1 = RES_COMMFAIL
RETURN
Here is the edited demo code that works with the wrong verble commands.I say for example COMPUTER,MOVE,LEFT and relay 3 lights up for a second and goes off.
' {$STAMP BS2}
' {$PBASIC 2.5}
' COM Parameters
COM_RX PIN 0 ' RX Pin
COM_TX PIN 2 ' TX Pin
COM_SPEED CON 84 ' baud 9600
RServo PIN 13 ' Right Wheel
LServo PIN 12 ' Right Wheel
PIN_LED PIN 4 ' LED Pin
' Protocol Command
CMD_BREAK CON "b" ' abort recog or ping
CMD_SLEEP CON "s" ' go to power down
CMD_KNOB CON "k" ' set si knob <1>
CMD_LEVEL CON "v" ' set sd level <1>
CMD_LANGUAGE CON "l" ' set si language <1>
CMD_TIMEOUT CON "o" ' set timeout <1>
CMD_RECOG_SI CON "i" ' do si recog from ws <1>
CMD_RECOG_SD CON "d" ' do sd recog at group <1> (0 = trigger mixed si/sd)
' Protocol Status
STS_AWAKEN CON "w" ' back from power down mode
STS_ERROR CON "e" ' signal error code <1-2>
STS_INVALID CON "v" ' invalid command or argument
STS_TIMEOUT CON "t" ' timeout expired
STS_INTERR CON "i" ' back from aborted recognition (see 'break')
STS_SUCCESS CON "o" ' no errors status
STS_RESULT CON "r" ' recognised sd command <1> - training similar to sd <1>
STS_SIMILAR CON "s" ' recognised si <1> (in mixed si/sd) - training similar to si <1>
' Protocol arguments are in the range 0x40 (-1) TO 0x60 (+31) inclusive
ARG_MIN CON 64 ' 0x40
ARG_MAX CON 96 ' 0x60
ARG_ZERO CON 65 ' 0x41
ARG_ACK CON 32 ' 0x20 'TO READ more status arguments
' Wordset
WST CON 0 ' wordset trigger
WS1 CON 1 ' Wordset 1 commands
WS2 CON 2 ' Wordset 2 actions
WS3 CON 3 ' Wordset 3 numbers
'Wordset Commands
WS1_Action CON 0
WS1_Move CON 1
WS1_Turn CON 2
WS1_Run CON 3
WS1_Look CON 4
WS1_Attack CON 5
WS1_Stop CON 6
WS1_Hello CON 7
WS2_Left CON 0
WS2_Right CON 1
WS2_Up CON 2
WS2_Down CON 3
WS2_Forward CON 4
WS2_Backward CON 5
WS3_Zero CON 0
WS3_One CON 1
WS3_Two CON 2
WS3_Three CON 3
WS3_Four CON 4
WS3_Five CON 5
WS3_Six CON 6
WS3_Seven CON 7
WS3_Eight CON 8
WS3_Nine CON 9
WS3_Ten CON 10
WS_Timeout CON 254
WS_Error CON 255
VAR_LANG DATA 0
VAR_KNOB DATA 2
VAR_LEVEL DATA 2
'Robot Constant
COMMAND_DURATION CON 2000
COMMAND_SPEED_HIGH CON 3
COMMAND_SPEED_LOW CON 1
'Global Variable
counter VAR Word
VRA VAR Byte
VRA1 VAR Byte
VRLED VAR Byte
WS VAR Byte
RXC VAR Byte
RXC_PREV VAR Byte
' Main Start
LOW VRLED
' AUTOMATIC SWITCHING MODALITY
MSG = $22
SEROUT COM_IN_TX, COM_SPEED, [MSG]
SERIN COM_IN_RX, COM_SPEED, 1000, MAIN_CONTROL, [MSG]
IF MSG <> $55 THEN GOTO MAIN_CONTROL
GOSUB VR_Wakeup
GOSUB VR_SetLanguage
SEROUT COM_IN_TX, COM_SPEED, [MSG]
GOTO PROGRAMMING
MAIN_CONTROL:
DEBUG CR, "ROBOT CONTROL"
DEBUG CR, "Wake Up Voice Module"
GOSUB VR_Wakeup
DEBUG CR, "Voice Module Waked up"
GOSUB VR_SetLanguage
'VRA1 = 255
VRA1 = 5
GOSUB VR_SetTimeout
'start with trigger
WS = WST
MAIN_LOOP:
LOW PIN_LED
DEBUG CR, "Wait for "
SELECT WS
CASE 0
DEBUG "Trigger"
CASE 1
DEBUG "WS1"
HIGH PIN_LED
CASE 2
DEBUG "WS2"
PAUSE 150
HIGH PIN_LED
CASE 3
DEBUG "WS3"
PAUSE 150
HIGH PIN_LED
ENDSELECT
'Wait for command
VRA1 = WS
GOSUB VR_Recognize
RXC = VRA1
LOW PIN_LED
IF RXC < WS_Timeout THEN
'Perform action and cycle
GOSUB ACTION
GOTO MAIN_LOOP
' Handle errors
ELSEIF RXC = WS_Timeout THEN
DEBUG CR, "Timeout"
ELSE'IF RXC = WS_Error THEN
DEBUG CR, "Error"
ENDIF
WS = WST
GOTO MAIN_LOOP
END
' Main END
ACTION:
SELECT WS
CASE WST
WS = WS1
IF RXC > 0 THEN
DEBUG CR, "Custom Trigger"
ENDIF
CASE WS1
RXC_PREV = RXC
WS = WST
SELECT RXC
CASE WS1_Move 'MOVE
DEBUG CR, "Move"
WS = WS2
CASE WS1_Turn 'TURN
DEBUG CR, "Turn"
WS = WS2
CASE WS1_Run 'RUN
DEBUG CR, "Run"
WS = WS2
'This command for testing numbers
CASE WS1_Action
DEBUG CR, "Action"
WS = WS3
'Following commands do nothing
CASE WS1_Look
DEBUG CR, "Look"
CASE WS1_Attack
DEBUG CR, "Attack"
CASE WS1_Hello
DEBUG CR, "Hello"
CASE WS1_Stop
DEBUG CR, "Stop"
CASE ELSE
DEBUG CR, "Invalid Command"
ENDSELECT
CASE WS2
SELECT RXC
CASE WS2_Left 'LEFT
DEBUG CR, "Left"
IF RXC_PREV = WS1_Move THEN ' MOVE
GOSUB TURN_LEFT
ELSEIF RXC_PREV = WS1_Turn THEN 'TURN
GOSUB SPIN_LEFT
ELSEIF RXC_PREV = WS1_Run THEN 'RUN
GOSUB TURN_LEFT
ENDIF
CASE WS2_Right 'RIGHT
DEBUG CR, "Right"
IF RXC_PREV = WS1_Move THEN 'MOVE
GOSUB TURN_RIGHT
ELSEIF RXC_PREV = WS1_Turn THEN 'TURN
GOSUB SPIN_RIGHT
ELSEIF RXC_PREV = WS1_Run THEN 'RUN
GOSUB TURN_RIGHT
ENDIF
CASE WS2_Forward 'FORWARD
DEBUG CR, "Forward"
IF RXC_PREV = WS1_Move THEN 'MOVE
GOSUB FORWARD
ELSEIF RXC_PREV = WS1_Run THEN 'RUN
GOSUB FORWARD
ENDIF
CASE WS2_Backward 'BACKWARD
DEBUG CR, "Backward"
IF RXC_PREV = WS1_Move THEN 'MOVE
GOSUB BACKWARD
ELSEIF RXC_PREV = WS1_Run THEN 'RUN
GOSUB BACKWARD
ENDIF
'Following commands do nothing
CASE WS2_Up 'UP
DEBUG CR, "Up"
CASE WS2_Down 'DOWN
DEBUG CR, "Down"
CASE ELSE
DEBUG CR, "Invalid Command"
ENDSELECT
WS = WST
CASE WS3
DEBUG CR, "Number ", DEC RXC
WS = WST
ENDSELECT
RETURN
' Wake up:
VR_Wakeup:
VRA = CMD_BREAK
SEROUT COM_TX, COM_SPEED, [VRA]
SERIN COM_RX, COM_SPEED, [VRA]
IF VRA <> STS_SUCCESS THEN GOTO VR_Wakeup
RETURN
' Inputs:
' VRA1 = language index (0 = english, ...)
VR_SetLanguage:
READ VAR_LANG, VRA1
VRA = CMD_LANGUAGE
SEROUT COM_TX, COM_SPEED, [VRA]
VRA1 = VRA1 + ARG_ZERO
SEROUT COM_TX, COM_SPEED, [VRA1]
VR_SetLanguage1:
SERIN COM_RX, COM_SPEED, 2000 ,VR_SetLanguage1, [VRA]
RETURN
' Inputs:
' VRA1 = timeout (in ms, 0=forever, 255=default)
VR_SetTimeout:
VRA = CMD_TIMEOUT
SEROUT COM_TX, COM_SPEED, [VRA]
VRA1 = VRA1 + ARG_ZERO
SEROUT COM_TX, COM_SPEED, [VRA1]
VR_SetTimeout1:
SERIN COM_RX, COM_SPEED, 2000 ,VR_SetTimeout1, [VRA]
RETURN
' Inputs:
' VRA1 = wordset (0=trigger)
' Ouputs:
' VRA1 = result (1-N=word, 254=timeout, 255=error)
' for trigger N>0 are custom words
VR_Recognize:
' START RECOG
IF VRA1 = 0 THEN
VRA = CMD_RECOG_SD
ELSE
VRA = CMD_RECOG_SI
ENDIF
SEROUT COM_TX, COM_SPEED, [VRA]
' SEND WS
VR_Recognize1:
VRA1 = VRA1 + ARG_ZERO
SEROUT COM_TX, COM_SPEED, [VRA1]
' wait for answer
SERIN COM_RX, COM_SPEED, [VRA]
IF VRA = STS_RESULT THEN
' send ack
VRA = ARG_ACK
SEROUT COM_TX, COM_SPEED, [VRA]
' wait for recognised command code
VR_Recognize2:
SERIN COM_RX, COM_SPEED, 1000, VR_Recognize2, [VRA1]
VRA1 = VRA1 - ARG_ZERO + 1
ELSEIF VRA = STS_SIMILAR THEN
' send ack
VRA = ARG_ACK
SEROUT COM_TX, COM_SPEED, [VRA]
' wait for recognised command code
VR_Recognize3:
SERIN COM_RX, COM_SPEED, 1000, VR_Recognize3, [VRA1]
VRA1 = VRA1 - ARG_ZERO
ELSEIF VRA = STS_TIMEOUT THEN
VRA1 = 254
'DEBUG CR, ? VRA
ELSE
VRA1 = 255
'DEBUG CR, ? VRA
ENDIF
RETURN
FORWARD:
'DEBUG CR, "Robot Forward"
HIGH 1
PAUSE 1000
LOW 1
PAUSE 1000
RETURN
BACKWARD:
'DEBUG CR, "Robot Backward"
HIGH 7
PAUSE 1000
LOW 7
PAUSE 1000
RETURN
SPIN_RIGHT:
'DEBUG CR, "Robot Spin right"
FOR counter = 1 TO 50
PULSOUT LServo, 1000
PULSOUT RServo, 1000
PAUSE 20
NEXT
RETURN
SPIN_LEFT:
'DEBUG CR, "Robot Spin left"
FOR counter = 1 TO 50
PULSOUT LServo, 500
PULSOUT RServo, 500
PAUSE 20
NEXT
RETURN
TURN_LEFT:
'DEBUG CR, "Robot Turn Left"
HIGH 5
PAUSE 1000
LOW 5
PAUSE 1000
RETURN
TURN_RIGHT:
'DEBUG CR, "Robot Turn Right"
HIGH 3
PAUSE 1000
LOW 3
PAUSE 1000
RETURN
PROGRAMMING:
'DEBUG CR, "VOICE PROGRAMMING"
' COM IN Parameters - PC serial port
COM_IN_RX CON 16 ' rx pin
COM_IN_TX CON 16 ' tx pin
' COM Parameters - Voice Module port
COM_OUT_RX CON COM_RX ' rx pin
COM_OUT_TX CON COM_TX ' tx pin
COM_TIMEOUT CON 5000
' Protocol Command
CMD_SEND CON 1 ' send request
CMD_SEND_RECEIVE CON 2 ' send and receive request
CMD_RECEIVE CON 3 ' receive request
CMD_LED CON 4 ' receive request
CMD_SET_LANG CON 5 ' receive request
CMD_GET_LANG CON 6 ' receive request
CODE_ERROR CON 48 ' 0x30
CODE_ACK CON 32 ' 0x20
MSG VAR Byte
LOW PIN_LED
PROGRAMMING_MAIN_LOOP:
' wait for a byte on input COM
SERIN COM_IN_RX, COM_SPEED, [MSG]
' send back Echo
SEROUT COM_IN_TX, COM_SPEED, [MSG]
SELECT MSG
CASE CMD_SEND ' send request
' wait for the byte to send
SERIN COM_IN_RX, COM_SPEED, COM_TIMEOUT, RX_ERROR, [MSG]
' send the byte to output COM
SEROUT COM_OUT_TX, COM_SPEED, [MSG]
' send back Echo
SEROUT COM_IN_TX, COM_SPEED, [MSG]
CASE CMD_SEND_RECEIVE ' send and receive request
' wait for the byte to send
SERIN COM_IN_RX, COM_SPEED, COM_TIMEOUT, RX_ERROR, [MSG]
' send back Echo
SEROUT COM_IN_TX, COM_SPEED, [MSG]
' light?
IF VRLED = 1 THEN HIGH PIN_LED
' send the byte to output COM
SEROUT COM_OUT_TX, COM_SPEED, [MSG]
' wait for a byte on output COM
SERIN COM_OUT_RX, COM_SPEED, [MSG]
' light?
IF VRLED = 1 THEN LOW PIN_LED
' send the byte to input COM
SEROUT COM_IN_TX, COM_SPEED, [MSG]
CASE CMD_RECEIVE ' receive request
MSG = CODE_ACK
' send a byte request to output COM
SEROUT COM_OUT_TX, COM_SPEED, [MSG]
' wait for a byte on output COM
SERIN COM_OUT_RX, COM_SPEED, COM_TIMEOUT, RX_ERROR, [MSG]
' send the byte to input COM
SEROUT COM_IN_TX, COM_SPEED, [MSG]
CASE CMD_LED ' LED request
' wait for the status byte
SERIN COM_IN_RX, COM_SPEED, COM_TIMEOUT, RX_ERROR, [MSG]
IF MSG = "0" THEN
'LED OFF
LOW PIN_LED
VRLED = 0
ELSE
'LED ON
'HIGH PIN_LED 'postpone to next cmd
VRLED = 1
ENDIF
' send back Echo
SEROUT COM_IN_TX, COM_SPEED, [MSG]
CASE CMD_SET_LANG ' set language on EEPROM
' wait for the byte to store
SERIN COM_IN_RX, COM_SPEED, COM_TIMEOUT, RX_ERROR, [MSG]
WRITE VAR_LANG, MSG
' send back Echo
SEROUT COM_IN_TX, COM_SPEED, [MSG]
CASE CMD_GET_LANG ' set language on EEPROM
' wait for the byte to store
READ VAR_LANG, MSG
' send back Echo
SEROUT COM_IN_TX, COM_SPEED, [MSG]
CASE ELSE
GOTO RX_ERROR
ENDSELECT
GOTO PROGRAMMING_MAIN_LOOP
RX_ERROR:
MSG = CODE_ERROR
SEROUT COM_IN_TX, COM_SPEED, [MSG]
GOTO PROGRAMMING_MAIN_LOOP

Comments
I even trained it up to wake up with "Computer".
The most recent code package is on the third page of the thread.
There are some issues you should be aware of with using the SayIt module... so consider building in manual control with a web interface using a PINK (now from NetBurner) or a Spinneret.
Have fun and feel free to ask any questions you can't figure out on this project.
Dave
basically.Hows the sx chip different?
I need to figure out what code to put in the "insert code here lines"in the code the GUI created.
I have 4 relay pins i want to make high or low depending on what you say.They are pins 1,3,5,7
I looked at that sx chip its way different
First, just in case, the BS2sx is not the same as the SX chip.., the Bs2sx is identical to the BS2 in the BoE except it has more memory.
Next, - and I'll provide more detail when I'm not on my iPod touch later - the code the SayIt Module (SIM) provides allows you to put basic if-then statements into the "code goes here" sections. The code I gave in my project is hairy, but if you look at only the slot 0 code, that's where the speech recognition section is. Look for the part of the code that looks like the SIM generated code you get.
The SIM generates the same general code every time, so there are large blocks of standard code that you can safely ignore (it needs to be in there, but you don't need to mess with it). Just look for the sections that refer to G0 and G1, etc. There, in the places where, in your generated code, it says "place your code here", you'll see I have mostly placed a set of calls to individual subroutines. You could just as easily replace one or more of those replaceable lines with a single command to make an output high or low.
When I'm on my regular system, I'll post a few simple examples using your generated code, and I think once you see it you'll get it right away (if you don't already) and you'll be making the thing do all sorts of cool stuff!
More soon,
Dave
VR_Action: DEBUG "got ", DEC VRCOMMAND SELECT VRGROUP CASE GROUP_0 SELECT VRCOMMAND CASE G0_COMPUTER PAUSE 0 '-- write your code here ENDSELECT CASE GROUP_1 SELECT VRCOMMAND CASE G1_KITCHEN PAUSE 0 '-- write your code here CASE G1_LIVINGROOM PAUSE 0 '-- write your code hereOK, the way you have your code written here, you need to change which VGROUP is selected based on the input command. So when you say COMPUTER to wake up the system, the code will automatically recognize that VRGROUP 0 has been selected. Therefore, in the code under the command "CASE GROUP_0" you can HIGH VRLED (assuming you have VRLED programmed in as to what pin it's on, in the constants/I/O definitions section of your code). But then you need to change which VRGROUP it is listening for in order for it to respond to any other command. In my code, I have, after the HIGH VRLED a command to a GOSUB that is incidental to this discussion (it chirps at me like the Star Trek computers do - an auditory acknowledgement that the command was recognized) and then - the important part - I switch the VRGROUP to be 1 now. Under VRGROUP_1 I have my commands for turning water on/off, etc. If you look at the code here under the section beginning with CASE GROUP_1, then skip a line down to where it says CASE G1_OUTSIDE_WATER_ON, you'll see that I set several variables (state, s1, and cmd), then I send it off with a GOSUB. In a simpler incarnation of this program, I could just as easily have set the pin that was controlling a light or relay to HIGH, and for CASE G1_OUTSIDE_WATER_OFF, I could then set that same pin LOW.
VR_Action: DEBUG DEC VRCOMMAND SELECT VRGROUP CASE GROUP_0 SELECT VRCOMMAND CASE G0_COMPUTER PAUSE 0 HIGH VRLED GOSUB Listen_Tone VRGROUP = 1 ENDSELECT CASE GROUP_1 SELECT VRCOMMAND CASE G1_OUTSIDE_WATER_ON PAUSE 0 state = 1 s1 = state cmd = 2 GOSUB Bank_Build CASE G1_OUTSIDE_WATER_OFF PAUSE 0 state = 0 s1 = state cmd = 2 GOSUB Bank_Build .......Now the way you have your code set up, you have a few levels to go through, which means when you say "COMPUTER", it will wake up and then switch VRGROUPS to GROUP_1 so it can listen for what room. Then, when it recognizes a G1 command (a room), it will then switch to VRGROUP_2 to listen for what device, and when it hears that, it will then switch to VRGROUP_3 to find out whether to turn that device on or off.However - while this makes logical sense, you should note that at each step of the way, you will also need to include code to set a few variables so the system will remember what has been selected at each, otherwise it will get to VRGROUP_3 and get the command to turn something on, but it won't remember what! :-) So set up a variable for which room (use a NIB as that will give you up to 16 selections), and another VAR NIB for devices, and then a VAR BIT for on/off.
Given that the SIM has some limitations, such as a maximum of 32 user-programmable commands, you may find it easier to make your commands larger blocks, so insteand of COMPUTER, KITCHEN, LIGHTS, ON, you can just have a wakeup command COMPUTER, and a single line "KITCHEN LIGHTS ON". Then you only need to switch code groups once, and then immediately include code under the KITCHEN_LIGHTS_ON code to activate the relay. A second command, KITCHEN_LIGHTS_OFF, would then immediately turn the relay off. This would eliminate some of the need for the housekeeping of tracking your choices along the way and having to "build" a command string in the code, and just allow you to speak the command quickly.
Let me know if I have been at all helpful here, or if I have just confused you more! :-)
Dave
Dave
Can i get some more detail on how to go about this part?Thanks
Adding these into the SayIt module code:
VR_Action: DEBUG "got ", DEC VRCOMMAND SELECT VRGROUP CASE GROUP_0 SELECT VRCOMMAND CASE G0_COMPUTER PAUSE 0 HIGH VRLED 'Optional if you have VRLED wired up and declared in your constants above VRGROUP = 1 ENDSELECT CASE GROUP_1 SELECT VRCOMMAND CASE G1_KITCHEN PAUSE 0 whatRoom = 1 CASE G1_LIVINGROOM PAUSE 0 whatRoom = 2 ... VRGROUP = 2 'this sends the SIM off to listen for what device now... ......So now you've developed a correspondence between rooms and your whatRoom variable, and at the end of that CASE statement, you change the listening bank to 2 (VRGROUP=2), to listen for the device to be activated/deactivated.
Then, do pretty much the same for whatDevice - for each CASE, stuff an instance of the variable whatDevice into that CASE's section, and set the variable equal to a number.
Then set your VRGROUP = 3 to listen for the state.
Finally, when you get to the ON/OFF section, when it hears ON, set the state variable = 1, and the OFF selection, state = 0.
Now you have at this point three variables, which are all destined for one relay (or more accurately, one pin on the BS2. You need to know what pin controls the relay in question, and set up a little SELECT/CASE statement yourself for each relay ) or an IF/THEN that basically says
IF whatRoom = 1 and whatDevice = 2, then relayX = state
You can also set up your relays in the constants/variables declaration at the top where you set up your whatRoom and whatDevice and state variables, for example:
relayA PIN 7
relayB PIN 8
relayX PIN 9
etc...
Setting relayX to state when state = 1 will make that output HIGH, and assuming you have something attached properly to that pin (an LED for testing (via a 470 ohm resistor) or a relay with a transistor driver (2N2222A is good) and a good diode clamp so you don't spike said transistor), you will get a state activation.
Once you have accomplished your activation/deactivation, you should then set all of your variables back to 0 and return to the SIM's listen loop. I like to use subroutines, so I would probably send the program out of the listening-loop once I had built my variable string, to a gosub to actually do the activation/deactivation, then return to the listening loop for the SIM.
I've described the code here for you as you've implemented it, where you build the info a piece at a time, but I do want to remind you that if you timeout at any point, you have to start from scratch again. This is another reason why I went with full commands as single units, rather than pieces. COMPUTER, OUTSIDE-WATER-ON, as opposed to COMPUTER, OUTSIDE, WATER, ON. The speech recognition (SR) on these things is good, but not infallable. They are subject to background noise and sometimes they just hiccup for no apparent reason and get an error, and you'll be trying to tell it LIGHTS but it's no longer listening in the proper bank. This is also why it's a good idea to provide a visual/auditory feedback in the form of a light/sound so you know IF the thing is listening to you at all. I'd recommend you think about trying a few solid commands in the form of
COMPUTER, "KITCHEN LIGHT ON"
COMPUTER, "LIVING ROOM LIGHT OFF"
Keeping in mind that, again, you can only have 32 TOTAL user-defined commands programmed in.
Let me know if this has been helpful.
Dave
Dave
' {$STAMP BS2} ' {$PBASIC 2.5} ' COM Parameters COM_RX PIN 0 ' rx pin COM_TX PIN 2 ' tx pin COM_SPEED CON 84 ' baud 9600 COM_10MS CON 10 ' 10ms unit ' Protocol Command CMD_BREAK CON "b" ' abort recog or ping CMD_SLEEP CON "s" ' go to power down CMD_KNOB CON "k" ' set si knob <1> CMD_LEVEL CON "v" ' set sd level <1> CMD_LANGUAGE CON "l" ' set si language <1> CMD_TIMEOUT CON "o" ' set timeout <1> CMD_RECOG_SI CON "i" ' do si recog from ws <1> CMD_RECOG_SD CON "d" ' do sd recog at group <1> (0 = trigger mixed si/sd) ' Protocol Status STS_AWAKEN CON "w" ' back from power down mode STS_ERROR CON "e" ' signal error code <1-2> STS_INVALID CON "v" ' invalid command or argument STS_TIMEOUT CON "t" ' timeout expired STS_INTERR CON "i" ' back from aborted recognition (see 'break') STS_SUCCESS CON "o" ' no errors status STS_RESULT CON "r" ' recognised sd command <1> - training similar to sd <1> STS_SIMILAR CON "s" ' recognised si <1> (in mixed si/sd) - training similar to si <1> ' Protocol arguments are in the range 0x40 (-1) TO 0x60 (+31) inclusive ARG_MIN CON 64 ' 0x40 ARG_MAX CON 96 ' 0x60 ARG_ZERO CON 65 ' 0x41 ARG_ACK CON 32 ' 0x20 'TO READ more status arguments 'Groups and Commands GROUP_0 CON 0 '(Command count: 1) G0_COMPUTER CON 0 GROUP_1 CON 1 '(Command count: 4) G1_KITCHEN CON 0 G1_LIVINGROOM CON 1 G1_MASTERBEDROOM CON 2 G1_OFFICE CON 3 GROUP_2 CON 2 '(Command count: 1) G2_LIGHTS CON 0 GROUP_3 CON 3 '(Command count: 2) G3_ON CON 0 G3_OFF CON 1 RES_ERROR CON 255 RES_TIMEOUT CON 254 RES_COMMFAIL CON 253 RES_BUILTIN CON 32 'Robot Constant VRLED PIN 4 'Global Variable VRA VAR Byte VRA1 VAR Byte VRGROUP VAR Byte VRCOMMAND VAR Byte whatRoom VAR Nib whatDevice VAR Nib state VAR Bit ' Main Start INPUT COM_RX HIGH COM_TX Restart: LOW VRLED VRGROUP = 0 DEBUG CR, "Setting up VRbot... " 'Wake up or stop recognition GOSUB VR_Wakeup DEBUG "awake... " 'Set SI Language VRA1 = 0 GOSUB VR_SetLanguage DEBUG "language ", DEC VRA1, "... " 'Set 5 seconds timeout VRA1 = 5 GOSUB VR_SetTimeout DEBUG "timeout ", DEC VRA1, "... " DEBUG CR, "VRbot ready!" VR_Loop: DEBUG CR, "VRbot in group ", DEC VRGROUP, " waiting for command... " LOW VRLED PAUSE 150 IF VRGROUP > 0 THEN HIGH VRLED VRA1 = VRGROUP GOSUB VR_RecognizeSD '-- handle errors or timeout IF VRA1 = RES_ERROR THEN DEBUG "error" 'try again in the same group GOTO VR_Loop ENDIF IF VRA1 = RES_TIMEOUT THEN DEBUG "timed out" VRGROUP = 0 ' back to trigger GOTO VR_Loop ENDIF IF VRA1 = RES_COMMFAIL THEN DEBUG "comm failed" 'resync and try again GOSUB VR_Wakeup GOTO VR_Loop ENDIF '-- got a command VRCOMMAND = VRA1 IF VRCOMMAND <= RES_BUILTIN THEN GOSUB VR_Action GOTO VR_Loop VR_Action: DEBUG "got ", DEC VRCOMMAND SELECT VRGROUP CASE GROUP_0 SELECT VRCOMMAND CASE G0_COMPUTER PAUSE 0 '-- write your code here HIGH VRLED VRGROUP = 1 ENDSELECT CASE GROUP_1 SELECT VRCOMMAND CASE G1_KITCHEN PAUSE 0 '-- write your code here whatRoom = 1 HIGH VRLED VRGROUP = 2 CASE G1_LIVINGROOM PAUSE 0 '-- write your code here whatRoom = 2 HIGH VRLED VRGROUP = 2 CASE G1_MASTERBEDROOM PAUSE 0 '-- write your code here whatRoom = 3 HIGH VRLED VRGROUP = 2 CASE G1_OFFICE PAUSE 0 '-- write your code here whatroom = 4 HIGH VRLED VRGROUP = 2 ENDSELECT CASE GROUP_2 SELECT VRCOMMAND CASE G2_LIGHTS PAUSE 0 '-- write your code here whatDevice = 1 HIGH VRLED VRGROUP = 3 ENDSELECT CASE GROUP_3 SELECT VRCOMMAND CASE G3_ON PAUSE 0 '-- write your code here state = 1 HIGH VRLED VRGROUP = 0 CASE G3_OFF PAUSE 0 '-- write your code here state = 0 HIGH VRLED VRGROUP = 0 ENDSELECT IF whatRoom = 1 AND whatDevice = 1 AND state = 1 THEN HIGH 1 IF whatRoom = 1 AND whatDevice = 1 AND state = 0 THEN LOW 1 IF whatRoom = 2 AND whatDevice = 1 AND state = 1 THEN HIGH 3 IF whatRoom = 2 AND whatDevice = 1 AND state = 0 THEN LOW 3 IF whatRoom = 3 AND whatDevice = 1 AND state = 1 THEN HIGH 5 IF whatRoom = 3 AND whatDevice = 1 AND state = 0 THEN LOW 5 IF whatRoom = 4 AND whatDevice = 1 AND state = 1 THEN HIGH 7 IF whatRoom = 4 AND whatDevice = 1 AND state = 0 THEN LOW 7 ENDSELECT RETURN '=== VR Routines === ' Wake up: VR_Wakeup: TOGGLE VRLED VRA = CMD_BREAK SEROUT COM_TX, COM_SPEED, [VRA] SERIN COM_RX, COM_SPEED, 100*COM_10MS, VR_Wakeup, [VRA] IF (VRA <> STS_SUCCESS) THEN GOTO VR_Wakeup LOW VRLED RETURN ' Inputs: ' VRA1 = language index (0 = english, ...) VR_SetLanguage: VRA = CMD_LANGUAGE SEROUT COM_TX, COM_SPEED, [VRA] VRA1 = VRA1 + ARG_ZERO SEROUT COM_TX, COM_SPEED, [VRA1] SERIN COM_RX, COM_SPEED, 20*COM_10MS, VR_CommFailed, [VRA] VRA1 = VRA1 - ARG_ZERO 'IF (VRA <> STS_SUCCESS) THEN GOTO VR_Wakeup RETURN ' Inputs: ' VRA1 = timeout (in ms, 0=forever, 255=default) VR_SetTimeout: VRA = CMD_TIMEOUT SEROUT COM_TX, COM_SPEED, [VRA] VRA1 = VRA1 + ARG_ZERO SEROUT COM_TX, COM_SPEED, [VRA1] SERIN COM_RX, COM_SPEED, 20*COM_10MS, VR_CommFailed, [VRA] VRA1 = VRA1 - ARG_ZERO 'IF (VRA <> STS_SUCCESS) THEN GOTO VR_Wakeup RETURN ' Inputs: ' VRA1 = SI knob (0=loosest, 2=normal, 4=tightest) VR_SetKnob: VRA = CMD_KNOB SEROUT COM_TX, COM_SPEED, [VRA] VRA1 = VRA1 + ARG_ZERO SEROUT COM_TX, COM_SPEED, [VRA1] SERIN COM_RX, COM_SPEED, 20*COM_10MS, VR_CommFailed, [VRA] VRA1 = VRA1 - ARG_ZERO 'IF (VRA <> STS_SUCCESS) THEN GOTO VR_Wakeup RETURN ' Inputs: ' VRA1 = SD level (1=easy, 2=default, 5=hard) VR_SetLevel: VRA = CMD_LEVEL SEROUT COM_TX, COM_SPEED, [VRA] VRA1 = VRA1 + ARG_ZERO SEROUT COM_TX, COM_SPEED, [VRA1] SERIN COM_RX, COM_SPEED, 20*COM_10MS, VR_CommFailed, [VRA] VRA1 = VRA1 - ARG_ZERO 'IF (VRA <> STS_SUCCESS) THEN GOTO VR_Wakeup RETURN ' Inputs: ' VRA1 = wordset (0=trigger) ' Ouputs: ' VRA1 = result (0-31=word, 32..=builtin, 253=comm err, 254=timeout, 255=error) VR_RecognizeSI: VRA = CMD_RECOG_SI GOTO VR_Recognize0 VR_RecognizeSD: VRA = CMD_RECOG_SD VR_Recognize0: SEROUT COM_TX, COM_SPEED, [VRA] ' send Group/WS VRA1 = VRA1 + ARG_ZERO SEROUT COM_TX, COM_SPEED, [VRA1] ' wait for answer SERIN COM_RX, COM_SPEED, 600*COM_10MS, VR_CommFailed, [VRA] IF VRA = STS_RESULT THEN ' send ack VRA = ARG_ACK SEROUT COM_TX, COM_SPEED, [VRA] ' wait for recognised command code SERIN COM_RX, COM_SPEED, 20*COM_10MS, VR_CommFailed, [VRA1] VRA1 = VRA1 - ARG_ZERO ELSEIF VRA = STS_SIMILAR THEN ' send ack VRA = ARG_ACK SEROUT COM_TX, COM_SPEED, [VRA] ' wait for recognised command code SERIN COM_RX, COM_SPEED, 20*COM_10MS, VR_CommFailed, [VRA1] VRA1 = VRA1 - ARG_ZERO + RES_BUILTIN ELSEIF VRA = STS_TIMEOUT THEN VRA1 = RES_TIMEOUT ELSE VRA1 = RES_ERROR ENDIF RETURN VR_CommFailed: VRA1 = RES_COMMFAIL RETURNI'll have to look through more in depth, but I'd say that if the LEDs all go off when they should all be on, there's a line somewhere that is setting the state = 0 and running the if/then lines. This is another reason why I use gosubs to avoid code running inline.
I'm packing for some travelling so I will look more in depth when I next have the time, but likely you'll have already figured it out by then.
The V-Stamp is even easier to use than the SIM. No programming/training required. Just three pins on the Basic Stamp, and a SEROUT line that contains a few setup parameters to adjust the voice style, and you're good to go. SEROUT a line with a few CRs in them and the text you want spoken in quotes and voila! It is spoken! Can't get much easier. The voice quality is quite good as well. At $75 a pop, they aren't cheap, but for what it saves in time and hassles - I have three of them!
Dave
its working mostly except when you got 4,5,6 relays on at once then the leds increasingly die out?
By the way - nice touch with the TNG sound effects! I add them (or a close approximation) to any project I can! :-)
nope further testing revealed the problem is still here.I suspect that the rest of parts are drawing to much power.