'{$STAMP BS2} 'This program captures and processes 7-segment LED data from the Zoom Micro Rhythym Trak 'MRT-3 Drum synthesizer by Zoom Corp. It then sends the 4-character LED display contents 'to a Walk 'n Talk Speech Synthesizer to allow users who are blind to "hear" the LED 'display spoken. 'This program is written in PBASIC2 for use with the BASIC Stamp II microprocessor module 'made by Parallax, Inc. The BASIC Stamp II is connected to a custom designed interface 'circuit which allows direct connection to the 7-segment LED display on the Zoom MRT-3 unit. 'Software Author & Hardware Designer: 'Wayne D. Thompson, P.E. 'Kentucky Department for the Blind 'Research & Development Unit 'P.O.Box 757 'Frankfort, KY 40601 '800-321-6668 'Initial Release Date: 'Version 1.0, September 30, 2004 'Revision History: 'Declare variables x VAR Nib 'misc temp counter variable temp1 VAR Byte 'most recently read 4 display chars (7-seg, then ASCII) temp2 VAR Byte temp3 VAR Byte temp4 VAR Byte temp1old VAR Byte 'previously read 4 display chars temp2old VAR Byte temp3old VAR Byte temp4old VAR Byte char1 VAR Byte 'previous valid 4 display chars (ASCII) char2 VAR Byte char3 VAR Byte char4 VAR Byte sega VAR Byte 'segment data read from LED display on Zoom unit segb VAR Byte segc VAR Byte segd VAR Byte sege VAR Byte segf VAR Byte segg VAR Byte segx VAR Byte sp1 VAR Bit '4 individual LED indicators on the Zoom unit sp2 VAR Bit 'that may need to be captured in the future sp3 VAR Bit sp4 VAR Bit manualspk VAR Bit 'manual speak, 0=speech requested (button pressed) autospk VAR Bit 'auto-speak on/off state, 0=off, 1=on addr VAR Word 'ASCII table pointer val VAR Byte 'ASCII table value 'Lookup table to convert from 7-segment data to ASCII table01 DATA %00000000," " 'space table02 DATA %00000110,"1" '1 table03 DATA %01011011,"2" '2 table04 DATA %01001111,"3" '3 table05 DATA %01100110,"4" '4 table06 DATA %01101101,"5" '5 table07 DATA %01111101,"6" '6 table08 DATA %00100111,"7" '7 table09 DATA %01111111,"8" '8 table10 DATA %01101111,"9" '9 table11 DATA %00111111,"0" '0 table12 DATA %01110111,"a" 'A table12a DATA %01011111,"a" 'a (a different LED pattern for lower case a) table13 DATA %00111000,"l" 'L table14 DATA %00111001,"c" 'C table15 DATA %01011100,"o" 'o table16 DATA %01110011,"p" 'P table17 DATA %01101110,"y" 'y table18 DATA %01011110,"d" 'd table19 DATA %01111001,"e" 'E table20 DATA %00110111,"m" 'M table21 DATA %01110001,"f" 'F table22 DATA %00011100,"u" 'u table23 DATA %01111000,"t" 't table24 DATA %01010000,"r" 'r table25 DATA %01101101,"s" 'S table26 DATA %01110110,"h" 'H table27 DATA %01010100,"n" 'n table28 DATA %00111110,"u" 'U table29 DATA %01000000,"-" '- table30 DATA %01111100,"b" 'b table99 DATA %11111111 'end of table marker 'Initialize all I/O ports on BASIC Stamp II DIRS=%1111111100000000 'set I/O pins direction INPUT 0 'segment data from LED char 1 INPUT 1 'segment data from LED char 2 INPUT 2 'segment data from LED char 3 INPUT 3 'segment data from LED char 4 INPUT 4 'spare INPUT 5 'spare INPUT 6 'auto speak on/off switch INPUT 7 'manual speak pushbutton OUTPUT 8 '3-bit segment select address (low bit) OUTPUT 9 '3-bit segment select address (middle bit) OUTPUT 10 '3-bit segment select address (high bit) OUTPUT 11 'spare OUTPUT 12 'spare OUTPUT 13 'spare OUTPUT 14 'spare OUTPUT 15 'serial text out to speech synthesizer 'Initialize Walk 'n Talk Speech Synthesizer PAUSE 2000 'wait until speech ckt is powered up SEROUT 15,84,[1,"1B",13] 'set speech punctuation level to "Most/Digits" SEROUT 15,84,[1,"16C",13] 'set speech to Character Mode SEROUT 15,84,[1,"2S",13] 'set speaking speed '---------------------------- 'Main program loop starts here start: GOSUB capture 'capture 7-segment data from Zoom unit GOSUB makechars 'assemble segment bits into 4 characters GOSUB changed 'speak display if chars changed since last reading GOTO start 'continue to monitor display for more changes 'End of main program loop '-------------------------------- '-------------------------------- 'Subroutines follow '-------------------------------- '--------------------------- 'Subroutine to capture 7-segment data from all four LED characters 'Read then store the segment bits in 8 "seg" variables and assemble the latest reading 'of the four LED characters into 4 "temp" variables as 7-segment data. capture: 'init temp1=0 'prepare to create 4 chars of 7-segment data temp2=0 temp3=0 temp4=0 'get a segments OUTC=0 : x=0 'set address to select segment a PAUSE 40 'delay 40 msec so 4528 chips have time to respond sega=INL 'read the segment data 'DEBUG x+48," ",BIN4 sega,CR temp1.BIT0 = sega.BIT0 'store segment of LED char position 1 (leftmost) temp2.BIT0 = sega.BIT1 'store segment of LED char position 2 temp3.BIT0 = sega.BIT2 'store segment of LED char position 3 temp4.BIT0 = sega.BIT3 'store segment of LED char position 4 (rightmost) manualspk=sega.BIT7 'update current manual speak pushbutton status autospk=sega.BIT6 'update current auto speak switch status GOSUB spkrequest 'check for user speak request 'get b segments OUTC=1 : x=1 'now address, read, and store segment b, etc..... PAUSE 40 segb=INL 'DEBUG x+48," ",BIN4 segb,CR temp1.BIT1 = segb.BIT0 temp2.BIT1 = segb.BIT1 temp3.BIT1 = segb.BIT2 temp4.BIT1 = segb.BIT3 manualspk=segb.BIT7 autospk=segb.BIT6 GOSUB spkrequest 'get c segments OUTC=2 : x=2 PAUSE 40 segc=INL 'DEBUG x+48," ",BIN4 segc,CR temp1.BIT2 = segc.BIT0 temp2.BIT2 = segc.BIT1 temp3.BIT2 = segc.BIT2 temp4.BIT2 = segc.BIT3 manualspk=segc.BIT7 autospk=segc.BIT6 GOSUB spkrequest 'get d segments OUTC=3 : x=3 PAUSE 40 segd=INL 'DEBUG x+48," ",BIN4 segd,CR temp1.BIT3 = segd.BIT0 temp2.BIT3 = segd.BIT1 temp3.BIT3 = segd.BIT2 temp4.BIT3 = segd.BIT3 manualspk=segd.BIT7 autospk=segd.BIT6 GOSUB spkrequest 'get e segments OUTC=4 : x=4 PAUSE 40 sege=INL 'DEBUG x+48," ",BIN4 sege,CR temp1.BIT4 = sege.BIT0 temp2.BIT4 = sege.BIT1 temp3.BIT4 = sege.BIT2 temp4.BIT4 = sege.BIT3 manualspk=sege.BIT7 autospk=sege.BIT6 GOSUB spkrequest 'get f segments OUTC=5 : x=5 PAUSE 40 segf=INL 'DEBUG x+48," ",BIN4 segf,CR temp1.BIT5 = segf.BIT0 temp2.BIT5 = segf.BIT1 temp3.BIT5 = segf.BIT2 temp4.BIT5 = segf.BIT3 manualspk=segf.BIT7 autospk=segf.BIT6 GOSUB spkrequest 'get g segments OUTC=6 : x=6 PAUSE 40 segg=INL 'DEBUG x+48," ",BIN4 segg,CR temp1.BIT6 = segg.BIT0 temp2.BIT6 = segg.BIT1 temp3.BIT6 = segg.BIT2 temp4.BIT6 = segg.BIT3 manualspk=segg.BIT7 autospk=segg.BIT6 GOSUB spkrequest 'get special LED indicators (Code remed out for now until needed in the future) 'These are not LED char segments, but rather up to four other misc single LED 'indicators that need to be captured. 'OUTC=7 : x=7 'PAUSE 40 'segx=INL 'DEBUG x+48," ",BIN4 segx,CR 'DEBUG BIN1 ? manualspk, BIN1 ? autospk, CR 'temp1.BIT7 = segx.BIT0 'temp2.BIT7 = segx.BIT1 'temp3.BIT7 = segx.BIT2 'temp4.BIT7 = segx.BIT3 'sp1=segx.BIT0 'sp2=segx.BIT1 'sp3=segx.BIT2 'sp4=segx.BIT3 'manualspk=segx.BIT7 'autospk=segx.BIT6 'GOSUB spkrequest 'DEBUG BIN8 temp1, CR, BIN8 temp2, CR, BIN8 temp3, CR, BIN8 temp4, CR RETURN '--------------------------- 'Subroutine to process the latest captured 7-segment data into ASCII characters makechars: 'Convert the four 7-segment formatted bytes temp1-temp4 to ASCII bytes. 'Look in table for ASCII code for 7-segment character 1 findchar1: addr=table01 'set address to start of ASCII table keeplooking1: READ addr,val 'get a byte from table IF val=$FF THEN abort1 'abort if at end of table IF val<>temp1 THEN chknext1 'check next table entry if 7-seg does not match addr=addr+1 'it matches, inc pointer to get ASCII equiv READ addr,temp1 'store ASCII equiv GOTO findchar2 'go get ASCII code for char 2 chknext1: 'inc pointer and keep looking addr=addr+2 GOTO keeplooking1 abort1: temp1=" " 'no lookup value found, load space char 'Look in table for ASCII code for 7-segment character 2 findchar2: addr=table01 'set address to start of ASCII table keeplooking2: READ addr,val 'get a byte from table IF val=$FF THEN abort2 'abort if at end of table IF val<>temp2 THEN chknext2 'check next table entry if 7-seg does not match addr=addr+1 'it matches, inc pointer to get ASCII equiv READ addr,temp2 'store ASCII equiv GOTO findchar3 'go get ASCII code for char 3 chknext2: 'inc pointer and keep looking addr=addr+2 GOTO keeplooking2 abort2: temp2=" " 'no lookup value found, load space char 'Look in table for ASCII code for 7-segment character 3 findchar3: addr=table01 'set address to start of ASCII table keeplooking3: READ addr,val 'get a byte from table IF val=$FF THEN abort3 'abort if at end of table IF val<>temp3 THEN chknext3 'check next table entry if 7-seg does not match addr=addr+1 'it matches, inc pointer to get ASCII equiv READ addr,temp3 'store ASCII equiv GOTO findchar4 'go get ASCII code for char 4 chknext3: 'inc pointer and keep looking addr=addr+2 GOTO keeplooking3 abort3: temp3=" " 'no lookup value found, load space char 'Look in table for ASCII code for 7-segment character 4 findchar4: addr=table01 'set address to start of ASCII table keeplooking4: READ addr,val 'get a byte from table IF val=$FF THEN abort4 'abort if at end of table IF val<>temp4 THEN chknext4 'check next table entry if 7-seg does not match addr=addr+1 'it matches, inc pointer to get ASCII equiv READ addr,temp4 'store ASCII equiv GOTO nomorechars 'finished with all 4 chars chknext4: 'inc pointer and keep looking addr=addr+2 GOTO keeplooking4 abort4: temp4=" " 'no lookup value found, load space char nomorechars: DEBUG temp1,temp2,temp3,temp4,CR 'echo characters captured to debug window RETURN '------------------------ 'Subroutine to see if LED display has changed since last reading changed: IF temp1 <> char1 THEN changedyes 'display changed since last valid reading? IF temp2 <> char2 THEN changedyes IF temp3 <> char3 THEN changedyes IF temp4 <> char4 THEN changedyes RETURN 'no, return changedyes: temp1old = temp1 'temporarilly save this reading temp2old = temp2 temp3old = temp3 temp4old = temp4 GOSUB capture 'read the display again to see if it is stable GOSUB makechars IF temp1 <> temp1old THEN nospeak 'return if display not stable IF temp2 <> temp2old THEN nospeak IF temp3 <> temp3old THEN nospeak IF temp4 <> temp4old THEN nospeak char1 = temp1 'display is stable & we have a valid new reading; store it char2 = temp2 char3 = temp3 char4 = temp4 IF autospk = 0 THEN nospeak 'speak only if autospeak switch is on GOSUB speak 'speak it nospeak: RETURN '-------------------------- 'Subroutine to speak the LED display contents previously captured speak: SEROUT 15,84,[char1,char2,char3,char4,13] 'send chars to speech synthesizer DEBUG "Speaking -- ",char1,char2,char3,char4,CR 'echo spoken characters to debug window RETURN '-------------------------- 'Subroutine to check for user "speak request" button press and process it spkrequest: IF manualspk=0 THEN spkrequest2 RETURN spkrequest2: GOSUB speak PAUSE 500 'pause 1/2 sec to allow user time to release pushbutton RETURN 'to prevent a second unintended speak request 'End of all code for the Zoom Micro Rhythym Trak MRT-3 Drum Synthesizer