This is a MIDI synthesizer with touchpads used for playing the notes. mbed will capture the touchpad press and release events and sends the appropriate MIDI commands to the PC. By using the C# windows forms application created by us, one can compose songs as though they were composed on a piano. We support all types of standard MIDI piano types.
main.cpp@0:e33f18af0471, 2011-10-13 (annotated)
- Committer:
- thejasvi3
- Date:
- Thu Oct 13 06:17:30 2011 +0000
- Revision:
- 0:e33f18af0471
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
thejasvi3 | 0:e33f18af0471 | 1 | #include <mbed.h> |
thejasvi3 | 0:e33f18af0471 | 2 | #include <string> |
thejasvi3 | 0:e33f18af0471 | 3 | #include <list> |
thejasvi3 | 0:e33f18af0471 | 4 | |
thejasvi3 | 0:e33f18af0471 | 5 | #include <mpr121.h> |
thejasvi3 | 0:e33f18af0471 | 6 | #include "NokiaLCD.h" |
thejasvi3 | 0:e33f18af0471 | 7 | |
thejasvi3 | 0:e33f18af0471 | 8 | |
thejasvi3 | 0:e33f18af0471 | 9 | DigitalOut led1(LED1); |
thejasvi3 | 0:e33f18af0471 | 10 | DigitalOut led2(LED2); |
thejasvi3 | 0:e33f18af0471 | 11 | DigitalOut led3(LED3); |
thejasvi3 | 0:e33f18af0471 | 12 | DigitalOut led4(LED4); |
thejasvi3 | 0:e33f18af0471 | 13 | |
thejasvi3 | 0:e33f18af0471 | 14 | // Pushbuttons to change the octaves of the touchpads |
thejasvi3 | 0:e33f18af0471 | 15 | InterruptIn octavePlus1(p18); // Pushbutton that increments the octave of touchpad1 |
thejasvi3 | 0:e33f18af0471 | 16 | InterruptIn octaveMinus1(p17); // Pushbutton that decrements the octave of touchpad1 |
thejasvi3 | 0:e33f18af0471 | 17 | InterruptIn octavePlus2(p16); // Pushbutton that increments the octave of touchpad2 |
thejasvi3 | 0:e33f18af0471 | 18 | InterruptIn octaveMinus2(p15); // Pushbutton that decrements the octave of touchpad2 |
thejasvi3 | 0:e33f18af0471 | 19 | |
thejasvi3 | 0:e33f18af0471 | 20 | // Create the interrupt receiver object on pin 26 |
thejasvi3 | 0:e33f18af0471 | 21 | InterruptIn interrupt1(p26); // IRQ of touchpad1 |
thejasvi3 | 0:e33f18af0471 | 22 | InterruptIn interrupt2(p8); // IRQ of touchpad2 |
thejasvi3 | 0:e33f18af0471 | 23 | |
thejasvi3 | 0:e33f18af0471 | 24 | // Setup the Serial to the PC for debugging |
thejasvi3 | 0:e33f18af0471 | 25 | Serial pc(USBTX, USBRX); |
thejasvi3 | 0:e33f18af0471 | 26 | |
thejasvi3 | 0:e33f18af0471 | 27 | // Setup the i2c bus on pins 28 and 27 |
thejasvi3 | 0:e33f18af0471 | 28 | I2C i2c1(p28, p27); |
thejasvi3 | 0:e33f18af0471 | 29 | I2C i2c2(p9,p10); |
thejasvi3 | 0:e33f18af0471 | 30 | |
thejasvi3 | 0:e33f18af0471 | 31 | |
thejasvi3 | 0:e33f18af0471 | 32 | //Setup NOKIA LCD |
thejasvi3 | 0:e33f18af0471 | 33 | NokiaLCD lcd(p5, p7, p12, p11, NokiaLCD::LCD6610); // mosi, sclk, cs, rst, type |
thejasvi3 | 0:e33f18af0471 | 34 | |
thejasvi3 | 0:e33f18af0471 | 35 | |
thejasvi3 | 0:e33f18af0471 | 36 | // Setup the Mpr121: |
thejasvi3 | 0:e33f18af0471 | 37 | // constructor(i2c object, i2c address of the mpr121) |
thejasvi3 | 0:e33f18af0471 | 38 | Mpr121 mpr121_1(&i2c1, Mpr121::ADD_VSS); |
thejasvi3 | 0:e33f18af0471 | 39 | Mpr121 mpr121_2(&i2c2, Mpr121::ADD_VSS); |
thejasvi3 | 0:e33f18af0471 | 40 | |
thejasvi3 | 0:e33f18af0471 | 41 | Timer t1; // to calulate delta time |
thejasvi3 | 0:e33f18af0471 | 42 | |
thejasvi3 | 0:e33f18af0471 | 43 | void midiEventGenerator1(); |
thejasvi3 | 0:e33f18af0471 | 44 | void midiEventGenerator2(); |
thejasvi3 | 0:e33f18af0471 | 45 | |
thejasvi3 | 0:e33f18af0471 | 46 | |
thejasvi3 | 0:e33f18af0471 | 47 | volatile char octave[2] = {0,1}; // Stores the current octave of both the touchpads |
thejasvi3 | 0:e33f18af0471 | 48 | volatile int prev_val[2] = {0,0}; // Stores the previous touchpad values |
thejasvi3 | 0:e33f18af0471 | 49 | volatile int cur_val[2] = {0,0}; // Stores the current touchpad values |
thejasvi3 | 0:e33f18af0471 | 50 | volatile int time_us = 0; // Stores the time between different events of the same touchpad |
thejasvi3 | 0:e33f18af0471 | 51 | |
thejasvi3 | 0:e33f18af0471 | 52 | |
thejasvi3 | 0:e33f18af0471 | 53 | const int backgroundColor = 0x0000FF; |
thejasvi3 | 0:e33f18af0471 | 54 | const int graphBarColor = 0xFFFFFF; |
thejasvi3 | 0:e33f18af0471 | 55 | const int graphAxesColor = 0xFFFFFF; |
thejasvi3 | 0:e33f18af0471 | 56 | |
thejasvi3 | 0:e33f18af0471 | 57 | int t = 0; |
thejasvi3 | 0:e33f18af0471 | 58 | |
thejasvi3 | 0:e33f18af0471 | 59 | // Key hit/release interrupt routine for touch pad 1 |
thejasvi3 | 0:e33f18af0471 | 60 | void fallInterrupt1() |
thejasvi3 | 0:e33f18af0471 | 61 | { |
thejasvi3 | 0:e33f18af0471 | 62 | time_us = t1.read_us(); |
thejasvi3 | 0:e33f18af0471 | 63 | t1.stop(); |
thejasvi3 | 0:e33f18af0471 | 64 | t1.reset(); |
thejasvi3 | 0:e33f18af0471 | 65 | t1.start(); |
thejasvi3 | 0:e33f18af0471 | 66 | cur_val[0] = mpr121_1.read(0x00); |
thejasvi3 | 0:e33f18af0471 | 67 | cur_val[0] += mpr121_1.read(0x01)<<8; |
thejasvi3 | 0:e33f18af0471 | 68 | |
thejasvi3 | 0:e33f18af0471 | 69 | midiEventGenerator1(); |
thejasvi3 | 0:e33f18af0471 | 70 | } |
thejasvi3 | 0:e33f18af0471 | 71 | |
thejasvi3 | 0:e33f18af0471 | 72 | |
thejasvi3 | 0:e33f18af0471 | 73 | // Key hit/release interrupt routine for touch pad 2 |
thejasvi3 | 0:e33f18af0471 | 74 | void fallInterrupt2() |
thejasvi3 | 0:e33f18af0471 | 75 | { |
thejasvi3 | 0:e33f18af0471 | 76 | time_us = t1.read_us(); |
thejasvi3 | 0:e33f18af0471 | 77 | t1.stop(); |
thejasvi3 | 0:e33f18af0471 | 78 | t1.reset(); |
thejasvi3 | 0:e33f18af0471 | 79 | t1.start(); |
thejasvi3 | 0:e33f18af0471 | 80 | cur_val[1] = mpr121_2.read(0x00); |
thejasvi3 | 0:e33f18af0471 | 81 | cur_val[1] += mpr121_2.read(0x01)<<8; |
thejasvi3 | 0:e33f18af0471 | 82 | |
thejasvi3 | 0:e33f18af0471 | 83 | midiEventGenerator2(); |
thejasvi3 | 0:e33f18af0471 | 84 | } |
thejasvi3 | 0:e33f18af0471 | 85 | |
thejasvi3 | 0:e33f18af0471 | 86 | void octaveIncrement1() |
thejasvi3 | 0:e33f18af0471 | 87 | { |
thejasvi3 | 0:e33f18af0471 | 88 | if(octave[0] < 9) |
thejasvi3 | 0:e33f18af0471 | 89 | octave[0]++; |
thejasvi3 | 0:e33f18af0471 | 90 | |
thejasvi3 | 0:e33f18af0471 | 91 | // Update the octave number on the LCD |
thejasvi3 | 0:e33f18af0471 | 92 | lcd.fill(48,8,8,8,backgroundColor); |
thejasvi3 | 0:e33f18af0471 | 93 | lcd.locate(6,1); |
thejasvi3 | 0:e33f18af0471 | 94 | lcd.printf("%d",octave[0]); |
thejasvi3 | 0:e33f18af0471 | 95 | |
thejasvi3 | 0:e33f18af0471 | 96 | wait(0.5); |
thejasvi3 | 0:e33f18af0471 | 97 | } |
thejasvi3 | 0:e33f18af0471 | 98 | |
thejasvi3 | 0:e33f18af0471 | 99 | void octaveIncrement2() |
thejasvi3 | 0:e33f18af0471 | 100 | { |
thejasvi3 | 0:e33f18af0471 | 101 | if(octave[1] < 9) |
thejasvi3 | 0:e33f18af0471 | 102 | octave[1]++; |
thejasvi3 | 0:e33f18af0471 | 103 | |
thejasvi3 | 0:e33f18af0471 | 104 | lcd.fill(112,8,8,8,backgroundColor); |
thejasvi3 | 0:e33f18af0471 | 105 | lcd.locate(14,1); |
thejasvi3 | 0:e33f18af0471 | 106 | lcd.printf("%d",octave[1]); |
thejasvi3 | 0:e33f18af0471 | 107 | |
thejasvi3 | 0:e33f18af0471 | 108 | wait(0.5); |
thejasvi3 | 0:e33f18af0471 | 109 | } |
thejasvi3 | 0:e33f18af0471 | 110 | |
thejasvi3 | 0:e33f18af0471 | 111 | void octaveDecrement1() |
thejasvi3 | 0:e33f18af0471 | 112 | { |
thejasvi3 | 0:e33f18af0471 | 113 | if(octave[0] > 0) |
thejasvi3 | 0:e33f18af0471 | 114 | octave[0]--; |
thejasvi3 | 0:e33f18af0471 | 115 | |
thejasvi3 | 0:e33f18af0471 | 116 | lcd.fill(48,8,8,8,backgroundColor); |
thejasvi3 | 0:e33f18af0471 | 117 | lcd.locate(6,1); |
thejasvi3 | 0:e33f18af0471 | 118 | lcd.printf("%d",octave[0]); |
thejasvi3 | 0:e33f18af0471 | 119 | |
thejasvi3 | 0:e33f18af0471 | 120 | wait(0.5); |
thejasvi3 | 0:e33f18af0471 | 121 | } |
thejasvi3 | 0:e33f18af0471 | 122 | |
thejasvi3 | 0:e33f18af0471 | 123 | void octaveDecrement2() |
thejasvi3 | 0:e33f18af0471 | 124 | { |
thejasvi3 | 0:e33f18af0471 | 125 | if(octave[1] > 0) |
thejasvi3 | 0:e33f18af0471 | 126 | octave[1]--; |
thejasvi3 | 0:e33f18af0471 | 127 | |
thejasvi3 | 0:e33f18af0471 | 128 | lcd.fill(112,8,8,8,backgroundColor); |
thejasvi3 | 0:e33f18af0471 | 129 | lcd.locate(14,1); |
thejasvi3 | 0:e33f18af0471 | 130 | lcd.printf("%d",octave[1]); |
thejasvi3 | 0:e33f18af0471 | 131 | |
thejasvi3 | 0:e33f18af0471 | 132 | wait(0.5); |
thejasvi3 | 0:e33f18af0471 | 133 | } |
thejasvi3 | 0:e33f18af0471 | 134 | |
thejasvi3 | 0:e33f18af0471 | 135 | void rx() |
thejasvi3 | 0:e33f18af0471 | 136 | { |
thejasvi3 | 0:e33f18af0471 | 137 | // reset timer when new file is to be created |
thejasvi3 | 0:e33f18af0471 | 138 | t1.stop(); |
thejasvi3 | 0:e33f18af0471 | 139 | t1.reset(); |
thejasvi3 | 0:e33f18af0471 | 140 | t1.start(); |
thejasvi3 | 0:e33f18af0471 | 141 | |
thejasvi3 | 0:e33f18af0471 | 142 | char temp = pc.getc(); |
thejasvi3 | 0:e33f18af0471 | 143 | } |
thejasvi3 | 0:e33f18af0471 | 144 | |
thejasvi3 | 0:e33f18af0471 | 145 | int main() |
thejasvi3 | 0:e33f18af0471 | 146 | { |
thejasvi3 | 0:e33f18af0471 | 147 | // Initialize LCD |
thejasvi3 | 0:e33f18af0471 | 148 | lcd.background(backgroundColor); |
thejasvi3 | 0:e33f18af0471 | 149 | lcd.cls(); |
thejasvi3 | 0:e33f18af0471 | 150 | |
thejasvi3 | 0:e33f18af0471 | 151 | lcd.fill(5,35,55,1,graphAxesColor); |
thejasvi3 | 0:e33f18af0471 | 152 | lcd.fill(5,35,1,85,graphAxesColor); |
thejasvi3 | 0:e33f18af0471 | 153 | |
thejasvi3 | 0:e33f18af0471 | 154 | lcd.fill(65,35,55,1,graphAxesColor); |
thejasvi3 | 0:e33f18af0471 | 155 | lcd.fill(65,35,1,85,graphAxesColor); |
thejasvi3 | 0:e33f18af0471 | 156 | |
thejasvi3 | 0:e33f18af0471 | 157 | lcd.locate(0,1); |
thejasvi3 | 0:e33f18af0471 | 158 | lcd.printf("Octv: %d",octave[0]); |
thejasvi3 | 0:e33f18af0471 | 159 | |
thejasvi3 | 0:e33f18af0471 | 160 | lcd.locate(8,1); |
thejasvi3 | 0:e33f18af0471 | 161 | lcd.printf("Octv: %d",octave[1]); |
thejasvi3 | 0:e33f18af0471 | 162 | |
thejasvi3 | 0:e33f18af0471 | 163 | // Initialize the pushbutton interrupts |
thejasvi3 | 0:e33f18af0471 | 164 | octavePlus1.mode(PullUp); |
thejasvi3 | 0:e33f18af0471 | 165 | octavePlus1.fall(&octaveIncrement1); |
thejasvi3 | 0:e33f18af0471 | 166 | octavePlus2.mode(PullUp); |
thejasvi3 | 0:e33f18af0471 | 167 | octavePlus2.fall(&octaveIncrement2); |
thejasvi3 | 0:e33f18af0471 | 168 | octaveMinus1.mode(PullUp); |
thejasvi3 | 0:e33f18af0471 | 169 | octaveMinus1.fall(&octaveDecrement1); |
thejasvi3 | 0:e33f18af0471 | 170 | octaveMinus2.mode(PullUp); |
thejasvi3 | 0:e33f18af0471 | 171 | octaveMinus2.fall(&octaveDecrement2); |
thejasvi3 | 0:e33f18af0471 | 172 | |
thejasvi3 | 0:e33f18af0471 | 173 | |
thejasvi3 | 0:e33f18af0471 | 174 | // for touch pad 1 |
thejasvi3 | 0:e33f18af0471 | 175 | interrupt1.mode(PullUp); |
thejasvi3 | 0:e33f18af0471 | 176 | interrupt1.fall(&fallInterrupt1); |
thejasvi3 | 0:e33f18af0471 | 177 | t1.reset(); |
thejasvi3 | 0:e33f18af0471 | 178 | t1.start(); |
thejasvi3 | 0:e33f18af0471 | 179 | |
thejasvi3 | 0:e33f18af0471 | 180 | |
thejasvi3 | 0:e33f18af0471 | 181 | // for touch pad 2 |
thejasvi3 | 0:e33f18af0471 | 182 | interrupt2.mode(PullUp); |
thejasvi3 | 0:e33f18af0471 | 183 | interrupt2.fall(&fallInterrupt2); |
thejasvi3 | 0:e33f18af0471 | 184 | |
thejasvi3 | 0:e33f18af0471 | 185 | // Setup interrupt for serial port rx. This is used to reset the deltatime timer when a new file is created on the PC |
thejasvi3 | 0:e33f18af0471 | 186 | pc.attach(&rx); |
thejasvi3 | 0:e33f18af0471 | 187 | |
thejasvi3 | 0:e33f18af0471 | 188 | int temp = 0; |
thejasvi3 | 0:e33f18af0471 | 189 | while (1) |
thejasvi3 | 0:e33f18af0471 | 190 | { |
thejasvi3 | 0:e33f18af0471 | 191 | temp ^= 1; |
thejasvi3 | 0:e33f18af0471 | 192 | led1 = temp;; |
thejasvi3 | 0:e33f18af0471 | 193 | wait(0.5); |
thejasvi3 | 0:e33f18af0471 | 194 | } |
thejasvi3 | 0:e33f18af0471 | 195 | } |
thejasvi3 | 0:e33f18af0471 | 196 | |
thejasvi3 | 0:e33f18af0471 | 197 | |
thejasvi3 | 0:e33f18af0471 | 198 | void midiEventGenerator1() |
thejasvi3 | 0:e33f18af0471 | 199 | { |
thejasvi3 | 0:e33f18af0471 | 200 | int temp; |
thejasvi3 | 0:e33f18af0471 | 201 | |
thejasvi3 | 0:e33f18af0471 | 202 | // Evaluate for touch pad 1 |
thejasvi3 | 0:e33f18af0471 | 203 | temp = cur_val[0] ^ prev_val[0]; |
thejasvi3 | 0:e33f18af0471 | 204 | |
thejasvi3 | 0:e33f18af0471 | 205 | for(int i = 0; i < 12; i++) |
thejasvi3 | 0:e33f18af0471 | 206 | { |
thejasvi3 | 0:e33f18af0471 | 207 | if((temp & 1) == 1) |
thejasvi3 | 0:e33f18af0471 | 208 | { |
thejasvi3 | 0:e33f18af0471 | 209 | int mask = (1 << i); |
thejasvi3 | 0:e33f18af0471 | 210 | |
thejasvi3 | 0:e33f18af0471 | 211 | if((cur_val[0] & mask) == mask) |
thejasvi3 | 0:e33f18af0471 | 212 | { |
thejasvi3 | 0:e33f18af0471 | 213 | pc.printf("on%01d%03d%010d",0,((octave[0] * 12) + i), time_us); // sending format: channel, note, deltaTime_uS |
thejasvi3 | 0:e33f18af0471 | 214 | lcd.fill(6,(36 + (7 * i)),50,6,graphBarColor); // Display the FFT |
thejasvi3 | 0:e33f18af0471 | 215 | } |
thejasvi3 | 0:e33f18af0471 | 216 | else |
thejasvi3 | 0:e33f18af0471 | 217 | { |
thejasvi3 | 0:e33f18af0471 | 218 | pc.printf("of%01d%03d%010d",0,((octave[0] * 12) + i), time_us); |
thejasvi3 | 0:e33f18af0471 | 219 | lcd.fill(6,(36 + (7 * i)),50,6,backgroundColor); |
thejasvi3 | 0:e33f18af0471 | 220 | } |
thejasvi3 | 0:e33f18af0471 | 221 | } |
thejasvi3 | 0:e33f18af0471 | 222 | temp = temp >> 1; |
thejasvi3 | 0:e33f18af0471 | 223 | } |
thejasvi3 | 0:e33f18af0471 | 224 | |
thejasvi3 | 0:e33f18af0471 | 225 | prev_val[0] = cur_val[0]; |
thejasvi3 | 0:e33f18af0471 | 226 | |
thejasvi3 | 0:e33f18af0471 | 227 | } |
thejasvi3 | 0:e33f18af0471 | 228 | |
thejasvi3 | 0:e33f18af0471 | 229 | void midiEventGenerator2() |
thejasvi3 | 0:e33f18af0471 | 230 | { |
thejasvi3 | 0:e33f18af0471 | 231 | int temp; |
thejasvi3 | 0:e33f18af0471 | 232 | |
thejasvi3 | 0:e33f18af0471 | 233 | // Evaluate for touch pad 2 |
thejasvi3 | 0:e33f18af0471 | 234 | temp = cur_val[1] ^ prev_val[1]; |
thejasvi3 | 0:e33f18af0471 | 235 | |
thejasvi3 | 0:e33f18af0471 | 236 | for(int i = 0; i < 12; i++) |
thejasvi3 | 0:e33f18af0471 | 237 | { |
thejasvi3 | 0:e33f18af0471 | 238 | if((temp & 1) == 1) |
thejasvi3 | 0:e33f18af0471 | 239 | { |
thejasvi3 | 0:e33f18af0471 | 240 | int mask = (1 << i); |
thejasvi3 | 0:e33f18af0471 | 241 | |
thejasvi3 | 0:e33f18af0471 | 242 | if((cur_val[1] & mask) == mask) |
thejasvi3 | 0:e33f18af0471 | 243 | { |
thejasvi3 | 0:e33f18af0471 | 244 | pc.printf("on%01d%03d%010d",0,((octave[1] * 12) + i), time_us); |
thejasvi3 | 0:e33f18af0471 | 245 | lcd.fill(66,(36 + (7 * i)),50,6,graphBarColor); |
thejasvi3 | 0:e33f18af0471 | 246 | } |
thejasvi3 | 0:e33f18af0471 | 247 | else |
thejasvi3 | 0:e33f18af0471 | 248 | { |
thejasvi3 | 0:e33f18af0471 | 249 | pc.printf("of%01d%03d%010d",0,((octave[1] * 12) + i), time_us); |
thejasvi3 | 0:e33f18af0471 | 250 | lcd.fill(66,(36 + (7 * i)),50,6,backgroundColor); |
thejasvi3 | 0:e33f18af0471 | 251 | } |
thejasvi3 | 0:e33f18af0471 | 252 | } |
thejasvi3 | 0:e33f18af0471 | 253 | temp = temp >> 1; |
thejasvi3 | 0:e33f18af0471 | 254 | } |
thejasvi3 | 0:e33f18af0471 | 255 | |
thejasvi3 | 0:e33f18af0471 | 256 | prev_val[1] = cur_val[1]; |
thejasvi3 | 0:e33f18af0471 | 257 | } |