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

Revision:
0:59b1d685427c
Child:
1:f0cc153fe8d3
diff -r 000000000000 -r 59b1d685427c main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat May 09 20:11:58 2015 +0000
@@ -0,0 +1,249 @@
+#include "mbed.h"
+#include "DMX.h"
+#include "spk_oled_ssd1305.h"
+#include "spk_oled_gfx.h"
+
+#define kUSB_BAUD 57600
+
+// MBED PINS
+
+#define kMBED_AIN_XFADE     p20
+#define kMBED_AIN_FADEUP    p19
+#define kMBED_DIN_TAP_L     p24
+#define kMBED_DIN_TAP_R     p23
+#define kMBED_ENC_SW        p15
+#define kMBED_ENC_A         p16
+#define kMBED_ENC_B         p17
+
+#define kMBED_RS232_TTLTX   p13
+#define kMBED_RS232_TTLRX   p14
+
+#define kMBED_OLED_MOSI     p5
+#define kMBED_OLED_SCK      p7
+#define kMBED_OLED_CS       p8
+#define kMBED_OLED_RES      p9
+#define kMBED_OLED_DC       p10
+
+#define kMBED_DIN_ETHLO_DMXHI       p30
+#define kMBED_DOUT_RS485_TXHI_RXLO  p29
+#define kMBED_RS485_TTLTX           p28
+#define kMBED_RS485_TTLRX           p27
+
+// DMX Fixtures
+
+#define kDMX_PARCAN_1 4
+#define kDMX_PARCAN_2 8
+#define kDMX_PARCAN_3 12
+#define kDMX_PARCAN_4 16
+
+#define kDMX_PARCAN_R 0
+#define kDMX_PARCAN_G 1
+#define kDMX_PARCAN_B 2
+#define kDMX_PARCAN_LUMA 3
+
+// MISC Defines
+
+#define kStringBufferLength 30
+
+//// USB Serial
+
+Serial usbSerial(USBTX, USBRX);
+
+//// DMX
+
+DigitalIn rj45ModeDIN(kMBED_DIN_ETHLO_DMXHI);
+DigitalOut dmxDirectionDOUT(kMBED_DOUT_RS485_TXHI_RXLO);
+enum { rj45Ethernet = 0, rj45DMX = 1}; // These values from circuit
+
+DMX dmx(kMBED_RS485_TTLTX, kMBED_RS485_TTLRX);
+
+//// Display
+
+// SPKDisplay(PinName mosi, PinName clk, PinName cs, PinName dc, PinName res, Serial *debugSerial = NULL);
+SPKDisplay screen(kMBED_OLED_MOSI, kMBED_OLED_SCK, kMBED_OLED_CS, kMBED_OLED_DC, kMBED_OLED_RES, NULL);
+
+//// mbed input
+
+DigitalIn button(kMBED_DIN_TAP_L);
+bool buttonLastState;
+
+string usbSerialString;
+bool newData = false;
+
+//// LAUREL VIOLIN DATA
+
+// [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.
+int TA, TB; 
+
+// [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
+float P1A, P1B, P2A, P2B, P3A, P3B, P4A, P4B;
+
+// [S: A] = signal strength.  A is RMS of audio signal in the buffer.
+float S1, S2, S3, S4;
+
+// [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)
+float F1, F2, F3, F4;
+
+// [B: A, B, C, D] = raw bow data, A is sensor closest to frog, D closest to tip. 
+float B1, B2, B3, B4;
+
+// [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.
+float EA, EB;
+int EC;
+
+// TOBY VIOLIN EXTRAS
+ 
+float sMax = 0.2;
+float sMultiplier = 255.0/sMax;
+ 
+void usbSerialReceive(void) 
+{
+    char receivedChar;
+ 
+    //if data is ready in the buffer
+    while (usbSerial.readable()) 
+    {
+        receivedChar = usbSerial.getc();
+ 
+        // Is end of line?
+        if (receivedChar == '\n' || receivedChar == '\r')
+        {
+            // [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]            
+            int scanCount;
+//            scanCount = sscanf(
+//                                usbSerialString.c_str(), 
+//                                "[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]",
+//                                &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
+//                               );
+//            if (scanCount == 25)
+            scanCount = sscanf(
+                                usbSerialString.c_str(), 
+                                "[S: %f, %f, %f, %f],[E: %f, %f, %d]",
+                                &S1, &S2, &S3, &S4, &EA, &EB, &EC
+                               );
+            
+            if (scanCount == 7)
+            {
+                newData = true;
+            }
+            else
+            {
+                screen.textToBuffer("Read vars failed", 6);        
+            }   
+            
+            // Clear to start again
+            usbSerialString.clear();
+        }
+        else
+        {
+            // Build string up
+            usbSerialString += receivedChar;
+            
+            screen.textToBuffer(usbSerialString.c_str(),4);
+        }
+    }
+}
+
+////  M A I N
+int main() {
+
+    // Set display font
+    screen.fontStartCharacter = &characterBytesStartChar;
+    screen.fontEndCharacter = &characterBytesEndChar;
+    screen.fontCharacters = characterBytes;
+    
+    // Splash screen
+    screen.imageToBuffer(spkDisplayLogo);
+    screen.textToBuffer("SPK:DMXer",0);
+    screen.textToBuffer("FRATRES 2015",1);
+    screen.textToBuffer("SW v01",2);
+    screen.sendBuffer();
+    
+    if (rj45ModeDIN == rj45DMX) screen.textToBuffer("RJ45: DMX Mode", 3);
+    else screen.textToBuffer("RJ45: Ethernet Mode", 3);
+    screen.sendBuffer();
+    
+    dmxDirectionDOUT = 1;
+    dmx.start();
+    
+//    unsigned char parCanData[4];
+//    parCanData[kDMX_PARCAN_R] = 255; 
+//    parCanData[kDMX_PARCAN_G] = 255; 
+//    parCanData[kDMX_PARCAN_B] = 255; 
+//    parCanData[kDMX_PARCAN_LUMA] = 0;
+//    dmx.put(parCanData, kDMX_PARCAN_1, 4);
+//    dmx.put(parCanData, kDMX_PARCAN_2, 4);
+//    dmx.put(parCanData, kDMX_PARCAN_3, 4);
+//    dmx.put(parCanData, kDMX_PARCAN_4, 4);
+
+    dmx.put(kDMX_PARCAN_1+kDMX_PARCAN_R, 255);
+    dmx.put(kDMX_PARCAN_1+kDMX_PARCAN_G, 255);
+    dmx.put(kDMX_PARCAN_1+kDMX_PARCAN_B, 255);
+    dmx.put(kDMX_PARCAN_1+kDMX_PARCAN_LUMA, 0);
+
+    dmx.put(kDMX_PARCAN_2+kDMX_PARCAN_R, 255);
+    dmx.put(kDMX_PARCAN_2+kDMX_PARCAN_G, 255);
+    dmx.put(kDMX_PARCAN_2+kDMX_PARCAN_B, 255);
+    dmx.put(kDMX_PARCAN_2+kDMX_PARCAN_LUMA, 0);
+        
+    dmx.put(kDMX_PARCAN_3+kDMX_PARCAN_R, 255);
+    dmx.put(kDMX_PARCAN_3+kDMX_PARCAN_G, 255);
+    dmx.put(kDMX_PARCAN_3+kDMX_PARCAN_B, 255);
+    dmx.put(kDMX_PARCAN_3+kDMX_PARCAN_LUMA, 0);
+    
+    dmx.put(kDMX_PARCAN_4+kDMX_PARCAN_R, 255);
+    dmx.put(kDMX_PARCAN_4+kDMX_PARCAN_G, 255);
+    dmx.put(kDMX_PARCAN_4+kDMX_PARCAN_B, 255);
+    dmx.put(kDMX_PARCAN_4+kDMX_PARCAN_LUMA, 0);
+
+    //// Serial
+    usbSerial.baud(kUSB_BAUD);
+    usbSerial.attach(usbSerialReceive);
+
+    //// TASK: Prime button change detection
+    buttonLastState = button;
+
+    //// TASK: GO!
+
+    // We've finished setting up, now loop this forever...
+    while (true) 
+    {            
+        if (newData)
+        {   
+            char S1DMX = S1 * sMultiplier;
+            char S2DMX = S2 * sMultiplier;
+            char S3DMX = S3 * sMultiplier;
+            char S4DMX = S4 * sMultiplier;        
+            dmx.put(kDMX_PARCAN_1+kDMX_PARCAN_LUMA, S1DMX);
+            dmx.put(kDMX_PARCAN_2+kDMX_PARCAN_LUMA, S2DMX);
+            dmx.put(kDMX_PARCAN_3+kDMX_PARCAN_LUMA, S3DMX);
+            dmx.put(kDMX_PARCAN_4+kDMX_PARCAN_LUMA, S4DMX);
+            
+            char dmxSummary[kStringBufferLength];
+            snprintf(dmxSummary, kStringBufferLength, "S %03u %03u %03u %03u", S1DMX, S2DMX, S3DMX, S4DMX);
+            screen.textToBuffer(dmxSummary,6);
+            
+            newData = false;
+        }
+        
+        // Has the button changed?
+        if (button != buttonLastState) {
+            // If so, lets update the lastState variable and then send an OSC message
+            buttonLastState = button;
+            
+            if (button) screen.textToBuffer("Sent: /mbed/button 1",5);
+            else        screen.textToBuffer("Sent: /mbed/button 0",5);            
+        }
+             
+//        for (int i = 0; i<256; i++)
+//        {
+//            for (int j = 0; j<256; j++)
+//            {
+//                dmx.put(j, i);
+//            }
+//            wait(0.01);
+//        }
+
+        screen.sendBuffer();
+    }
+}