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:
diviavad
Date:
Fri Mar 09 22:10:35 2018 +0000
Parent:
5:9817756efc34
Commit message:
lab 2.2.3

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
diff -r 9817756efc34 -r 2180a272ba06 main.cpp
--- a/main.cpp	Tue Feb 27 10:29:30 2018 +0000
+++ b/main.cpp	Fri Mar 09 22:10:35 2018 +0000
@@ -1,70 +1,145 @@
 #include "mbed.h"
 #include "rtos.h"
 #include "wdt.h"
-
+ 
 // Sample program using the Watchdog
 // ---------------------------------
 //    * Three threads co-operate to flash two LEDs
-//    * A simple way to inject a fault, by pressing a button 
+//    * A simple way to inject a fault, by pressing a button
 //    * The watchdog is configured with a 32ms timeout
-
+ 
 #define ON 1
 #define OFF 0
 DigitalOut led_red(LED_RED, ON);
 DigitalIn button(PTD0, PullUp);
 DigitalOut led1(PTC12, OFF);
 DigitalOut led2(PTC13, OFF);
-
+ 
+AnalogIn ain1(A0) ; // Analog input
+AnalogIn ain2(A1) ; // Analog input
+Serial pc(USBTX, USBRX); // tx, rx, for debugging
+ 
+ 
 // This ticker is used to feed the watch dog
 Ticker tick;
-
+ 
 // Threads
-Thread threadT ; // timer thread 
-Thread threadLED1 ; // thread LED1
-Thread threadLED2 ; // thread LED2
-
+Thread threadT(osPriorityNormal, 2000) ; // timer thread
+Thread threadLED1(osPriorityNormal, 2000) ; // thread LED1
+Thread threadLED2(osPriorityNormal, 2000) ; // thread LED2
+ 
 // ------------Fault Injection Button-------------
 //  Wait while the button is down
 //     Use this to simulate a STUCK fault
 // -----------------------------------------------
-void waitButton() {
-    while (!button) ;  
+void waitButton()
+{
+    while (!button) ;
+}
+ 
+// Message type
+typedef struct {
+    uint16_t analog; /* Analog input value */
+} message_t;
+ 
+// Mail box
+Mail<message_t, 2> mailbox_led1;
+ 
+// Function called every 10ms to read ADC
+// Low pass filter
+// Every 10th value is sent to mailbox
+volatile int samples_led1 = 0 ;
+volatile uint16_t smoothed_led1 = 0 ;
+void readA0()
+{
+    smoothed_led1 = (smoothed_led1 >> 1) + (ain1.read_u16() >> 1) ; // divided by 2 - reduce the signal noise
+    samples_led1++ ;
+    if (samples_led1 == 10) {
+        // send to thread
+        message_t *mess = mailbox_led1.alloc() ; // may fail but does not block
+        if (mess) {
+            mess->analog = smoothed_led1;
+            mailbox_led1.put(mess); // fails but does not block if full
+        }
+        samples_led1 = 0;
+    }
 }
-
+ 
+// Mail box
+Mail<message_t, 2> mailbox_led2;
+ 
+// Function called every 10ms to read ADC
+// Low pass filter
+// Every 10th value is sent to mailbox
+volatile int samples_led2 = 0 ;
+volatile uint16_t smoothed_led2 = 0 ;
+void readA1()
+{
+    smoothed_led2 = (smoothed_led2 >> 1) + (ain2.read_u16() >> 1) ; // divided by 2 - reduce the signal noise
+    samples_led1++ ;
+    if (samples_led2 == 10) {
+        // send to thread
+        message_t *mess = mailbox_led2.alloc() ; // may fail but does not block
+        if (mess) {
+            mess->analog = smoothed_led2;
+            mailbox_led2.put(mess); // fails but does not block if full
+        }
+        samples_led2 = 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) ;
+}
+ 
 // ---Thread for controlling LED 1----------------
-//   Turn LED1 on/off in response to signals 
+//   Turn LED1 on/off in response to signals
 // -----------------------------------------------
-void led1_thread() {  // method to run in thread
+void led1_thread()    // method to run in thread
+{
     osEvent evt ;
     while (true) {
         evt = Thread::signal_wait(0x0); // wait for any signal
         if (evt.status == osEventSignal) {
             if (evt.value.signals & 0x01) led1 = ON ;
             if (evt.value.signals & 0x02) led1 = OFF ;
-        } 
+        }
         waitButton() ;  // POSSIBLE FAULT HERE
+        wdt_kickA();
     }
 }
-
+ 
 // ---Thread for controlling LED 2----------------
-//   Turn LED2 on/off in response to signals 
+//   Turn LED2 on/off in response to signals
 // -----------------------------------------------
-void led2_thread() {  // method to run in thread
+void led2_thread()    // method to run in thread
+{
     osEvent evt ;
     while (true) {
         evt = Thread::signal_wait(0x0); // wait for any signal
         if (evt.status == osEventSignal) {
             if (evt.value.signals & 0x01) led2 = ON ;
             if (evt.value.signals & 0x02) led2 = OFF ;
-        } 
-        // waitButton() ; // POSSIBLE FAULT HERE
+        }
+        //waitButton() ; // POSSIBLE FAULT HERE
+        wdt_kickB();
     }
 }
-
+ 
 // ---Thread for timing --------------------------
 //   Send signals to the other threads
 // -----------------------------------------------
-void timer_thread() {  // method to run in thread
+void timer_thread()    // method to run in thread
+{
     while (true) {
         Thread::wait(250) ;
         threadLED1.signal_set(0x1) ;
@@ -72,29 +147,94 @@
         Thread::wait(250) ;
         threadLED1.signal_set(0x2) ;
         threadLED2.signal_set(0x2) ;
-        // waitButton() ; // POSSIBLE FAULT HERE
+        //waitButton() ; // POSSIBLE FAULT HERE
     }
 }
-
+ 
 // -----------MAIN-------------------------------
-//    Configure watchdog. Start threads. 
+//    Configure watchdog. Start threads.
 //    Show start up with RED for 1sec
 //    Remember the watchdog is running
 //       - 1024ms to set it once
-//       - then must feed it every 32ms  
+//       - then must feed it every 32ms
 // ----------------------------------------------
-
-int main(void) {
-    wdt_32ms() ; // initialise watchdog - 32ms timeout
-    tick.attach_us(callback(&wdt_kick_all), 20000); // ticks every 20ms    
-    
+ 
+int main(void)
+{
+    wdt_1sec() ; // initialise watchdog - 32ms timeout
+    //tick.attach_us(callback(&wdt_kick_all), 20000); // ticks every 20ms
+ 
     // 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
+ 
+    int volts = 0 ;
+    const int threshold = 100 ; // 1 vol
+    int counter1 = 0 ;
+    int counter2 = 0 ;
+    char vstring[] = "X.XX\r\n" ;
+ 
+    tick.attach_us(callback(&readA0), 10000); // ticks every 10ms -> 10000 micro second
+//    tick.attach_us(callback(&readA1), 10000); // ticks every 10ms -> 10000 micro second
+ 
     // show start-up
     led_red = OFF;
     Thread::wait(1000) ;
     led_red = ON;
+ 
+    while (true) {
+ 
+        // LED1 process
+        osEvent evt1 = mailbox_led1.get(); // wait for mail
+        // every 100 ms this loop operates
+        if (evt1.status == osEventMail) {
+            message_t* mess = (message_t*)evt1.value.p ;
+            volts = (mess->analog * 330) / 0xffff ; // 2 ^ 16
+            mailbox_led1.free(mess) ;  // free the message space
+            counter1++;
+ 
+ 
+ 
+            vToString(volts, vstring) ;
+            // every 1 s this loop will operate
+            if (counter1 == 10) {  // limit bandwidth of serial
+                pc.printf(vstring) ;
+                 if(volts >= 150-threshold && volts <= 150+threshold) {
+                    pc.printf("LED1 - Nomral \r\n\r\n") ;
+                } else if (volts == 0) {
+                    pc.printf("LED1 - open circuit \r\n\r\n") ;
+                } else if(volts > 300) {
+                    pc.printf("LED1 - short circuit \r\n\r\n") ;
+                }
+                counter1 = 0 ;
+            }
+        }
+        
+        // LED2 process
+        if(false) {
+        osEvent evt2 = mailbox_led2.get(); // wait for mail
+        // every 100 ms this loop operates
+        if (evt2.status == osEventMail) {
+            message_t* mess = (message_t*)evt2.value.p ;
+            volts = (mess->analog * 330) / 0xffff ; // 2 ^ 16
+            mailbox_led1.free(mess) ;  // free the message space
+            vToString(volts, vstring) ;
+            counter2++;
+ 
+            // every 1 s this loop will operate
+            if (counter2 == 10) {  // limit bandwidth of serial
+                pc.printf(vstring) ;
+                 if(volts >= 150-threshold && volts <= 150+threshold) {
+                    pc.printf("LED2 - Nomral \r\n\r\n") ;
+                } else if (volts == 0) {
+                    pc.printf("LED2 - open circuit \r\n\r\n" ) ;
+                } else if(volts > 300) {
+                    pc.printf("LED2 - short circuit \r\n\r\n") ;
+                }
+                counter2 = 0 ;
+            }
+        }
+        }
+    }
 }
\ No newline at end of file