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@1:f0cc153fe8d3, 2015-05-13 (annotated)
- Committer:
- tobyspark
- Date:
- Wed May 13 18:35:06 2015 +0000
- Revision:
- 1:f0cc153fe8d3
- Parent:
- 0:59b1d685427c
- Child:
- 2:24d9b7a3073c
c++ string to c buffer
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 | 1:f0cc153fe8d3 | 6 | // https://developer.mbed.org/forum/mbed/post/4526/ |
tobyspark | 1:f0cc153fe8d3 | 7 | // 110, 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 57600, 115200, 230400, 460800, 921600 |
tobyspark | 0:59b1d685427c | 8 | #define kUSB_BAUD 57600 |
tobyspark | 0:59b1d685427c | 9 | |
tobyspark | 0:59b1d685427c | 10 | // MBED PINS |
tobyspark | 0:59b1d685427c | 11 | |
tobyspark | 0:59b1d685427c | 12 | #define kMBED_AIN_XFADE p20 |
tobyspark | 0:59b1d685427c | 13 | #define kMBED_AIN_FADEUP p19 |
tobyspark | 0:59b1d685427c | 14 | #define kMBED_DIN_TAP_L p24 |
tobyspark | 0:59b1d685427c | 15 | #define kMBED_DIN_TAP_R p23 |
tobyspark | 0:59b1d685427c | 16 | #define kMBED_ENC_SW p15 |
tobyspark | 0:59b1d685427c | 17 | #define kMBED_ENC_A p16 |
tobyspark | 0:59b1d685427c | 18 | #define kMBED_ENC_B p17 |
tobyspark | 0:59b1d685427c | 19 | |
tobyspark | 0:59b1d685427c | 20 | #define kMBED_RS232_TTLTX p13 |
tobyspark | 0:59b1d685427c | 21 | #define kMBED_RS232_TTLRX p14 |
tobyspark | 0:59b1d685427c | 22 | |
tobyspark | 0:59b1d685427c | 23 | #define kMBED_OLED_MOSI p5 |
tobyspark | 0:59b1d685427c | 24 | #define kMBED_OLED_SCK p7 |
tobyspark | 0:59b1d685427c | 25 | #define kMBED_OLED_CS p8 |
tobyspark | 0:59b1d685427c | 26 | #define kMBED_OLED_RES p9 |
tobyspark | 0:59b1d685427c | 27 | #define kMBED_OLED_DC p10 |
tobyspark | 0:59b1d685427c | 28 | |
tobyspark | 0:59b1d685427c | 29 | #define kMBED_DIN_ETHLO_DMXHI p30 |
tobyspark | 0:59b1d685427c | 30 | #define kMBED_DOUT_RS485_TXHI_RXLO p29 |
tobyspark | 0:59b1d685427c | 31 | #define kMBED_RS485_TTLTX p28 |
tobyspark | 0:59b1d685427c | 32 | #define kMBED_RS485_TTLRX p27 |
tobyspark | 0:59b1d685427c | 33 | |
tobyspark | 0:59b1d685427c | 34 | // DMX Fixtures |
tobyspark | 0:59b1d685427c | 35 | |
tobyspark | 0:59b1d685427c | 36 | #define kDMX_PARCAN_1 4 |
tobyspark | 0:59b1d685427c | 37 | #define kDMX_PARCAN_2 8 |
tobyspark | 0:59b1d685427c | 38 | #define kDMX_PARCAN_3 12 |
tobyspark | 0:59b1d685427c | 39 | #define kDMX_PARCAN_4 16 |
tobyspark | 0:59b1d685427c | 40 | |
tobyspark | 0:59b1d685427c | 41 | #define kDMX_PARCAN_R 0 |
tobyspark | 0:59b1d685427c | 42 | #define kDMX_PARCAN_G 1 |
tobyspark | 0:59b1d685427c | 43 | #define kDMX_PARCAN_B 2 |
tobyspark | 0:59b1d685427c | 44 | #define kDMX_PARCAN_LUMA 3 |
tobyspark | 0:59b1d685427c | 45 | |
tobyspark | 0:59b1d685427c | 46 | // MISC Defines |
tobyspark | 0:59b1d685427c | 47 | |
tobyspark | 0:59b1d685427c | 48 | #define kStringBufferLength 30 |
tobyspark | 1:f0cc153fe8d3 | 49 | #define kUSBSerialBufferLength 256 |
tobyspark | 0:59b1d685427c | 50 | |
tobyspark | 0:59b1d685427c | 51 | //// USB Serial |
tobyspark | 0:59b1d685427c | 52 | |
tobyspark | 0:59b1d685427c | 53 | Serial usbSerial(USBTX, USBRX); |
tobyspark | 0:59b1d685427c | 54 | |
tobyspark | 0:59b1d685427c | 55 | //// DMX |
tobyspark | 0:59b1d685427c | 56 | |
tobyspark | 0:59b1d685427c | 57 | DigitalIn rj45ModeDIN(kMBED_DIN_ETHLO_DMXHI); |
tobyspark | 0:59b1d685427c | 58 | DigitalOut dmxDirectionDOUT(kMBED_DOUT_RS485_TXHI_RXLO); |
tobyspark | 0:59b1d685427c | 59 | enum { rj45Ethernet = 0, rj45DMX = 1}; // These values from circuit |
tobyspark | 0:59b1d685427c | 60 | |
tobyspark | 0:59b1d685427c | 61 | DMX dmx(kMBED_RS485_TTLTX, kMBED_RS485_TTLRX); |
tobyspark | 0:59b1d685427c | 62 | |
tobyspark | 0:59b1d685427c | 63 | //// Display |
tobyspark | 0:59b1d685427c | 64 | |
tobyspark | 0:59b1d685427c | 65 | // SPKDisplay(PinName mosi, PinName clk, PinName cs, PinName dc, PinName res, Serial *debugSerial = NULL); |
tobyspark | 0:59b1d685427c | 66 | SPKDisplay screen(kMBED_OLED_MOSI, kMBED_OLED_SCK, kMBED_OLED_CS, kMBED_OLED_DC, kMBED_OLED_RES, NULL); |
tobyspark | 0:59b1d685427c | 67 | |
tobyspark | 0:59b1d685427c | 68 | //// mbed input |
tobyspark | 0:59b1d685427c | 69 | |
tobyspark | 0:59b1d685427c | 70 | DigitalIn button(kMBED_DIN_TAP_L); |
tobyspark | 0:59b1d685427c | 71 | bool buttonLastState; |
tobyspark | 0:59b1d685427c | 72 | |
tobyspark | 1:f0cc153fe8d3 | 73 | char usbSerialBuffer[kUSBSerialBufferLength]; |
tobyspark | 1:f0cc153fe8d3 | 74 | int usbSerialBufferPosition = 0; |
tobyspark | 0:59b1d685427c | 75 | bool newData = false; |
tobyspark | 0:59b1d685427c | 76 | |
tobyspark | 0:59b1d685427c | 77 | //// LAUREL VIOLIN DATA |
tobyspark | 0:59b1d685427c | 78 | |
tobyspark | 0:59b1d685427c | 79 | // [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 | 80 | int TA, TB; |
tobyspark | 0:59b1d685427c | 81 | |
tobyspark | 0:59b1d685427c | 82 | // [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 | 83 | float P1A, P1B, P2A, P2B, P3A, P3B, P4A, P4B; |
tobyspark | 0:59b1d685427c | 84 | |
tobyspark | 0:59b1d685427c | 85 | // [S: A] = signal strength. A is RMS of audio signal in the buffer. |
tobyspark | 0:59b1d685427c | 86 | float S1, S2, S3, S4; |
tobyspark | 0:59b1d685427c | 87 | |
tobyspark | 0:59b1d685427c | 88 | // [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 | 89 | float F1, F2, F3, F4; |
tobyspark | 0:59b1d685427c | 90 | |
tobyspark | 0:59b1d685427c | 91 | // [B: A, B, C, D] = raw bow data, A is sensor closest to frog, D closest to tip. |
tobyspark | 0:59b1d685427c | 92 | float B1, B2, B3, B4; |
tobyspark | 0:59b1d685427c | 93 | |
tobyspark | 0:59b1d685427c | 94 | // [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 | 95 | float EA, EB; |
tobyspark | 0:59b1d685427c | 96 | int EC; |
tobyspark | 0:59b1d685427c | 97 | |
tobyspark | 0:59b1d685427c | 98 | // TOBY VIOLIN EXTRAS |
tobyspark | 0:59b1d685427c | 99 | |
tobyspark | 0:59b1d685427c | 100 | float sMax = 0.2; |
tobyspark | 0:59b1d685427c | 101 | float sMultiplier = 255.0/sMax; |
tobyspark | 0:59b1d685427c | 102 | |
tobyspark | 0:59b1d685427c | 103 | void usbSerialReceive(void) |
tobyspark | 0:59b1d685427c | 104 | { |
tobyspark | 0:59b1d685427c | 105 | char receivedChar; |
tobyspark | 0:59b1d685427c | 106 | |
tobyspark | 0:59b1d685427c | 107 | //if data is ready in the buffer |
tobyspark | 0:59b1d685427c | 108 | while (usbSerial.readable()) |
tobyspark | 0:59b1d685427c | 109 | { |
tobyspark | 0:59b1d685427c | 110 | receivedChar = usbSerial.getc(); |
tobyspark | 0:59b1d685427c | 111 | |
tobyspark | 0:59b1d685427c | 112 | // Is end of line? |
tobyspark | 0:59b1d685427c | 113 | if (receivedChar == '\n' || receivedChar == '\r') |
tobyspark | 0:59b1d685427c | 114 | { |
tobyspark | 0:59b1d685427c | 115 | // [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 | 116 | int scanCount; |
tobyspark | 0:59b1d685427c | 117 | // scanCount = sscanf( |
tobyspark | 0:59b1d685427c | 118 | // usbSerialString.c_str(), |
tobyspark | 0:59b1d685427c | 119 | // "[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 | 120 | // &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 | 121 | // ); |
tobyspark | 0:59b1d685427c | 122 | // if (scanCount == 25) |
tobyspark | 0:59b1d685427c | 123 | scanCount = sscanf( |
tobyspark | 1:f0cc153fe8d3 | 124 | usbSerialBuffer, |
tobyspark | 0:59b1d685427c | 125 | "[S: %f, %f, %f, %f],[E: %f, %f, %d]", |
tobyspark | 0:59b1d685427c | 126 | &S1, &S2, &S3, &S4, &EA, &EB, &EC |
tobyspark | 0:59b1d685427c | 127 | ); |
tobyspark | 0:59b1d685427c | 128 | |
tobyspark | 0:59b1d685427c | 129 | if (scanCount == 7) |
tobyspark | 0:59b1d685427c | 130 | { |
tobyspark | 0:59b1d685427c | 131 | newData = true; |
tobyspark | 0:59b1d685427c | 132 | } |
tobyspark | 0:59b1d685427c | 133 | else |
tobyspark | 0:59b1d685427c | 134 | { |
tobyspark | 0:59b1d685427c | 135 | screen.textToBuffer("Read vars failed", 6); |
tobyspark | 0:59b1d685427c | 136 | } |
tobyspark | 0:59b1d685427c | 137 | |
tobyspark | 0:59b1d685427c | 138 | // Clear to start again |
tobyspark | 1:f0cc153fe8d3 | 139 | usbSerialBufferPosition = 0; |
tobyspark | 0:59b1d685427c | 140 | } |
tobyspark | 1:f0cc153fe8d3 | 141 | else if (usbSerialBufferPosition < kUSBSerialBufferLength) |
tobyspark | 0:59b1d685427c | 142 | { |
tobyspark | 0:59b1d685427c | 143 | // Build string up |
tobyspark | 1:f0cc153fe8d3 | 144 | usbSerialBuffer[usbSerialBufferPosition++] = receivedChar; |
tobyspark | 1:f0cc153fe8d3 | 145 | usbSerialBuffer[usbSerialBufferPosition] = 0; |
tobyspark | 0:59b1d685427c | 146 | |
tobyspark | 1:f0cc153fe8d3 | 147 | screen.textToBuffer(usbSerialBuffer,4); |
tobyspark | 0:59b1d685427c | 148 | } |
tobyspark | 0:59b1d685427c | 149 | } |
tobyspark | 0:59b1d685427c | 150 | } |
tobyspark | 0:59b1d685427c | 151 | |
tobyspark | 0:59b1d685427c | 152 | //// M A I N |
tobyspark | 0:59b1d685427c | 153 | int main() { |
tobyspark | 0:59b1d685427c | 154 | |
tobyspark | 0:59b1d685427c | 155 | // Set display font |
tobyspark | 0:59b1d685427c | 156 | screen.fontStartCharacter = &characterBytesStartChar; |
tobyspark | 0:59b1d685427c | 157 | screen.fontEndCharacter = &characterBytesEndChar; |
tobyspark | 0:59b1d685427c | 158 | screen.fontCharacters = characterBytes; |
tobyspark | 0:59b1d685427c | 159 | |
tobyspark | 0:59b1d685427c | 160 | // Splash screen |
tobyspark | 0:59b1d685427c | 161 | screen.imageToBuffer(spkDisplayLogo); |
tobyspark | 0:59b1d685427c | 162 | screen.textToBuffer("SPK:DMXer",0); |
tobyspark | 0:59b1d685427c | 163 | screen.textToBuffer("FRATRES 2015",1); |
tobyspark | 0:59b1d685427c | 164 | screen.textToBuffer("SW v01",2); |
tobyspark | 0:59b1d685427c | 165 | screen.sendBuffer(); |
tobyspark | 0:59b1d685427c | 166 | |
tobyspark | 0:59b1d685427c | 167 | if (rj45ModeDIN == rj45DMX) screen.textToBuffer("RJ45: DMX Mode", 3); |
tobyspark | 0:59b1d685427c | 168 | else screen.textToBuffer("RJ45: Ethernet Mode", 3); |
tobyspark | 0:59b1d685427c | 169 | screen.sendBuffer(); |
tobyspark | 0:59b1d685427c | 170 | |
tobyspark | 0:59b1d685427c | 171 | dmxDirectionDOUT = 1; |
tobyspark | 0:59b1d685427c | 172 | dmx.start(); |
tobyspark | 0:59b1d685427c | 173 | |
tobyspark | 0:59b1d685427c | 174 | // unsigned char parCanData[4]; |
tobyspark | 0:59b1d685427c | 175 | // parCanData[kDMX_PARCAN_R] = 255; |
tobyspark | 0:59b1d685427c | 176 | // parCanData[kDMX_PARCAN_G] = 255; |
tobyspark | 0:59b1d685427c | 177 | // parCanData[kDMX_PARCAN_B] = 255; |
tobyspark | 0:59b1d685427c | 178 | // parCanData[kDMX_PARCAN_LUMA] = 0; |
tobyspark | 0:59b1d685427c | 179 | // dmx.put(parCanData, kDMX_PARCAN_1, 4); |
tobyspark | 0:59b1d685427c | 180 | // dmx.put(parCanData, kDMX_PARCAN_2, 4); |
tobyspark | 0:59b1d685427c | 181 | // dmx.put(parCanData, kDMX_PARCAN_3, 4); |
tobyspark | 0:59b1d685427c | 182 | // dmx.put(parCanData, kDMX_PARCAN_4, 4); |
tobyspark | 0:59b1d685427c | 183 | |
tobyspark | 0:59b1d685427c | 184 | dmx.put(kDMX_PARCAN_1+kDMX_PARCAN_R, 255); |
tobyspark | 0:59b1d685427c | 185 | dmx.put(kDMX_PARCAN_1+kDMX_PARCAN_G, 255); |
tobyspark | 0:59b1d685427c | 186 | dmx.put(kDMX_PARCAN_1+kDMX_PARCAN_B, 255); |
tobyspark | 0:59b1d685427c | 187 | dmx.put(kDMX_PARCAN_1+kDMX_PARCAN_LUMA, 0); |
tobyspark | 0:59b1d685427c | 188 | |
tobyspark | 0:59b1d685427c | 189 | dmx.put(kDMX_PARCAN_2+kDMX_PARCAN_R, 255); |
tobyspark | 0:59b1d685427c | 190 | dmx.put(kDMX_PARCAN_2+kDMX_PARCAN_G, 255); |
tobyspark | 0:59b1d685427c | 191 | dmx.put(kDMX_PARCAN_2+kDMX_PARCAN_B, 255); |
tobyspark | 0:59b1d685427c | 192 | dmx.put(kDMX_PARCAN_2+kDMX_PARCAN_LUMA, 0); |
tobyspark | 0:59b1d685427c | 193 | |
tobyspark | 0:59b1d685427c | 194 | dmx.put(kDMX_PARCAN_3+kDMX_PARCAN_R, 255); |
tobyspark | 0:59b1d685427c | 195 | dmx.put(kDMX_PARCAN_3+kDMX_PARCAN_G, 255); |
tobyspark | 0:59b1d685427c | 196 | dmx.put(kDMX_PARCAN_3+kDMX_PARCAN_B, 255); |
tobyspark | 0:59b1d685427c | 197 | dmx.put(kDMX_PARCAN_3+kDMX_PARCAN_LUMA, 0); |
tobyspark | 0:59b1d685427c | 198 | |
tobyspark | 0:59b1d685427c | 199 | dmx.put(kDMX_PARCAN_4+kDMX_PARCAN_R, 255); |
tobyspark | 0:59b1d685427c | 200 | dmx.put(kDMX_PARCAN_4+kDMX_PARCAN_G, 255); |
tobyspark | 0:59b1d685427c | 201 | dmx.put(kDMX_PARCAN_4+kDMX_PARCAN_B, 255); |
tobyspark | 0:59b1d685427c | 202 | dmx.put(kDMX_PARCAN_4+kDMX_PARCAN_LUMA, 0); |
tobyspark | 0:59b1d685427c | 203 | |
tobyspark | 0:59b1d685427c | 204 | //// Serial |
tobyspark | 0:59b1d685427c | 205 | usbSerial.baud(kUSB_BAUD); |
tobyspark | 0:59b1d685427c | 206 | usbSerial.attach(usbSerialReceive); |
tobyspark | 0:59b1d685427c | 207 | |
tobyspark | 0:59b1d685427c | 208 | //// TASK: Prime button change detection |
tobyspark | 0:59b1d685427c | 209 | buttonLastState = button; |
tobyspark | 0:59b1d685427c | 210 | |
tobyspark | 0:59b1d685427c | 211 | //// TASK: GO! |
tobyspark | 0:59b1d685427c | 212 | |
tobyspark | 0:59b1d685427c | 213 | // We've finished setting up, now loop this forever... |
tobyspark | 0:59b1d685427c | 214 | while (true) |
tobyspark | 0:59b1d685427c | 215 | { |
tobyspark | 0:59b1d685427c | 216 | if (newData) |
tobyspark | 0:59b1d685427c | 217 | { |
tobyspark | 0:59b1d685427c | 218 | char S1DMX = S1 * sMultiplier; |
tobyspark | 0:59b1d685427c | 219 | char S2DMX = S2 * sMultiplier; |
tobyspark | 0:59b1d685427c | 220 | char S3DMX = S3 * sMultiplier; |
tobyspark | 0:59b1d685427c | 221 | char S4DMX = S4 * sMultiplier; |
tobyspark | 0:59b1d685427c | 222 | dmx.put(kDMX_PARCAN_1+kDMX_PARCAN_LUMA, S1DMX); |
tobyspark | 0:59b1d685427c | 223 | dmx.put(kDMX_PARCAN_2+kDMX_PARCAN_LUMA, S2DMX); |
tobyspark | 0:59b1d685427c | 224 | dmx.put(kDMX_PARCAN_3+kDMX_PARCAN_LUMA, S3DMX); |
tobyspark | 0:59b1d685427c | 225 | dmx.put(kDMX_PARCAN_4+kDMX_PARCAN_LUMA, S4DMX); |
tobyspark | 0:59b1d685427c | 226 | |
tobyspark | 0:59b1d685427c | 227 | char dmxSummary[kStringBufferLength]; |
tobyspark | 0:59b1d685427c | 228 | snprintf(dmxSummary, kStringBufferLength, "S %03u %03u %03u %03u", S1DMX, S2DMX, S3DMX, S4DMX); |
tobyspark | 0:59b1d685427c | 229 | screen.textToBuffer(dmxSummary,6); |
tobyspark | 0:59b1d685427c | 230 | |
tobyspark | 0:59b1d685427c | 231 | newData = false; |
tobyspark | 0:59b1d685427c | 232 | } |
tobyspark | 0:59b1d685427c | 233 | |
tobyspark | 0:59b1d685427c | 234 | // Has the button changed? |
tobyspark | 0:59b1d685427c | 235 | if (button != buttonLastState) { |
tobyspark | 0:59b1d685427c | 236 | // If so, lets update the lastState variable and then send an OSC message |
tobyspark | 0:59b1d685427c | 237 | buttonLastState = button; |
tobyspark | 0:59b1d685427c | 238 | |
tobyspark | 0:59b1d685427c | 239 | if (button) screen.textToBuffer("Sent: /mbed/button 1",5); |
tobyspark | 0:59b1d685427c | 240 | else screen.textToBuffer("Sent: /mbed/button 0",5); |
tobyspark | 0:59b1d685427c | 241 | } |
tobyspark | 0:59b1d685427c | 242 | |
tobyspark | 0:59b1d685427c | 243 | // for (int i = 0; i<256; i++) |
tobyspark | 0:59b1d685427c | 244 | // { |
tobyspark | 0:59b1d685427c | 245 | // for (int j = 0; j<256; j++) |
tobyspark | 0:59b1d685427c | 246 | // { |
tobyspark | 0:59b1d685427c | 247 | // dmx.put(j, i); |
tobyspark | 0:59b1d685427c | 248 | // } |
tobyspark | 0:59b1d685427c | 249 | // wait(0.01); |
tobyspark | 0:59b1d685427c | 250 | // } |
tobyspark | 0:59b1d685427c | 251 | |
tobyspark | 0:59b1d685427c | 252 | screen.sendBuffer(); |
tobyspark | 0:59b1d685427c | 253 | } |
tobyspark | 0:59b1d685427c | 254 | } |