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:
- 5:1186eb1f3c2b
- Parent:
- 4:400a042e762a
File content as of revision 5:1186eb1f3c2b:
#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 = 200; 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. // Chords consist of 3 notes, and an integer for the ASCII character // that it will output via serial. // Note that 7 is no button pressed, or a 'silent' pitch. int chords [LETTERS][BUZZERS + 1] = { {0, 7, 7, 114}, // single notes {1, 7, 7, 32}, {2, 7, 7, 106}, {3, 7, 7, 107}, {4, 7, 7, 109}, {5, 7, 7, 113}, {6, 7, 7, 122}, {0, 2, 7, 115}, // diads {0, 3, 7, 112}, {0, 4, 7, 110}, {0, 5, 7, 102}, {1, 3, 7, 105}, {1, 4, 7, 98}, {1, 5, 7, 103}, {1, 6, 7, 104}, {2, 4, 7, 100}, {2, 5, 7, 121}, {2, 6, 7, 120}, {3, 4, 7, 99}, {3, 5, 7, 117}, {4, 6, 7, 119}, {0, 2, 4, 101}, // triads {0, 2, 5, 118}, {0, 3, 5, 108}, {1, 3, 6, 97}, {1, 4, 6, 116}, {1, 3, 4, 111} }; void playChord(int chordIndex) { int *chord = chords[chordIndex]; for (int i = 0; i < BUZZERS; i++) { int noteIndex = chord[i]; if (noteIndex == 7) { buzzers[i] = 0; } else { buzzers[i] = .5f; int period = notePeriods[noteIndex]; buzzers[i].period_us(period); } } } 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].fall(&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() == 0) { 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(); if (chordIndex != -1) { playChord(chordIndex); int charAscii = chords[chordIndex][BUZZERS]; pc.printf("%c", charAscii); } } wait_ms(10); } } int main() { silenceBuzzers(); registerButtonInterrupts(); waitForChord(); }