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

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?

UserRevisionLine numberNew 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 }