OSC-CV Converter

Dependencies:   Bonjour OSCReceiver TextLCD mbed mbed-rpc BurstSPI DebouncedInterrupt FastIO MIDI OSC OSCtoCV ClockControl

OSC to CV Converter

http://gtbts.tumblr.com/post/125663817741/osc-to-cv-converter-ver2-mbed-osctocv

/media/uploads/casiotone401/tumblr_nsg7y4pkfg1qlle9fo1_540.png

Revision:
4:b9f5ae574447
Parent:
3:ca15241dd6b4
Child:
5:e305509d53f3
--- a/main.cpp	Fri Jan 11 11:33:55 2013 +0000
+++ b/main.cpp	Sat Jan 19 12:03:20 2013 +0000
@@ -41,6 +41,8 @@
 #define MODE_QDor           3       // Dorian
 #define MODE_Q5th           4       // 5th
 #define MODE_QWht           5       // Wholetone
+#define MODE_SEQ            6       // Sequencer & Shift Register
+#define MODE_Calb           7       // Calibration (VCO Tuning)
 
 #define QUAN_RES1           116     // Quantize voltage Steps
 #define QUAN_RES2           69
@@ -48,7 +50,7 @@
 #define QUAN_RES4           17
 #define QUAN_RES5           58
 
-#define MODE_NUM            6        // Modes
+#define MODE_NUM            8        // Modes
 
 #define SPI_RATE            40000000 // 40Mbps SPI Clock
 #define SCALING_N           38400.0
@@ -77,15 +79,17 @@
 //-------------------------------------------------------------
 // Functions
 
-void NetPoll(void);
+inline void NetPoll(void);
 void InitOSCCV(void);
-void UpdateCV(unsigned char, unsigned char, unsigned int);
+inline void UpdateCV(int, int, const unsigned int*);
 void SetCV(void);
+void SeqCV(void);
 void CheckSW(void);
-void CVMeter(unsigned int, unsigned int);
+void CVMeter(int, const unsigned int*);
+void LCD();
 void WriteCustomChar(unsigned char, unsigned char*);
 int  SetupEthNetIf(void);
-void onUDPSocketEvent(UDPSocketEvent);
+inline void onUDPSocketEvent(UDPSocketEvent);
 
 //-------------------------------------------------------------
 // Silentway Calibration Data Mapping
@@ -164,7 +168,7 @@
 
 };
 
-//  5th
+//  Whole tone
 const float calibMap5[QUAN_RES5] = {
 0.00663080,    0.02202980,    0.03742880,    0.05282781,    0.06822681,
 0.08362581,    0.09902481,    0.11442380,    0.12951356,    0.14392516,
@@ -196,8 +200,12 @@
 //-------------------------------------------------------------
 // Global Variables
 
-float           gOSC_cv[8];
-float           gGlide;
+static float    gOSC_cv[8];
+static float    gSeq_cv1[8];
+static float    gSeq_cv2[8];
+static float    gGlide;
+static float    gCtrl[2];
+unsigned int    gCtrlSW[2];
 unsigned int    gMode;
 
 //-------------------------------------------------------------
@@ -216,7 +224,7 @@
 AnalogIn    gAIN(p17);  // Glide Potentiometer
 InterruptIn gSW(p30);   // Mode SW
 
-Ticker      gSetter;    // Ticker SetCV
+Timer       gTimer;     // Timer
 Ticker      gPoller;    // Ticker Polling
 
 // Ethernet
@@ -228,12 +236,11 @@
  
 int main() 
 { 
-    int i;
     float pot, _pot;
     
     if(SetupEthNetIf() == -1)
     {
-        for(i = 0; i < 4; i++) 
+        for(int i = 0; i < 4; i++) 
         {
             gLEDS[i] = 1;
             wait(0.25);
@@ -244,6 +251,7 @@
     // mdns (Bonjour)
     HTTPServer svr;
     mDNSResponder mdns;
+    
     svr.addHandler<SimpleHandler>("/");
     svr.bind(INPUT_PORT);
     IpAddr ip = gEth.getIp();
@@ -251,34 +259,41 @@
     
     InitOSCCV();
     
-    pot = _pot = 0; 
-    
-    gLCD.locate( 9, 0 );
-    gLCD.printf("OSC-CV");
+    pot = _pot = 0;
+    gGlide = gMode = 0;
+        
+    LCD();
     gLCD.locate( 0, 1 );
     gLCD.printf("12345678 G>>%3.2f", gGlide);
     
-    
     // loop
     while(1) 
     {
         gGlide = pot = gAIN.read();
         
-        if(abs(pot - _pot) > 0.01) 
+        if(abs(pot - _pot) > 0.01f) 
         {
             gLCD.locate( 0, 1 );
             gLCD.printf("12345678 G>>%3.2f", gGlide);
+            
             _pot = gAIN.read();
         }
         
-        SetCV();
+        if(gMode == MODE_SEQ)
+        {
+            SeqCV();
+            
+        } else {
+
+            SetCV();
+        }
     }
 }
 
 //-------------------------------------------------------------
 // Ethernet Polling
 
-void NetPoll()
+inline void NetPoll()
 {
     Net::poll();
 }
@@ -305,11 +320,9 @@
     
     UpdateCV(CLR, 0, 0);    // Ignore CLR Pin
     
-    gSW.mode(PullUp);       //Use internal pullup for ModeSW
+    gSW.mode(PullUp);       // Use internal pullup for ModeSW
     wait(.001);
     
-    gMode = 0;
-    
     gSW.rise(&CheckSW);     // InterruptIn rising edge(ModeSW)
     gPoller.attach_us(&NetPoll, POLLING_INTERVAL);  // Ticker Polling
     
@@ -320,44 +333,43 @@
 // SPI Transfer
 // DAC8568 data word length 32bit (8bit shift out)
 
-void UpdateCV(unsigned char control, unsigned char address, unsigned int data)
+inline void UpdateCV(int control, int address, const unsigned int *data)
 {
     __disable_irq();
     
     switch(control)
     {
         case WRITE_UPDATE_N:
-        {   
+
             gSYNCMODE = _DISABLE;
-            gSPI.write(00000000|control);           //padding at beginning of byte and control bits
-            gSPI.write(address << 4 | data >> 12);  //address(ch) bits
-            gSPI.write((data << 4) >> 8);           // middle 8 bits of data
-            gSPI.write((data << 12) >> 8 | 00001111);
+            gSPI.write(00000000|control);            // padding at beginning of byte and control bits
+            gSPI.write(address << 4 | *data >> 12);  // address(ch) bits
+            gSPI.write((*data << 4) >> 8);           // middle 8 bits of data
+            gSPI.write((*data << 12) >> 8 | 00001111);
             gSYNCMODE = _ENABLE;
             gLDAC = _DISABLE;
             gLDAC = _ENABLE;
             break;
-        }
+
         case RESET:
-        {   
+
             gSYNCMODE = _DISABLE;
-            gSPI.write(00000111);   //Software RESET
+            gSPI.write(00000111);   // Software RESET
             gSPI.write(00000000);
             gSPI.write(00000000);
             gSPI.write(00000000);
             gSYNCMODE = _ENABLE;
             break;
-        }
+
         case CLR:
-        {            
+        
             gSYNCMODE = _DISABLE;
-            gSPI.write(00000101);   //CLR Register
+            gSPI.write(00000101);   // CLR Register
             gSPI.write(00000000);
             gSPI.write(00000000);
-            gSPI.write(00000011);   //Ignore CLR Pin
+            gSPI.write(00000011);   // Ignore CLR Pin
             gSYNCMODE = _ENABLE;
             break;
-        }
     }
     
     __enable_irq();
@@ -368,7 +380,7 @@
 
 void SetCV()
 {
-    static unsigned int ch;
+    static int ch;
     float glidecv[8];
     unsigned int cv[8];
     static float oldcv[8];
@@ -378,94 +390,314 @@
     switch(gMode) 
         {
             case MODE_LIN:
-            
+                
                 glidecv[ch] = oldcv[ch] * gGlide + gOSC_cv[ch] * (1.0f - gGlide);
                 oldcv[ch] = glidecv[ch];
                 cv[ch] = (unsigned int)glidecv[ch];
                     
-                UpdateCV(WRITE_UPDATE_N, ch, cv[ch]);
+                UpdateCV(WRITE_UPDATE_N, ch, &cv[ch]);
                 break;
                     
             case MODE_QChr:
             
-                quan = 43690 / QUAN_RES1;
-                qcv = calibMap1[(unsigned int)(gOSC_cv[ch] / quan )];
+                quan = 40616 / QUAN_RES1;
+                qcv = calibMap1[(unsigned int)(gOSC_cv[ch] / quan)];
+                    
+                glidecv[ch] = oldcv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+                oldcv[ch] = glidecv[ch];
+                cv[ch] = (unsigned int)glidecv[ch];
+                        
+                UpdateCV(WRITE_UPDATE_N, ch, &cv[ch]);
+                break;
+                
+            case MODE_QMaj:
+                
+                quan = 40616 / QUAN_RES2;
+                qcv = calibMap2[(unsigned int)(gOSC_cv[ch] / quan)];
                     
                 glidecv[ch] = oldcv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
                 oldcv[ch] = glidecv[ch];
                 cv[ch] = (unsigned int)glidecv[ch];
                         
-                UpdateCV(WRITE_UPDATE_N, ch, cv[ch]);
+                UpdateCV(WRITE_UPDATE_N, ch, &cv[ch]);
                 break;
+                    
+            case MODE_QDor:
                 
-            case MODE_QMaj:
-                
-                quan = 43690 / QUAN_RES2;
-                qcv = calibMap2[(unsigned int)(gOSC_cv[ch] / quan )];
+                quan = 40616 / QUAN_RES3;
+                qcv = calibMap3[(unsigned int)(gOSC_cv[ch] / quan)];
                     
                 glidecv[ch] = oldcv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
                 oldcv[ch] = glidecv[ch];
                 cv[ch] = (unsigned int)glidecv[ch];
                         
-                UpdateCV(WRITE_UPDATE_N, ch, cv[ch]);
+                UpdateCV(WRITE_UPDATE_N, ch, &cv[ch]);
                 break;
+                
+            case MODE_Q5th:
+                
+                quan = 40616 / QUAN_RES4;
+                qcv = calibMap4[(unsigned int)(gOSC_cv[ch] / quan)];
                     
-            case MODE_QDor:
+                glidecv[ch] = oldcv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+                oldcv[ch] = glidecv[ch];
+                cv[ch] = (unsigned int)glidecv[ch];
+                        
+                UpdateCV(WRITE_UPDATE_N, ch, &cv[ch]);
+                break;
                 
-                quan = 43690 / QUAN_RES3;
-                qcv = calibMap3[(unsigned int)(gOSC_cv[ch] / quan )];
+            case MODE_QWht:
+                
+                quan = 40616 / QUAN_RES5;
+                qcv = calibMap5[(unsigned int)(gOSC_cv[ch] / quan)];
                     
                 glidecv[ch] = oldcv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
                 oldcv[ch] = glidecv[ch];
                 cv[ch] = (unsigned int)glidecv[ch];
                         
-                UpdateCV(WRITE_UPDATE_N, ch, cv[ch]);
-                break;
-                
-            case MODE_Q5th:
-                
-                quan = 43690 / QUAN_RES4;
-                qcv = calibMap4[(unsigned int)(gOSC_cv[ch] / quan )];
-                    
-                glidecv[ch] = oldcv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
-                oldcv[ch] = glidecv[ch];
-                cv[ch] = (unsigned int)glidecv[ch];
-                        
-                UpdateCV(WRITE_UPDATE_N, ch, cv[ch]);
+                UpdateCV(WRITE_UPDATE_N, ch, &cv[ch]);
                 break;
                 
-            case MODE_QWht:
+            case MODE_Calb:
                 
-                quan = 43690 / QUAN_RES5;
-                qcv = calibMap5[(unsigned int)(gOSC_cv[ch] / quan )];
-                    
-                glidecv[ch] = oldcv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
-                oldcv[ch] = glidecv[ch];
-                cv[ch] = (unsigned int)glidecv[ch];
+                cv[ch] = 19212;     // A440.0Hz
                         
-                UpdateCV(WRITE_UPDATE_N, ch, cv[ch]);
+                UpdateCV(WRITE_UPDATE_N, ch, &cv[ch]);
                 break;
         }
+
+        CVMeter(ch, &cv[ch]);
         
-        CVMeter(ch, cv[ch]);
         ch++;
         ch &= 0x07;
 }
 
 //-------------------------------------------------------------
+// Sequence & Shift Out CV
+
+void SeqCV()
+{
+    static int ch;
+    static int count;
+    static unsigned int SeqMode;
+    static float glidecv[8];
+    unsigned int cv[8];
+    static float shiftcv[8];
+    static unsigned int quan;
+    float qcv;
+    static float clock;
+    static float time;
+    
+    SeqMode = (unsigned int)(gCtrl[1] * (MODE_NUM - 3)); // Sequencer Quantize Mode
+    
+    time = gTimer.read();
+    clock = gCtrl[0] * 0.5 + 0.01;
+    
+    gLEDS[0] = gGATES[0] = 0;       // Trigger
+    
+    if(time > (clock / 2)) 
+    {
+        gLEDS[1] = gGATES[1] = 0;   // Gate
+        
+    } else if (count % 2) {
+            
+        gLEDS[2] = gGATES[2] = 0;
+        
+    } else if (count % 3) {
+            
+        gLEDS[3] = gGATES[3] = 0;
+        count = 0;
+    }
+    
+    switch(SeqMode) 
+        {
+            case MODE_LIN:
+            
+                if(ch < 8)
+                {
+                    glidecv[0] = glidecv[0] * gGlide + gSeq_cv1[ch] * (1.0f - gGlide);
+                            
+                } else {
+                        
+                    glidecv[0] = glidecv[0] * gGlide + gSeq_cv2[ch-8] * (1.0f - gGlide);
+                }
+                
+                cv[0] = (unsigned int)glidecv[0];
+                
+                UpdateCV(WRITE_UPDATE_N, 0, &cv[0]);
+                break;
+                    
+            case MODE_QChr:
+            
+                quan = 40616 / QUAN_RES1;
+                
+                if(ch < 8)
+                {
+                    qcv = calibMap1[(unsigned int)(gSeq_cv1[ch] / quan)];
+                            
+                } else {
+                        
+                    qcv = calibMap1[(unsigned int)(gSeq_cv2[ch-8] / quan)];
+                }
+                    
+                glidecv[0] = glidecv[0] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+                cv[0] = (unsigned int)glidecv[0];
+                
+                UpdateCV(WRITE_UPDATE_N, 0, &cv[0]);
+                break;
+                
+            case MODE_QMaj:
+                
+                quan = 40616 / QUAN_RES2;
+                
+                if(ch < 8)
+                {
+                    qcv = calibMap2[(unsigned int)(gSeq_cv1[ch] / quan)];
+                            
+                } else {
+                        
+                    qcv = calibMap2[(unsigned int)(gSeq_cv2[ch-8] / quan)];
+                }
+                    
+                glidecv[0] = glidecv[0] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+                cv[0] = (unsigned int)glidecv[0];
+                
+                UpdateCV(WRITE_UPDATE_N, 0, &cv[0]);
+                break;
+                    
+            case MODE_QDor:
+                
+                quan = 40616 / QUAN_RES3;
+                
+                if(ch < 8)
+                {
+                    qcv = calibMap3[(unsigned int)(gSeq_cv1[ch] / quan)];
+                            
+                } else {
+                        
+                    qcv = calibMap3[(unsigned int)(gSeq_cv2[ch-8] / quan)];
+                }
+                
+                glidecv[0] = glidecv[0] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+                cv[0] = (unsigned int)glidecv[0];
+                
+                UpdateCV(WRITE_UPDATE_N, 0, &cv[0]);
+                break;
+                
+            case MODE_Q5th:
+                
+                quan = 40616 / QUAN_RES4;
+                
+                if(ch < 8)
+                {
+                    qcv = calibMap4[(unsigned int)(gSeq_cv1[ch] / quan)];
+                            
+                } else {
+                        
+                    qcv = calibMap4[(unsigned int)(gSeq_cv2[ch-8] / quan)];
+                }
+                
+                glidecv[0] = glidecv[0] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+                cv[0] = (unsigned int)glidecv[0];
+                
+                UpdateCV(WRITE_UPDATE_N, 0, &cv[0]);
+                break;
+                
+            case MODE_QWht:
+                
+                quan = 40616 / QUAN_RES5;
+                
+                if(ch < 8)
+                {
+                    qcv = calibMap5[(unsigned int)(gSeq_cv1[ch] / quan)];
+                            
+                } else {
+                        
+                    qcv = calibMap5[(unsigned int)(gSeq_cv2[ch-8] / quan)];
+                }
+                    
+                glidecv[0] = glidecv[0] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+                cv[0] = (unsigned int)glidecv[0];
+                
+                UpdateCV(WRITE_UPDATE_N, 0, &cv[0]);
+                break;
+        }
+        
+        for(int i = 1; i < 8; ++i)
+        {
+            glidecv[i] = glidecv[i] * gGlide + shiftcv[i] * (1.0f - gGlide);
+            cv[i] = (unsigned int)glidecv[i];
+                    
+            UpdateCV(WRITE_UPDATE_N, i, &cv[i]);            
+        }
+        
+        if(time > clock)
+        {
+            gLEDS[0] = gGATES[0] = 1;
+            gLEDS[1] = gGATES[1] = 1;
+            gLEDS[2] = gGATES[2] = 1;
+            gLEDS[3] = gGATES[3] = 1;
+            
+            count++;
+            
+            for(int j = 1; j < 8; ++j)      // Shift Note
+            {
+                shiftcv[j] = glidecv[j-1];
+            }
+            
+            ch++;
+            ch &= 0x0F;
+            gTimer.reset();
+        }
+        
+        if(ch < 8)
+        {
+            CVMeter(ch, &cv[0]);
+                            
+        } else {
+                        
+            CVMeter((ch-8), &cv[0]);
+        }
+}
+
+//-------------------------------------------------------------
 // Check SW
 
-void CheckSW() 
+void CheckSW()
 {   
+    wait(0.01);
+    
     if(gMode < MODE_NUM - 1) 
     {   
         gMode++;
             
     } else {
-        
+                
         gMode = 0;
     }
     
+    LCD();
+}
+
+//-------------------------------------------------------------
+// CV meter
+
+void CVMeter(int ch, const unsigned int *level)
+{
+    unsigned int cvmeter;
+    
+    cvmeter = *level / 4860;
+    // cvmeter = *level / (SCALING_N / 7.9);
+        
+    gLCD.locate ( ch, 0 );
+    gLCD.putc(cvmeter);     // put custom char
+}
+
+//-------------------------------------------------------------
+// Print LCD Menu
+
+void LCD()
+{
     switch(gMode) 
         {
             case MODE_LIN:
@@ -497,23 +729,22 @@
                 gLCD.locate( 9, 0 );
                 gLCD.printf("QUAN_W "); 
                 break;
+                
+            case MODE_SEQ:  
+                gLCD.locate( 9, 0 );
+                gLCD.printf("ASRSEQ ");
+                
+                gTimer.start();     // Sequencer Timer Start
+                break;
+                
+            case MODE_Calb: 
+                gLCD.locate( 9, 0 );
+                gLCD.printf("Calibr "); 
+                break;
         }
 }
 
 //-------------------------------------------------------------
-// CV meter
-
-void CVMeter(unsigned int ch, unsigned int level)
-{
-    unsigned int cvmeter;
-    
-    cvmeter = level / (SCALING_N / 7.9);
-        
-    gLCD.locate ( ch, 0 );
-    gLCD.putc(cvmeter);     // put custom char
-}
-
-//-------------------------------------------------------------
 // Write command Custom Char LCD CGRAM(CV Meter) 
 
 void WriteCustomChar(unsigned char addr, unsigned char *c)
@@ -525,6 +756,7 @@
     {
         gLCD.writeCommand(addr | cnt);
         gLCD.writeData(*c);
+        
         cnt++;
         c++;
     }
@@ -545,7 +777,6 @@
         gLCD.locate( 0, 1 );
         gLCD.printf("Error in setup.");
 //  printf("Error %d in setup.\r\n", ethErr);
-        
         return -1;
     }
 //  printf("Setup OK\r\n");
@@ -554,10 +785,10 @@
     Host broadcast(IpAddr(gEth.getIp()[0], gEth.getIp()[1], gEth.getIp()[2], 255), INPUT_PORT, NULL);
     gUdp.setOnEvent(&onUDPSocketEvent);
     gUdp.bind(broadcast);
- 
+    
     gLCD.locate( 0, 1 );
     gLCD.printf("%03d.%03d.%03d.%03d", gEth.getIp()[0], gEth.getIp()[1], gEth.getIp()[2], gEth.getIp()[3]);
-    wait(2.0);
+    wait(1.0);
     
     return 0;
 }
@@ -565,14 +796,14 @@
 //-------------------------------------------------------------
 // Handller receive UDP Packet
 
-void onUDPSocketEvent(UDPSocketEvent e)
+inline void onUDPSocketEvent(UDPSocketEvent e)
 {
     union OSCarg msg[10];
     static int num;
     
     switch(e)
     {
-        case UDPSOCKET_READABLE: //The only event for now
+        case UDPSOCKET_READABLE: // The only event for now
         char buf[256] = {0};
         Host host;
             
@@ -587,10 +818,16 @@
             //  msg[0].address, msg[1].typeTag, msg[2].f, msg[2].i);
                 
             len = strlen(msg[0].address);
-            if(isdigit(msg[0].address[len-1])) num = msg[0].address[len-1] - '0' - 1;
-            else num = -1;
+            
+            if(isdigit(msg[0].address[len-1]))
+                
+                num = msg[0].address[len-1] - '0' - 1;
             
-            unsigned int absv = msg[2].f * 1; //convert -0 to 0
+            else
+                
+                num = -1;
+            
+            unsigned int absv = msg[2].f + 0; //convert -0 to 0
             
             // address pattern SYNC & GATE (Type Tag int, float)
             if((strncmp(msg[0].address+(len-1)-4, "sync", 4)==0) && (num == -1)) { 
@@ -616,6 +853,7 @@
                             if(absv >= 1 || msg[2].i >= 1) gLEDS[num] = gGATES[num] = 1;
                             else                           gLEDS[num] = gGATES[num] = 0;
                             break;
+                            
                             } else if ((strncmp(msg[0].address,"/1/multipush",12)==0) && (num != -1)) {
                                 if(num > 3) break;
                                 if(absv >= 1 || msg[2].i >= 1) gLEDS[num] = gGATES[num] = 1;
@@ -654,7 +892,31 @@
                                                 } else if ((strncmp(msg[0].address+(len-1)-12, "multifader1/", 12)==0) && (num != -1)) {
                                                     if(num > 7) break;
                                                     if(msg[1].typeTag[1] == 'f') gOSC_cv[num] = msg[2].f * (SCALING_N);
+                                                    break;
+                                                    
+                                                    } else if ((strncmp(msg[0].address+(len-1)-11, "sequencer1/", 11)==0) && (num != -1)) {
+                                                        if(num > 7) break;
+                                                        if(msg[1].typeTag[1] == 'f') gSeq_cv1[num] = msg[2].f * (SCALING_N);
+                                                        break;
+                                                        
+                                                        } else if ((strncmp(msg[0].address+(len-1)-11, "sequencer2/", 11)==0) && (num != -1)) {
+                                                            if(num > 7) break;
+                                                            if(msg[1].typeTag[1] == 'f') gSeq_cv2[num] = msg[2].f * (SCALING_N);
+                                                            break;
+                                                        }
+                                                
+                                                       // address pattern controller
+                                                        if ((strncmp(msg[0].address+(len-1)-6, "ctrlsw", 6)==0) && (num != -1)) {
+                                                            if(num > 2) break;
+                                                            if(absv >= 1 || msg[2].i >= 1) gCtrlSW[num] = 1;
+                                                            else                           gCtrlSW[num] = 0;
+                                                            break;
+                                                        
+                                                            } else if ((strncmp(msg[0].address+(len-1)-4, "ctrl", 4)==0) && (num != -1)) {
+                                                                if(num > 2) break;                                                     
+                                                                if(msg[1].typeTag[1] == 'f') gCtrl[num] = msg[2].f;
+                                                                break;
+                                                            }
+                                                        }                           
+                                                    }
                                                 }
-                                            }
-                                        }                           
-                                    }