void setProgMode() { storedVars.begin("baseVars", false); for (k=0;k<22;k++) if (bitRead(touchedCols,k)) { // this is select, not toggle if (k>14) { dprintln("layout tres"); if (!storedVars.putUChar("symbolTableTemp",3)) dprintln("error preferences symbolTable 3"); turnOnLED(3,-1,-1); loadSymbols(3); k=22; } else { if (k>7) { dprintln("layout dos"); if (!storedVars.putUChar("symbolTableTemp",2)) dprintln("error preferences symbolTable 2"); turnOnLED(2,-1,-1); loadSymbols(2); k=22; } else { dprintln("layout uno"); if (!storedVars.putUChar("symbolTableTemp",1)) dprintln("error preferences symbolTable 1"); turnOnLED(1,-1,-1); loadSymbols(1); k=22; } } } storedVars.end(); } void printTouchData() { lastSymNum = 99; lastSym = 99; seqOK = true; for (r=0; r<14; r++) if (bitRead(touchedRows,r)) for (c=0; c<22; c++) if (bitRead(touchedCols,c)) { currSymNum = sym2Pix[r][c]; currSym = symbol[currSymNum]; if (lastSymNum != 99 && currSym != lastSym) { //not the first cycle and diff symbols touched seqOK = false; c=22; r=14; dprintln("\nSeq Not Ok: diff symbols"); } else { if (currSym == '&') { //touched a blank space in QWERTY layout seqOK = false; c=22; r=14; dprintln("\nSeq Not Ok: blank space"); } else { if (currSymNum > (vSym*hSym)) { //touched area doesn't have a symbol -> sym2Pix is 14x22 w/default value=98 seqOK = false; c=22; r=14; dprintln("\nSeq Not Ok: outside area"); } } } lastSymNum = currSymNum; lastSym = currSym; } if (seqOK) { switch (int(currSym)) { case 32: sym4LED = 12; if (bleMode) { if (letterKeyb) {dprint(currSym); bleKeyb.print(currSym);} //-------if LETTER else { if (wordKeyb) { //------------------------------------------------if WORD pch = strrchr(charCache, ' '); if (pch != NULL) {dprintln(&charCache[pch - charCache + 1]); bleKeyb.print(&charCache[pch - charCache + 1]);} else {dprintln(charCache); bleKeyb.print(charCache); } bleKeyb.print(currSym); } } if (phraseKeyb) {charCache[charCount] = currSym; charCount++; } //---if PHRASE else charCount = 0; charCache[charCount] = '\0'; } break; case 8: sym4LED = 13; if (bleMode) { if (charCount > 0) {charCount--; charCache[charCount] = '\0'; bleKeyb.print(currSym);} } break; case 10: sym4LED = 14; if (bleMode) { if (phraseKeyb) { //-------------------------------------------------if PHRASE bleKeyb.print(currSym); delay(350); //time for read last word and CR/LF pch = strtok(charCache," "); while (pch != NULL) { dprint(pch); bleKeyb.print(pch); dprint(" "); bleKeyb.print(" "); delay(135 * strlen(pch)); //give iOS time to read whole word pch = strtok(NULL," "); } bleKeyb.print(currSym); }else { if (wordKeyb && !letterKeyb) { //----------------------------------if WORD pch = strrchr(charCache, ' '); if (pch != NULL) {dprintln(&charCache[pch - charCache + 1]); bleKeyb.print(&charCache[pch - charCache + 1]);} else {dprintln(charCache); bleKeyb.print(charCache); } } dprintln(currSym); bleKeyb.print(currSym); //----------------------if LETTER } charCount = 0; charCache[charCount] = '\0'; } break; default: sym4LED = 11; if (bleMode) { charCache[charCount] = currSym; charCount++; charCache[charCount] = '\0'; if (letterKeyb) { dprint(currSym); bleKeyb.print(currSym); } //----------------------if LETTER /*bleKeyb.println(micros() - speed);*/ } break; } turnOnLED(sym4LED,LEDrSym[currSymNum],LEDcSym[currSymNum]); buzz(50); //dprint("time="); dprintln(micros() - speed); }else { // invalid keypress buzz(51); turnOnLED(10,-1,-1); } } void resetTouchVars() { touchedRows = 0; touchedCols = 0; releasedRows = 0; releasedCols = 0; oldRows = 0; oldCols = 0; currRows = 0; currCols = 0; lastTouch = 0; currSymNum = 0; currSym = 99; } void chkTouched() { //Read Registers 00 & 01 (bytes 1 & 2) and build 14 bit & 22 bit row & col bytes Wire.requestFrom(0x5A,2); tReg5A = (Wire.read() + (Wire.read() << 8)) & 0x0FFF; Wire.requestFrom(0x5C,2); tReg5C = (Wire.read() + (Wire.read() << 8)) & 0x0FFF; Wire.requestFrom(0x5D,2); tReg5D = (Wire.read() + (Wire.read() << 8)) & 0x0FFF; currRows = bitRead(tReg5A,11) << 13; //R14 in Sensor A for (k=0; k<=11; k++) currRows += (bitRead(tReg5D,k) << (k + 12 - (k * 2))); //R13 to R02 in Sensor D currRows += bitRead(tReg5C,0); //R01 in Sensor C currCols = 0; for (k=10; k>=0; k--) { currCols += (bitRead(tReg5A,k) << ((k * 2) + 1)); //Even´s C02 to C22 in Sensor A currCols += (bitRead(tReg5C,k + 11 - (k * 2)) << (k * 2)); //Odd´s C21 to C01 in Sensor C } //below follows the acum results of several T/R's until (T´s = R´s) or (500mS have elasped) NOToldRows = (~oldRows) & 0x3FFF; NOTcurrRows = (~currRows) & 0x3FFF; //keep only rightmost 14 bits NOToldCols = (~oldCols) & 0x3FFFFF; NOTcurrCols = (~currCols) & 0x3FFFFF; //keep only rightmost 22 bits touchedRows |= (currRows & NOToldRows); touchedCols |= (currCols & NOToldCols); //(touched now) AND (NOT touched before) releasedRows |= (NOTcurrRows & oldRows); releasedCols |= (NOTcurrCols & oldCols); //(NOT touched now) AND (touched before) if ((currRows & NOToldRows) + (currCols & NOToldCols) + //something touched (NOTcurrRows & oldRows) + (NOTcurrCols & oldCols) > 0) //something released lastTouch = millis(); //something changed in this loop cycle only, therefore register the millis oldRows = currRows; oldCols = currCols; if (touchedRows > 0 && touchedCols > 0) { //ACUM of (touched now) AND (NOT touched before). At least 1 row AND 1 col if ((touchedRows == releasedRows) && (touchedCols == releasedCols)) { speed = micros(); if (!progMode) printTouchData(); else setProgMode(); resetTouchVars(); }else { if (millis() - lastTouch > 500) { //no matching pairs but 500ms have elapsed since last T/R change if (!progMode) {dprintln("unpaired timeout"); printTouchData(); } else setProgMode(); resetTouchVars(); } } }else { /*nothing was touched OR only 1 row/col was touched up to this loop cycle: maybe in process of reading full touch event or maybe touch event is done with partial read if (nothing was touched) then exit (i.e. continue). Can be known if T+R == 0 if (in process of reading full touch) then exit (i.e. continue). Unknowable if (partial touch finished, i.e. less than 1r AND 1c) then invalid keypress. Can be known only after time lapse */ if ((touchedRows > 0 && touchedCols == 0) || (touchedRows == 0 && touchedCols > 0)) //only 1r OR only 1c touched, else, nothing has been touched if (millis() - lastTouch > 200) { //if timeout has not occured, wait for more loops to see if another r/c is coming dprintln("\npartial touch timeout"); //need to press harder dprint("rows:"); dprintBIN(touchedRows); dprint(", cols:"); dprintlnBIN(touchedCols); //also the point of board noise = mystery buzz(51); turnOnLED(10,-1,-1); resetTouchVars(); } } } void chkSwitches() { //called when sFlag set TRUE by Interrupt (physical switch changed), which is also called with each Buzz from ground bounce) //will hit this with every tick caused by buzz from waitingOnBLE. Fix w/board 2.0 cap debouncer sFlag = false; letterKeyb = FS[0].value; dprintln("\n0:letter: " + String(letterKeyb)); wordKeyb = FS[1].value; dprintln("1:word: " + String(wordKeyb)); phraseKeyb = FS[2].value; dprintln("2:phrase: " + String(phraseKeyb)); ledKeyb = FS[3].value; dprintln("3:LED: " + String(ledKeyb)); buzzKeyb = FS[4].value; dprintln("4:Buzz: " + String(buzzKeyb)); if (letterKeyb + wordKeyb + phraseKeyb + ledKeyb + buzzKeyb == 0) // since something changed (i.e. we're here) and all=0, user selected progMode {progMode = true; buzz(70);} else { if (progMode) {progMode = false; buzz(71);} //could've changed any one switch so need to chk if we were in progMode else buzz(60); //audio witness for non-progMode switch change } if (letterKeyb + wordKeyb + phraseKeyb == 0) { dprintln("bleMode OFF"); bleMode = false; bleKeyb.end(); } else if (!bleMode) { dprintln("bleMode ON"); bleMode = true; bleKeyb.setName("RPM Board GEN3"); bleKeyb.begin(); } } void IRAM_ATTR readInterrupts(void *arg) { if (!buzzFlag || waitingOnBLE) { // to filter out interruts triggered by ground bounce from ledcWriteTone command // and allow to go into progMode if waitingOnBLE fSwitch *fs = static_cast(arg); oldRead = digitalRead(fs->PIN); debCount = 0; while (debCount < 3) { newRead = digitalRead(fs->PIN); if (oldRead == newRead) debCount++; oldRead = newRead; } fs->value = newRead; sFlag = true; } }