Interactive Device Design / Mbed 2 deprecated ChordJoy

Dependencies:   PinDetect_KL25Z mbed-rtos mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "rtos.h"
00003 
00004 
00005 const int BUTTONS = 7;
00006 const int BUZZERS = 3;
00007 const int LETTERS = 27;
00008 
00009 // Collection is the time that it takes after pressing one key and then reading
00010 // all the keys to determine what the chord is.
00011 const int COLLECTION_MS = 200;
00012 Timer collectionTimer;
00013 
00014 InterruptIn buttons [BUTTONS] = {
00015     InterruptIn(D2),
00016     InterruptIn(D4),
00017     InterruptIn(D5),
00018     InterruptIn(D8),
00019     InterruptIn(D9),
00020     InterruptIn(D10),
00021     InterruptIn(D11)
00022 };
00023 Serial pc(USBTX, USBRX);
00024 
00025 // Note: there are only THREE PWMs on the board. So this is all we can use
00026 // for this particular method of sound output. The pins chosen are important
00027 // because the same PWM will map to multiple outputs. See the reference
00028 // manual for Mbed for which pins map to distinct PWMs.
00029 PwmOut buzzers [3] = {
00030     PwmOut(D0),
00031     PwmOut(D7),
00032     PwmOut(D3)
00033 };
00034 
00035 // Periods of notes in microseconds
00036 int notePeriods [8] = {
00037     3818,   // C4
00038     3412,   // D4
00039     3030,   // E4
00040     2895,   // F4
00041     2551,   // G4
00042     2273,   // A4
00043     2024,   // B4
00044     10000000 // inaudible pitch
00045 };
00046 // Possible chords that can be played.
00047 // Chords consist of 3 notes, and an integer for the ASCII character
00048 //  that it will output via serial.
00049 // Note that 7 is no button pressed, or a 'silent' pitch.
00050 int chords [LETTERS][BUZZERS + 1] = {
00051     {0, 7, 7, 114}, // single notes
00052     {1, 7, 7, 32},
00053     {2, 7, 7, 106},
00054     {3, 7, 7, 107},
00055     {4, 7, 7, 109},
00056     {5, 7, 7, 113},
00057     {6, 7, 7, 122},
00058     {0, 2, 7, 115}, // diads
00059     {0, 3, 7, 112},
00060     {0, 4, 7, 110},
00061     {0, 5, 7, 102},
00062     {1, 3, 7, 105},
00063     {1, 4, 7, 98},
00064     {1, 5, 7, 103},
00065     {1, 6, 7, 104},
00066     {2, 4, 7, 100},
00067     {2, 5, 7, 121},
00068     {2, 6, 7, 120},
00069     {3, 4, 7, 99},
00070     {3, 5, 7, 117},
00071     {4, 6, 7, 119},
00072     {0, 2, 4, 101}, // triads
00073     {0, 2, 5, 118},
00074     {0, 3, 5, 108},
00075     {1, 3, 6, 97},
00076     {1, 4, 6, 116},
00077     {1, 3, 4, 111}
00078 };
00079 
00080 void playChord(int chordIndex) {
00081     int *chord = chords[chordIndex];
00082     for (int i = 0; i < BUZZERS; i++) {
00083         int noteIndex = chord[i];
00084         if (noteIndex == 7) {
00085             buzzers[i] = 0;
00086         }
00087         else {
00088             buzzers[i] = .5f;
00089             int period = notePeriods[noteIndex];
00090             buzzers[i].period_us(period);
00091         }
00092     }
00093 }
00094 
00095 void setFlag() {
00096     collectionTimer.start();
00097 }
00098 
00099 void silenceBuzzers(void) {
00100     // Initialize all duty cycles to off, so we hear nothing.
00101     for (int i = 0; i < BUZZERS; i++) {
00102         buzzers[i] = 0.0f;
00103     }
00104 }
00105 
00106 void registerButtonInterrupts(void) {
00107     for (int i =  0; i < BUTTONS; i++) {
00108         buttons[i].fall(&setFlag);
00109     }   
00110 }
00111 
00112 int readChord(void) {
00113     /* Detect the current chord from the keys pressed. Return int index of chord.
00114        Return -1 if no chord can be found with the current keys.
00115        Note that we can only read as many keys as there are buzzers, so check
00116        on each key in an ascending order. */
00117     int firstThreeButtons[BUZZERS] = {7, 7, 7};
00118     int pressedCount = 0;
00119     for (int i = 0; i < BUTTONS; i++) {
00120         if (buttons[i].read() == 0) {
00121             firstThreeButtons[pressedCount] = i;
00122             pressedCount++;   
00123         }
00124         if (pressedCount >= BUZZERS) {
00125             break;
00126         }
00127     }
00128     int matchIndex = -1;
00129     for (int i = 0; i < LETTERS; i++) {
00130         bool chordMatches = true;
00131         for (int j = 0; j < BUZZERS; j++) {
00132             if (firstThreeButtons[j] != chords[i][j]) {
00133                 chordMatches = false;
00134                 break;            
00135             }
00136         }
00137         if (chordMatches == true) {
00138             matchIndex = i;
00139             break;
00140         }
00141     }
00142     // pc.printf("Matched chord %d\n", matchIndex);
00143     return matchIndex;
00144 }
00145 
00146 void waitForChord(void) {
00147      /* This method should be run in the main loop so that it can print */
00148      while (true) {
00149         if (collectionTimer.read_ms() > COLLECTION_MS) {
00150             collectionTimer.stop();
00151             collectionTimer.reset();
00152             int chordIndex = readChord();
00153             if (chordIndex != -1) {
00154                 playChord(chordIndex);
00155                 int charAscii = chords[chordIndex][BUZZERS];
00156                 pc.printf("%c", charAscii);
00157             }
00158         }
00159         wait_ms(10);
00160     }   
00161 }
00162 
00163 int main() {
00164     silenceBuzzers();
00165     registerButtonInterrupts();
00166     waitForChord();
00167 }