direction commands updated to Up down RPM value

Dependencies:   MAX7219pot MCP23S17 mbed

Fork of POT_V_1_0 by Marine Electricals

Revision:
4:710464cb44fc
Parent:
3:ae45e29f5d4f
Child:
5:f7b7ee0702cc
--- a/main.cpp	Sat Jan 13 11:49:18 2018 +0000
+++ b/main.cpp	Sat Apr 28 10:22:22 2018 +0000
@@ -1,3 +1,9 @@
+/*Board configuration
+>>>>>place JP5 to E5V side to use external  5V supply
+>>>>>Remove jumper link SB13,SB14 usb uart debug disabled
+>>>>>Place jumper link SB62,SB63...uart PA2,PA3 enabled by these jumper links
+*/
+
 #include "mbed.h"
 #include "pot.h"
 #include "max7219.h"
@@ -21,12 +27,12 @@
 Ticker HB_fail;
 Ticker RTC_ticker;
 Ticker led_refresh;
+Timeout timeout;
 
 //SPI instances creation//
 SPI _SPI2(SPI2_MOSI, SPI2_MISO, SPI2_SCK);  //for displays max7219
 SPI _SPI3(SPI3_MOSI, SPI3_MISO, SPI3_SCK);  //for keyscan  mcp23s17
 
-
 //class object instances for key I/O expander and segment driver//
 MCP23S17 mcp23s17_1(1,_SPI3, SPI3_CS1,SPI3_RST);  //class MCP23S17 object instance for mcp23s17 IC-1 key detection
 MCP23S17 mcp23s17_2(2,_SPI3, SPI3_CS2,SPI3_RST);  //class MCP23S17 object instance for mcp23s17 IC-2 key detection
@@ -43,24 +49,26 @@
 DigitalOut cs_key1(SPI3_CS1);    
 DigitalOut cs_key2(SPI3_CS2);    //mcp23s17
 
-DigitalOut Drive_En(Tx_EN);      //uart driver enable
+DigitalOut Drive_En(TX_EN);      //uart driver enable
 
 //discrete outputs definations buzzer and hooter
 DigitalOut buzzer(BUZ);
 DigitalOut hooter(HTR); 
 
+
 int err_ALL,sync_count,Hrs_1,Hrs_2, Mins_1, Mins_2, current_cmd, current_status,current_status_dir;
 int addr, req,ack, send_ADDR, rcvd_ADDR, ach_S,ach_M,test_cnt,req_ADDR,ack_ADDR, err_ID, err_Status;
 int rpm_data[4] = {0,0,0,0};               //digits 0-3
 int last_entry[4] = {0,0,0,0};          //digits 0-3
 
+
 uint8_t spi_error,no_pot_connected,num_bytes,ticker_count,ticker_count_fast,norm_count,set_bit;
 
-uint8_t digit_disp1, digit_disp2, digit_disp3;        //disp1 for new rpm, disp2 for current rpm, disp3 for rtc
 
 int dir, last_dir;
+int checksum_send_byte,checksum_rcvd_byte;
 
-char pot_Addr,addr_ID,checksum;
+char pot_Addr,addr_ID;
 
 float HB_timer,duty_cycle,sync_time;
 
@@ -74,13 +82,15 @@
 
 bool HB_send, CMD_send, BROADCAST_send, REQ_send, ACK_send;
 
-bool ENTER_ACK_key,DIR_key,REQ_key,ACK_key;
+bool ENTER_ACK_key,DIR_key,REQ_key,ACK_key,disp_clear;
 
 bool switch_CH, pot_MCR_err, pot_ER_err, ACH_SW_over;
+bool data_fail,disp_test;
+
+int device_addr = -1;
 
 char valid;
-int device_addr = -1;
-
+char valid_sentence[8] = {'A', 'A','A','A','A','A','A','A'};
 char rx_buf[RX_BUFFER_SIZE+1];
 char tx_buf[TX_BUFFER_SIZE+1];
 char RTC_buffer[5] = {1,2,3,4,0};
@@ -161,7 +171,7 @@
 enum display_KEY
 {
     clr_ENTRY = 0,           //CE
-    last_ENTRY,              //C
+    clr_ALL,                 //C, all data turns to zero
     ENTER_ACK,               //enter in case of master and ACK in case of slaves/repeaters
     FALSE3 = 3
 };
@@ -186,7 +196,6 @@
 enum CHANNEL ch;
 
 
-
 /**************************************************************************************
  EOT RTC display update FUNCTIONS
  **************************************************************************************/
@@ -251,12 +260,20 @@
         {
                 LED_ACH[i] = ON;                  //duty cycle 10%
         }
-        
-        /*TO DO DISPLAY TEST */
+        max7219.set_display_test();                  //all on
+        wait_us(1);
+        disp_test = true;
     }
     else
     {
-        ///////////////////////////////////
+            if(disp_test)
+                {
+                    disp_test = false;
+                    max7219.clear_display_test();                //normal operation
+                }
+            else
+                __nop();
+            
             if(led_cmd_ack == ON)          //status update LED_CMD_ACK
                 LED_CMD_ACK = ON;
             else
@@ -276,7 +293,7 @@
             }
             else
                 __nop();
-        /////////////////////////////////////
+            
         for(uint8_t i=0;i<=1;i++)          //status update LED_CTRL 
         {
             if(led_ctrl[i] == ON)
@@ -299,7 +316,30 @@
             else
                 __nop();
         }
-        ///////////////////////////////////
+        
+        for(uint8_t i=0;i<=1;i++)          //status update LED_CTRL 
+        {
+            if(led_dir[i] == ON)
+                LED_DIR[i] = ON;
+            else
+                __nop();
+                
+            if(led_dir[i] == OFF)
+                LED_DIR[i] = OFF;                  //duty cycle 10%
+            else
+                __nop();
+                
+            if(led_dir[i] == _FLASH)
+            {
+                 if(toggle)
+                    LED_DIR[i]= ON;
+                else
+                    LED_DIR[i] = OFF;
+            }
+            else
+                __nop();
+        }
+        
         for(uint8_t i=0;i<=7;i++)          //status update LED_ACH
         {
             if(led_ach[i] == ON)
@@ -339,7 +379,7 @@
 /**************************************************************************************
   POT State Machines FUNCTIONS
  **************************************************************************************/
-void HB_State_Machine()                       //run for 50ms at an interval of 10ms,event driven start stop
+void HB_State_Machine()                       //run at an interval of 10ms,event driven start stop
 {
     static int hb_state_cnt = 0;
     if(HB_send)
@@ -355,17 +395,17 @@
         HB_ack_rcvd = false;
         HB_Ticker.detach();
         POT[device_addr].err_cnt = 0;
-        if(POT[device_addr].err_status)              //if that specific device is in error before but revert bak to healthy state
+        if(POT[device_addr].err_status)                //if that specific device is in error before but revert back to healthy state
         {
             POT[device_addr].err_status = false;
             err_Status = 0;
             err_ID = POT[device_addr].slave_ID;
             
             set_bit =  (uint8_t)1<<(err_ID-1);
-            err_ALL = err_ALL^set_bit;                   //bitwise XOR
+            err_ALL = err_ALL^set_bit;                  //bitwise XOR
             
             BROADCAST_send = true;                      // to tell all device that error diminished
-            switch_CH = true;                           // to tell specific device active channell                                
+            switch_CH = true;                           // to tell specific device abot active channels and rpm data                                
             if(POT[device_addr].slave_ID == pot_Slave_MCR)
             {
                 pot_MCR_err = false;
@@ -395,26 +435,36 @@
                 __nop();
         }
         else
-            __nop();
+        {
+            POT[device_addr].err_status = false;
+            hb_state_cnt = 0;
+            err_Status = 0;
             
-        POT[device_addr].err_status = false;
-        hb_state_cnt = 0;
-        err_Status = 0;
-        if(POT[device_addr].slave_ID == ach_S)
-            led_ach[send_ADDR - 1] = ON;
-        else
-            led_ach[send_ADDR - 1] = OFF;
-        
+            if((POT[device_addr].slave_ID == ach_S)&&(led_ach[send_ADDR - 1] != ON))
+                led_ach[send_ADDR - 1] = ON;
+            else if((POT[device_addr].slave_ID != ach_S)&&(led_ach[send_ADDR - 1] != OFF))
+                led_ach[send_ADDR - 1] = OFF; 
+            else
+                __nop();  
+                
+            if((addr_ID == ach_M)&&(led_ach[ach_M-1] != ON))
+                led_ach[ach_M-1] = ON;
+            else if((addr_ID != ach_M)&&(led_ach[ach_M-1] != OFF))
+                led_ach[ach_M-1] = OFF;
+            else
+                __nop();
+        }
     }
     else
     {
-        if(++hb_state_cnt >= 5)
+        if(++hb_state_cnt >= 5)             //if HB_response not arrived till 50ms
         {
             hb_state_cnt=0;
             HB_Ticker.detach();
             
-            if((++POT[device_addr].err_cnt >= 3)&&(!POT[device_addr].err_status))  //specific device come to the error state
+            if((++POT[device_addr].err_cnt >= 5)&&(!POT[device_addr].err_status))  //specific device  in error state after 05 hb response missing
             {
+                POT[device_addr].err_cnt = 0;
                 led_ach[send_ADDR - 1] = _FLASH;
                 err_ID = POT[device_addr].slave_ID; 
                 
@@ -484,6 +534,33 @@
         
     if(RPM_cmd_ack)                        //PEOTX,CMD received in Master/SUB_Master, non Active Slave & Listner
     {
+        for(uint8_t i = 0; i <=3; i++)
+        {
+            last_entry[i] = rpm_data[i];           //data saved to last entery
+        }
+        for(uint8_t i = 5; i <=8; i++)
+        {
+            max7219.write_digit(1,i,last_entry[i-5]);     //last entery displayed
+        }
+        if(addr_ID == ach_M)
+        {
+            mcp23s17_1.gpintena(0xff);      //ACK key interrupts disabled
+            wait_us(1);
+            mcp23s17_1.gpintenb(0xff);      //ACK key interrupts disabled
+            wait_us(1);
+            disp_clear = true;
+        }
+        else if(addr_ID == ach_S)
+        {
+            int_B.rise(NULL);             //all key functions/interrupt disabled for PORTA,B
+            wait_us(1);
+            mcp23s17_1.gpintenb(0x00);    //interrupts disabled
+            wait_us(1); 
+        }
+        else
+            __nop();
+            
+        led_cmd_ack = ON;
         current_status =  1;              //display steady
         cmd_state_cnt = 0;
         RPM_cmd = false; 
@@ -493,46 +570,27 @@
         hooter = OFF;
         CMD_Ticker.detach();                        //cmd state machine ticker stopped in all devices
     }
-    else 
+    else if(++cmd_state_cnt >= 12)                       //Hotter ON after 3sec
     {
-        if(addr_ID != ach_S)                //PEOTC, CMD received in other than Active Slave
-            return;
-        else if(RPM_cmd_ack_send)           //if RPM_cmd_ack in acitve slave
+        if((hooter == OFF)&&(addr_ID == ach_S))              //if hooter still off
         {
-            led_cmd_ack = ON;               //RPM cmd ACK by active slave
-            cmd_state_cnt = 0; 
-            buzzer = OFF;                                                       //steady ON 
+            cmd_state_cnt = 0;
+            hooter = ON;
+       /* if(++cmd_state_cnt >= 96)                     //still command ack not recived for 24 sec
+        {
+            LED_CMD[cmd].OFF();                //command suspended
+            buzzer = OFF;
             hooter = OFF;
-            cmd_state_cnt=0;
-            RPM_cmd_ack_send = false;
-            RPM_cmd = false;                    
-            int_B.rise(NULL);             //all key functions/interrupt disabled for PORTA,B
-            mcp23s17_1.gpintenb(0x00);    //interrupts disabled
-            wait_us(10);
-            CMD_Ticker.detach();             //would be stopped in active slave only
-        }
-        else if(hooter == OFF)              //if hooter still off
-        {
-            if(++cmd_state_cnt >= 12)                       //Hotter ON after 3sec
-            {
-                cmd_state_cnt = 0;
-                hooter = ON;
-               /* if(++cmd_state_cnt >= 96)                     //still command ack not recived for 24 sec
-                {
-                    LED_CMD[cmd].OFF();                //command suspended
-                    buzzer = OFF;
-                    hooter = OFF;
-                    int_A.rise(NULL);
-                    int_A.rise(NULL);
-                    CMD_ticker.detach();           //timer stoped in all connected devices if ack not received in 3sec
-                } */
-            }
-            else
-                __nop();
+            int_A.rise(NULL);
+            int_A.rise(NULL);
+            CMD_ticker.detach();           //timer stoped in all connected devices if ack not received in 3sec
+        } */
         }
         else
-         __nop();
+            __nop();
     }
+    else
+        __nop();
 }
 
 void R_A_Statemachine()
@@ -541,9 +599,10 @@
     if(++state_cnt >= 60)             //REQ not acknowledged for 30 sec, leds turn off, timer stopped
     {
         state_cnt = 0;
+        REQ_rcvd = false;            //clear any pending request
         R_A_Ticker.detach();
-        
-        if(addr_ID != ach_M)               //*********** TODO****************//
+    /*  
+        if(addr_ID != ach_M)      // TODO         
         {
             int_B.rise(NULL);
             mcp23s17_1.gpintenb(0x00);      //portb of mcp1 keys disabled related to ACK
@@ -551,6 +610,7 @@
         }
         else
             __nop();
+     */
             
         led_ctrl[REQ_-1] = OFF;
         led_ctrl[ACK_-1] = OFF;
@@ -633,17 +693,20 @@
     else if(++fail_count >=3)             // if max 07 number of connected eots 7x3=21, it takes 150x21=3.150 sec to alarm
     {
         fail_count = 0;
-        led_dir[dir] = OFF;               //current command if any turned OFF
-       // led_cmd[current_cmd] = OFF;
+        led_dir[dir-1] = OFF;               //current command if any turned OFF
+        led_cmd_ack = OFF;
         display_flash = false;
         device_ERR = true;
         max7219.disable_device(2);              //shutdown mode
         wait_ms(2);
-        for(uint8_t i = 0; i <=7; i++)
+        if(addr_ID != ach_M)
         {
-            led_ach[i] = OFF;             //all other active chnnels leds or device errors
+            for(uint8_t i = 0; i <=7; i++)
+            {
+                led_ach[i] = OFF;             //all other active chnnels leds or device errors
+            }
+            led_ach[addr_ID - 1] = _FLASH;    //specific device is in error flshes only
         }
-        led_ach[addr_ID - 1] = _FLASH;    //specific device is in error flshes only
         HB_fail.detach();
     }
 }
@@ -656,14 +719,28 @@
         {                                                                                  
         if(((ach_M == pot_Master) && (addr_ID == pot_Master)) || ((ach_M == pot_Submaster) && (addr_ID == pot_Submaster)))                               //for Master
             {
-                if(digit_disp1 <= 1)
-                    digit_disp1 = 4;
+                if(disp_clear)                   //if last command has been acknowledged
+                {
+                    for (uint8_t j = 0; j < 4; j++)
+                    {
+                        rpm_data[j] = 0;          //clear rpm_data to enter new values
+                    } 
+                    disp_clear = false;
+                } 
                 else
-                    digit_disp1-- ;
+                    __nop();
                     
-                rpm_data[digit_disp1-1] = num;                               //data stored in global buffer
-                max7219.write_digit(2,digit_disp1,rpm_data[digit_disp1-1]);  //4th digit updated on first press, then 3rd on next press....soon
-                wait_us(10);                             
+                for (uint8_t j = 0; j < 4; j++)
+                {
+                        rpm_data[j] = rpm_data[j + 1];   //at every key press array shift to left
+                }
+                
+                rpm_data[3] = num;   //new value be updated at place of digit 4
+                
+                for (uint8_t j = 1; j <= 4; j++)
+                {
+                    max7219.write_digit(2,j,rpm_data[j-1]);
+                }                                     
             }
         else
             __nop();
@@ -679,7 +756,7 @@
     {
         if((addr_ID == pot_Slave_MCR) || (addr_ID == pot_Slave_ER))
         {
-            if(CTRL_ID == REQ_)
+            if((CTRL_ID == REQ_)&&(!REQ_rcvd))  //if no request has been received
             {   
                 req = REQ_;                     //req data updated 0 here, same int values as in enum
                 REQ_key = true;
@@ -757,15 +834,15 @@
             case clr_ENTRY:                                      //CE,elete only last/4th digit and shift others digits towards right/4th digit
                 if(addr_ID == ach_M)
                 {
-                    for(uint8_t i = 3; i >= 0 ; i--)
+                    for (uint8_t j = 3; j > 0; j--)
                     {
-                        rpm_data[i] = rpm_data[i-1];
-                        if(i==0)
-                        rpm_data[i] = 0;                         //data 0 means left most digit will be blank bcoz no decode mode is used
+                        rpm_data[j] = rpm_data[j - 1];   //at every key press array shift to left
                     }
-                    for(uint8_t i = 0; i <=3; i++)
+                    rpm_data[0] = 0;
+                
+                    for (uint8_t j = 1; j <= 4; j++)
                     {
-                        max7219.write_digit(2,i+1,rpm_data[i]);    //4th digit will be deleted whilers are shifted towards right 1st will be blank
+                        max7219.write_digit(2,j,rpm_data[j-1]);
                     }
                 }
                 else
@@ -774,12 +851,16 @@
                 }
             break;
             
-            case last_ENTRY: 
+            case clr_ALL: 
                 if(addr_ID == ach_M) 
                 {                                    //C      delete all digits in DS1 and show last entered value                                 
-                    for(uint8_t i = 0; i >=3; i++)
+                    for (uint8_t j = 0; j <=3; j++)
                     {
-                        max7219.write_digit(2,i+1,last_entry[i]);     //last entery displayed
+                        rpm_data[j] = 0;   //at every key press array shift to left
+                    }
+                    for (uint8_t j = 1; j <= 4; j++)      // all digits turns to zero
+                    {
+                        max7219.write_digit(2,j,rpm_data[j-1]);
                     }
                 }
                 else
@@ -790,21 +871,23 @@
             
             case ENTER_ACK:                                    //work as Enter in master and CMD ACK in slave
                 if((addr_ID == ach_S)&&(RPM_cmd))                    //RPM command ack needs to be sent
-                {    
+                {
+                    RPM_cmd = false;    
                     display_flash = false; 
                     buzzer = OFF;
-                    ENTER_ACK_key = true;                                               //flashing display1 turned steady
-                    RPM_cmd_ack = true;                              //RPM command acknowledged by active slave
+                    int_B.rise(NULL);
+                    wait_us(10);
+                    mcp23s17_1.gpintenb(0x00);      //ACK key interrupts disabled
+                    wait_us(10);
+                    ENTER_ACK_key = true;           //flashing display1 turned steady                              //RPM command acknowledged by active slave
                 } 
                 else  if (addr_ID == ach_M)                                 //in case of active masters
                 {                                              //disp1 start flashing, and data sent over UART for all digits 1-4
-                    for(uint8_t i = 0; i >=3; i++)
-                    {
-                        last_entry[i] = rpm_data[i];           //data saved to last entery
-                    }
                     display_flash = true;             //display starts flashing
-                    int_A.rise(NULL);                 //all key functions DISabled for PORTA,B in active MASTER only        
-                    int_B.rise(NULL);
+                    mcp23s17_1.gpintena(0x00);      //ACK key interrupts disabled
+                    wait_us(10);
+                    mcp23s17_1.gpintenb(0x00);      //ACK key interrupts disabled
+                    wait_us(10);
                     current_status =  2;              //flash
                     buzzer = ON;
                     RPM_cmd = true;                   //command need to be send
@@ -835,16 +918,16 @@
         {
             case INC:
                 duty_cycle = mypwm.read();     //as duty cycle decreases creases brightnes increases
-                if( duty_cycle >= 0.01f)
+                if( duty_cycle > 0.02f)
                 {
                     duty_cycle = duty_cycle-0.01f;
                     mypwm.write(duty_cycle);
                 }
                 else
                 {
-                    duty_cycle = 0.01;
+                    duty_cycle = 0.01f;
                 }
-                if((DEVICE1.intensity || DEVICE2.intensity) <= 0x0f)
+                if(DEVICE1.intensity  < 14)
                 {
                     DEVICE1.intensity ++;                               //intensity modified
                     DEVICE2.intensity ++;
@@ -853,8 +936,8 @@
                 }
                 else
                 {
-                    DEVICE1.intensity =0x0f;
-                    DEVICE2.intensity =0x0f;
+                    DEVICE1.intensity =15;
+                    DEVICE2.intensity =15;
                     max7219.set_intensity(DEVICE1);       //updating brightness value of DEVICE1
                     max7219.set_intensity(DEVICE2);       //updating brightness value of DEVICE2
                 }
@@ -862,16 +945,16 @@
         
             case DEC:
                 duty_cycle = mypwm.read();
-                if( duty_cycle < 0.99f)          //as duty cycle increases brightnes decreases
+                if( duty_cycle < 0.98f)          //as duty cycle increases brightnes decreases
                 {
                     duty_cycle = duty_cycle+0.01f;
                     mypwm.write(duty_cycle);
                 }
                 else
                 {
-                    duty_cycle = 0.99;
+                    duty_cycle = 0.99f;
                 }
-                if((DEVICE1.intensity || DEVICE2.intensity) >= 0x01)
+                if(DEVICE1.intensity  > 2)
                 {
                     DEVICE1.intensity --;                              //intensity modified
                     DEVICE2.intensity --;
@@ -880,8 +963,8 @@
                 }
                 else
                 {
-                    DEVICE1.intensity =0x01;
-                    DEVICE2.intensity =0x01;                                //minimum brightnes
+                    DEVICE1.intensity =1;
+                    DEVICE2.intensity =1;                                //minimum brightnes
                     max7219.set_intensity(DEVICE1);       //updating brightness value of DEVICE1
                     max7219.set_intensity(DEVICE2);       //updating brightness value of DEVICE2
                 }
@@ -1023,7 +1106,7 @@
                 DISP_handler(disp_KEY);
             break;
             case 0xbf:                     //0xbf  GPA6
-                disp_KEY = last_ENTRY;             //C
+                disp_KEY = clr_ALL;             //C
                 DISP_handler(disp_KEY);
             break;
             case 0x7f:                    //0x7f  GPA7
@@ -1075,45 +1158,48 @@
 /**************************************************************************************
 POT Serial Data Out FUNCTIONS
  **************************************************************************************/
-uint8_t get_checksum(const char *sentence)
+uint8_t  get_checksum(const char *sentence)
 {
     const char *n = sentence + 1; // Plus one, skip '$'
     uint8_t chk = 0;
 
     /* While current char isn't '*' or sentence ending (newline) */
-    while ('*' != *n && NMEA_END_CHAR_1 != *n) 
+    while (('*' != *n) &&(NMEA_END_CHAR_1 != *n))
     {
         if ('\0' == *n || n - sentence > NMEA_MAX_LENGTH) 
         {
             /* Sentence too long or short */
-            return 0;
+            chk = 0;
         }
         chk ^= (uint8_t) *n;
         n++;
     }
-
     return chk;
 }
 
 void resp_HB(uint8_t seq)      //presentees(submaster,slaves,listeners will respond back to the HB along with REQ and CMD ack status
 {
-    switch(seq)
+   switch(seq)
     {
         case 0:
-            sprintf(tx_buf,"$PPOTA,%u,%c", addr_ID, valid);
+            sprintf(tx_buf,"$PPOTA,%u,%c*", addr_ID,valid);
+            checksum_send_byte = get_checksum(tx_buf);
+            sprintf(tx_buf,"$PPOTA,%u,%c*%u",addr_ID,valid,checksum_send_byte);
         break;
         case 1:
-            sprintf(tx_buf,"$PPOTR,%u,%u,%c", addr_ID, REQ_, valid);
+            sprintf(tx_buf,"$PPOTR,%u,%u,%c*", addr_ID, REQ_,'A');
+            checksum_send_byte = get_checksum(tx_buf);
+            sprintf(tx_buf,"$PPOTR,%u,%u,%c*%u",addr_ID,REQ_,'A',checksum_send_byte);
         break;
         case 2:
-            sprintf(tx_buf,"$PPOTK,%u,%u,%c", addr_ID, ACK_, valid);
+            sprintf(tx_buf,"$PPOTK,%u,%u,%c*", addr_ID, ACK_,'A');
+            checksum_send_byte = get_checksum(tx_buf);
+            sprintf(tx_buf,"$PPOTK,%u,%u,%c*%u",addr_ID, ACK_,'A',checksum_send_byte);
         break;
         default:
-            sprintf(tx_buf,"$PPOTA,%u,%c", addr_ID, valid);
+            __nop(); //sprintf(tx_buf,"$PPOTA,%u,%c", addr_ID, valid);
         break;
-    }
-    //checksum=get_checksum(tx_buf);                
-    //sprintf(tx_buf,"%u",checksum);
+    }                
     Drive_En = 1;              
     UART.printf("%s\r\n",tx_buf);
     wait_ms(2);
@@ -1122,20 +1208,9 @@
 
 void send_ack_CMD(uint8_t cmd_t)
 {
-    switch(cmd_t)
-    {
-        case 1:                                       //RPM cmd ack
-        sprintf(tx_buf,"$PPOTX,%u,%u,%c", addr_ID, cmd_t, valid);
-        break;
-        case 2:                                       //DIR cmd Ack
-        sprintf(tx_buf,"$PPOTX,%u,%u,%c", addr_ID, cmd_t, valid);
-        break;
-        default:
-        __nop();
-        break;
-    }
-    //checksum=get_checksum(tx_buf);                
-    //sprintf(tx_buf,"%u",checksum);
+    sprintf(tx_buf,"$PPOTX,%u,%u,%c*", addr_ID, cmd_t,'A');
+    checksum_send_byte = get_checksum(tx_buf);                
+    sprintf(tx_buf,"$PPOTX,%u,%u,%c*%u",addr_ID,cmd_t,'A',checksum_send_byte);
     Drive_En = 1;              
     UART.printf("%s\r\n",tx_buf);
     wait_ms(2);
@@ -1144,9 +1219,9 @@
 
 void send_RPM(uint8_t _adr)
 {
-    sprintf(tx_buf,"$PPOTC,%u,%u,%u,%u,%u,%c", _adr, rpm_data[0],rpm_data[1],rpm_data[2],rpm_data[3], valid);
-    //checksum=get_checksum(tx_buf);                
-    //sprintf(tx_buf,"%u",checksum);
+    sprintf(tx_buf,"$PPOTC,%u,%u,%u,%u,%u,%c*", _adr, rpm_data[0],rpm_data[1],rpm_data[2],rpm_data[3],'A');
+    checksum_send_byte = get_checksum(tx_buf);                
+    sprintf(tx_buf,"$PPOTC,%u,%u,%u,%u,%u,%c*%u",_adr, rpm_data[0],rpm_data[1],rpm_data[2],rpm_data[3],'A',checksum_send_byte);
     Drive_En = 1;              
     UART.printf("%s\r\n",tx_buf);
     wait_ms(2);
@@ -1155,31 +1230,31 @@
 
 void send_DIR(uint8_t _adr)             //addr 1-8 of leds,error=1 or 0(no error)
 {
-    sprintf(tx_buf,"$PPOTD,%u,%u,%c",_adr,dir,valid);             // dir is 1 for ahead, 2 for astern
-    //checksum=get_checksum(tx_buf);                
-    //sprintf(tx_buf,"%u",checksum);
+    sprintf(tx_buf,"$PPOTD,%u,%u,%c*",_adr,dir,'A');             // dir is 1 for ahead, 2 for astern
+    checksum_send_byte = get_checksum(tx_buf);                
+    sprintf(tx_buf,"$PPOTD,%u,%u,%c*%u",_adr,dir,'A',checksum_send_byte);
     Drive_En = 1;              
     UART.printf("%s\r\n",tx_buf);
     wait_ms(2);
     Drive_En = 0;
 }
 
-void send_HB(uint8_t _adr)                   //master will send the haertbeat to all presentees at periodic intervals
+void send_HB(uint8_t _adr)                   //master will send the heartbeat to all presentees at periodic intervals
 {      
-    sprintf(tx_buf,"$PPOTH,%u,%c", _adr, valid);
-    //checksum=get_checksum(tx_buf);                
-    //sprintf(tx_buf,"%u",checksum);
+    sprintf(tx_buf,"$PPOTH,%u,%c*", _adr,'A');
+    checksum_send_byte = get_checksum(tx_buf);                
+    sprintf(tx_buf,"$PPOTH,%u,%c*%u",_adr,'A',checksum_send_byte);
     Drive_En = 1;              
     UART.printf("%s\r\n",tx_buf);
     wait_ms(2);
     Drive_En = 0;
 }
 
-void send_BROADCAST()             //addr 1-8 of leds,error=1 or 0(no error)
+void send_BROADCAST()                        //addr 1-8 of leds,error=1 or 0(no error)
 {
-    sprintf(tx_buf,"$PPOTB,%u,%u,%c",err_ALL,err_Status,valid);
-    //checksum=get_checksum(tx_buf);                
-    //sprintf(tx_buf,"%u",checksum);
+    sprintf(tx_buf,"$PPOTB,%u,%u,%c*",err_ALL,err_Status,'A');
+    checksum_send_byte = get_checksum(tx_buf);                
+    sprintf(tx_buf,"$PPOTB,%u,%u,%c*%u",err_ALL,err_Status,'A',checksum_send_byte);
     Drive_En = 1;              
     UART.printf("%s\r\n",tx_buf);
     wait_ms(2);
@@ -1189,9 +1264,9 @@
  /** Function will send ac-M, ac-S, rpm-data(04digits), cmd_state)**/
 void send_ACH()                 
 {
-    sprintf(tx_buf,"$PPOTS,%u,%u,%u,%u,%u,%u,%u,,%u,%u,%c", ach_M, ach_S, rpm_data[0],rpm_data[1],rpm_data[2],rpm_data[3],dir,current_status,current_status_dir,valid);
-    //checksum=get_checksum(tx_buf);                
-    //sprintf(tx_buf,"%u",checksum);
+    sprintf(tx_buf,"$PPOTS,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%c*", ach_M, ach_S, rpm_data[0],rpm_data[1],rpm_data[2],rpm_data[3],last_entry[0],last_entry[1],last_entry[2],last_entry[3],dir,current_status,current_status_dir,'A');
+    checksum_send_byte = get_checksum(tx_buf);                
+    sprintf(tx_buf,"$PPOTS,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%c,*%u", ach_M, ach_S, rpm_data[0],rpm_data[1],rpm_data[2],rpm_data[3],last_entry[0],last_entry[1],last_entry[2],last_entry[3],dir,current_status,current_status_dir,'A',checksum_send_byte);
     Drive_En = 1;              
     UART.printf("%s\r\n",tx_buf);
     wait_ms(2);
@@ -1201,9 +1276,9 @@
 void ask_TIME()
 {
     Hrs_1 = Hrs_2 = Mins_1 = Mins_2 = 0;
-    sprintf(tx_buf,"$PPOTQ,%u,%u,%u,%u,%c", Hrs_1,Hrs_2, Mins_1, Mins_2,valid);    //querry to CPU for time
-    //checksum=get_checksum(tx_buf);                
-    //sprintf(tx_buf,"%u",checksum);
+    sprintf(tx_buf,"$PPOTQ,%u,%u,%u,%u,%c*", Hrs_1,Hrs_2, Mins_1, Mins_2,'A');    //querry to CPU for time
+    checksum_send_byte = get_checksum(tx_buf);                
+    sprintf(tx_buf,"$PPOTQ,%u,%u,%u,%u,%c*%u", Hrs_1,Hrs_2, Mins_1, Mins_2,'A',checksum_send_byte);
     Drive_En = 1;              
     UART.printf("%s\r\n",tx_buf);
     wait_ms(2);
@@ -1215,7 +1290,7 @@
  **************************************************************************************/
 void rcvd_HB()      //all devices check for HB  along with req response for all presentees
 {
-    if(rcvd_ADDR == addr_ID)             //==addr_ID  self address received
+    if(rcvd_ADDR == addr_ID)             //addr_ID  self address received
     {   
         HB_rcvd = true;       
         if(addr_ID > pot_Slave_ER)
@@ -1224,10 +1299,10 @@
         }
         else                             //in case of active slave
         {
-            if(ENTER_ACK_key)               //RPM ACK key is detected at active slave
+            if(ENTER_ACK_key)               //RPM ACK key is detected at active slave only
             {
-                send_ack_CMD(1);           
-                RPM_cmd_ack_send = true;
+                send_ack_CMD(1);  
+                RPM_cmd_ack = true;  
                 ENTER_ACK_key = false;
             }
             else if(DIR_key)                //dir ack key detected at active slave
@@ -1256,35 +1331,59 @@
 }
 
 void resp_rcvd_HB()                  //master and active/passive slaves check HB response along with req/ack commands
-{   
+{ 
+    static uint8_t checksum_flt[8] = {0,0,0,0,0,0,0,0}; 
+    static bool checksum_err[8] = {false,false,false,false,false,false,false,false};
     if(addr_ID == pot_Master)                                       //only master will be able to monitor status of all eots connected
     { 
-        if(send_ADDR == rcvd_ADDR)
-            HB_ack_rcvd = true;
+        if(send_ADDR == rcvd_ADDR)              //valid broadcast not received  
+        {
+            if(valid_sentence[rcvd_ADDR] == 'A')
+            {
+                HB_ack_rcvd = true;
+                checksum_err[rcvd_ADDR] = false;
+                checksum_flt[rcvd_ADDR] = 0;
+            } 
+            else if((valid_sentence[rcvd_ADDR] == 'V')&&(++checksum_flt[rcvd_ADDR]<=3))
+            {
+                HB_ack_rcvd = true;
+                BROADCAST_send = true;    //again broadcast
+                switch_CH = true;         //send active channels again
+            }
+            else if((valid_sentence[rcvd_ADDR] == 'V')&&(checksum_flt[rcvd_ADDR]>3)&&(!checksum_err[rcvd_ADDR]))
+            {
+               HB_ack_rcvd = false;
+               checksum_err[rcvd_ADDR] = true;
+            } 
+            else
+                __nop();
+            
+        }
         else
-            HB_ack_rcvd = false;       
+            HB_ack_rcvd = false;     
     }
     else
         __nop();
 }
+
 void rcvd_ACH()
 {
     led_ach[ach_M-1] = ON;
     if(current_status == 2)
     {
-        led_dir[dir-1] = _FLASH;
+        led_cmd_ack = _FLASH;
         max7219.enable_device(2);
         display_flash = true; 
     }
     else if(current_status == 1)
     {
-        led_dir[dir-1] = ON;
+        led_cmd_ack = ON;
         max7219.enable_device(2);
         display_flash = false;
     }
     else
     {
-        led_dir[dir-1] = OFF;
+        led_cmd_ack = OFF;
         max7219.enable_device(2);
     }
 
@@ -1301,10 +1400,15 @@
         led_dir[dir-1] = OFF;
     }
     
-    for(uint8_t i = 3; i <= 7 ; i++)
-        {
-            max7219.write_digit(1,i+1,rpm_data[i]);     //device 1 digits 1-4                  //data 0 means left most digit will be blank bcoz no decode mode is used
-        }
+    for(uint8_t i = 1; i <= 4 ; i++)    //current cmd information
+    {
+        max7219.write_digit(2,i,rpm_data[i-1]);     //device 2 digits 1-4                  //data 0 means left most digit will be blank bcoz no decode mode is used
+    }
+    
+    for(uint8_t i = 5; i <=8; i++)     //last command executed
+    {
+        max7219.write_digit(1,i,last_entry[i-5]);     //last cmd 0000
+    }
         
     if(ach_S != 9)
     {
@@ -1356,9 +1460,9 @@
     display_flash = true;                     //display start flashing                                                         //buzzer on                                                     
     
     if(ach_S == addr_ID)
-    {        
-        int_B.rise(&read_KEY_B);   //only PORTB needs to be enabled
-        wait_us(10);
+    {   
+        int_B.rise(&read_KEY_B);
+        wait_us(10);     
         mcp23s17_1.gpintenb(0xff);    //ff
         wait_us(10);                                              //portc is always enbaled in all cases and PORTA is enabled only for active master
     }
@@ -1399,14 +1503,9 @@
         }
         else
             __nop();
-    }
-    for(uint8_t i = 3; i <= 7 ; i++)
-    {
-        max7219.write_digit(2,i+1,rpm_data[i]);     //device 2 digits 4-8                  //data 0 means left most digit will be blank bcoz no decode mode is used
-    }  
-    wait_us(10);
-    
+    } 
 }
+
 void rcvd_TIME()
 {
     uint8_t Hrs,Mins;
@@ -1426,11 +1525,21 @@
     time_RCVD = true;
 }
 
+void at_timeout()
+{
+    timeout.detach();
+    data_fail = true;
+}
+
 void read_SERIAL()
-{
+{  
     char rcvd_char;
+    char rcvd_valid;
     int cmd_t;
-    while(UART.readable() && (num_bytes < RX_BUFFER_SIZE))
+    uint8_t checksum_calculated;
+    timeout.attach(&at_timeout,0.100);    //100ms timeout
+    data_fail = false;
+    while(UART.readable() && (num_bytes < RX_BUFFER_SIZE)&&(!data_fail))
     {
         rcvd_char = UART.getc();
         if(rcvd_char == '$')             //first character
@@ -1440,24 +1549,54 @@
             
         rx_buf[num_bytes] = rcvd_char;
         num_bytes++;
-        if(rcvd_char == '\n')             //last character   
+        if(rcvd_char == '\n')             //last character received
         {
+            timeout.detach();
             strtok(rx_buf,",");
             if(strcmp(rx_buf,"$PPOTH") == 0)                      //* present submaster,Slaves or lsitners receive HB *// 
             {
-                sscanf(strtok (NULL,","), "%u", &rcvd_ADDR);        //address of connected device
-                rcvd_HB();                                   //set flag when Heartbeat received
+                sscanf(strtok (NULL,","),"%u", &rcvd_ADDR);        //address of connected device
+                sscanf(strtok (NULL,"*"),"%c", &rcvd_valid);        //sentence validity char
+                sscanf(strtok (NULL,","),"%u", &checksum_rcvd_byte);
+                sprintf(rx_buf,"$PPOTH,%u,%c*",rcvd_ADDR,rcvd_valid);
+                checksum_calculated = get_checksum(rx_buf);
+                if(checksum_calculated == checksum_rcvd_byte)
+                {
+                    rcvd_HB();               //valid sentence received   
+                }                   
+                else
+                    __nop();              //valid sentence receivedrcvd_HB();                                   //set flag when Heartbeat received
             }
             else if(strcmp(rx_buf,"$PPOTA") == 0)                  //* Master,submaster and Slaves receive  heartbeat resp *//
             {
-                sscanf(strtok (NULL,","), "%u", &rcvd_ADDR);
-                resp_rcvd_HB();
+                sscanf(strtok (NULL,","),"%u", &rcvd_ADDR);
+                sscanf(strtok (NULL,"*"),"%c", &rcvd_valid);
+                sscanf(strtok (NULL,","),"%u", &checksum_rcvd_byte);
+                sprintf(rx_buf,"$PPOTA,%u,%c*",rcvd_ADDR,rcvd_valid);
+                checksum_calculated = get_checksum(rx_buf);
+                if(checksum_calculated == checksum_rcvd_byte)
+                {
+                    valid_sentence[rcvd_ADDR] = rcvd_valid;
+                    resp_rcvd_HB();               //valid sentence received  
+                }                    
+                else
+                    __nop();
             }
             else if(strcmp(rx_buf,"$PPOTB") == 0)                 //* submaster,Slaves or listener receive broadcast *//
             {
                 sscanf(strtok (NULL,","), "%u", &err_ALL);       //device in error with addr_ID =  err_ID
-                sscanf(strtok (NULL,","), "%u", &err_Status);
-                rcvd_BROADCAST();
+                sscanf(strtok (NULL,","), "%u",&err_Status);
+                sscanf(strtok (NULL,"*"),"%c", &rcvd_valid);        //sentence validity char
+                sscanf(strtok (NULL,","),"%u", &checksum_rcvd_byte);
+                sprintf(rx_buf,"$PPOTB,%u,%u,%c*",err_ALL,err_Status,rcvd_valid);
+                checksum_calculated = get_checksum(rx_buf);
+                if(checksum_calculated == checksum_rcvd_byte)
+                {               //valid sentence received  
+                    valid = 'A';
+                    rcvd_BROADCAST();   
+                }                 
+                else
+                    valid = 'V';              //not valid 
             }
             else if(strcmp(rx_buf,"$PPOTC") == 0)                 //* submaster,Slaves or listener receive CMD *//
             {
@@ -1465,38 +1604,68 @@
                 sscanf(strtok (NULL,","), "%u", &rpm_data[0]);     //rpm data digit 1 and soon
                 sscanf(strtok (NULL,","), "%u", &rpm_data[1]);       
                 sscanf(strtok (NULL,","), "%u", &rpm_data[2]);
-                sscanf(strtok (NULL,","), "%u", &rpm_data[3]);
-                RPM_cmd = true;                                    // in all devices who receive RPM command
-                rcvd_rpm_CMD();
+                sscanf(strtok (NULL,","), "%u",&rpm_data[3]);
+                sscanf(strtok (NULL,"*"),"%c", &rcvd_valid);        //sentence validity char
+                sscanf(strtok (NULL,","),"%u", &checksum_rcvd_byte);
+                sprintf(rx_buf,"$PPOTC,%u,%u,%u,%u,%u,%c*",rcvd_ADDR,rpm_data[0],rpm_data[1],rpm_data[2],rpm_data[3],rcvd_valid);
+                checksum_calculated = get_checksum(rx_buf);
+                if(checksum_calculated == checksum_rcvd_byte)
+                   {
+                    valid = 'A';             
+                    RPM_cmd = true;                                    // in all devices who receive RPM command
+                    rcvd_rpm_CMD();
+                   }
+                else
+                    valid = 'V';
             }
             else if(strcmp(rx_buf,"$PPOTD") == 0)                      //* present submaster,Slaves or lsitners receive HB *// 
             {
                 sscanf(strtok (NULL,","), "%u", &rcvd_ADDR);        //address of connected device
-                sscanf(strtok (NULL,","), "%u", &dir);        // 1 for ahead and 2 for astern
-                DIR_cmd = true;
-                rcvd_dir_CMD();                                   //set flag when Heartbeat received
+                sscanf(strtok (NULL,","), "%u",&dir);        // 1 for ahead and 2 for astern
+                sscanf(strtok (NULL,"*"),"%c", &rcvd_valid);        //sentence validity char
+                sscanf(strtok (NULL,","),"%u", &checksum_rcvd_byte);
+                sprintf(rx_buf,"$PPOTD,%u,%u,%c*",rcvd_ADDR,dir,rcvd_valid);
+                checksum_calculated = get_checksum(rx_buf);
+                if(checksum_calculated == checksum_rcvd_byte)
+                {
+                    valid = 'A';
+                    DIR_cmd = true;
+                    rcvd_dir_CMD(); 
+                }
+                else
+                    valid = 'V';                                   //set flag when Heartbeat received
             }
             else if(strcmp(rx_buf,"$PPOTX") == 0)                //* Master,submaster,Slave or listners receive CMD acknowledge *//
             {
                 sscanf(strtok (NULL,","), "%u", &rcvd_ADDR);       //address extracted
-                sscanf(strtok (NULL,","), "%u", &cmd_t);
-                switch(cmd_t)
-                {
-                    case 1:
-                        RPM_cmd_ack = true;
-                    break;
+                sscanf(strtok (NULL,","), "%u",&cmd_t);
+                sscanf(strtok (NULL,"*"),"%c", &rcvd_valid);        //sentence validity char
+                sscanf(strtok (NULL,","),"%u", &checksum_rcvd_byte);
+                sprintf(rx_buf,"$PPOTX,%u,%u,%c*",rcvd_ADDR,cmd_t,rcvd_valid);
+                checksum_calculated = get_checksum(rx_buf);
+                if(checksum_calculated == checksum_rcvd_byte)
+                    {
+                        valid = 'A';
+                        switch(cmd_t)
+                        {
+                        case 1:
+                            RPM_cmd_ack = true;
+                        break;
                     
-                    case 2:
-                        DIR_cmd_ack = true;
-                        led_dir[last_dir-1] = OFF;
-                        last_dir = dir;
-                        led_dir[dir-1] = ON;
-                    break;
+                        case 2:
+                            DIR_cmd_ack = true;
+                            led_dir[last_dir-1] = OFF;
+                            last_dir = dir;
+                            led_dir[dir-1] = ON;
+                        break;
                     
-                    default:
-                        __nop();
-                    break;       
-                }        
+                        default:
+                            __nop();
+                        break;       
+                        }  
+                    }                      
+                else
+                     valid = 'V';               // not valid sentence received;       
             }
             else if(strcmp(rx_buf,"$PPOTS") == 0)                 //*active channel status recieved *//
             {
@@ -1506,77 +1675,124 @@
                 sscanf(strtok (NULL,","), "%u", &rpm_data[1]);
                 sscanf(strtok (NULL,","), "%u", &rpm_data[2]);
                 sscanf(strtok (NULL,","), "%u", &rpm_data[3]);
+                sscanf(strtok (NULL,","), "%u", &last_entry[0]);
+                sscanf(strtok (NULL,","), "%u", &last_entry[1]);
+                sscanf(strtok (NULL,","), "%u", &last_entry[2]);
+                sscanf(strtok (NULL,","), "%u", &last_entry[3]);
                 sscanf(strtok (NULL,","), "%u", &dir);
                 sscanf(strtok (NULL,","), "%u", &current_status);
-                sscanf(strtok (NULL,","), "%u", &current_status_dir);
-                rcvd_ACH(); 
+                sscanf(strtok (NULL,","),"%u", &current_status_dir);
+                sscanf(strtok (NULL,"*"),"%c", &rcvd_valid);        //sentence validity char
+                sscanf(strtok (NULL,","),"%u", &checksum_rcvd_byte);
+                sprintf(rx_buf,"$PPOTS,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%c*",ach_M,ach_S,rpm_data[0],rpm_data[1],rpm_data[2],rpm_data[3],last_entry[0],last_entry[1],last_entry[2],last_entry[3],dir,current_status,current_status_dir,rcvd_valid);
+                checksum_calculated = get_checksum(rx_buf);
+                if(checksum_calculated == checksum_rcvd_byte)
+                    {
+                        valid = 'A';              //valid sentence received
+                        rcvd_ACH(); 
+                    }                      
+                else
+                    valid = 'V';  
             }
             else if(strcmp(rx_buf,"$PPOTR") == 0)               //* control transfer request arrived*//
             {
-                sscanf(strtok (NULL,","), "%u", &rcvd_ADDR);
-                sscanf(strtok (NULL,","), "%u", &req);    //e.g $R req or $K ack 
+                sscanf(strtok (NULL,","),"%u", &rcvd_ADDR);
+                sscanf(strtok (NULL,","),"%u", &req);    //e.g $R req or $K ack 
+                sscanf(strtok (NULL,"*"),"%c", &rcvd_valid);        //sentence validity char
+                sscanf(strtok (NULL,","),"%u", &checksum_rcvd_byte);
                 if(addr_ID <= pot_Slave_ER)
                 {
-                    REQ_rcvd = true;
-                    req_ADDR = rcvd_ADDR;
-                    if(((rcvd_ADDR == pot_Master) && (addr_ID == pot_Submaster)) || ((rcvd_ADDR == pot_Submaster) && (addr_ID == pot_Master)))
-                    {
-                        int_B.rise(&read_KEY_B);        //to enable ACK key interrupt
-                        wait_us(10);
-                        mcp23s17_1.gpintenb(0xff);      // portb of mcp1 ACK key enabled
-                        wait_us(10);
-                        led_ctrl[ACK_-1] = _FLASH;        //ack led blink
-                    }
-                    else 
-                        __nop();
-                        
-                    if(((rcvd_ADDR == pot_Slave_MCR) && (addr_ID == pot_Slave_ER)) || ((rcvd_ADDR == pot_Slave_ER) && (addr_ID == pot_Slave_MCR)))
-                    {
-                        int_B.rise(&read_KEY_B);        //to enable ACK key interrupt
-                        wait_us(10);
-                        mcp23s17_1.gpintenb(0xff);      //portb of mcp1 ACK key enabled
-                        wait_us(10);
-                        led_ctrl[ACK_-1] = _FLASH;       //ack led blink
-                    }
+                    sprintf(rx_buf,"$PPOTR,%u,%u,%c*",rcvd_ADDR,req,rcvd_valid);
+                    checksum_calculated = get_checksum(rx_buf);
+                    if(checksum_calculated == checksum_rcvd_byte)
+                        { 
+                            valid = 'A';                  
+                            REQ_rcvd = true;
+                            req_ADDR = rcvd_ADDR;
+                            if(((rcvd_ADDR == pot_Master) && (addr_ID == pot_Submaster)) || ((rcvd_ADDR == pot_Submaster) && (addr_ID == pot_Master)))
+                            {
+                                int_B.rise(&read_KEY_B);        //to enable ACK key interrupt
+                                wait_us(10);
+                                mcp23s17_1.gpintenb(0xff);      // portb of mcp1 ACK key enabled
+                                wait_us(10);
+                                led_ctrl[ACK_-1] = _FLASH;        //ack led blink
+                            }
+                            else 
+                                __nop();
+                                
+                            if(((rcvd_ADDR == pot_Slave_MCR) && (addr_ID == pot_Slave_ER)) || ((rcvd_ADDR == pot_Slave_ER) && (addr_ID == pot_Slave_MCR)))
+                            {
+                                int_B.rise(&read_KEY_B);        //to enable ACK key interrupt
+                                wait_us(10);
+                                mcp23s17_1.gpintenb(0xff);      //portb of mcp1 ACK key enabled
+                                wait_us(10);
+                                led_ctrl[ACK_-1] = _FLASH;       //ack led blink
+                            }
+                            else
+                                __nop();
+                    
+                            R_A_Ticker.attach(&R_A_Statemachine,0.5);
+                        }
                     else
+                        valid = 'V'; 
+                }
+                else
                     __nop();
-                    
-                    R_A_Ticker.attach(&R_A_Statemachine,0.5);
-                }
             }
             else if(strcmp(rx_buf,"$PPOTK") == 0)               //* Master,submaster,Slave or listners REQ acknowledge *//
             {
                 sscanf(strtok (NULL,","), "%u", &rcvd_ADDR);
-                sscanf(strtok (NULL,","), "%u", &ack);    //e.g $R req or $K ack
+                sscanf(strtok (NULL,","),"%u", &ack);    //e.g $R req or $K ack
+                sscanf(strtok (NULL,"*"),"%c", &rcvd_valid); 
+                sscanf(strtok (NULL,","),"%u", &checksum_rcvd_byte);
+                
                 if(addr_ID <= pot_Slave_ER)
                 {
-                    ack_ADDR = rcvd_ADDR;
-                    ACK_rcvd = true;
-                    //ACH_SW_over = true;
-                
-                if(((rcvd_ADDR == pot_Master) && (addr_ID == pot_Submaster)) || ((rcvd_ADDR == pot_Submaster) && (addr_ID == pot_Master)))
-                    {
-                         led_ctrl[ACK_-1] = OFF;
-                         //R_A_Ticker.detach();
-                    }
-                else if(((rcvd_ADDR == pot_Slave_ER) && (addr_ID == pot_Slave_MCR)) || ((rcvd_ADDR == pot_Slave_MCR) && (addr_ID == pot_Slave_ER)))
-                    {
-                        led_ctrl[ACK_-1] = OFF;
-                        //R_A_Ticker.detach();
-                    }
-                else
-                    __nop();
-                }
+                    sprintf(rx_buf,"$PPOTK,%u,%u,%c*",rcvd_ADDR,ack,rcvd_valid);
+                    checksum_calculated = get_checksum(rx_buf);
+                    if(checksum_calculated == checksum_rcvd_byte)
+                        { 
+                            valid = 'A';
+                            ack_ADDR = rcvd_ADDR;
+                            ACK_rcvd = true;
+                            //ACH_SW_over = true;
+                        
+                            if(((rcvd_ADDR == pot_Master) && (addr_ID == pot_Submaster)) || ((rcvd_ADDR == pot_Submaster) && (addr_ID == pot_Master)))
+                            {
+                                 led_ctrl[ACK_-1] = OFF;
+                                 //R_A_Ticker.detach();
+                            }
+                            else if(((rcvd_ADDR == pot_Slave_ER) && (addr_ID == pot_Slave_MCR)) || ((rcvd_ADDR == pot_Slave_MCR) && (addr_ID == pot_Slave_ER)))
+                            {
+                                led_ctrl[ACK_-1] = OFF;
+                                //R_A_Ticker.detach();
+                            }
+                            else
+                                __nop();
+                        }
+                    else
+                        valid = 'V';
+                }                    
                 else
                     __nop();
             }
-            else if(strcmp(rx_buf,"$PEOTT") == 0)                 //* submaster,Slaves or listener receive CMD *//
+            else if(strcmp(rx_buf,"$PPOTT") == 0)                 //* submaster,Slaves or listener receive CMD *//
             {
                 sscanf(strtok (NULL,","), "%u", &Hrs_1);       //cmd extracted
                 sscanf(strtok (NULL,","), "%u", &Hrs_2); 
                 sscanf(strtok (NULL,","), "%u", &Mins_1);
-                sscanf(strtok (NULL,","), "%u", &Mins_2);
-                rcvd_TIME();
+                sscanf(strtok (NULL,","),"%u", &Mins_2);
+                sscanf(strtok (NULL,"*"),"%c", &rcvd_valid);        //sentence validity char
+                sscanf(strtok (NULL,","),"%u", &checksum_rcvd_byte);
+                sprintf(rx_buf,"$PPOTT,%u,%u,%u,%u,%c*",Hrs_1,Hrs_2,Mins_1,Mins_2,rcvd_valid);
+                checksum_calculated = get_checksum(rx_buf);
+                if(checksum_calculated == checksum_rcvd_byte)
+                {
+                    valid = 'A';
+                    rcvd_TIME();
+                }                     
+                else
+                    valid = 'V';
             }
             else
                 __nop();
@@ -1605,7 +1821,7 @@
         if(ach_M == pot_Master)
         {   
             device_addr++;
-            if(device_addr >= no_pot_connected)
+            if(device_addr == no_pot_connected)    //max no-pot-conneted = 7
                 device_addr = 0;
         }
         else
@@ -1624,7 +1840,9 @@
             }
         }
                         */
+        
         send_ADDR = POT[device_addr].slave_ID;
+        
         if(RPM_cmd)
         {
             send_RPM(send_ADDR);
@@ -1657,7 +1875,7 @@
         else
         {    
             send_HB(send_ADDR);   //hb is to be going on
-            HB_Ticker.attach(&HB_State_Machine,0.010);                          //HB_state_machine timer started
+            HB_Ticker.attach(&HB_State_Machine,0.015);                          //HB_state_machine timer started
         }
     }
     else if(++norm_count >= 5)
@@ -1843,6 +2061,11 @@
         LED_CTRL[i] = ON;
         wait_ms(1);
     }
+    for(uint8_t i=0;i<=1;i++)             //ctrl led intialisation
+    {
+        LED_DIR[i] = ON;
+        wait_ms(1);
+    }
     for(uint8_t i=0; i<=7;i++)            //ach led initialisation
     {
         LED_ACH[i] = ON ; 
@@ -1851,6 +2074,7 @@
     
     wait(1);
     
+    LED_CMD_ACK = OFF;
     led_cmd_ack = OFF;
     wait_ms(1);
     
@@ -1860,6 +2084,12 @@
         led_ctrl[i] = OFF;
         wait_ms(1);
     }
+    for(uint8_t i=0;i<=1;i++)             //ctrl led intialisation
+    {
+        LED_DIR[i] = OFF;
+        led_dir[i] = OFF;
+        wait_ms(1);
+    }
     for(uint8_t i=0; i<=7;i++)         //ach led turned off
     {
         LED_ACH[i] = OFF; 
@@ -1870,9 +2100,9 @@
 
 void pwm_init()
 {
-    mypwm.period_ms(50);           //initialy 20ms
+    mypwm.period_ms(10);           //initialy 20ms
     wait_us(1);
-    mypwm.write(.90);      //90%duty cycle
+    mypwm.write(.10);      //10%duty cycle more bright with less duty cycle
     wait_us(1);
 }
 
@@ -1986,14 +2216,14 @@
 {
     max7219.set_num_devices(2);                 //total 02 no. of devices
     DEVICE1.device_number = 0x01;
-    DEVICE1.decode_mode = 0x00;                 //bcd decode mode
+    DEVICE1.decode_mode = 0xff;                 //bcd decode mode
     DEVICE1.intensity = 0x01;                   //Max7219::MAX7219_INTENSITY_8,
-    DEVICE1.scan_limit = 0x08;                  // 1-4 digits current CMD
+    DEVICE1.scan_limit = 0x07;                  // 1-4 digits RTC,5-8 digits last cmd RPM
     wait_ms(1);
     DEVICE2.device_number = 0x02;               //
     DEVICE2.decode_mode = 0xff;                 //bcd decode mode
     DEVICE2.intensity = 0x01;                   //Max7219::MAX7219_INTENSITY_8,     //intensity moderate
-    DEVICE2.scan_limit = 0x04;                  //1-4 digits RTC,5-8 digits last cmd RPM
+    DEVICE2.scan_limit = 0x03;                  //1-4 digits current
     wait_ms(1);
 
     max7219.init_device(DEVICE1);               //DEVICE 1 configured as per above settings
@@ -2008,19 +2238,22 @@
     wait(1);
     max7219.clear_display_test();                //normal operation
     wait_ms(1);
-    for(uint8_t i=0; i<=3;i++)
+    for(uint8_t i=1; i<=4; i++)  
     {
-        max7219.write_digit(1, i+1, 0x00);   //device 1 current cmd, digit 1-4 ,data 0x01
-    }
-    wait_ms(1);
-    for(uint8_t i=3; i<=7;i++)
-    {
-        max7219.write_digit(1, i+1, 0x02);   //device 2 RTC, digit 1-4 ,data 0x01
+        max7219.write_digit(1, i, 0x00);   //device 1 RTC, digit 1-4 ,data 0x01
+        wait_us(100);
     }
     wait_ms(100);
-    for(uint8_t i=0; i<=3;i++)
+    
+    for(uint8_t i=4; i<=8; i++)
     {
-        max7219.write_digit(2, i+1, 0x00);   //device 2 Last CMD, digit 4-8 ,data 0x01
+        max7219.write_digit(1, i, 0x00);   //device 1 last cmd, digit 4-8 ,data 0x01
+        wait_us(100);
+    }
+    wait_ms(100);
+    for(uint8_t i=1; i<=4;i++)
+    {
+        max7219.write_digit(2, i, 0x00);   //device 2 current CMD, digits 1-4 ,data 0x01
     }
     wait_ms(100);
 }
@@ -2063,6 +2296,7 @@
     RPM_cmd = false;              //if true RPM command is raised
     DIR_cmd = false;              //if true DIR command is raised
     ENTER_ACK_key = false;
+    disp_clear = false;
     
     /*intialization of all bool data types indicating flags while serial receive */ 
     RPM_cmd_ack = false;
@@ -2072,6 +2306,7 @@
     REQ_rcvd = false;
     ACK_rcvd = false;
     time_RCVD = false;
+    data_fail = false;
     
     /*intialization of all bool data types indicating flags while serial transmit */ 
     BROADCAST_send = false;
@@ -2083,6 +2318,7 @@
     
     /*intialization of all bool data types indicating active channel changeover*/
     test=false;
+    disp_test = false;
     ACH_SW_over = switch_CH = false;
     
     display_flash = false;
@@ -2091,14 +2327,16 @@
     addr = req = ack = ach_S = ach_M = duty_cycle = sync_count = 0;
     pot_Addr = addr_ID = send_ADDR = rcvd_ADDR = req_ADDR = ack_ADDR = 0;
     test_cnt = err_ID = err_Status = ticker_count = ticker_count_fast  = current_status = current_status_dir= 0;
-    spi_error = set_bit = err_ALL = no_pot_connected = checksum = norm_count = Hrs_1 = Hrs_2 = Mins_1 = Mins_2 = 0;
+    spi_error = set_bit = err_ALL = no_pot_connected = norm_count = Hrs_1 = Hrs_2 = Mins_1 = Mins_2 = 0;
+    checksum_send_byte = checksum_rcvd_byte = 0;
+    
+    dir = last_dir = 0;
     HB_timer =0;
     sync_time = 0;
     num_bytes = 0;
 
     device_addr = -1;
-    
-    valid = 'V';
+    valid = 'A';
     
     POT = new  _POT[NO_MAX_POT];
 }
@@ -2145,7 +2383,8 @@
     wait_ms(1);
     
     if((addr_ID == pot_Master)&&(!pot_Error))                         //if addres of master eot found, by default master
-    {   
+    {
+        wait(10);                             //wait for 10sec,as MCU take time to read time from GPS
         led_ach[ach_M-1] = ON;   
         int_A.rise(&read_KEY_A);              //all key functions enabled for PORTA,B,C        
         int_B.rise(&read_KEY_B);                
@@ -2168,6 +2407,8 @@
     }
     else if(pot_Submaster <= addr_ID <= pot_Listner_ASP)
     {
+        wait(1);
+        led_ach[0] = ON;           //by default master led turns on
         int_A.rise(NULL);          //all key functions/interrupt disabled for PORTA,B       
         int_B.rise(NULL);
         int_C.rise(&read_KEY_C);   //only PORTC needs to be intialized in other all cases,inc,dec,tst,req
@@ -2193,7 +2434,7 @@
 {
     POT_INIT();
     
-    led_refresh.attach(&update_led , 0.020);   
+    led_refresh.attach(&update_led , 0.020);   //refresh rate 20ms
     wait_ms(2);
     
     RTC_ticker.attach(&read_RTC , 59);   //after 60 sec