/ TalkieTrellis / TalkieTrellis.ino
TalkieTrellis.ino
1 // SPDX-FileCopyrightText: 2019 Phillip Burgess for Adafruit Industries 2 // 3 // SPDX-License-Identifier: MIT 4 5 // Speak & Spell sound board for the Adafruit NeoTrellis M4. 6 // Requires the following libraries, install with Arduino Library Manager: 7 // - Adafruit_NeoTrellisM4 8 // - Adafruit_Keypad 9 // - Adafruit_NeoPixel 10 // Also requires the Adafruit fork of the Talkie library, install manually: 11 // - https://github.com/adafruit/Talkie 12 // 13 // Connect headphones or speaker to the Trellis audio output. 14 // Tap buttons to hear letters, numbers, words and phrases. Hold one of the 15 // bottom row buttons to enable one of eight sets of 31 sounds (plus the 24 16 // sounds when no bottom-row button is held). 17 // What you're hearing are not simply WAV files. Instead, the Talkie library 18 // emulates the TMS5100 speech chip used in the original Speak & Spell. 19 // File words.h contains a selection of speech data exactly as it was stored 20 // in the original ROM in a highly-compressed lossy format called LPC-10. 21 22 #include <Adafruit_NeoTrellisM4.h> 23 #include <talkie.h> 24 #include "words.h" 25 26 Adafruit_NeoTrellisM4 trellis; 27 Talkie voice; 28 29 // These tables assign sounds to each button. These are just pointers to 30 // sound data in the file words.h, or NULL where no sound is assigned. 31 // There are 9 goups of 32 buttons, the first is with none of the 8 32 // bottom-row "shift" buttons held, the other 8 groups are for each of 33 // the 8 shifted states. 34 const uint8_t *sound[9][32] = { 35 { sp0 , sp1 , sp2 , sp3 , sp4 , sp5 , sp6 , sp7 , 36 sp8 , sp9 , spTEN, spABOVE, spACHIEVE, spAGAINST, spALMOST, spALREADY, 37 spANCIENT, spANOTHER, spANSWER, spANYTHING, spAPPROVE, spBEAUTY, spBELIEVE, spBOULDER, 38 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, // "Shift" keys, leave this row NULL 39 { spBROTHER, spBUILT, spBULLET, spBULLETIN, spBUREAU, spBUSHEL, spBUSINESS, spCARAVAN, 40 spCARRY, spCHALK, spCHILD, spCIRCUIT, spCLEANSER, spCOLOR, spCOMFORT, spCOMING, 41 spCONQUER, spCORRECT, spCOULDNT, spCOUNTRY, spCOUPLE, spCOURAGE, spCOUSIN, spDISCOVER, 42 NULL, spDOES, spDOZEN, spDUNGEON, spEARLY, spEARNEST, spEARTH, spECHO }, 43 { spEGG, spENOUGH, spERROR, spEVERY, spEVERYONE, spEXTRA, spEYEBROW, spFEATHER, 44 spFIELD, spFINGER, spFIRED, spFLOOD, spFLOOR, spFREIGHT, spFRONT, spGARAGE, 45 spGLACIER, spGLOVE, spGREATER, spGUARD, spGUESS, spGUIDE, spHALF, spHASTE, 46 spHEALTH, NULL, spHEALTHY, spHEAVY, spHEROES, spHONEY, spHONOR, spHOSTESS }, 47 { spHYGIENE, spIMPROVE, spINSTEAD, spIRON, spIS, spISLAND, spISLE, spJOURNEY, 48 spKEY, spLANGUAGE, spLAUGH, spLAUGHTER, spLEARN, spLEATHER, spLEISURE, spLETTUCE, 49 spLIBRARY, spLINGER, spLOSE, spMACHINE, spMEADOW, spMEANING, spMEASURE, spMECHANIC, 50 spMILD, spMINUTE, NULL, spMIRROR, spMISTAKE, spMONEY, spMOSQUITO, spMOST }, 51 { spMOTHER, spMOVIE, spMUSTACHE, spNARROW, spNEIGHBOR, spNUISANCE, spOCEAN, spONCE, 52 spONION, spOTHER, spOUTDOOR, spOVEN, spPERIOD, spPIANOS, spPIERCE, spPINT, 53 spPLAGUE, spPLEASANT, spPLEASURE, spPLUNGER, spPLURAL, spPOSTAGE, spPOULTRY, spPRETTY, 54 spPROMISE, spPULL, spPUSH, NULL, spQUESTION, spQUIET, spQUOTIENT, spRANGE }, 55 { spRANGER, spREADY, spREINDEER, spRELIEF, spRELIEVE, spREMOVE, spRHYTHM, spROCK, 56 spRURAL, spSAYS, spSCHEDULE, spSCHOOL, spSCISSORS, spSEARCH, spSERIOUS, spSHIELD, 57 spSHOULD, spSHOULDER, spSHOVEL, spSIGN, spSKI, spSOMEONE, spSOMETIME, spSOURCE, 58 spSPELL, spSPONGE, spSPREAD, spSQUAD, NULL, spSQUASH, spSQUAT, spSTATUE }, 59 { spSTOMACH, spSTRANGER, spSUGAR, spSURE, spSURGEON, spSWAMP, spSWAN, spSWAP, 60 spSWEAT, spSWEATER, spTALK, spTODAY, spTOMORROW, spTON, spTONGUE, spTOUCH, 61 spTOUGH, spTOWARD, spTREASURE, spTRY, spUNCOVER, spUNION, spUSUAL, spVIEW, 62 spWALK, spWARM, spWAS, spWASH, spWATCH, NULL, spWATER, spWEALTH }, 63 { spWEIRD, spWELCOME, spWILD, spWOLVES, spWOMAN, spWONDER, spWORD, spWORLD, 64 spWORTH, spWRONG, spYIELD, spYOLK, spYOUNG, spYOURSELF, spZEROS, spHERE_IS_YOUR_SCORE, 65 spI_WIN, spNEXT_SPELL, spNOW_SPELL, spNOW_TRY, spPERFECT_SCORE, spSAY_IT, spTHAT_IS_CORRECT, spTHAT_IS_INCORRECT, 66 spTHAT_IS_RIGHT, spTHE_CORRECT_SPELLING_OF, spTO_WED, spTRY_AGAIN, spYOU_ARE_CORRECT, spYOU_ARE_RIGHT, NULL, spYOU_WIN }, 67 { spA , spB , spC , spD , spE , spF , spG , spH , 68 spI , spJ , spK , spL , spM , spN , spO , spP , 69 spQ , spR , spS , spT , spU , spV , spW , spX , 70 spY , spZ , spAPOSTROPHE , spBEEPS_1 , spBEEPS_2 , spBEEPS_3 , spBEEPS_4, NULL } }; 71 72 uint8_t shiftmode = 0; // Which of 8 shift buttons is held (0 = none) 73 74 // Lights the bottom-most row of buttons in the "ready for input" pattern 75 void idle(void) { 76 trellis.fill(0); 77 for(int i=0; i<8; i++) { 78 trellis.setPixelColor(24 + i, trellis.ColorHSV(i * 65536 / 8, 255, 6)); 79 } 80 } 81 82 // SETUP FUNCTION - RUNS ONCE AT STARTUP *********************************** 83 84 void setup() { 85 trellis.begin(); 86 87 // You MUST call this function before issuing Speak & Spell data to the 88 // Talkie library. By default, that library emulates the TMS5220, a later 89 // speech chip (used in the TI-99/4A and others) that uses a slightly 90 // different data format. This puts it in TMS5100-compatible mode: 91 voice.mode(TALKIE_TMS5100); 92 93 idle(); // Light Trellis buttons in the "ready for input" pattern 94 } 95 96 // LOOP FUNCTION - AFTER SETUP, RUNS REPEATEDLY **************************** 97 98 void loop() { 99 trellis.tick(); // Generate button events 100 while(trellis.available()) { // Process each event... 101 keypadEvent e = trellis.read(); 102 if(e.bit.EVENT == KEY_JUST_PRESSED) { // Button press? 103 if(shiftmode || (e.bit.KEY < 24)) { // If not a shift-button 104 if(sound[shiftmode][e.bit.KEY] != NULL) { // and has word assigned, 105 voice.say(sound[shiftmode][e.bit.KEY], false); // Say it! 106 } 107 } else { // Is a shift-button 108 shiftmode = e.bit.KEY - 23; // shiftmode = 1 to 8 109 trellis.fill(trellis.ColorHSV((shiftmode-1) * 65536 / 8, 255, 2)); 110 } 111 } else if(e.bit.EVENT == KEY_JUST_RELEASED) { // Button release? 112 if(e.bit.KEY == (shiftmode + 23)) { // Shift mode button? 113 shiftmode = 0; // Un-shift 114 idle(); // Restore 'ready' lights 115 } 116 } 117 } 118 }