Dual CANbus monitor and instrumentation cluster supporting ILI9341 display controller

Dependencies:   SPI_TFTx2_ILI9341 TOUCH_TFTx2_ILI9341 TFT_fonts mbed

Fork of CANary by Tick Tock

Revision:
12:8e42d7ba8468
Parent:
11:e9d155aad4e2
Child:
13:62e0f7f39ff5
--- a/main.cpp	Wed Feb 27 03:47:06 2013 +0000
+++ b/main.cpp	Sun Mar 03 15:50:54 2013 +0000
@@ -1,504 +1,23 @@
-#include "CANary.h"
+//#include "utility.h"
+//#include "displayModes.h"
 //To Do:
-// USB device detect
-// config file on local fs
-// user programmable message decode
-// brake trainer
-// write and read the Mode Data
-LocalFileSystem local("local");
-
-// to write to USB Flash Drives, or equivalent (SD card in Reader/Writer)
-MSCFileSystem fs("fs"); // to write to a USB Flash Drive
-
-extern "C" void mbed_reset();
-
-time_t seconds ;
-Beep spkr(p21);
-
-Ticker ticker;
-Timer timer;
-DigitalOut led1(LED1);
-DigitalOut led2(LED2);
-DigitalOut led3(LED3);
-DigitalOut led4(LED4);
-PwmOut dled(p24);
-
-InterruptIn touchpad(p17);
-CAN can1(p9, p10);      // CAN2 uses pins 9 and 10 (rx, tx) and pin 27 (rs)
-DigitalOut can1SleepMode(p8);     // Use pin 8 to control the sleep mode of can2
-CAN can2(p30, p29);     // CAN1 uses pins 30 and 29 (rx, tx) and pin 28 (rs)
-DigitalOut can2SleepMode(p28);     // Use pin 28 to control the sleep mode of can1
-
-bool logEn = true,logOpen = false;
-FILE *rfile;
-FILE *file;
-char fileName[35] = "" ;
-char writeBuffer[maxBufLen][13]; // buffer for USB write
-char indexLastMsg[0x800]={0}; // index table for last message
-CANMessage lastMsg[100]; // table to store last message of eachtype
-unsigned char battData[256]={0};
-unsigned char msgChanged[100]; // inidcates which bytes changed
-char c;
-volatile int writePointer = 0;
-volatile int secsNoMsg = 0, secsNoTouch = 0;
-volatile bool canIdle = false, userIdle = false;
-bool getXY=0; //flag to read touchscreen
-char counter = 0;
-unsigned char dMode[2] = {7,2}; //display mode
-unsigned char sMode = 0; // setup mode
-unsigned char lastDMode[2] = {0,0}; //last screen mode
-char displayLog[20][40];
-unsigned char displayLoc = 0;
-unsigned char indexOffset = 1;
-bool showCP = false;
-
-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=(++secsNoMsg>canTimeout);
-    userIdle=(++secsNoTouch>userTimeout);
-    LPC_RTC->ILR |= (1<<0); // clear interrupt to prepare for next
-}
-
-extern "C" void RTC_Init (void) {
-    LPC_RTC->ILR=0x00; // set up the RTC interrupts
-    LPC_RTC->CIIR=0x01; // interrupts each second
-    LPC_RTC->CCR = 0x01;  // Clock enable
-    //NVIC_SetPriority( RTC_IRQn, 10 );
-    NVIC_EnableIRQ( RTC_IRQn );
-}
-
-void logMsg (char *msg) {
-    strcpy(displayLog[displayLoc],msg);
-    displayLoc=displayLoc>17?0:displayLoc+1;
-}
-
-void touched(){
-    LPC_GPIOINT->IO2IntClr = (LPC_GPIOINT->IO2IntStatR | LPC_GPIOINT->IO2IntStatF);
-    secsNoTouch = 0;
-    getXY=true;
-}
-
-unsigned short getTimeStamp() {
-    unsigned short msec = timer.read_ms() ; // read ms from the timer
-    unsigned long secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900
-    unsigned short isecs = secs%60 ; // modulo 60 for 0-59 seconds from RTC
-    return ((isecs<<10)+msec) ; // return the two byte time stamp
-}
-
-void logCan (char mType, CANMessage canRXmsg) {
-    char sTemp[40];
-    unsigned short ts = getTimeStamp();
-    unsigned long secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900
-    static unsigned char ii = 0, lasti = 0; // indexindex
-    unsigned char changed,i;
-    static unsigned char bdi;
-    if(logOpen){
-        if(canRXmsg.id>0) {
-            writeBuffer[writePointer][0]=mType;
-            writeBuffer[writePointer][1]=((secs%60)<<2)+((ts&0x300)>>8);
-            writeBuffer[writePointer][2]=ts&0xff;
-            writeBuffer[writePointer][3]=canRXmsg.id&0xff;
-            writeBuffer[writePointer][4]=(canRXmsg.id>>8)+(canRXmsg.len<<4);
-            for(i=5;i<13;i++){
-                writeBuffer[writePointer][i]=canRXmsg.data[i-5];
-            }
-            if (++writePointer >= maxBufLen) {
-                writePointer = 0;
-                led3 = !led3;
-            }
-        }
-    }//if logOpen
-    if(indexLastMsg[canRXmsg.id]==0) { //Check if no entry
-        ii=ii<99?ii+1:0;
-        indexLastMsg[canRXmsg.id]=ii; //Create entry if first message
-    }
-    if(dMode[0]==changedMode||dMode[1]==changedMode){
-        changed=msgChanged[indexLastMsg[canRXmsg.id]];
-        for(i=0;i<8;i++){
-            if(lastMsg[indexLastMsg[canRXmsg.id]].data[i]!=canRXmsg.data[i]){
-                changed |= 1<<i;
-            }
-        }
-        msgChanged[indexLastMsg[canRXmsg.id]]=changed;
-    }
-    lastMsg[indexLastMsg[canRXmsg.id]]=canRXmsg; //Store in table
-    if(mType==1&&canRXmsg.id==0x7bb){ // is battery data?  Need to store all responses
-        if(canRXmsg.data[0]<0x20){
-            if(canRXmsg.data[3]==2){//cellpair data
-                bdi=0;
-                sprintf(sTemp,"Getting cell pair data\n");
-                logMsg(sTemp);
-           }else if(canRXmsg.data[3]==4){//temperature data
-                bdi=0x20;
-                sprintf(sTemp,"Getting temperature data\n");
-                logMsg(sTemp);
-            }else bdi=0;
-            lasti=0;
-        }
-        i=canRXmsg.data[0]&0x0f; //lower nibble of D0 is index
-        if(lasti>i){ //detect rolloever and offset index appropriately
-            bdi=0x10;
-        }
-        lasti=i; //remember the msb to detect rollover next time around
-        i+=bdi;
-        i*=7;
-        if(i<0xfa){
-            battData[i+0]=canRXmsg.data[1];
-            battData[i+1]=canRXmsg.data[2];
-            battData[i+2]=canRXmsg.data[3];
-            battData[i+3]=canRXmsg.data[4];
-            battData[i+4]=canRXmsg.data[5];
-            battData[i+5]=canRXmsg.data[6];
-            battData[i+6]=canRXmsg.data[7];
-        }
-    }//if 0x7bb
-}
-
-void logTS () {
-    CANMessage tsMsg;
-    unsigned long secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900
-    tsMsg.id=0xfff;
-    tsMsg.len=0xf;
-    tsMsg.data[0]=secs&0xff;
-    tsMsg.data[1]=(secs>>8)&0xff;
-    tsMsg.data[2]=(secs>>16)&0xff;
-    tsMsg.data[3]=secs>>24;
-    tsMsg.data[4]=0xff;
-    tsMsg.data[5]=0xff;
-    tsMsg.data[6]=0xff;
-    tsMsg.data[7]=0xff;
-    logCan(0,tsMsg);
-}
-
-void sendCPreq() {
-    char i;
-    char data[8] = {0x02, 0x21, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff};
-    can1.monitor(false); // set to active mode
-    can1SleepMode = 0; // enable TX
-    can1.write(CANMessage(0x79b, data, 8));
-    data[0]=0x30; //change to request next line message
-    data[1]=0x01;
-    data[2]=0x00;
-    for(i=0;i<64;i++){
-        wait_ms(16); //wait 16ms
-        can1.write(CANMessage(0x79b, data, 8));
-    }
-    can1SleepMode = 1; // disable TX
-    can1.monitor(true); // set to snoop mode
-}
-
-void sendTreq() {
-    char i;
-    char data[8] = {0x02, 0x21, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff};
-    can1.monitor(false); // set to active mode
-    can1SleepMode = 0; // enable TX
-    can1.write(CANMessage(0x79b, data, 8));
-    data[0]=0x30; //change to request next line message
-    data[1]=0x01;
-    data[2]=0x00;
-    for(i=0;i<8;i++){
-        wait_ms(16); //wait 16ms
-        can1.write(CANMessage(0x79b, data, 8));
-    }
-    can1SleepMode = 1; // disable TX
-    can1.monitor(true); // set to snoop mode
-}
-
-void recieve1() {
-    CANMessage msg1;
-    secsNoMsg=0; // reset deadman switch
-    can1.read(msg1);
-    logCan(1, msg1);
-    led1 = !led1;
-}
-
-void recieve2() {
-    CANMessage msg2;
-    secsNoMsg=0; // reset deadman switch
-    can2.read(msg2);
-    logCan(2, msg2);
-    led2 = !led2;
-}
-
-void printLast (bool force){
-    CANMessage msg;
-    tt.locate(0,6);
-    tt.foreground(Red);
-    tt.background(Yellow);
-    if(force) tt.cls(); // Just clear screen if forced - always update display
-    tt.set_font((unsigned char*) Arial12x12_prop);  // select the font
-    for(int i=0; i<19; i++){
-        msg = lastMsg[i+indexOffset];
-        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]);
-    }
-}
-
-void printChanged (bool force){
-    CANMessage msg;
-    unsigned char i,j;
-    tt.locate(0,6);
-    tt.foreground(Red);
-    tt.background(Yellow);
-    if(force) tt.cls(); // Just clear screen if forced - always update display
-    tt.set_font((unsigned char*) Arial12x12_prop);  // select the font
-    i=0;
-    j=indexOffset;
-    do{
-        j=j<99?j+1:j;
-        if(msgChanged[j]>0){
-            msg = lastMsg[j];
-            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]);
-            i++;
-        }// if changed
-    }while(i<19&&j<99);
-}
-
-void printLog (bool force){
-    static unsigned char lastDisplayLoc = 0;
-    if(force||displayLoc!=lastDisplayLoc){ //only update if changed
-        tt.foreground(Amber);
-        tt.background(Black);
-        tt.cls();
-        tt.locate(0,6);
-        tt.set_font((unsigned char*) Arial12x12);
-        for(int i=0; i<19; i++){
-            printf("%s",displayLog[displayLoc]);
-            displayLoc=displayLoc>17?0:displayLoc+1;
-        }
-    }
-    lastDisplayLoc=displayLoc;
-}
-
-void printDTE (bool force){
-    unsigned short gids, SOC, packV;
-    static unsigned short lgids=0, lSOC=0, lpackV=0;
-    CANMessage msg;
-
-    msg = lastMsg[indexLastMsg[0x5bc]]; //Get gids
-    gids = (msg.data[0]<<2)+(msg.data[1]>>6);
-    msg = lastMsg[indexLastMsg[0x55b]]; //Get SOC
-    SOC = (msg.data[0]<<2)+(msg.data[1]>>6);
-    msg = lastMsg[indexLastMsg[0x1db]]; //Get pack volts
-    packV = (msg.data[2]<<2)+(msg.data[3]>>6);
-
-    tt.background(Navy);
-    if(force) tt.cls();
-    if(force||gids!=lgids){
-        tt.foreground(Amber);
-        tt.set_font((unsigned char*) Arial28x28);
-        tt.locate(10,10);
-        printf("%4d gids\n",gids);
-        tt.locate(10,200);
-        printf("%4.1f kWh\n",(float)gids*0.08);
-        tt.set_font((unsigned char*) SCProSB31x55);
-        //tt.set_font((unsigned char*) Neu42x35);
-        tt.foreground(Green);
-        tt.locate(60,96);
-        printf("%4.1f mi\n",(float)gids*0.33); // Approx for now
-        lgids=gids;
-    }
-    if(force||SOC!=lSOC){
-        tt.foreground(Amber);
-        tt.set_font((unsigned char*) Arial28x28);
-        tt.locate(200,10);
-        printf("%4.1f%s\n",(float)SOC/10,"%");
-        lSOC=SOC;
-    }
-    if(force||packV!=lpackV){
-        tt.foreground(Amber);
-        tt.set_font((unsigned char*) Arial28x28);
-        tt.locate(200,200);
-        printf("%4.1fV\n",(float)packV/2);
-        lpackV=packV;
-    }
-}
-
-void braking (bool force, bool prdata){
-    unsigned short targetBraking, regenBraking, speed;
-    static unsigned short maxTarget = 0, maxRegen = 0, tarDivReg = 0;
-    short rpm;
-    unsigned long temp;
-    static unsigned char lastPressure[4] = {200,200,200,200};
-    unsigned char i,r,t;
-    static unsigned char lr, lt;
-    CANMessage msg;
-
-    msg = lastMsg[indexLastMsg[0x1cb]]; //Get Target and Regen
-    regenBraking = (msg.data[0]<<3)+(msg.data[1]>>5);
-    targetBraking = (msg.data[2]<<3)+(msg.data[3]>>5);
-    if (targetBraking>maxTarget) maxTarget=targetBraking;
-    if (regenBraking>maxRegen) maxRegen=regenBraking;
-    if (regenBraking>50) {
-        temp = 1000*targetBraking;
-        temp /= regenBraking;
-        if (temp>tarDivReg) tarDivReg=temp;
-    }
-    msg = lastMsg[indexLastMsg[0x176]]; //Get rpms - not sure what this is but scales to mph with .0725
-    rpm = ((short)msg.data[0]<<8)+msg.data[1];
-    speed =rpm>0?rpm>>3:-rpm>>3; //Take absolute to get speed; div8
-    msg = lastMsg[indexLastMsg[0x1ca]]; //Get brake pressure
-
-    tt.background(Navy);
-    if (force) {
-        tt.cls();
-        tt.rect(0,111,170,239,White);
-        tt.line(0,207,170,207,White);
-        tt.line(0,175,170,175,White);
-        tt.line(0,143,170,143,White);
-        lastPressure[0] = 200;
-        lastPressure[1] = 200;
-        lastPressure[2] = 200;
-        lastPressure[3] = 200;
-    }
-    // plot bar graph for each wheel pressure
-    for (i=0; i<4; i++){
-        if (msg.data[i]<239) {
-            if (msg.data[i]>lastPressure[i]){
-                tt.fillrect(10+40*i,239-msg.data[i],40+40*i,239,Red);
-            } else if (msg.data[i]<lastPressure[i]) {
-                tt.fillrect(10+40*i,238-lastPressure[i],40+40*i,238-msg.data[i],Navy);
-            }
-            lastPressure[i]=msg.data[i];
-        }
-    }
-
-    if(targetBraking>50){
-        targetBraking *= speed;
-        regenBraking *= speed;
-        temp = 200*targetBraking/maxTarget;
-        t = (char) temp;
-        temp = 200*regenBraking*tarDivReg/maxTarget;
-        r = (char) temp;
-        if(lr!=r&&prdata){
-            tt.foreground(Amber);
-            tt.set_font((unsigned char*) Arial28x28);
-            tt.locate(100,50);
-            printf("%d %d    \n",regenBraking,maxRegen);
-            tt.locate(100,90);
-            printf("%3.1f (%3.1f%s)    \n",(float)tarDivReg/1000,(float)regenBraking*tarDivReg/targetBraking/1000,"%");
-        }    
-        if(lt!=t&&prdata){
-            tt.foreground(Amber);
-            tt.set_font((unsigned char*) Arial28x28);
-            tt.locate(100,10);
-            printf("%d %d    \n",targetBraking,maxTarget);
-        }
-        if((lr!=r||lt!=t)&&!prdata){
-            if(r<lr)
-                tt.fillrect(200,239-lr,300,239-r,Red);
-            else
-                tt.fillrect(200,239-r,300,239,Green);
-            if(t<lt)
-                tt.fillrect(200,239-lt,300,239-t,Navy);
-            else
-                tt.fillrect(200,239-t,300,238-r,Red);
-            lt=t;
-            lr=r;
-        }
-    }
-}
-
-void cpData(bool force){
-    short unsigned max, min, jv, i, bd;
-    unsigned avg;
-    if(force){
-        tt.foreground(White);
-        tt.background(Navy);
-        tt.set_font((unsigned char*) Arial12x12_prop);  // select the font
-        max=0;
-        min=9999;
-        avg=0;
-        for(i=0; i<96; i++){
-           bd=(battData[i*2+3]<<8)+battData[i*2+4];
-           avg+=bd;
-            if(bd>max) max=bd;
-            if(bd<min) min=bd;
-        }
-        avg /= 96;
-        jv=avg-(max-avg)*2.5;
-        tt.cls();
-        tt.locate(0,6);
-        printf(" MAX  MIN  AVG CVLI T1  T2  T3  T4\n %04d %04d %04d %04d %02dC %02dC %02dC %02dC\n\n",max,min,avg,jv,battData[224+5],battData[224+8],battData[224+11],battData[224+14]);
-        tt.locate(0,36);
-        for(i=0; i<16; i++){
-            printf("%02d-%02d : %04d %04d %04d %04d %04d %04d\n",i*6+1,i*6+6,(battData[i*12+3]<<8)+battData[i*12+4],(battData[i*12+5]<<8)+battData[i*12+6],(battData[i*12+7]<<8)+battData[i*12+8],(battData[i*12+9]<<8)+battData[i*12+10],(battData[i*12+11]<<8)+battData[i*12+12],(battData[i*12+13]<<8)+battData[i*12+14]);
-        }
-        tt.rect(8+0*41,16,40+0*41,28,Green);
-        tt.rect(8+1*41,16,40+1*41,28,Yellow);
-        //tt.rect(8+2*41,16,40+2*41,28,White);
-        tt.rect(8+3*41,16,40+3*41,28,Red);
-        for(i=0; i<96; i++){
-            bd=(battData[i*2+3]<<8)+battData[i*2+4];
-            if(bd>0){
-                if(bd==max) tt.rect(58+(i%6)*41,34+(int)(i/6)*12,90+(i%6)*41,46+(int)(i/6)*12,Green);
-                //if(bd==avg) tt.rect(58+(i%6)*41,34+(int)(i/6)*12,90+(i%6)*41,46+(int)(i/6)*12,White);
-                if(bd==min) tt.rect(58+(i%6)*41,34+(int)(i/6)*12,90+(i%6)*41,46+(int)(i/6)*12,Yellow);
-                if(bd<jv) tt.rect(58+(i%6)*41,34+(int)(i/6)*12,90+(i%6)*41,46+(int)(i/6)*12,Red);
-            }
-        }
-        showCP=false;
-    }
-}
-
-void updateDisplay(char display){
-    bool changed;
-    changed = dMode[display]!=lastDMode[display];
-    tt.set_display(display);
-    switch (dMode[display]) {
-        case logMode:
-            printLog(changed);
-            break;
-        case dteMode:
-            printDTE(changed);
-            break;
-        case brakeMode:
-            braking(changed,true);
-            break;
-        case powerMode:
-            braking(changed,false);
-            break;
-        case monitorMode:
-            printLast(changed);
-            break;
-        case changedMode:
-            printChanged(changed);
-            break;
-        case cpMode:
-            cpData(changed||showCP);
-            break;
-        default:
-            tt.background(Black);
-            tt.cls();
-            break;
-    }
-    lastDMode[display]=dMode[display];
-
-    switch (sMode) {
-        case 1:
-            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;
-    }
-}
+// * USB device detect
+// * config file on local fs with touchscreen calibration
+// * user programmable message decode
+// * brake trainer
+// * write and read the Mode Data
+// * Date entry config screen (keypad)
+// * auto-poll option for cellpair data
+// * cellpair histogram
+// * 
+#include "mbed.h"
+#include "CAN.h"
+#include "beep.h"
+#include "MSCFileSystem.h"
+#include "PowerControl.h"
+#include "EthernetPowerControl.h"
+#include "utility.h"
+#include "displayModes.h"
 
 int main() {
     int readPointer=0;
@@ -522,9 +41,13 @@
     tt.background(Black);
     tt.cls();
     tt.set_display(0);       // select left display
-    tt.calibrate();           // calibrate the touch
+    if(true){ // bypass calibration
+        tt.setcal(5570, 34030, 80, 108, 33700, 5780, 82, 108, 32500);
+    } else {  // calibrate the touch
+        tt.calibrate();   
+    }
     tt.claim(stdout);        // send stdout to the TFT display
-    touchpad.rise(&touched);
+    touchpad.rise(&touch_ISR);
     tt.wfi();               // enable interrupt on touch
     dled = 0.8; // turn on display LED 80%
     timer.start() ;
@@ -563,6 +86,7 @@
         //    strftime(sTemp, 32, "%a %m/%d/%Y %X", localtime(&seconds));
         //    printf("%s\n", sTemp); // DAY MM/DD/YYYY HH:MM:SS
     }
+    //ticker.attach(&tickerISR, 60);  //poll cellpair data every minute
     while (true) {
         if (!logOpen) { // Open new file if one is not already open
             if(logEn){ //logging enable
@@ -623,7 +147,7 @@
             secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900
             while (secsNoMsg>canTimeout && secsNoTouch>userTimeout) {
                 //DeepPowerDown();
-                tt.wfi(); //enable touchpad input
+                tt.wfi(); //enable touch interrupt
                 __wfi(); // freeze CPU and wait for interrupt (from canbus or touch)
                 //Sleep();
                 //DeepPowerDown();
@@ -642,10 +166,10 @@
             }
         } // if idle
         
-        if(getXY){
+        if(touched){
             lastTouch = tt.get_touch();       
             lastTouch = tt.to_pixel(lastTouch);          // convert to pixel pos
-            getXY = false; // clear interrupt flag
+            touched = false; // clear interrupt flag
         }
         if (!userIdle) {
             if (secsNoTouch<2) {// Recently touched
@@ -659,15 +183,15 @@
                 if (lastTouch.y>btn11y1 && lastTouch.y<btn11y2) {
                     if(sMode==1){
                         if (lastTouch.x>btn31x1 && lastTouch.x<btn31x2) {
-                            dMode[i]=dMode[i]>0?dMode[i]-1:maxModes;
+                            dMode[i]=dMode[i]>0?dMode[i]-1:maxScreens;
                         } else if (lastTouch.x>btn32x1 && lastTouch.x<btn32x2) {
                             secsNoTouch = userTimeout; // immediately exit config mode
                         } else if (lastTouch.x>btn33x1 && lastTouch.x<btn33x2) {
-                            dMode[i]=dMode[i]<maxModes?dMode[i]+1:0;
+                            dMode[i]=dMode[i]<maxScreens?dMode[i]+1:0;
                         }
                     } else sMode=1;
                 } else {
-                    if (dMode[i]==monitorMode||dMode[i]==changedMode) {
+                    if (dMode[i]==monitorScreen||dMode[i]==changedScreen) {
                         if (lastTouch.x>btn31x1 && lastTouch.x<btn31x2) {
                             indexOffset=indexOffset>4?indexOffset-4:1;
                         } else if (lastTouch.x>btn32x1 && lastTouch.x<btn32x2) {
@@ -676,13 +200,9 @@
                         } else if (lastTouch.x>btn33x1 && lastTouch.x<btn33x2) {
                             indexOffset=indexOffset<77?indexOffset+4:80;
                         }
-                    } else if (dMode[i]==cpMode) {
+                    } else if (dMode[i]==cpScreen) {
                         if (lastTouch.x>btn32x1 && lastTouch.x<btn32x2){
-                            sendCPreq(); // send cellpair data request.
-                            wait_ms(16);
-                            sendTreq(); //send temperature request
-                            wait_ms(16);
-                            showCP=true;
+                            pollCP=true;
                         }
                     }
                 } //top of screen
@@ -694,6 +214,14 @@
                 lastDMode[1]=99;
             }
         }
+        if(pollCP){
+            sendCPreq(); // send cellpair data request.
+            wait_ms(16);
+            sendTreq(); //send temperature request
+            wait_ms(16);
+            pollCP=false;
+            showCP=true;
+        }
         display=display<1?display+1:0; // toggle display
         updateDisplay(display);
         //wait(0.1); // We get >2K messages per second