ChordJoy is a keyboard application that accepts chordal input from a set of digital ports, outputting letters and the chords that correspond to the piano keyboard keys the user has pressed.
Dependencies: PinDetect_KL25Z mbed-rtos mbed
main.cpp
- Committer:
- andrewhead
- Date:
- 2014-09-22
- Revision:
- 3:ed89297af2ce
- Parent:
- 2:49e2b1273f16
- Child:
- 4:400a042e762a
File content as of revision 3:ed89297af2ce:
#include "mbed.h" #include "rtos.h" const int BUTTONS = 7; const int BUZZERS = 3; const int LETTERS = 27; // Collection is the time that it takes after pressing one key and then reading // all the keys to determine what the chord is. const int COLLECTION_MS = 500; Timer collectionTimer; InterruptIn buttons [BUTTONS] = { InterruptIn(D2), InterruptIn(D4), InterruptIn(D5), InterruptIn(D8), InterruptIn(D9), InterruptIn(D10), InterruptIn(D11) }; Serial pc(USBTX, USBRX); // Note: there are only THREE PWMs on the board. So this is all we can use // for this particular method of sound output. The pins chosen are important // because the same PWM will map to multiple outputs. See the reference // manual for Mbed for which pins map to distinct PWMs. PwmOut buzzers [3] = { PwmOut(D0), PwmOut(D7), PwmOut(D3) }; // Periods of notes in microseconds int notePeriods [8] = { 3818, // C4 3412, // D4 3030, // E4 2895, // F4 2551, // G4 2273, // A4 2024, // B4 10000000 // inaudible pitch }; // Possible chords that can be played. // Note that 7 is no button pressed, or a 'silent' pitch. int chords [LETTERS][BUZZERS] = { {0, 7, 7}, // single notes {1, 7, 7}, {2, 7, 7}, {3, 7, 7}, {4, 7, 7}, {5, 7, 7}, {6, 7, 7}, {0, 2, 7}, // diads {0, 3, 7}, {0, 4, 7}, {0, 5, 7}, {1, 3, 7}, {1, 4, 7}, {1, 5, 7}, {1, 6, 7}, {2, 4, 7}, {2, 5, 7}, {2, 6, 7}, {3, 4, 7}, {3, 5, 7}, {4, 6, 7}, {0, 2, 4}, // triads {0, 2, 5}, {0, 3, 5}, {1, 4, 6}, {1, 3, 4}, {1, 3, 6} }; void playAllChords(void) { for (int i = 0; i < LETTERS; i++) { int *chord = chords[i]; for (int j = 0; j < BUZZERS; j++) { int noteIndex = chord[j]; if (noteIndex == 7) { buzzers[j] = 0; } else { buzzers[j] = .5f; int period = notePeriods[noteIndex]; buzzers[j].period_us(period); } } wait_ms(10000); } } void setFlag() { collectionTimer.start(); } void silenceBuzzers(void) { // Initialize all duty cycles to off, so we hear nothing. for (int i = 0; i < BUZZERS; i++) { buzzers[i] = 0.0f; } } void registerButtonInterrupts(void) { for (int i = 0; i < BUTTONS; i++) { buttons[i].rise(&setFlag); } } int readChord(void) { /* Detect the current chord from the keys pressed. Return int index of chord. Return -1 if no chord can be found with the current keys. Note that we can only read as many keys as there are buzzers, so check on each key in an ascending order. */ int firstThreeButtons[BUZZERS] = {7, 7, 7}; int pressedCount = 0; for (int i = 0; i < BUTTONS; i++) { if (buttons[i].read() == 1) { firstThreeButtons[pressedCount] = i; pressedCount++; } if (pressedCount >= BUZZERS) { break; } } int matchIndex = -1; for (int i = 0; i < LETTERS; i++) { bool chordMatches = true; for (int j = 0; j < BUZZERS; j++) { if (firstThreeButtons[j] != chords[i][j]) { chordMatches = false; break; } } if (chordMatches == true) { matchIndex = i; break; } } pc.printf("Matched chord %d\n", matchIndex); return matchIndex; } void waitForChord(void) { /* This method should be run in the main loop so that it can print */ while (true) { if (collectionTimer.read_ms() > COLLECTION_MS) { collectionTimer.stop(); collectionTimer.reset(); int chordIndex = readChord(); } wait_ms(10); } } int main() { silenceBuzzers(); registerButtonInterrupts(); waitForChord(); }