Uses *spark d-fuser controller hardware as a USB-DMX interface. Developed for visualising Laurel Pardue’s augmented violin with lights.
Dependencies: DMX mbed spk_oled_ssd1305
main.cpp@0:59b1d685427c, 2015-05-09 (annotated)
- Committer:
- tobyspark
- Date:
- Sat May 09 20:11:58 2015 +0000
- Revision:
- 0:59b1d685427c
- Child:
- 1:f0cc153fe8d3
Initial Commit. Working with Laurel's Violin.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
tobyspark | 0:59b1d685427c | 1 | #include "mbed.h" |
tobyspark | 0:59b1d685427c | 2 | #include "DMX.h" |
tobyspark | 0:59b1d685427c | 3 | #include "spk_oled_ssd1305.h" |
tobyspark | 0:59b1d685427c | 4 | #include "spk_oled_gfx.h" |
tobyspark | 0:59b1d685427c | 5 | |
tobyspark | 0:59b1d685427c | 6 | #define kUSB_BAUD 57600 |
tobyspark | 0:59b1d685427c | 7 | |
tobyspark | 0:59b1d685427c | 8 | // MBED PINS |
tobyspark | 0:59b1d685427c | 9 | |
tobyspark | 0:59b1d685427c | 10 | #define kMBED_AIN_XFADE p20 |
tobyspark | 0:59b1d685427c | 11 | #define kMBED_AIN_FADEUP p19 |
tobyspark | 0:59b1d685427c | 12 | #define kMBED_DIN_TAP_L p24 |
tobyspark | 0:59b1d685427c | 13 | #define kMBED_DIN_TAP_R p23 |
tobyspark | 0:59b1d685427c | 14 | #define kMBED_ENC_SW p15 |
tobyspark | 0:59b1d685427c | 15 | #define kMBED_ENC_A p16 |
tobyspark | 0:59b1d685427c | 16 | #define kMBED_ENC_B p17 |
tobyspark | 0:59b1d685427c | 17 | |
tobyspark | 0:59b1d685427c | 18 | #define kMBED_RS232_TTLTX p13 |
tobyspark | 0:59b1d685427c | 19 | #define kMBED_RS232_TTLRX p14 |
tobyspark | 0:59b1d685427c | 20 | |
tobyspark | 0:59b1d685427c | 21 | #define kMBED_OLED_MOSI p5 |
tobyspark | 0:59b1d685427c | 22 | #define kMBED_OLED_SCK p7 |
tobyspark | 0:59b1d685427c | 23 | #define kMBED_OLED_CS p8 |
tobyspark | 0:59b1d685427c | 24 | #define kMBED_OLED_RES p9 |
tobyspark | 0:59b1d685427c | 25 | #define kMBED_OLED_DC p10 |
tobyspark | 0:59b1d685427c | 26 | |
tobyspark | 0:59b1d685427c | 27 | #define kMBED_DIN_ETHLO_DMXHI p30 |
tobyspark | 0:59b1d685427c | 28 | #define kMBED_DOUT_RS485_TXHI_RXLO p29 |
tobyspark | 0:59b1d685427c | 29 | #define kMBED_RS485_TTLTX p28 |
tobyspark | 0:59b1d685427c | 30 | #define kMBED_RS485_TTLRX p27 |
tobyspark | 0:59b1d685427c | 31 | |
tobyspark | 0:59b1d685427c | 32 | // DMX Fixtures |
tobyspark | 0:59b1d685427c | 33 | |
tobyspark | 0:59b1d685427c | 34 | #define kDMX_PARCAN_1 4 |
tobyspark | 0:59b1d685427c | 35 | #define kDMX_PARCAN_2 8 |
tobyspark | 0:59b1d685427c | 36 | #define kDMX_PARCAN_3 12 |
tobyspark | 0:59b1d685427c | 37 | #define kDMX_PARCAN_4 16 |
tobyspark | 0:59b1d685427c | 38 | |
tobyspark | 0:59b1d685427c | 39 | #define kDMX_PARCAN_R 0 |
tobyspark | 0:59b1d685427c | 40 | #define kDMX_PARCAN_G 1 |
tobyspark | 0:59b1d685427c | 41 | #define kDMX_PARCAN_B 2 |
tobyspark | 0:59b1d685427c | 42 | #define kDMX_PARCAN_LUMA 3 |
tobyspark | 0:59b1d685427c | 43 | |
tobyspark | 0:59b1d685427c | 44 | // MISC Defines |
tobyspark | 0:59b1d685427c | 45 | |
tobyspark | 0:59b1d685427c | 46 | #define kStringBufferLength 30 |
tobyspark | 0:59b1d685427c | 47 | |
tobyspark | 0:59b1d685427c | 48 | //// USB Serial |
tobyspark | 0:59b1d685427c | 49 | |
tobyspark | 0:59b1d685427c | 50 | Serial usbSerial(USBTX, USBRX); |
tobyspark | 0:59b1d685427c | 51 | |
tobyspark | 0:59b1d685427c | 52 | //// DMX |
tobyspark | 0:59b1d685427c | 53 | |
tobyspark | 0:59b1d685427c | 54 | DigitalIn rj45ModeDIN(kMBED_DIN_ETHLO_DMXHI); |
tobyspark | 0:59b1d685427c | 55 | DigitalOut dmxDirectionDOUT(kMBED_DOUT_RS485_TXHI_RXLO); |
tobyspark | 0:59b1d685427c | 56 | enum { rj45Ethernet = 0, rj45DMX = 1}; // These values from circuit |
tobyspark | 0:59b1d685427c | 57 | |
tobyspark | 0:59b1d685427c | 58 | DMX dmx(kMBED_RS485_TTLTX, kMBED_RS485_TTLRX); |
tobyspark | 0:59b1d685427c | 59 | |
tobyspark | 0:59b1d685427c | 60 | //// Display |
tobyspark | 0:59b1d685427c | 61 | |
tobyspark | 0:59b1d685427c | 62 | // SPKDisplay(PinName mosi, PinName clk, PinName cs, PinName dc, PinName res, Serial *debugSerial = NULL); |
tobyspark | 0:59b1d685427c | 63 | SPKDisplay screen(kMBED_OLED_MOSI, kMBED_OLED_SCK, kMBED_OLED_CS, kMBED_OLED_DC, kMBED_OLED_RES, NULL); |
tobyspark | 0:59b1d685427c | 64 | |
tobyspark | 0:59b1d685427c | 65 | //// mbed input |
tobyspark | 0:59b1d685427c | 66 | |
tobyspark | 0:59b1d685427c | 67 | DigitalIn button(kMBED_DIN_TAP_L); |
tobyspark | 0:59b1d685427c | 68 | bool buttonLastState; |
tobyspark | 0:59b1d685427c | 69 | |
tobyspark | 0:59b1d685427c | 70 | string usbSerialString; |
tobyspark | 0:59b1d685427c | 71 | bool newData = false; |
tobyspark | 0:59b1d685427c | 72 | |
tobyspark | 0:59b1d685427c | 73 | //// LAUREL VIOLIN DATA |
tobyspark | 0:59b1d685427c | 74 | |
tobyspark | 0:59b1d685427c | 75 | // [T: A, B] - T = timestamp. A is the time count (in minutes or something. Not presently very useful), B is sample count. I can change what is creating the stamp. Also, as I'm using sample count, this is only useful/changes when I record. |
tobyspark | 0:59b1d685427c | 76 | int TA, TB; |
tobyspark | 0:59b1d685427c | 77 | |
tobyspark | 0:59b1d685427c | 78 | // [P: A, B] - P = pitch. A is hardware estimate- i.e the pitch estimate that is determined solely from the fingerboard data. B is the combined hardware + audio data (more accurate, slightly slower). -1 = no data/not confident enough to estimate |
tobyspark | 0:59b1d685427c | 79 | float P1A, P1B, P2A, P2B, P3A, P3B, P4A, P4B; |
tobyspark | 0:59b1d685427c | 80 | |
tobyspark | 0:59b1d685427c | 81 | // [S: A] = signal strength. A is RMS of audio signal in the buffer. |
tobyspark | 0:59b1d685427c | 82 | float S1, S2, S3, S4; |
tobyspark | 0:59b1d685427c | 83 | |
tobyspark | 0:59b1d685427c | 84 | // [F: A, B, C, D] = finger on string raw data. generally ranges 1 (no contact) to like .4, 1 being no string down, .9 being low pitch near nut, .4 higher up in pitch closer to the bridge. A is G string (i think) |
tobyspark | 0:59b1d685427c | 85 | float F1, F2, F3, F4; |
tobyspark | 0:59b1d685427c | 86 | |
tobyspark | 0:59b1d685427c | 87 | // [B: A, B, C, D] = raw bow data, A is sensor closest to frog, D closest to tip. |
tobyspark | 0:59b1d685427c | 88 | float B1, B2, B3, B4; |
tobyspark | 0:59b1d685427c | 89 | |
tobyspark | 0:59b1d685427c | 90 | // [E: A, B, C] = bow Estimate. (currently broken) This should be A - pos estimate (0 to 1 normalized frog to tip), B- pressure (0 -400?) and C- on string/off (0, 1 if B is > 40) 0 for A/B means it isn't ready to estimate. -1 means bow off string. |
tobyspark | 0:59b1d685427c | 91 | float EA, EB; |
tobyspark | 0:59b1d685427c | 92 | int EC; |
tobyspark | 0:59b1d685427c | 93 | |
tobyspark | 0:59b1d685427c | 94 | // TOBY VIOLIN EXTRAS |
tobyspark | 0:59b1d685427c | 95 | |
tobyspark | 0:59b1d685427c | 96 | float sMax = 0.2; |
tobyspark | 0:59b1d685427c | 97 | float sMultiplier = 255.0/sMax; |
tobyspark | 0:59b1d685427c | 98 | |
tobyspark | 0:59b1d685427c | 99 | void usbSerialReceive(void) |
tobyspark | 0:59b1d685427c | 100 | { |
tobyspark | 0:59b1d685427c | 101 | char receivedChar; |
tobyspark | 0:59b1d685427c | 102 | |
tobyspark | 0:59b1d685427c | 103 | //if data is ready in the buffer |
tobyspark | 0:59b1d685427c | 104 | while (usbSerial.readable()) |
tobyspark | 0:59b1d685427c | 105 | { |
tobyspark | 0:59b1d685427c | 106 | receivedChar = usbSerial.getc(); |
tobyspark | 0:59b1d685427c | 107 | |
tobyspark | 0:59b1d685427c | 108 | // Is end of line? |
tobyspark | 0:59b1d685427c | 109 | if (receivedChar == '\n' || receivedChar == '\r') |
tobyspark | 0:59b1d685427c | 110 | { |
tobyspark | 0:59b1d685427c | 111 | // [T: 352, 16896000],[P: 196, -1, 196, -1, 196, -1, 196, -1],[S: 0, 0, 0, 0],[F: 1, 1, 1, 1],[B: 0.5346, 0.5781, 0.9043, 0.9029],[E: 0, 0, 0] |
tobyspark | 0:59b1d685427c | 112 | int scanCount; |
tobyspark | 0:59b1d685427c | 113 | // scanCount = sscanf( |
tobyspark | 0:59b1d685427c | 114 | // usbSerialString.c_str(), |
tobyspark | 0:59b1d685427c | 115 | // "[T: %d, %d],[P: %f, %f, %f, %f, %f, %f, %f, %f],[S: %f, %f, %f, %f],[F: %f, %f, %f, %f],[B: %f, %f, %f, %f],[E: %f, %f, %d]", |
tobyspark | 0:59b1d685427c | 116 | // &TA, &TB, &P1A, &P1B, &P2A, &P2B, &P3A, &P3B, &P4A, &P4B, &S1, &S2, &S3, &S4, &F1, &F2, &F3, &F4, &B1, &B2, &B3, &B4, &EA, &EB, &EC |
tobyspark | 0:59b1d685427c | 117 | // ); |
tobyspark | 0:59b1d685427c | 118 | // if (scanCount == 25) |
tobyspark | 0:59b1d685427c | 119 | scanCount = sscanf( |
tobyspark | 0:59b1d685427c | 120 | usbSerialString.c_str(), |
tobyspark | 0:59b1d685427c | 121 | "[S: %f, %f, %f, %f],[E: %f, %f, %d]", |
tobyspark | 0:59b1d685427c | 122 | &S1, &S2, &S3, &S4, &EA, &EB, &EC |
tobyspark | 0:59b1d685427c | 123 | ); |
tobyspark | 0:59b1d685427c | 124 | |
tobyspark | 0:59b1d685427c | 125 | if (scanCount == 7) |
tobyspark | 0:59b1d685427c | 126 | { |
tobyspark | 0:59b1d685427c | 127 | newData = true; |
tobyspark | 0:59b1d685427c | 128 | } |
tobyspark | 0:59b1d685427c | 129 | else |
tobyspark | 0:59b1d685427c | 130 | { |
tobyspark | 0:59b1d685427c | 131 | screen.textToBuffer("Read vars failed", 6); |
tobyspark | 0:59b1d685427c | 132 | } |
tobyspark | 0:59b1d685427c | 133 | |
tobyspark | 0:59b1d685427c | 134 | // Clear to start again |
tobyspark | 0:59b1d685427c | 135 | usbSerialString.clear(); |
tobyspark | 0:59b1d685427c | 136 | } |
tobyspark | 0:59b1d685427c | 137 | else |
tobyspark | 0:59b1d685427c | 138 | { |
tobyspark | 0:59b1d685427c | 139 | // Build string up |
tobyspark | 0:59b1d685427c | 140 | usbSerialString += receivedChar; |
tobyspark | 0:59b1d685427c | 141 | |
tobyspark | 0:59b1d685427c | 142 | screen.textToBuffer(usbSerialString.c_str(),4); |
tobyspark | 0:59b1d685427c | 143 | } |
tobyspark | 0:59b1d685427c | 144 | } |
tobyspark | 0:59b1d685427c | 145 | } |
tobyspark | 0:59b1d685427c | 146 | |
tobyspark | 0:59b1d685427c | 147 | //// M A I N |
tobyspark | 0:59b1d685427c | 148 | int main() { |
tobyspark | 0:59b1d685427c | 149 | |
tobyspark | 0:59b1d685427c | 150 | // Set display font |
tobyspark | 0:59b1d685427c | 151 | screen.fontStartCharacter = &characterBytesStartChar; |
tobyspark | 0:59b1d685427c | 152 | screen.fontEndCharacter = &characterBytesEndChar; |
tobyspark | 0:59b1d685427c | 153 | screen.fontCharacters = characterBytes; |
tobyspark | 0:59b1d685427c | 154 | |
tobyspark | 0:59b1d685427c | 155 | // Splash screen |
tobyspark | 0:59b1d685427c | 156 | screen.imageToBuffer(spkDisplayLogo); |
tobyspark | 0:59b1d685427c | 157 | screen.textToBuffer("SPK:DMXer",0); |
tobyspark | 0:59b1d685427c | 158 | screen.textToBuffer("FRATRES 2015",1); |
tobyspark | 0:59b1d685427c | 159 | screen.textToBuffer("SW v01",2); |
tobyspark | 0:59b1d685427c | 160 | screen.sendBuffer(); |
tobyspark | 0:59b1d685427c | 161 | |
tobyspark | 0:59b1d685427c | 162 | if (rj45ModeDIN == rj45DMX) screen.textToBuffer("RJ45: DMX Mode", 3); |
tobyspark | 0:59b1d685427c | 163 | else screen.textToBuffer("RJ45: Ethernet Mode", 3); |
tobyspark | 0:59b1d685427c | 164 | screen.sendBuffer(); |
tobyspark | 0:59b1d685427c | 165 | |
tobyspark | 0:59b1d685427c | 166 | dmxDirectionDOUT = 1; |
tobyspark | 0:59b1d685427c | 167 | dmx.start(); |
tobyspark | 0:59b1d685427c | 168 | |
tobyspark | 0:59b1d685427c | 169 | // unsigned char parCanData[4]; |
tobyspark | 0:59b1d685427c | 170 | // parCanData[kDMX_PARCAN_R] = 255; |
tobyspark | 0:59b1d685427c | 171 | // parCanData[kDMX_PARCAN_G] = 255; |
tobyspark | 0:59b1d685427c | 172 | // parCanData[kDMX_PARCAN_B] = 255; |
tobyspark | 0:59b1d685427c | 173 | // parCanData[kDMX_PARCAN_LUMA] = 0; |
tobyspark | 0:59b1d685427c | 174 | // dmx.put(parCanData, kDMX_PARCAN_1, 4); |
tobyspark | 0:59b1d685427c | 175 | // dmx.put(parCanData, kDMX_PARCAN_2, 4); |
tobyspark | 0:59b1d685427c | 176 | // dmx.put(parCanData, kDMX_PARCAN_3, 4); |
tobyspark | 0:59b1d685427c | 177 | // dmx.put(parCanData, kDMX_PARCAN_4, 4); |
tobyspark | 0:59b1d685427c | 178 | |
tobyspark | 0:59b1d685427c | 179 | dmx.put(kDMX_PARCAN_1+kDMX_PARCAN_R, 255); |
tobyspark | 0:59b1d685427c | 180 | dmx.put(kDMX_PARCAN_1+kDMX_PARCAN_G, 255); |
tobyspark | 0:59b1d685427c | 181 | dmx.put(kDMX_PARCAN_1+kDMX_PARCAN_B, 255); |
tobyspark | 0:59b1d685427c | 182 | dmx.put(kDMX_PARCAN_1+kDMX_PARCAN_LUMA, 0); |
tobyspark | 0:59b1d685427c | 183 | |
tobyspark | 0:59b1d685427c | 184 | dmx.put(kDMX_PARCAN_2+kDMX_PARCAN_R, 255); |
tobyspark | 0:59b1d685427c | 185 | dmx.put(kDMX_PARCAN_2+kDMX_PARCAN_G, 255); |
tobyspark | 0:59b1d685427c | 186 | dmx.put(kDMX_PARCAN_2+kDMX_PARCAN_B, 255); |
tobyspark | 0:59b1d685427c | 187 | dmx.put(kDMX_PARCAN_2+kDMX_PARCAN_LUMA, 0); |
tobyspark | 0:59b1d685427c | 188 | |
tobyspark | 0:59b1d685427c | 189 | dmx.put(kDMX_PARCAN_3+kDMX_PARCAN_R, 255); |
tobyspark | 0:59b1d685427c | 190 | dmx.put(kDMX_PARCAN_3+kDMX_PARCAN_G, 255); |
tobyspark | 0:59b1d685427c | 191 | dmx.put(kDMX_PARCAN_3+kDMX_PARCAN_B, 255); |
tobyspark | 0:59b1d685427c | 192 | dmx.put(kDMX_PARCAN_3+kDMX_PARCAN_LUMA, 0); |
tobyspark | 0:59b1d685427c | 193 | |
tobyspark | 0:59b1d685427c | 194 | dmx.put(kDMX_PARCAN_4+kDMX_PARCAN_R, 255); |
tobyspark | 0:59b1d685427c | 195 | dmx.put(kDMX_PARCAN_4+kDMX_PARCAN_G, 255); |
tobyspark | 0:59b1d685427c | 196 | dmx.put(kDMX_PARCAN_4+kDMX_PARCAN_B, 255); |
tobyspark | 0:59b1d685427c | 197 | dmx.put(kDMX_PARCAN_4+kDMX_PARCAN_LUMA, 0); |
tobyspark | 0:59b1d685427c | 198 | |
tobyspark | 0:59b1d685427c | 199 | //// Serial |
tobyspark | 0:59b1d685427c | 200 | usbSerial.baud(kUSB_BAUD); |
tobyspark | 0:59b1d685427c | 201 | usbSerial.attach(usbSerialReceive); |
tobyspark | 0:59b1d685427c | 202 | |
tobyspark | 0:59b1d685427c | 203 | //// TASK: Prime button change detection |
tobyspark | 0:59b1d685427c | 204 | buttonLastState = button; |
tobyspark | 0:59b1d685427c | 205 | |
tobyspark | 0:59b1d685427c | 206 | //// TASK: GO! |
tobyspark | 0:59b1d685427c | 207 | |
tobyspark | 0:59b1d685427c | 208 | // We've finished setting up, now loop this forever... |
tobyspark | 0:59b1d685427c | 209 | while (true) |
tobyspark | 0:59b1d685427c | 210 | { |
tobyspark | 0:59b1d685427c | 211 | if (newData) |
tobyspark | 0:59b1d685427c | 212 | { |
tobyspark | 0:59b1d685427c | 213 | char S1DMX = S1 * sMultiplier; |
tobyspark | 0:59b1d685427c | 214 | char S2DMX = S2 * sMultiplier; |
tobyspark | 0:59b1d685427c | 215 | char S3DMX = S3 * sMultiplier; |
tobyspark | 0:59b1d685427c | 216 | char S4DMX = S4 * sMultiplier; |
tobyspark | 0:59b1d685427c | 217 | dmx.put(kDMX_PARCAN_1+kDMX_PARCAN_LUMA, S1DMX); |
tobyspark | 0:59b1d685427c | 218 | dmx.put(kDMX_PARCAN_2+kDMX_PARCAN_LUMA, S2DMX); |
tobyspark | 0:59b1d685427c | 219 | dmx.put(kDMX_PARCAN_3+kDMX_PARCAN_LUMA, S3DMX); |
tobyspark | 0:59b1d685427c | 220 | dmx.put(kDMX_PARCAN_4+kDMX_PARCAN_LUMA, S4DMX); |
tobyspark | 0:59b1d685427c | 221 | |
tobyspark | 0:59b1d685427c | 222 | char dmxSummary[kStringBufferLength]; |
tobyspark | 0:59b1d685427c | 223 | snprintf(dmxSummary, kStringBufferLength, "S %03u %03u %03u %03u", S1DMX, S2DMX, S3DMX, S4DMX); |
tobyspark | 0:59b1d685427c | 224 | screen.textToBuffer(dmxSummary,6); |
tobyspark | 0:59b1d685427c | 225 | |
tobyspark | 0:59b1d685427c | 226 | newData = false; |
tobyspark | 0:59b1d685427c | 227 | } |
tobyspark | 0:59b1d685427c | 228 | |
tobyspark | 0:59b1d685427c | 229 | // Has the button changed? |
tobyspark | 0:59b1d685427c | 230 | if (button != buttonLastState) { |
tobyspark | 0:59b1d685427c | 231 | // If so, lets update the lastState variable and then send an OSC message |
tobyspark | 0:59b1d685427c | 232 | buttonLastState = button; |
tobyspark | 0:59b1d685427c | 233 | |
tobyspark | 0:59b1d685427c | 234 | if (button) screen.textToBuffer("Sent: /mbed/button 1",5); |
tobyspark | 0:59b1d685427c | 235 | else screen.textToBuffer("Sent: /mbed/button 0",5); |
tobyspark | 0:59b1d685427c | 236 | } |
tobyspark | 0:59b1d685427c | 237 | |
tobyspark | 0:59b1d685427c | 238 | // for (int i = 0; i<256; i++) |
tobyspark | 0:59b1d685427c | 239 | // { |
tobyspark | 0:59b1d685427c | 240 | // for (int j = 0; j<256; j++) |
tobyspark | 0:59b1d685427c | 241 | // { |
tobyspark | 0:59b1d685427c | 242 | // dmx.put(j, i); |
tobyspark | 0:59b1d685427c | 243 | // } |
tobyspark | 0:59b1d685427c | 244 | // wait(0.01); |
tobyspark | 0:59b1d685427c | 245 | // } |
tobyspark | 0:59b1d685427c | 246 | |
tobyspark | 0:59b1d685427c | 247 | screen.sendBuffer(); |
tobyspark | 0:59b1d685427c | 248 | } |
tobyspark | 0:59b1d685427c | 249 | } |