Added hardware failure detection to watchdog example.

Fork of Watchdog_sample_nocoverage by William Marsh

Files at this revision

API Documentation at this revision

Comitter:
natgovor
Date:
Fri Mar 09 15:45:02 2018 +0000
Parent:
5:9817756efc34
Commit message:
Added hardware failure detection to watchdog example.

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Tue Feb 27 10:29:30 2018 +0000
+++ b/main.cpp	Fri Mar 09 15:45:02 2018 +0000
@@ -15,13 +15,77 @@
 DigitalOut led1(PTC12, OFF);
 DigitalOut led2(PTC13, OFF);
 
+DigitalOut redLed(LED1);
+DigitalOut greenLed(LED2);
+
+// Analog inputs
+AnalogIn ain1(A0);
+AnalogIn ain2(A1);
+
+Serial pc(USBTX, USBRX); // tx, rx, for debugging
+
 // This ticker is used to feed the watch dog
-Ticker tick;
+Ticker tick1;
+Ticker tick2;
 
 // Threads
-Thread threadT ; // timer thread 
-Thread threadLED1 ; // thread LED1
-Thread threadLED2 ; // thread LED2
+Thread threadT(osPriorityNormal, 1000); // timer thread 
+Thread threadLED1(osPriorityNormal, 1000); // thread LED1
+Thread threadLED2(osPriorityNormal, 1000); // thread LED2
+Thread threadCheckLED1(osPriorityNormal, 1000);
+Thread threadCheckLED2(osPriorityNormal, 1000);
+
+// Message type
+typedef struct {
+  uint16_t analog; /* Analog input value */
+  bool buttonPressed;
+} message_t;
+
+// Mail box
+Mail<message_t, 2> mailbox1;
+Mail<message_t, 2> mailbox2;
+
+volatile int samples1 = 0;
+volatile uint16_t smoothed1 = 0; 
+void readA0() {   
+    smoothed1 = (smoothed1 >> 1) + (ain1.read_u16() >> 1);
+    samples1++;
+    if (samples1 == 10) {
+        // send to thread
+        message_t *mess = mailbox1.alloc(); // may fail but does not block
+        if (mess) {
+            mess->analog = smoothed1;
+            mailbox1.put(mess); // fails but does not block if full
+        }
+        samples1 = 0;
+    }       
+}
+
+volatile int samples2 = 0;
+volatile uint16_t smoothed2 = 0; 
+void readA1() {   
+    smoothed2 = (smoothed2 >> 1) + (ain2.read_u16() >> 1);
+    samples2++;
+    if (samples2 == 10) {
+        // send to thread
+        message_t *mess = mailbox2.alloc(); // may fail but does not block
+        if (mess) {
+            mess->analog = smoothed2;
+            mailbox2.put(mess); // fails but does not block if full
+        }
+        samples2 = 0;
+    }       
+}
+
+// Write voltage digits
+//   v  Voltage as scale int, e.g. 3.30 is 330
+void vToString(int v, char* s) {    
+    s[3] = '0' + (v % 10) ;
+    v = v / 10 ;
+    s[2] = '0' + (v % 10) ;
+    v = v / 10 ;
+    s[0] = '0' + (v % 10) ;
+}
 
 // ------------Fault Injection Button-------------
 //  Wait while the button is down
@@ -41,8 +105,9 @@
         if (evt.status == osEventSignal) {
             if (evt.value.signals & 0x01) led1 = ON ;
             if (evt.value.signals & 0x02) led1 = OFF ;
+            wdt_kickA();
         } 
-        waitButton() ;  // POSSIBLE FAULT HERE
+        //waitButton() ;  // POSSIBLE FAULT HERE
     }
 }
 
@@ -56,8 +121,9 @@
         if (evt.status == osEventSignal) {
             if (evt.value.signals & 0x01) led2 = ON ;
             if (evt.value.signals & 0x02) led2 = OFF ;
+            wdt_kickB();
         } 
-        // waitButton() ; // POSSIBLE FAULT HERE
+        //waitButton() ; // POSSIBLE FAULT HERE
     }
 }
 
@@ -72,7 +138,80 @@
         Thread::wait(250) ;
         threadLED1.signal_set(0x2) ;
         threadLED2.signal_set(0x2) ;
-        // waitButton() ; // POSSIBLE FAULT HERE
+        
+        waitButton() ; // POSSIBLE FAULT HERE
+    }
+}
+
+void check_led1() {
+    int volts = 0;
+    int counter = 0;
+    char vstring[] = "X.XX\r\n";
+    
+    while (true) {
+        osEvent evt = mailbox1.get(); // wait for mail 
+        if (evt.status == osEventMail) {
+            message_t* mess = (message_t*)evt.value.p;
+            volts = (mess->analog * 330) / 0xffff;
+            mailbox1.free(mess);  // free the message space
+            
+            if (led1 == 1) {
+                if (volts < 160 && volts > 140) {
+                    // normal
+                } else if (volts == 0) {
+                    // failed open circuit
+                    pc.printf("Failed open circuit 1\n\r");
+                    redLed = 0;
+                } else if (volts > 300) {
+                    // failed short circuit
+                    pc.printf("Failed short circuit 1\n\r");
+                    greenLed = 0;
+                }
+            }
+                       
+            vToString(volts, vstring);
+            counter++;
+            if (counter == 10) {  // limit bandwidth of serial
+                pc.printf(vstring);
+                counter = 0;
+            }
+        }
+    }
+}
+
+void check_led2() {
+    int volts = 0;
+    int counter = 0;
+    char vstring[] = "X.XX\r\n";
+    
+    while (true) {
+        osEvent evt = mailbox2.get(); // wait for mail 
+        if (evt.status == osEventMail) {
+            message_t* mess = (message_t*)evt.value.p;
+            volts = (mess->analog * 330) / 0xffff;
+            mailbox2.free(mess);  // free the message space
+            
+            if (led2 == 1) {
+                if (volts < 160 && volts > 140) {
+                    // normal
+                } else if (volts == 0) {
+                    // failed open circuit
+                    pc.printf("Failed open circuit 2\n\r");
+                    redLed = 0;
+                } else if (volts > 300) {
+                    // failed short circuit
+                    pc.printf("Failed open circuit 2\n\r");
+                    greenLed = 0;
+                }
+            }
+                       
+            vToString(volts, vstring);
+            counter++;
+            if (counter == 10) {  // limit bandwidth of serial
+                pc.printf(vstring);
+                counter = 0;
+            }
+        }
     }
 }
 
@@ -85,16 +224,23 @@
 // ----------------------------------------------
 
 int main(void) {
-    wdt_32ms() ; // initialise watchdog - 32ms timeout
-    tick.attach_us(callback(&wdt_kick_all), 20000); // ticks every 20ms    
+    redLed = 1;
+    greenLed = 1;
+    
+    wdt_1sec(); // initialise watchdog - 1sec timeout  
+    
+    tick1.attach_us(callback(&readA0), 10000); // ticks every 10ms
+    tick2.attach_us(callback(&readA1), 10000); // ticks every 10ms
     
     // start threads
-    threadT.start(&timer_thread) ; // start the timer thread 
-    threadLED1.start(&led1_thread) ; // start the LED1 control thread 
-    threadLED2.start(&led2_thread) ; // start the LED2 control thread 
+    threadT.start(&timer_thread); // start the timer thread 
+    threadLED1.start(&led1_thread); // start the LED1 control thread 
+    threadLED2.start(&led2_thread); // start the LED2 control thread 
+    threadCheckLED1.start(&check_led1); // start the LED2 control thread 
+    threadCheckLED2.start(&check_led2); // start the LED2 control thread 
     
     // show start-up
     led_red = OFF;
-    Thread::wait(1000) ;
+    Thread::wait(1000);
     led_red = ON;
 }
\ No newline at end of file