Dual CANbus monitor and instrumentation cluster

Dependencies:   SPI_TFTx2 TFT_fonts TOUCH_TFTx2 beep mbed

Fork of CANary by Tick Tock

Revision:
4:8d7759f4fe7a
Parent:
3:3e879b043bc5
Child:
5:ebf6fa994b78
--- a/main.cpp	Tue Feb 12 04:08:05 2013 +0000
+++ b/main.cpp	Sun Feb 17 16:44:59 2013 +0000
@@ -1,95 +1,12 @@
-//CANary.cpp
-
-//LEAF OBD
-//1:
-//2:
-//3:    AVCAN-L     White/Blue
-//4:
-//5:    VSS         Brown,White/Brown
-//6:    CARCAN-H    Green
-//7:
-//8:    12V-SW      Orange,White/Orange
-//9:
-//10:
-//11:   AVCAN-H     Blue
-//12:   EVCAN-L     White/Grey
-//13:   EVCAN-H     Grey
-//14:   CARCAN-L    White/Green
-//15:
-//16:   12V-AON     Red/Blue,Blue/Red
-
-//VP230
-//1:D   
-//2:GND 
-//3:VCC 
-//4:R   
-//5:Vref
-//6:CANL
-//7:CANH
-//8:RS
-
-//LPC1768
-//1:    VSS
-//2:        NC:VIN  (4.5-9V supply)
-//3:        NC:VB
-//4:        NC:nR
-//5:    SPI:CS0
-//6:    SPI:CS1
-//7:    SPI:Reset
-//8:    CAN1:Sleep -->  8:CAN1:RS
-//9:    CAN1:RX    -->  4:CAN1:R
-//10:   CAN1:TX    -->  1:CAN1:D
-//11:   SPI:MOSI
-//12:   SPI:MISO
-//13:   SPI:SCLK
-//14:       NC:Ain
-//15:   MON12V     -->  4K to 12V, 1K to VSS  (To be implemented)
-//16:   TOUCH_X+
-//17:   TOUCH_X-
-//18:       NC:Aout
-//19:   TOUCH_Y+
-//20:   TOUCH_Y-
-//21:   Spkr+
-//22:   Spkr-           (optional complimentary output for more volume)
-//23:       NC:pwm
-//24:       LED
-//25:       NC:pwm
-//26:       NC:pwm
-//27:       NC
-//28:   CAN2:Sleep -->  8:CAN2:RS
-//29:   CAN2:TX    -->  1:CAN2:D
-//30:   CAN2:RX    -->  4:CAN2:R
-//31:   USB_D+
-//32:   USB_D-
-//33:       NC:Eth_TD+
-//34:       NC:Eth_TD-
-//35:       NC:Eth_RD+
-//36:       NC:Eth_RD-
-//37:       NC:IF+
-//38:       NC:IF-
-//39:       NC:5Vout (only available when connected as USB device)
-//40:   VCC3.3
-#include "mbed.h"
-#include "CAN.h"
-#include "beep.h"
-#include "MSCFileSystem.h"
-#include "SPI_TFTx2.h"
-#include "Arial12x12.h"
-#include "Arial12x12_prop.h"
-#include "Arial28x28.h"
-#include "TOUCH_TFTx2.h"
-#define upLine "\033[1A"
-#define maxBufLen 1536
-#define canTimeout 5
-
+//To Do:
+// USB device detec
+#include "CANary.h"
 // write and read the Mode Data
 LocalFileSystem local("local"); // test the local file system to write files
 
 // to write to USB Flash Drives, or equivalent (SD card in Reader/Writer)
 MSCFileSystem fs("fs"); // to write to a USB Flash Drive
 
-void Log (char *message);
-void LogErr (char *message);
 extern "C" void mbed_reset();
 
 time_t seconds ;
@@ -101,6 +18,10 @@
 DigitalOut led2(LED2);
 DigitalOut led3(LED3);
 DigitalOut led4(LED4);
+PwmOut dled(p24);
+
+InterruptIn touchpad(p17);
+
 CAN can1(p9, p10);      // CAN1 uses pins 9 and 10 (rx, tx) and pin 27 (rs)
 DigitalOut can1_SleepMode(p8);     // Use pin 8 to control the sleep mode of can1
 CAN can2(p30, p29);     // CAN2 uses pins 30 and 29 (rx, tx) and pin 28 (rs)
@@ -115,16 +36,23 @@
 char ii = 0; // indexindex
 char c;
 volatile int writePointer = 0;
-volatile int secsIdle = 0;
-volatile bool canIdle = false;
-
+volatile int secsNoMsg = 0, secsNoTouch = 0;
+volatile bool canIdle = false, userIdle = false;
+point lastTouch;
 char counter = 0;
+int dMode[2] = {1,6}; //display mode
+int sMode = 0; // setup mode
+int lastDMode[2]; //last screen mode
+int lastSMode = 0;
+char displayLog[19][40];
+int displayLoc = 0;
 
 TOUCH_TFTx2 tt(p16, p17, p19, p20, p11, p12, p13, p6, p7, p5, "TFT"); // x+,x-,y+,y-,mosi, miso, sclk, cs0, cs1, reset
 
 extern "C" void RTC_IRQHandler() {
     timer.reset(); // zero ms at the-seconds-tic
-    canIdle=(++secsIdle>canTimeout);
+    canIdle=(++secsNoMsg>canTimeout);
+    userIdle=(++secsNoTouch>userTimeout);
     LPC_RTC->ILR |= (1<<0); // clear interrupt to prepare for next
 }
 
@@ -143,52 +71,32 @@
     return ((isecs<<10)+msec) ; // return the two byte time stamp
 }
 
-void readLog (){
-    unsigned char c;
-    int i=0;
-    char lastMsgNum[]={0,0};
-    char curMsgNum[]={0,0};
-    char canNum=0;
-    printf("printing file\n");
-    file = fopen(fileName, "r");
-    if (file == NULL) {
-        printf("no file found\n");
-    }
-    while (!feof(file)) {
-        c=fgetc(file);
-        printf("%02x ",c);
-        if (i==0){
-            canNum=c;
-        }else if (i==5){
-            curMsgNum[canNum]=c;
-        }
-        if (++i>12) {
-            if (curMsgNum[canNum]>(lastMsgNum[canNum]+1)) {
-                printf(" ***");
-            }
-            lastMsgNum[canNum]=curMsgNum[canNum];
-            printf("\n");
-            i=0;
-        }
-    }
-    printf("\n\n");
-    fclose(file);
-}
-
 void printLast (){
-    char i;
+    int i;
     CANMessage msg;
-    tt.set_display(1);     // select right display
     tt.locate(0,6);
-    tt.background(Yellow);
     tt.foreground(Red);
+    tt.set_font((unsigned char*) Arial12x12_prop);  // select the font
     for(i=0; i<19; i++){
         msg = lastMsg[i+1];
         printf("%03x : %02x %02x %02x %02x %02x %02x %02x %02x    \n",msg.id,msg.data[0],msg.data[1],msg.data[2],msg.data[3],msg.data[4],msg.data[5],msg.data[6],msg.data[7]);
     }
-    tt.set_display(0);     // select left display
-    tt.background(Black);
-    tt.foreground(Cyan);
+}
+
+void printLog (){
+    int i;
+    tt.locate(0,6);
+    tt.foreground(Amber);
+    tt.cls();
+    for(i=0; i<19; i++){
+        printf("%s",displayLog[displayLoc]);
+        displayLoc=displayLoc>17?0:displayLoc+1;
+    }
+}
+
+void logMsg (char *msg) {
+    strcpy(displayLog[displayLoc],msg);
+    displayLoc=displayLoc>17?0:displayLoc+1;
 }
 
 void logCan (char mtype, CANMessage canRXmsg) {
@@ -248,7 +156,7 @@
 
 void recieve1() {
     CANMessage msg1;
-    secsIdle=0; // reset deadman switch
+    secsNoMsg=0; // reset deadman switch
     can1.read(msg1);
     //printf("Can1 rxd: %d\n", msg1.data[0]);
     if(logOpen)
@@ -258,7 +166,7 @@
 
 void recieve2() {
     CANMessage msg2;
-    secsIdle=0; // reset deadman switch
+    secsNoMsg=0; // reset deadman switch
     can2.read(msg2);
     //printf("Can2 rxd: %d\n", msg2.data[0]);
     if(logOpen)
@@ -266,14 +174,103 @@
     led2 = !led2;
 }
 
+void touched(){
+    LPC_GPIOINT->IO2IntClr = (LPC_GPIOINT->IO2IntStatR | LPC_GPIOINT->IO2IntStatF);
+    lastTouch = tt.get_touch();       
+    lastTouch = tt.to_pixel(lastTouch);          // convert to pixel pos
+    //printf("X=%d Y=%d\n",lastTouch.x,lastTouch.y);
+    /*if (lastTouch.x > tt.width()){
+        tt.set_display(1);
+        tt.fillcircle(lastTouch.x-tt.width(),lastTouch.y,10,Blue);
+    }else{
+        tt.set_display(0);
+        tt.fillcircle(lastTouch.x,lastTouch.y,10,Blue);
+    }*/
+    secsNoTouch = 0;
+}
+
+void updateDisplay(){
+    static int lastDisplayLoc = 0;
+    for (int i=0; i<2; i++){
+        tt.set_display(i);
+        switch (dMode[i]) {
+            case logMode:
+                tt.background(Black);
+                if(dMode[i]!=lastDMode[i]||(lastSMode>0&&sMode==0)||(lastDisplayLoc!=displayLoc)){
+                    printLog();
+                    lastDisplayLoc=displayLoc;
+                }
+                break;
+            case dteMode:
+                tt.background(Black);
+                if(dMode[i]!=lastDMode[i]||(lastSMode>0&&sMode==0)) tt.cls();
+                tt.fillrect(10,10,300,50,Blue);
+               break;
+            case brakeMode:
+                tt.background(Black);
+                if(dMode[i]!=lastDMode[i]||(lastSMode>0&&sMode==0)) tt.cls();
+                tt.fillcircle(100,100,15,Red);
+                break;
+            case powerMode:
+                tt.background(Black);
+                if(dMode[i]!=lastDMode[i]||(lastSMode>0&&sMode==0)) tt.cls();
+                tt.fillrect(10,10,300,50,Green);
+                break;
+            case controlMode:
+                tt.background(Black);
+                if(dMode[i]!=lastDMode[i]||(lastSMode>0&&sMode==0)) tt.cls();
+                tt.fillcircle(100,100,15,Orange);
+                break;
+            case monitorMode:
+                tt.background(Yellow);
+                if(dMode[i]!=lastDMode[i]||(lastSMode>0&&sMode==0)) tt.cls();
+                printLast();
+                break;
+            default:
+                tt.background(Black);
+                if(dMode[i]!=lastDMode[i]||(lastSMode>0&&sMode==0)) tt.cls();
+                break;
+        }
+        lastDMode[i]=dMode[i];
+    } // for (i=0; i<1; i++)
+
+    switch (sMode) {
+        case 1:
+            tt.set_display(2); // select both displays
+            tt.foreground(Yellow);
+            tt.background(DarkCyan);
+            tt.set_font((unsigned char*) Arial12x12);
+            tt.fillrect(btn31x1,btn11y1,btn31x2,btn11y2,DarkCyan);
+            tt.locate(btn31x1+5,btn11y1+5);
+            printf("<-Prev\n");
+            tt.fillrect(btn32x1,btn11y1,btn32x2,btn11y2,DarkCyan);
+            tt.fillrect(btn33x1,btn11y1,btn33x2,btn11y2,DarkCyan);
+            tt.locate(btn33x2-50,btn11y1+5);
+            printf("Next->\n");
+            tt.set_display(0);
+            tt.locate(btn32x1+15,btn11y1+5);
+            printf("Select %d\n",dMode[0]);
+            tt.set_display(1);
+            tt.locate(btn32x1+15,btn11y1+5);
+            printf("Select %d\n",dMode[1]);
+            tt.background(Black);
+            break;
+        default:
+            break;
+    }
+    lastSMode=sMode;
+}
+
 int main() {
     int readPointer=0;
     int fmon;
     int fday;
     int ftime;
-    char sTemp[35];
+    char sTemp[40];
     unsigned long secs;
     bool bit = false;
+    int i,j;
+    
     can1.frequency(500000);
     can2.frequency(500000);
     //can1_SleepMode = 0;         // Enable TX
@@ -281,21 +278,21 @@
     can1_SleepMode = 1;         // Turn on Monitor_only Mode
     can2_SleepMode = 1;         // Turn on Monitor_only Mode
     //ticker.attach(&send1, 0.5);
-    ticker.attach(&printLast, 0.5); // Display messages
+    ticker.attach(&updateDisplay, 0.25); // Display messages
     can1.attach(&recieve1);
     can2.attach(&recieve2);
+    
     tt.set_orientation(1);
     tt.set_font((unsigned char*) Arial12x12_prop);  // select the font
-    tt.set_display(1);     // select right display
-    tt.background(Yellow);
+    tt.set_display(2);     // select right display
+    tt.background(Black);
     tt.cls();
     tt.set_display(0);       // select left display
-    tt.background(Black);    // set background to black
-    tt.foreground(Cyan);    // set chars to white
-    tt.cls();                // clear the screen
-
-    //tt.calibrate();           // calibrate the touch
+    tt.calibrate();           // calibrate the touch
     tt.claim(stdout);        // send stdout to the TFT display
+    touchpad.rise(&touched);
+    tt.wfi();               // enable interrupt on touch
+    dled = 1; // turn on display LED 80%
     timer.start() ;
     RTC_Init(); // start the RTC Interrupts that sync the timer
     struct tm t; // pointer to a static tm structure
@@ -305,8 +302,6 @@
     strftime(sTemp, 32, "%a %m/%d/%Y %X", &t);
     //tt.locate(0,0);
     //printf("\nCurrent time : %s\n", sTemp); // DAY MM/DD/YYYY HH:MM:SS
-    tt.set_display(0);     // select left display
-    tt.locate(0,0);
 
     // is it a date before 2012 ?
     if ((t.tm_year + 1900) < 2012 ) {
@@ -334,121 +329,152 @@
         //    printf("%s\n", sTemp); // DAY MM/DD/YYYY HH:MM:SS
     }
     while (true) {
-        if(1 == 1) {
-            if (!logOpen) { // Open new file if one is not already open
-                seconds = time(NULL);
-                t = *localtime(&seconds) ;
-                strftime(fileName, 32, "/fs/%m%d%H%M.alc", &t); //mmddhhmm.alc
+        if (!logOpen) { // Open new file if one is not already open
+            seconds = time(NULL);
+            t = *localtime(&seconds) ;
+            strftime(fileName, 32, "/fs/%m%d%H%M.alc", &t); //mmddhhmm.alc
 
-                printf("Using file %s\n",fileName);
-                file = fopen(fileName, "ab");
-                
-                if(file==NULL){
-                    printf("\nUnable to open %s\n\n\n\n",fileName);
-                    wait(10);
-                    mbed_reset();
-                } else {
-                    logOpen = true;
-                    readPointer=writePointer;
-                    printf("\nStarting Can Log %s\n",fileName);
-                    logTS();
-                    fclose(file);
-                    file = fopen("/fs/loglog.txt", "a");
-                    fprintf(file,"%s\r\n",fileName);
-                    fclose(file);
+            tt.set_display(0);     // select left display
+            tt.locate(0,0);
+            tt.foreground(Cyan);    // set chars to Cyan
+            //printf("Using file %s\n",fileName);
+            sprintf(sTemp,"Using file %s\n",fileName);
+            logMsg(sTemp);
+            file = fopen(fileName, "ab");
+            
+            if(file==NULL){
+                sprintf(sTemp,"\nUnable to open %s\n\n\n\n",fileName);
+                logMsg(sTemp);
+            } else {
+                logOpen = true;
+                readPointer=writePointer;
+                sprintf(sTemp,"Starting Can Log %s\n",fileName);
+                logMsg(sTemp);
+                logTS();
+                fclose(file);
+                file = fopen("/fs/loglog.txt", "a");
+                fprintf(file,"%s\r\n",fileName);
+                fclose(file);
+            }
+        } else { // if (!logOpen)
+            if (((writePointer+maxBufLen-readPointer)%maxBufLen)>(maxBufLen/2)||canIdle) {
+                // Dump buffer if > 1/2 full, canbus has stopped, or PB1 pressed
+                if (logOpen) {
+                    file = fopen(fileName, "ab");
+                    if (file == NULL) {
+                        logOpen = false;
+                        sprintf(sTemp,"Failed to append log file.\n\n");
+                        logMsg(sTemp);
+                    } else {
+                        while (readPointer != writePointer) {
+                            for (j = 0; j<13; j++){
+                                fprintf(file,"%c",writeBuffer[readPointer][j]);
+                            }
+                            if(++readPointer >= maxBufLen)
+                                readPointer=0;
+                        }
+                        led3 = !led3;
+                        fclose(file);
+                    }
+                } // if (logOpen)
+            } // if > 1/2 full, canbus has stopped, or PB1 pressed
+        } // if logOpen
+        if (canIdle&&userIdle) { // canbus idle --> sleep to save power
+            if (logOpen){
+                // First take advantage of the idle time to clear some room
+                bit = false;
+                rfile = fopen("/fs/loglog.txt", "r");
+                file = fopen("/fs/loglog.new", "w");
+                while (!feof(rfile)) {
+                    fscanf(rfile,"/fs/%2d%2d%4d.alc\r\n",&fmon,&fday,&ftime);
+                    //if ((fmon<t.tm_mon)&&(fday<=t.tm_mday)){ // Delete all files more than 1 month old
+                    if ((fmon < 12) || (t.tm_mon > 1)){
+                        fday = fday + fmon*31; //crude - february will store 3 extra days of data
+                    }
+                    if ((fday+14)<(t.tm_mday+t.tm_mon*31)){ // Delete all files more than ~14 days old
+                        bit=true;
+                        sprintf(sTemp,"/fs/%02d%02d%04d.alc",fmon,fday,ftime);
+                        if ((remove(sTemp)==NULL)) {
+                            sprintf(sTemp,"Removed file %s\n",sTemp);
+                            logMsg(sTemp);
+                        }
+                    }else{
+                        fprintf(file,"/fs/%02d%02d%04d.alc\r\n",fmon,fday,ftime);
+                    }
                 }
-            } // if (!logOpen)
-            do {
-                if (((writePointer+maxBufLen-readPointer)%maxBufLen)>(maxBufLen/2)||canIdle) {
-                    // Dump buffer if > 1/2 full, canbus has stopped, or PB1 pressed
-                    if (logOpen) {
-                        file = fopen(fileName, "ab");
-                        if (file == NULL) {
-                            logOpen = false;
-                            printf("Failed to append log file.\n\n");
-                        } else {
-                            while (readPointer != writePointer) {
-                                for (int j = 0; j<13; j++){
-                                    fprintf(file,"%c",writeBuffer[readPointer][j]);
-                                }
-                                if(++readPointer >= maxBufLen)
-                                    readPointer=0;
-                            }
-                            led3 = !led3;
-                            fclose(file);
-                        }
-                    } // if (logOpen)
-                } // if > 1/2 full, canbus has stopped, or PB1 pressed
-                if (canIdle) { // canbus idle --> sleep to save power
-                    // First take advantage of the idle time to clear some room
-                    
-                    bit = false;
-                    rfile = fopen("/fs/loglog.txt", "r");
-                    file = fopen("/fs/loglog.new", "w");
+                fclose (file);
+                fclose (rfile);
+                if (bit) {
+                    remove ("/fs/loglog.txt");
+                    //rename not working so do it the hard way
+                    //rename ("/fs/loglog.new","/fs/loglog.txt");
+                    rfile = fopen("/fs/loglog.new", "r");
+                    file = fopen("/fs/loglog.txt", "w");
                     while (!feof(rfile)) {
-                        fscanf(rfile,"/fs/%2d%2d%4d.alc\r\n",&fmon,&fday,&ftime);
-                        //if ((fmon<t.tm_mon)&&(fday<=t.tm_mday)){ // Delete all files more than 1 month old
-                        if ((fmon < 12) || (t.tm_mon > 1)){
-                            fday = fday + fmon*31; //crude - february will store 3 extra days of data
-                        }
-                        if ((fday+14)<(t.tm_mday+t.tm_mon*31)){ // Delete all files more than ~14 days old
-                            bit=true;
-                            sprintf(sTemp,"/fs/%02d%02d%04d.alc",fmon,fday,ftime);
-                            if ((remove(sTemp)==NULL)) {
-                                printf("Removed file %s\n",sTemp);
-                            }
-                        }else{
-                            fprintf(file,"/fs/%02d%02d%04d.alc\r\n",fmon,fday,ftime);
-                        }
+                        fscanf(rfile,"%s\r\n",&sTemp);
+                        fprintf(file,"%s\r\n",sTemp);
                     }
                     fclose (file);
                     fclose (rfile);
-                    if (bit) {
-                        remove ("/fs/loglog.txt");
-                        //rename not working so do it the hard way
-                        //rename ("/fs/loglog.new","/fs/loglog.txt");
-                        rfile = fopen("/fs/loglog.new", "r");
-                        file = fopen("/fs/loglog.txt", "w");
-                        while (!feof(rfile)) {
-                            fscanf(rfile,"%s\r\n",&sTemp);
-                            fprintf(file,"%s\r\n",sTemp);
-                        }
-                        fclose (file);
-                        fclose (rfile);
+                }
+                remove ("/fs/loglog.new");                    
+                wait(5); // wait a few seconds to ensure fsRAM is done
+            } // if (logOpen)
+            sprintf(sTemp,"Putting uC to sleep.\n");
+            logMsg(sTemp);
+            //LPC_RTC->CIIR=0x00; // block RTC interrupts
+            led1=0;
+            led2=0;
+            led3=0;
+            led4=0;
+            dled=0; // turn off display
+            secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900
+            while (secsNoMsg>canTimeout && secsNoTouch>userTimeout) {
+                //DeepPowerDown();
+                tt.wfi(); //enable touchpad input
+                //__wfi(); // freeze CPU and wait for interrupt (from canbus or touch)
+                Sleep();
+                //DeepPowerDown();
+            }
+            canIdle=secsNoMsg>canTimeout;
+            userIdle=userIdle>userTimeout;
+            dled=1; // turn on display LED
+            sprintf(sTemp,"Waking uC.\n");
+            logMsg(sTemp);
+            if (time(NULL)>(secs+1800)) {
+                logOpen = false; // Start new file if asleep for more than 30 minutes
+                if (secsNoTouch>100) secsNoTouch = 100; // also mostly reset user Idle counter
+            } else { // insert timestamp on each wake
+                logTS();
+            }
+            //LPC_RTC->CIIR=0x01; // re-enable RTC interrupts
+        } // if idle
+        
+        if (!userIdle) {
+            if (secsNoTouch<2) {// Recently touched
+                secsNoTouch +=2; // increment to prevent double touch
+                sMode=1;
+                if (lastTouch.x>320){
+                    i=1;
+                    lastTouch.x-=320;
+                } else {
+                    i=0;
+                }
+                if (lastTouch.y>btn11y1 && lastTouch.y<btn11y2){
+                    if (lastTouch.x>btn31x1 && lastTouch.x<btn31x2) {
+                        dMode[i]=dMode[i]>0?dMode[i]-1:maxModes;
+                    } else if (lastTouch.x>btn33x1 && lastTouch.x<btn33x2) {
+                        dMode[i]=dMode[i]<maxModes?dMode[i]+1:0;
                     }
-                    remove ("/fs/loglog.new");                    
-                    wait(5); // wait a few seconds to ensure fsRAM is done
-
-                    printf("Putting uC to sleep.\n");
-                    //LPC_RTC->CIIR=0x00; // block RTC interrupts
-                    led1=0;
-                    led2=0;
-                    led3=0;
-                    led4=0;
-                    secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900
-                    while (secsIdle>canTimeout) {
-                        //DeepPowerDown();
-                        __wfi(); // freeze CPU and wait for interrupt (from canbus)
-                    }
-                    canIdle=false;
-                    printf("Waking uC.\n");
-                    if (time(NULL)>(secs+1800)) {
-                        logOpen = false; // Start new file if asleep for more than 30 minutes
-                    } else { // insert timestamp on each wake
-                        logTS();
-                    }
-                    //LPC_RTC->CIIR=0x01; // re-enable RTC interrupts
+                } else {
+                    sprintf(sTemp,"missed button\n");
+                    logMsg(sTemp);
                 }
-                wait(0.2); // We get >2K messages per second
-            } while (logOpen); // keep going until button or fsram removed
-        } else {
-            printf("\nNo fUSB Inserted.\n\n");
-            logOpen=false;
-            led1=!led1;
-            led2=led1;
-            led3=led1;
-            led4=led1;
-            wait(5);
-        } //if (CD==1)
+            }
+        } else { // userIdle
+            sMode=0;
+        }
+        
+        wait(0.1); // We get >2K messages per second
     } //while (true)
 }
\ No newline at end of file