A simple touch sensor that sends a message to computer when it notices touch. I'm using a simple voltage divider with 10k resistor and body impedance.

Dependencies:   mbed

Committer:
Vekotin
Date:
Thu Jan 30 06:13:55 2014 +0000
Revision:
1:7ed7d128d225
egw

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Vekotin 1:7ed7d128d225 1 /* Copyright (c) 2010-2011 mbed.org, MIT License
Vekotin 1:7ed7d128d225 2 *
Vekotin 1:7ed7d128d225 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
Vekotin 1:7ed7d128d225 4 * and associated documentation files (the "Software"), to deal in the Software without
Vekotin 1:7ed7d128d225 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
Vekotin 1:7ed7d128d225 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
Vekotin 1:7ed7d128d225 7 * Software is furnished to do so, subject to the following conditions:
Vekotin 1:7ed7d128d225 8 *
Vekotin 1:7ed7d128d225 9 * The above copyright notice and this permission notice shall be included in all copies or
Vekotin 1:7ed7d128d225 10 * substantial portions of the Software.
Vekotin 1:7ed7d128d225 11 *
Vekotin 1:7ed7d128d225 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
Vekotin 1:7ed7d128d225 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Vekotin 1:7ed7d128d225 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
Vekotin 1:7ed7d128d225 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
Vekotin 1:7ed7d128d225 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Vekotin 1:7ed7d128d225 17 */
Vekotin 1:7ed7d128d225 18
Vekotin 1:7ed7d128d225 19 #ifndef MIDIMESSAGE_H
Vekotin 1:7ed7d128d225 20 #define MIDIMESSAGE_H
Vekotin 1:7ed7d128d225 21
Vekotin 1:7ed7d128d225 22 #include "mbed.h"
Vekotin 1:7ed7d128d225 23
Vekotin 1:7ed7d128d225 24 // MIDI Message Format
Vekotin 1:7ed7d128d225 25 //
Vekotin 1:7ed7d128d225 26 // [ msg(4) | channel(4) ] [ 0 | n(7) ] [ 0 | m(7) ]
Vekotin 1:7ed7d128d225 27 //
Vekotin 1:7ed7d128d225 28 // MIDI Data Messages (Channel Specific)
Vekotin 1:7ed7d128d225 29 //
Vekotin 1:7ed7d128d225 30 // Message msg n m
Vekotin 1:7ed7d128d225 31 // ---------------------------------------------
Vekotin 1:7ed7d128d225 32 // Note Off 0x8 Key Velocity
Vekotin 1:7ed7d128d225 33 // Note On 0x9 Key Velocity
Vekotin 1:7ed7d128d225 34 // Polyphonic Aftertouch 0xA Key Pressure
Vekotin 1:7ed7d128d225 35 // Control Change 0xB Controller Value
Vekotin 1:7ed7d128d225 36 // Program Change 0xC Program -
Vekotin 1:7ed7d128d225 37 // Channel Aftertouch 0xD Pressure -
Vekotin 1:7ed7d128d225 38 // Pitch Wheel 0xE LSB MSB
Vekotin 1:7ed7d128d225 39
Vekotin 1:7ed7d128d225 40 #define CABLE_NUM (0<<4)
Vekotin 1:7ed7d128d225 41
Vekotin 1:7ed7d128d225 42 /** A MIDI message container */
Vekotin 1:7ed7d128d225 43 class MIDIMessage {
Vekotin 1:7ed7d128d225 44 public:
Vekotin 1:7ed7d128d225 45 MIDIMessage() {}
Vekotin 1:7ed7d128d225 46
Vekotin 1:7ed7d128d225 47 MIDIMessage(uint8_t *buf) {
Vekotin 1:7ed7d128d225 48 *((uint32_t *)data) = *((uint32_t *)buf);
Vekotin 1:7ed7d128d225 49 }
Vekotin 1:7ed7d128d225 50
Vekotin 1:7ed7d128d225 51 // create messages
Vekotin 1:7ed7d128d225 52
Vekotin 1:7ed7d128d225 53 /** Create a NoteOff message
Vekotin 1:7ed7d128d225 54 * @param key Key ID
Vekotin 1:7ed7d128d225 55 * @param velocity Key velocity (0-127, default = 127)
Vekotin 1:7ed7d128d225 56 * @param channel Key channel (0-15, default 0)
Vekotin 1:7ed7d128d225 57 * @returns A MIDIMessage
Vekotin 1:7ed7d128d225 58 */
Vekotin 1:7ed7d128d225 59 static MIDIMessage NoteOff(int key, int velocity = 127, int channel = 0) {
Vekotin 1:7ed7d128d225 60 MIDIMessage msg;
Vekotin 1:7ed7d128d225 61 msg.data[0] = CABLE_NUM | 0x08;
Vekotin 1:7ed7d128d225 62 msg.data[1] = 0x80 | (channel & 0x0F);
Vekotin 1:7ed7d128d225 63 msg.data[2] = key & 0x7F;
Vekotin 1:7ed7d128d225 64 msg.data[3] = velocity & 0x7F;
Vekotin 1:7ed7d128d225 65 return msg;
Vekotin 1:7ed7d128d225 66 }
Vekotin 1:7ed7d128d225 67
Vekotin 1:7ed7d128d225 68 /** Create a NoteOn message
Vekotin 1:7ed7d128d225 69 * @param key Key ID
Vekotin 1:7ed7d128d225 70 * @param velocity Key velocity (0-127, default = 127)
Vekotin 1:7ed7d128d225 71 * @param channel Key channel (0-15, default 0)
Vekotin 1:7ed7d128d225 72 * @returns A MIDIMessage
Vekotin 1:7ed7d128d225 73 */
Vekotin 1:7ed7d128d225 74 static MIDIMessage NoteOn(int key, int velocity = 127, int channel = 0) {
Vekotin 1:7ed7d128d225 75 MIDIMessage msg;
Vekotin 1:7ed7d128d225 76 msg.data[0] = CABLE_NUM | 0x09;
Vekotin 1:7ed7d128d225 77 msg.data[1] = 0x90 | (channel & 0x0F);
Vekotin 1:7ed7d128d225 78 msg.data[2] = key & 0x7F;
Vekotin 1:7ed7d128d225 79 msg.data[3] = velocity & 0x7F;
Vekotin 1:7ed7d128d225 80 return msg;
Vekotin 1:7ed7d128d225 81 }
Vekotin 1:7ed7d128d225 82
Vekotin 1:7ed7d128d225 83 /** Create a PolyPhonic Aftertouch message
Vekotin 1:7ed7d128d225 84 * @param key Key ID
Vekotin 1:7ed7d128d225 85 * @param pressure Aftertouch pressure (0-127)
Vekotin 1:7ed7d128d225 86 * @param channel Key channel (0-15, default 0)
Vekotin 1:7ed7d128d225 87 * @returns A MIDIMessage
Vekotin 1:7ed7d128d225 88 */
Vekotin 1:7ed7d128d225 89 static MIDIMessage PolyphonicAftertouch(int key, int pressure, int channel = 0) {
Vekotin 1:7ed7d128d225 90 MIDIMessage msg;
Vekotin 1:7ed7d128d225 91 msg.data[0] = CABLE_NUM | 0x0A;
Vekotin 1:7ed7d128d225 92 msg.data[1] = 0xA0 | (channel & 0x0F);
Vekotin 1:7ed7d128d225 93 msg.data[2] = key & 0x7F;
Vekotin 1:7ed7d128d225 94 msg.data[3] = pressure & 0x7F;
Vekotin 1:7ed7d128d225 95 return msg;
Vekotin 1:7ed7d128d225 96 }
Vekotin 1:7ed7d128d225 97
Vekotin 1:7ed7d128d225 98 /** Create a Control Change message
Vekotin 1:7ed7d128d225 99 * @param control Controller ID
Vekotin 1:7ed7d128d225 100 * @param value Controller value (0-127)
Vekotin 1:7ed7d128d225 101 * @param channel Controller channel (0-15, default 0)
Vekotin 1:7ed7d128d225 102 * @returns A MIDIMessage
Vekotin 1:7ed7d128d225 103 */
Vekotin 1:7ed7d128d225 104 static MIDIMessage ControlChange(int control, int value, int channel = 0) {
Vekotin 1:7ed7d128d225 105 MIDIMessage msg;
Vekotin 1:7ed7d128d225 106 msg.data[0] = CABLE_NUM | 0x0B;
Vekotin 1:7ed7d128d225 107 msg.data[1] = 0xB0 | (channel & 0x0F);
Vekotin 1:7ed7d128d225 108 msg.data[2] = control & 0x7F;
Vekotin 1:7ed7d128d225 109 msg.data[3] = value & 0x7F;
Vekotin 1:7ed7d128d225 110 return msg;
Vekotin 1:7ed7d128d225 111 }
Vekotin 1:7ed7d128d225 112
Vekotin 1:7ed7d128d225 113 /** Create a Program Change message
Vekotin 1:7ed7d128d225 114 * @param program Program ID
Vekotin 1:7ed7d128d225 115 * @param channel Channel (0-15, default 0)
Vekotin 1:7ed7d128d225 116 * @returns A MIDIMessage
Vekotin 1:7ed7d128d225 117 */
Vekotin 1:7ed7d128d225 118 static MIDIMessage ProgramChange(int program, int channel = 0) {
Vekotin 1:7ed7d128d225 119 MIDIMessage msg;
Vekotin 1:7ed7d128d225 120 msg.data[0] = CABLE_NUM | 0x0C;
Vekotin 1:7ed7d128d225 121 msg.data[1] = 0xC0 | (channel & 0x0F);
Vekotin 1:7ed7d128d225 122 msg.data[2] = program & 0x7F;
Vekotin 1:7ed7d128d225 123 msg.data[3] = 0x00;
Vekotin 1:7ed7d128d225 124 return msg;
Vekotin 1:7ed7d128d225 125 }
Vekotin 1:7ed7d128d225 126
Vekotin 1:7ed7d128d225 127 /** Create a Channel Aftertouch message
Vekotin 1:7ed7d128d225 128 * @param pressure Pressure
Vekotin 1:7ed7d128d225 129 * @param channel Key channel (0-15, default 0)
Vekotin 1:7ed7d128d225 130 * @returns A MIDIMessage
Vekotin 1:7ed7d128d225 131 */
Vekotin 1:7ed7d128d225 132 static MIDIMessage ChannelAftertouch(int pressure, int channel = 0) {
Vekotin 1:7ed7d128d225 133 MIDIMessage msg;
Vekotin 1:7ed7d128d225 134 msg.data[0] = CABLE_NUM | 0x0D;
Vekotin 1:7ed7d128d225 135 msg.data[1] = 0xD0 | (channel & 0x0F);
Vekotin 1:7ed7d128d225 136 msg.data[2] = pressure & 0x7F;
Vekotin 1:7ed7d128d225 137 msg.data[3] = 0x00;
Vekotin 1:7ed7d128d225 138 return msg;
Vekotin 1:7ed7d128d225 139 }
Vekotin 1:7ed7d128d225 140
Vekotin 1:7ed7d128d225 141 /** Create a Pitch Wheel message
Vekotin 1:7ed7d128d225 142 * @param pitch Pitch (-8192 - 8191, default = 0)
Vekotin 1:7ed7d128d225 143 * @param channel Channel (0-15, default 0)
Vekotin 1:7ed7d128d225 144 * @returns A MIDIMessage
Vekotin 1:7ed7d128d225 145 */
Vekotin 1:7ed7d128d225 146 static MIDIMessage PitchWheel(int pitch = 0, int channel = 0) {
Vekotin 1:7ed7d128d225 147 MIDIMessage msg;
Vekotin 1:7ed7d128d225 148 int p = pitch + 8192; // 0 - 16383, 8192 is center
Vekotin 1:7ed7d128d225 149 msg.data[0] = CABLE_NUM | 0x0E;
Vekotin 1:7ed7d128d225 150 msg.data[1] = 0xE0 | (channel & 0x0F);
Vekotin 1:7ed7d128d225 151 msg.data[2] = p & 0x7F;
Vekotin 1:7ed7d128d225 152 msg.data[3] = (p >> 7) & 0x7F;
Vekotin 1:7ed7d128d225 153 return msg;
Vekotin 1:7ed7d128d225 154 }
Vekotin 1:7ed7d128d225 155
Vekotin 1:7ed7d128d225 156 /** Create an All Notes Off message
Vekotin 1:7ed7d128d225 157 * @param channel Channel (0-15, default 0)
Vekotin 1:7ed7d128d225 158 * @returns A MIDIMessage
Vekotin 1:7ed7d128d225 159 */
Vekotin 1:7ed7d128d225 160 static MIDIMessage AllNotesOff(int channel = 0) {
Vekotin 1:7ed7d128d225 161 return ControlChange(123, 0, channel);
Vekotin 1:7ed7d128d225 162 }
Vekotin 1:7ed7d128d225 163
Vekotin 1:7ed7d128d225 164 // decode messages
Vekotin 1:7ed7d128d225 165
Vekotin 1:7ed7d128d225 166 /** MIDI Message Types */
Vekotin 1:7ed7d128d225 167 enum MIDIMessageType {
Vekotin 1:7ed7d128d225 168 ErrorType,
Vekotin 1:7ed7d128d225 169 NoteOffType,
Vekotin 1:7ed7d128d225 170 NoteOnType,
Vekotin 1:7ed7d128d225 171 PolyphonicAftertouchType,
Vekotin 1:7ed7d128d225 172 ControlChangeType,
Vekotin 1:7ed7d128d225 173 ProgramChangeType,
Vekotin 1:7ed7d128d225 174 ChannelAftertouchType,
Vekotin 1:7ed7d128d225 175 PitchWheelType,
Vekotin 1:7ed7d128d225 176 AllNotesOffType
Vekotin 1:7ed7d128d225 177 };
Vekotin 1:7ed7d128d225 178
Vekotin 1:7ed7d128d225 179 /** Read the message type
Vekotin 1:7ed7d128d225 180 * @returns MIDIMessageType
Vekotin 1:7ed7d128d225 181 */
Vekotin 1:7ed7d128d225 182 MIDIMessageType type() {
Vekotin 1:7ed7d128d225 183 switch((data[1] >> 4) & 0xF) {
Vekotin 1:7ed7d128d225 184 case 0x8: return NoteOffType;
Vekotin 1:7ed7d128d225 185 case 0x9: return NoteOnType;
Vekotin 1:7ed7d128d225 186 case 0xA: return PolyphonicAftertouchType;
Vekotin 1:7ed7d128d225 187 case 0xB:
Vekotin 1:7ed7d128d225 188 if(controller() < 120) { // standard controllers
Vekotin 1:7ed7d128d225 189 return ControlChangeType;
Vekotin 1:7ed7d128d225 190 } else if(controller() == 123) {
Vekotin 1:7ed7d128d225 191 return AllNotesOffType;
Vekotin 1:7ed7d128d225 192 } else {
Vekotin 1:7ed7d128d225 193 return ErrorType; // unsupported atm
Vekotin 1:7ed7d128d225 194 }
Vekotin 1:7ed7d128d225 195 case 0xC: return ProgramChangeType;
Vekotin 1:7ed7d128d225 196 case 0xD: return ChannelAftertouchType;
Vekotin 1:7ed7d128d225 197 case 0xE: return PitchWheelType;
Vekotin 1:7ed7d128d225 198 default: return ErrorType;
Vekotin 1:7ed7d128d225 199 }
Vekotin 1:7ed7d128d225 200 }
Vekotin 1:7ed7d128d225 201
Vekotin 1:7ed7d128d225 202 /** Read the channel number */
Vekotin 1:7ed7d128d225 203 int channel() {
Vekotin 1:7ed7d128d225 204 return (data[1] & 0x0F);
Vekotin 1:7ed7d128d225 205 }
Vekotin 1:7ed7d128d225 206
Vekotin 1:7ed7d128d225 207 /** Read the key ID */
Vekotin 1:7ed7d128d225 208 int key() {
Vekotin 1:7ed7d128d225 209 return (data[2] & 0x7F);
Vekotin 1:7ed7d128d225 210 }
Vekotin 1:7ed7d128d225 211
Vekotin 1:7ed7d128d225 212 /** Read the velocity */
Vekotin 1:7ed7d128d225 213 int velocity() {
Vekotin 1:7ed7d128d225 214 return (data[3] & 0x7F);
Vekotin 1:7ed7d128d225 215 }
Vekotin 1:7ed7d128d225 216
Vekotin 1:7ed7d128d225 217 /** Read the controller value */
Vekotin 1:7ed7d128d225 218 int value() {
Vekotin 1:7ed7d128d225 219 return (data[3] & 0x7F);
Vekotin 1:7ed7d128d225 220 }
Vekotin 1:7ed7d128d225 221
Vekotin 1:7ed7d128d225 222 /** Read the aftertouch pressure */
Vekotin 1:7ed7d128d225 223 int pressure() {
Vekotin 1:7ed7d128d225 224 if(type() == PolyphonicAftertouchType) {
Vekotin 1:7ed7d128d225 225 return (data[3] & 0x7F);
Vekotin 1:7ed7d128d225 226 } else {
Vekotin 1:7ed7d128d225 227 return (data[2] & 0x7F);
Vekotin 1:7ed7d128d225 228 }
Vekotin 1:7ed7d128d225 229 }
Vekotin 1:7ed7d128d225 230
Vekotin 1:7ed7d128d225 231 /** Read the controller number */
Vekotin 1:7ed7d128d225 232 int controller() {
Vekotin 1:7ed7d128d225 233 return (data[2] & 0x7F);
Vekotin 1:7ed7d128d225 234 }
Vekotin 1:7ed7d128d225 235
Vekotin 1:7ed7d128d225 236 /** Read the program number */
Vekotin 1:7ed7d128d225 237 int program() {
Vekotin 1:7ed7d128d225 238 return (data[2] & 0x7F);
Vekotin 1:7ed7d128d225 239 }
Vekotin 1:7ed7d128d225 240
Vekotin 1:7ed7d128d225 241 /** Read the pitch value */
Vekotin 1:7ed7d128d225 242 int pitch() {
Vekotin 1:7ed7d128d225 243 int p = ((data[3] & 0x7F) << 7) | (data[2] & 0x7F);
Vekotin 1:7ed7d128d225 244 return p - 8192; // 0 - 16383, 8192 is center
Vekotin 1:7ed7d128d225 245 }
Vekotin 1:7ed7d128d225 246
Vekotin 1:7ed7d128d225 247 uint8_t data[4];
Vekotin 1:7ed7d128d225 248 };
Vekotin 1:7ed7d128d225 249
Vekotin 1:7ed7d128d225 250 #endif