Laser Sensing Display for UI interfaces in the real world

Dependencies:   mbed

Fork of skinGames_forktest by Alvaro Cassinelli

Revision:
1:a4050fee11f7
Parent:
0:345b3bc7a0ea
Child:
2:34157ebbf56b
--- a/main.cpp	Wed Mar 28 14:40:01 2012 +0000
+++ b/main.cpp	Sat Mar 31 08:19:31 2012 +0000
@@ -15,8 +15,11 @@
 //DigitalOut myled3(LED2);
 
 
-// To test the time it takes for executing one loop in the main program: 
-//#define LOOPTIMECOMPUTE
+// To test the time it takes for executing one loop in the main program:
+#define LOOPTIMECOMPUTE
+
+// To get serial commands (for debug, or other things using a Terminal - for instance, a laser scan)
+//#define SERIAL_COMMANDS
 
 //----------  ETHERNET / OSC related (in the future, put somewhere else...): -------------------------------------------
 // mbed IP address (server):
@@ -24,311 +27,335 @@
 EthernetNetIf eth;
 #else
 EthernetNetIf eth(
-  IpAddr(10,0,0,2), //IP Address
-  IpAddr(255,255,255,0), //Network Mask
-  IpAddr(10,0,0,1), //Gateway
-  IpAddr(10,0,0,1)  //DNS
+    IpAddr(10,0,0,2), //IP Address
+    IpAddr(255,255,255,0), //Network Mask
+    IpAddr(10,0,0,1), //Gateway
+    IpAddr(10,0,0,1)  //DNS
 );
 #endif
 
 //uint8_t serverMac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
 uint8_t serverIp[]  = { 10, 0, 0, 2 }; // not needed perhaps!
 int  serverPort  = 10000;
-  
+
 uint8_t destIp[]  = { 10, 0, 0, 1};
 int  destPort = 12000;
-  
+
 char *topAddress="/mbed";
 char *subAddress[3]={ "/test1" , "/test2" , "/test3" };
-  
+
 OSCMessage recMes;
 OSCMessage sendMes;
-  
-OSCClass osc;    
-//OSCClass osc(&recMes);  // instantiate OSC communication object, and set the receiver container from the OSC packets  
- 
-void processOSC(UDPSocketEvent e); 
+
+OSCClass osc;
+//OSCClass osc(&recMes);  // instantiate OSC communication object, and set the receiver container from the OSC packets
+
+void processOSC(UDPSocketEvent e);
 // ----------------------------------------------------------------------------------------------------------------------
 
 Ticker timerForRendering;
+Ticker timerForSendingData;
 Timer measureLoopPeriod;
+Timer measureUpdatePeriod;
 
+// to get serial commands (not necessary perhaps)
 void  processSerial();
- 
+
 int main() {
-    
+
     // Initialize the hardware (laser powers, positions...):
     IO.init();
 
-  // -------------------------------
-  // Set the Ethernet port: 
-  printf("Setting up...\r\n");
-  EthernetErr ethErr = eth.setup();
-  if(ethErr)
-  {
-    printf("Error %d in setup.\r\n", ethErr);
-    return -1;
-  }
-  printf("Setup OK\r\n");
-    
-   //(1) Sending message:
-   // Set IP and Port: 
-   sendMes.setIp( destIp );
-   sendMes.setPort( destPort );
-   // Set data: 
-   // sendMes.setTopAddress(topAddress);
-   
-   //setting osc functionnality:
-   //(2) Receiving: 
-  // recMes.setIp( serverIp ); // not needed?
-   osc.setReceiveMessage(&recMes); // this sets the receiver container for the OSC packets (we can avoid doing this if we use osc.getMessage() to get messages)
-   osc.begin(serverPort, &processOSC); // binds the upd (osc) messages to an arbitrary listening port ("server" port), and callback function
-   // -------------------------------
-    
+    // -------------------------------
+    // Set the Ethernet port:
+    printf("Setting up...\r\n");
+    EthernetErr ethErr = eth.setup();
+    if (ethErr) {
+        printf("Error %d in setup.\r\n", ethErr);
+        return -1;
+    }
+    printf("Setup OK\r\n");
+
+    //(1) Sending message:
+    // Set IP and Port:
+    sendMes.setIp( destIp );
+    sendMes.setPort( destPort );
+    // Set data:
+    // sendMes.setTopAddress(topAddress);
+
+    //setting osc functionnality:
+    //(2) Receiving:
+    // recMes.setIp( serverIp ); // not needed?
+    osc.setReceiveMessage(&recMes); // this sets the receiver container for the OSC packets (we can avoid doing this if we use osc.getMessage() to get messages)
+    osc.begin(serverPort, &processOSC); // binds the upd (osc) messages to an arbitrary listening port ("server" port), and callback function
+    // -------------------------------
+
     /* // sending seems not to work right after setting the osc object??
     wait(1);
     sendMes.setTopAddress("starting");
-    sendMes.setSubAddress(""); 
+    sendMes.setSubAddress("");
     osc.sendOsc( &sendMes );
     */
-    
+
     // initialize with the desired blob configuration:
-   
+
     // Tested modes:
-    //blobconf.oneElasticLoopContractCentral();
-    blobconf.addOneElasticContourFollowing();
+    blobconf.clearConfig();
+//   blobconf.addOneElasticLoopContractCentral();
+//     blobconf.addOneElasticContourFollowing();
+
+    blobconf.addOneRigidLoopBouncing();
+   //    blobconf.addOneRigidLoopBouncing();
+
     // Important: first, set the initial position for all the blobs, this will be useful because
     // when changing modes we can use the previous central position...
-   // blobconf.setInitialPos(CENTER_AD_MIRROR_X, CENTER_AD_MIRROR_Y);
-     
-    
+    // blobconf.setInitialPos(CENTER_AD_MIRROR_X, CENTER_AD_MIRROR_Y);
+
+
     // RENRERER (attn: setConfigToRender must be called when the blobconf is set - i.e., the number of blobs and number of points/blob is fixed)
-   lsr.setConfigToRender(&blobconf);
-    
-    // Timer on the rendering function of the oneLoop object: 
-     timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); // the address of the object, member function, and interval (in seconds)
-  //  timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); // the address of the object, member function, and interval (in seconds)
+    lsr.setConfigToRender(&blobconf);
+
+    // Timer on the rendering function of the oneLoop object:
+    // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); // the address of the object, member function, and interval (in seconds)
+    timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); // the address of the object, member function, and interval (in seconds)
+
+    // Timer for sending OSC data:
+    timerForSendingData.attach(&blobconf, &blobConfig::sendConfData, 0.025); // time in seconds (25ms -> 40Hz)
+
+    //==========================================   INFINITE LOOP (in USER PROGRAM CONTEXT) ===================================================================
+#ifdef LOOPTIMECOMPUTE
+    int timeCounterNum=1000;
+#endif
+
+  measureUpdatePeriod.start();
+
+    while (true) {
+
+        if (measureUpdatePeriod.read_ms()>4) { // 4 or 5 ms seems to be the minimum time required for performing one
+                                               // loop with laser rendering every 110us (total loop time 4300us, 3100us of effective loop time, and each laser interrupt about 30us)
+            measureUpdatePeriod.stop();
+            measureUpdatePeriod.reset();
+            
+            // update config dynamics (this also could be threaded?):
+            blobconf.update();
+
+            // draw the config (note: each kind of blob renders differently)
+            blobconf.draw();
+            
+            measureUpdatePeriod.start();
+        }
 
-     //==========================================   INFINITE LOOP (in USER PROGRAM CONTEXT) ===================================================================
-   #ifdef LOOPTIMECOMPUTE
-    int timeCounterNum=100000;
-    #endif
-    
-    
-    while(true) {
-      
-      // update config dynamics (this also could be threaded?):
-      blobconf.update();
-      
-      // draw the config (note: each kind of blob renders differently)
-     // blobconf.draw();
-    
-      // COMMUNICATION:
-      // (a) Reading commands:  
-      // Ethernet:
-      Net::poll(); // this will take care of calling processOSC(UDPSocketEvent e) when a new packet arrives.
-    
-      // Serial: 
-      if(pc.readable()>0) processSerial();
-      
-      // (b)Sending Data: // PUT THIS IN AN INTERRUPT OR A TIMER!!! it may be TOO FAST...
-      blobconf.sendConfData();
-      
-      // text:
-      /*
-       sendMes.setTopAddress("/hello"); 
-       sendMes.setSubAddress("/daito");  // ATTENTION: the host computer needs to know in advance how many points are in the loop (I did not implement "bundle" messages yet...)
-       int x=(long)10;
-       sendMes.setArgs( "i", &x);
-       osc.sendOsc( &sendMes );
-       */
-       
+        // COMMUNICATION:
+        // (a) Reading commands:
+        // Ethernet:
+        Net::poll(); // this will take care of calling processOSC(UDPSocketEvent e) when a new packet arrives.
+
+        // Serial:
+#ifdef SERIAL_COMMANDS
+        if (pc.readable()>0) processSerial();
+#endif
+        // (b)Sending Data: // PUT THIS IN AN INTERRUPT OR A TIMER!!! it may be TOO FAST...
+        //blobconf.sendConfData();
+
+        // text:
+        /*
+         sendMes.setTopAddress("/hello");
+         sendMes.setSubAddress("/daito");  // ATTENTION: the host computer needs to know in advance how many points are in the loop (I did not implement "bundle" messages yet...)
+         int x=(long)10;
+         sendMes.setArgs( "i", &x);
+         osc.sendOsc( &sendMes );
+         */
+
 #ifdef LOOPTIMECOMPUTE
-      if (timeCounterNum>50000)  myled = 0;
-      //if (timeCounterNum%100==0) blobconf.sendConfData();
-      if (timeCounterNum>100000) {
-      myled = 1;
-      measureLoopPeriod.stop();
-      sendMes.setTopAddress("/timeloop");
-      sendMes.setSubAddress("/"); 
-      long x=(long)(int(measureLoopPeriod.read_us()/100000));     
-      sendMes.setArgs( "i", &x);
-      osc.sendOsc( &sendMes );
-      timeCounterNum=0;
-      measureLoopPeriod.reset();
-      measureLoopPeriod.start();
-      } else timeCounterNum++;
+        if (timeCounterNum>500)  myled = 0;
+       // if (timeCounterNum%10==0) blobconf.sendConfData();
+        if (timeCounterNum>1000) {
+            myled = 1;
+            measureLoopPeriod.stop();
+            sendMes.setTopAddress("/timeloop");
+            sendMes.setSubAddress("/");
+            long x=(long)(int(measureLoopPeriod.read_us()/1000.0));
+            sendMes.setArgs( "i", &x);
+            osc.sendOsc( &sendMes );
+            timeCounterNum=0;
+            measureLoopPeriod.reset();
+            measureLoopPeriod.start();
+        } else timeCounterNum++;
 #endif
 
     }
 }
 
- // ================= INTERPRET COMMAND =========================
+// ================= INTERPRET COMMAND =========================
 // NOTE: the following arrays are GLOBAL (used in processOSC and processSerial, as well as in interpretCommand function):
- // max of two addresses (top and sub), of a max length of 24 characters:
+// max of two addresses (top and sub), of a max length of 24 characters:
 char address[2][24];
 //long auxdata[2]; // to store a max of two arguments (note: we will only use LONGs)
-int data[2]; // this is to have -1 as NO DATA, to detect errors. 
- 
-//interpretCommand(const char& address[2][], const int& data[2]) {  
+int data[2]; // this is to have -1 as NO DATA, to detect errors.
+
+//interpretCommand(const char& address[2][], const int& data[2]) {
 void interpretCommand() {
     // (I) =========================================== SPECIAL FUNCTIONS (reset, rescan LUT, etc) ====================================================
     if ( !strcmp(address[0], "takeSnapshot" ) ) { // will reset all the spots, but the 0, and use it for taking measures:
-       
-       // for test:
-       for (int i=0; i<2 ; i++) {
-             myled = 1;  wait(0.1); myled = 0;  wait(0.1);
-             }
-       
-        // First, we need to disable the threaded display for the loop: 
-         timerForRendering.detach(); 
-         
-        // Then, do the scan (sending values on serial port):  
-         IO.scan_serial();
-        
-        // Finally, start again threaded display: 
-         timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); // the address of the object, member function, and interval (in seconds)
-        }  
-        
-      else if ( !strcmp(address[0], "mbedReset" ) ) mbed_reset();
-      
-      else if ( !strcmp(address[0], "calibrate" ) ) {
-      // First, we need to disable the threaded display for the loop: 
-         timerForRendering.detach(); 
-       // RESCAN (and save LUT table):
-       IO.scanLUT();
-       // Finally, start again threaded display: 
-         timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL);
-       }
-        
-      // (II) ========================================= GLOBAL CONFIG and HARDWARE COMMANDS ===========================================
-      
-      else if ( !strcmp(address[0], "setGreenLaser" ) ) { 
-       int value=data[0];
-       if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
-        if (value==0) IO.setGreenPower(0); else IO.setGreenPower(1); 
-       }
-     } 
-      
-      // SIMPLE BEHAVIOUR MODES (to be read from an XML file in the future): 
-      else if (!strcmp(address[0], "crawling")) { // 
-          timerForRendering.detach(); 
+
+        // for test:
+        for (int i=0; i<2 ; i++) {
+            myled = 1;
+            wait(0.1);
+            myled = 0;
+            wait(0.1);
+        }
+
+        // First, we need to disable the threaded display for the loop:
+        timerForRendering.detach();
+
+        // Then, do the scan (sending values on serial port):
+        IO.scan_serial();
+
+        // Finally, start again threaded display:
+        timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); // the address of the object, member function, and interval (in seconds)
+    }
+
+    else if ( !strcmp(address[0], "mbedReset" ) ) mbed_reset();
+
+    else if ( !strcmp(address[0], "calibrate" ) ) {
+        // First, we need to disable the threaded display for the loop:
+        timerForRendering.detach();
+        // RESCAN (and save LUT table):
+        IO.scanLUT();
+        // Finally, start again threaded display:
+        timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL);
+    }
+
+    // (II) ========================================= GLOBAL CONFIG and HARDWARE COMMANDS ===========================================
+
+    else if ( !strcmp(address[0], "setGreenLaser" ) ) {
+        int value=data[0];
+        if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
+            if (value==0) IO.setGreenPower(0);
+            else IO.setGreenPower(1);
+        }
+    }
+
+    // SIMPLE BEHAVIOUR MODES (to be read from an XML file in the future):
+    else if (!strcmp(address[0], "crawling")) { //
+        timerForRendering.detach();
         // blobconf.computeBoundingBox();
-         blobconf.clearConfig();      
-         blobconf.addOneElasticContourFollowing();
-         lsr.setConfigToRender(&blobconf);        
+        blobconf.clearConfig();
+        blobconf.addOneElasticContourFollowing();
+        lsr.setConfigToRender(&blobconf);
         timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL);
-      }
-       else if (!strcmp(address[0], "loop")) { // 
+    } else if (!strcmp(address[0], "loop")) { //
+        timerForRendering.detach();
+        // blobconf.computeBoundingBox();
+        blobconf.clearConfig();
+        blobconf.addOneElasticLoopContractCentral();
+        lsr.setConfigToRender(&blobconf);
+        timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL);
+    }
+
+    else if (!strcmp(address[0], "bouncing")) {
         timerForRendering.detach();
         // blobconf.computeBoundingBox();
-         blobconf.clearConfig();  
-         blobconf.addOneElasticLoopContractCentral();
-          lsr.setConfigToRender(&blobconf);
+        blobconf.clearConfig();
+        blobconf.addOneElasticBouncing();
+        lsr.setConfigToRender(&blobconf);
         timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL);
-      }
-      
-      else if (!strcmp(address[0], "bouncing")) {
-       timerForRendering.detach(); 
-        // blobconf.computeBoundingBox();
-         blobconf.clearConfig(); 
-         blobconf.addOneElasticBouncing();
-          lsr.setConfigToRender(&blobconf);
-        timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL);
-      }
-      
-      // other: 
-      
-      else if ( !strcmp(address[0], "standby" ) ) { // will put ALL the spots in stand by mode
+    }
+
+    // other:
+
+    else if ( !strcmp(address[0], "standby" ) ) { // will put ALL the spots in stand by mode
         blobconf.allStandBy(); // will avoid the update function
-      }        
-      else if ( !strcmp(address[0], "resume" ) ) { // will put ALL the spots in stand by mode
+    } else if ( !strcmp(address[0], "resume" ) ) { // will put ALL the spots in stand by mode
         blobconf.allResume(); // will avoid the update function
-      }    
-      
-      // (III) ========================================= Loop control (parameters, etc) =========================================== 
-      // NOte: for the time being, we only have ONE loop, so there is no "per loop or per config" mode.
-      
-      else if (!strcmp( address[0], "sendOSC" ) ) { 
-           int value=data[0];
-           if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
-               for (int i=0; i< blobconf.numBlobs; i++) {
-                  blobconf.blobArray[i]->sendOSC=(value>0);
-               }
-           }
-     }
-     
-      else if (!strcmp( address[0], "sendArea" ) ) { 
-           int value=data[0];
-           if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
-               for (int i=0; i< blobconf.numBlobs; i++) {
-                  blobconf.blobArray[i]->sendingBlobArea=(value>0);
-               }
-           }
-     }
-      
-    else if (!strcmp( address[0], "sendPos" ) ) { 
-           int value=data[0];
-           if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
-               for (int i=0; i< blobconf.numBlobs; i++) {
-                  blobconf.blobArray[i]->sendingLoopPositions=(value>0);
-               }
-           }
-     } 
-     
-     else if (!strcmp( address[0], "sendRegions" ) ) { 
-           int value=data[0];
-           if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
-               for (int i=0; i< blobconf.numBlobs; i++) {
-                  blobconf.blobArray[i]->sendingLoopRegions=(value>0);
-               }
-           }
-     } 
-     
-     else if (!strcmp( address[0], "sendTouched" ) ) { 
-           int value=data[0];
-           if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
-               for (int i=0; i< blobconf.numBlobs; i++) {
-                  blobconf.blobArray[i]->sendingTouched=(value>0);
-               }
-           }
-     } 
-     
-     
-     
+    }
+
+    // (III) ========================================= Loop control (parameters, etc) ===========================================
+    // NOte: for the time being, we only have ONE loop, so there is no "per loop or per config" mode.
+
+    else if (!strcmp( address[0], "sendOSC" ) ) {
+        int value=data[0];
+        if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
+            for (int i=0; i< blobconf.numBlobs; i++) {
+                blobconf.blobArray[i]->sendOSC=(value>0);
+            }
+        }
+    }
+
+    else if (!strcmp( address[0], "sendArea" ) ) {
+        int value=data[0];
+        if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
+            for (int i=0; i< blobconf.numBlobs; i++) {
+                blobconf.blobArray[i]->sendingBlobArea=(value>0);
+            }
+        }
+    }
+
+    else if (!strcmp( address[0], "sendPos" ) ) {
+        int value=data[0];
+        if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
+            for (int i=0; i< blobconf.numBlobs; i++) {
+                blobconf.blobArray[i]->sendingLoopPositions=(value>0);
+            }
+        }
+    }
+
+    else if (!strcmp( address[0], "sendRegions" ) ) {
+        int value=data[0];
+        if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
+            for (int i=0; i< blobconf.numBlobs; i++) {
+                blobconf.blobArray[i]->sendingLoopRegions=(value>0);
+            }
+        }
+    }
+
+    else if (!strcmp( address[0], "sendTouched" ) ) {
+        int value=data[0];
+        if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
+            for (int i=0; i< blobconf.numBlobs; i++) {
+                blobconf.blobArray[i]->sendingTouched=(value>0);
+            }
+        }
+    }
+
+
+
 }
 
 //============= RECEIVE OSC COMMANDS =========================
-// This is the callback function called when there are packets on the listening socket. It is not nice to have it 
-// here, but for the time being having a "wrapping global" is the simplest solution (we cannot pass a member-function pointer 
-// as handler to the upd object).  
+// This is the callback function called when there are packets on the listening socket. It is not nice to have it
+// here, but for the time being having a "wrapping global" is the simplest solution (we cannot pass a member-function pointer
+// as handler to the upd object).
 void processOSC(UDPSocketEvent e) {
     osc.onUDPSocketEvent(e);
 
     if (osc.newMessage) {
-     // in fact, there is no need to check this if using the method of a global callback function - it is clear this is a new packet... however, it may be 
-     // interesting to use a timer, and process data (answers, etc) only after a certain amount of time, so as to avoid blocking the program in IRQ context...
-        
-     // Acquire the addresses and arguments and put them in the GLOBAL variables:
-      strcpy(address[0],""); strcpy(address[1],"");
-      for (int i=0; i<recMes.getAddressNum(); i++)  strcpy(address[i],recMes.getAddress(i)); // NOTE: up to the rest of the program to check if address[1] is really not null
-      // Acquire data:
-      data[0]=-1;  data[1]=-1; 
-      for (int i=0; i<recMes.getArgNum(); i++) data[i]=(int)recMes.getArgInt(i);
-  
-      // Finally, interpret the command:
-      interpretCommand();//address, data);
-      
+        // in fact, there is no need to check this if using the method of a global callback function - it is clear this is a new packet... however, it may be
+        // interesting to use a timer, and process data (answers, etc) only after a certain amount of time, so as to avoid blocking the program in IRQ context...
+
+        // Acquire the addresses and arguments and put them in the GLOBAL variables:
+        strcpy(address[0],"");
+        strcpy(address[1],"");
+        for (int i=0; i<recMes.getAddressNum(); i++)  strcpy(address[i],recMes.getAddress(i)); // NOTE: up to the rest of the program to check if address[1] is really not null
+        // Acquire data:
+        data[0]=-1;
+        data[1]=-1;
+        for (int i=0; i<recMes.getArgNum(); i++) data[i]=(int)recMes.getArgInt(i);
+
+        // Finally, interpret the command:
+        interpretCommand();//address, data);
+
     }
- }
- 
+}
+
 //============= RECEIVE SERIAL COMMANDS =========================
 //
-// NOTE: - NUMERIC PARAMETERS have to be send BEFORE the command word. They must be sent as ASCII DEC, without end character. 
+// NOTE: - NUMERIC PARAMETERS have to be send BEFORE the command word. They must be sent as ASCII DEC, without end character.
 //       - Commands words SHOULD NOT have numbers in it. They should be C compliant STRINGS (ended with character '0')
-//       - order is irrelevant: we can send 10 RADIUS or RADIUS 10. 
+//       - order is irrelevant: we can send 10 RADIUS or RADIUS 10.
 
-// String to store ALPHANUMERIC DATA (i.e., integers, floating point numbers, unsigned ints, etc represented as DEC) sent wirelessly: 
+// String to store ALPHANUMERIC DATA (i.e., integers, floating point numbers, unsigned ints, etc represented as DEC) sent wirelessly:
 char stringData[24]; // note: an integer is two bytes long, represented with a maximum of 5 digits, but we may send floats or unsigned int...
 int indexStringData=0;//position of the byte in the string
 
@@ -339,81 +366,81 @@
 
 void processSerial() {
 
- while(pc.readable()>0){
-        
-       char val =pc.getc();
+    while (pc.readable()>0) {
+
+        char val =pc.getc();
         // pc.printf("Got :%d\n", incomingByte);
-         //pc.putc(incomingByte);
-  
-  // Save ASCII numeric characters (ASCII 0 - 9) on stringData:
-    if ((val >= '0') && (val <= '9')){ // this is 45 to 57 (included)
-      stringData[indexStringData] = val;
-      indexStringData++;
-    }
-    
-  // Save ASCII letters in stringCommand:
-    if ((val >= 'A') && (val <= 'z')){ // this is 65 to 122 (included)
-      stringCommand[indexStringCommand] = val;
-      indexStringCommand++;
-    }
-   // is command ready?
-   if (val=='/') {
-     commandReady=true; 
-     stringCommand[indexStringCommand] = 0; // string termination.
-     indexStringCommand=0; // reset index string for acquiring next command
-     //Serial.println(stringCommand);
-   }
-    
-    // COMMANDS (with or without numeric parameters):
-    if (commandReady==true) { // it means we can interpret the command string:
-      commandReady=false;
-     
-      stringData[indexStringData] = 0 ;// string termination for numeric values;
-      indexStringData=0;
-     
-   // PARSE DATA: (TO DO!!!!!!!!!!!!!!): 
-   
-    // (a) Parse command (get address[0] and address[1]):
-    //ex:  "/1/standBy" -- > address[0]="1" and address[1]="standBy"
-    // address[2]
-     
-    // Serial.println(stringCommand);
-    // Serial.println(stringData);
-      
-     // (b) Parse data:
-     
-    // char address[2][24];
-    //long auxdata[2]; // to store a max of two arguments (note: we will only use LONGs)
-    //int data[2]; // this is to have -1 as NO DATA, to detect errors. 
+        //pc.putc(incomingByte);
+
+        // Save ASCII numeric characters (ASCII 0 - 9) on stringData:
+        if ((val >= '0') && (val <= '9')) { // this is 45 to 57 (included)
+            stringData[indexStringData] = val;
+            indexStringData++;
+        }
+
+        // Save ASCII letters in stringCommand:
+        if ((val >= 'A') && (val <= 'z')) { // this is 65 to 122 (included)
+            stringCommand[indexStringCommand] = val;
+            indexStringCommand++;
+        }
+        // is command ready?
+        if (val=='/') {
+            commandReady=true;
+            stringCommand[indexStringCommand] = 0; // string termination.
+            indexStringCommand=0; // reset index string for acquiring next command
+            //Serial.println(stringCommand);
+        }
+
+        // COMMANDS (with or without numeric parameters):
+        if (commandReady==true) { // it means we can interpret the command string:
+            commandReady=false;
+
+            stringData[indexStringData] = 0 ;// string termination for numeric values;
+            indexStringData=0;
+
+            // PARSE DATA: (TO DO!!!!!!!!!!!!!!):
 
-     // FOR THE TIME BEING there is no parsing for serial commands:
-   
-     // SCANNING: 
-      if (!strcmp(stringCommand , "takeSnapshot")) {
-        // First, we need to disable the threaded display for the loop: 
-         timerForRendering.detach(); 
-         
-        // Then, do the scan (sending values on serial port):  
-         IO.scan_serial();
-        
-        // Finally, start again threaded display: 
-         timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); // the address of the object, member function, and interval (in seconds)
+            // (a) Parse command (get address[0] and address[1]):
+            //ex:  "/1/standBy" -- > address[0]="1" and address[1]="standBy"
+            // address[2]
+
+            // Serial.println(stringCommand);
+            // Serial.println(stringData);
+
+            // (b) Parse data:
+
+            // char address[2][24];
+            //long auxdata[2]; // to store a max of two arguments (note: we will only use LONGs)
+            //int data[2]; // this is to have -1 as NO DATA, to detect errors.
+
+            // FOR THE TIME BEING there is no parsing for serial commands:
+
+            // SCANNING:
+            if (!strcmp(stringCommand , "takeSnapshot")) {
+                // First, we need to disable the threaded display for the loop:
+                timerForRendering.detach();
+
+                // Then, do the scan (sending values on serial port):
+                IO.scan_serial();
+
+                // Finally, start again threaded display:
+                timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); // the address of the object, member function, and interval (in seconds)
+
+            }
+
+            if (!strcmp(stringCommand , "REDON"))   IO.setRedPower(1); // pc.printf("%d\n",incomingByte);
+
+            if (!strcmp(stringCommand , "REDOFF"))  IO.setRedPower(0);
+
+            if  (!strcmp(stringCommand , "READVALUE")) pc.printf("Value read: %f", lockin.getSmoothValue());//lockin.getLastValue());/
+
+            // FINALLY, interpret commands (but only after parsing):
+            //  interpretCommand();//address, data);
 
         }
-        
-     if (!strcmp(stringCommand , "REDON"))   IO.setRedPower(1); // pc.printf("%d\n",incomingByte);
+    }
+}
 
-     if (!strcmp(stringCommand , "REDOFF"))  IO.setRedPower(0);
-       
-     if  (!strcmp(stringCommand , "READVALUE")) pc.printf("Value read: %f", lockin.getSmoothValue());//lockin.getLastValue());/
-        
-      // FINALLY, interpret commands (but only after parsing): 
-      //  interpretCommand();//address, data);
-      
-    }
-    }
- }
- 
 
 
 // ================ MISCELANEA
@@ -426,19 +453,19 @@
 
 import oscP5.*;
 import netP5.*;
-  
+
 OscP5 oscP5;
 NetAddress myRemoteLocation;
 
 void setup() {
   size(400,400);
   frameRate(25);
-  // start oscP5, listening for incoming messages at port 12000 
+  // start oscP5, listening for incoming messages at port 12000
   oscP5 = new OscP5(this,12000);
-  
+
   // myRemoteLocation is a NetAddress. a NetAddress takes 2 parameters,
   // an ip address and a port number. myRemoteLocation is used as parameter in
-  // oscP5.send() when sending osc packets to another computer, device, 
+  // oscP5.send() when sending osc packets to another computer, device,
   // application. usage see below. for testing purposes the listening port
   // and the port of the remote location address are the same, hence you will
   // send messages back to this sketch.
@@ -447,27 +474,26 @@
 
 
 void draw() {
-  background(0);  
+  background(0);
 }
 
 void mousePressed() {
-  // in the following different ways of creating osc messages are shown by example 
+  // in the following different ways of creating osc messages are shown by example
   OscMessage myMessage = new OscMessage("/mbed/test1");
-  
-  myMessage.add(123); // add an int to the osc message 
+
+  myMessage.add(123); // add an int to the osc message
 
-  // send the message 
-  oscP5.send(myMessage, myRemoteLocation); 
+  // send the message
+  oscP5.send(myMessage, myRemoteLocation);
 }
 
 
-// incoming osc message are forwarded to the oscEvent method. 
+// incoming osc message are forwarded to the oscEvent method.
 void oscEvent(OscMessage theOscMessage) {
-  // print the address pattern and the typetag of the received OscMessage 
+  // print the address pattern and the typetag of the received OscMessage
   print("### received an osc message.");
   print(" addrpattern: "+theOscMessage.addrPattern());
   println(" typetag: "+theOscMessage.typetag());
 }
 
 */
-   
\ No newline at end of file