Lab 6 - Step 3: Add Detection of Hardware Failure

Fork of ADCandticker_sample by William Marsh

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "rtos.h"
00003 #include "wdt.h"
00004 
00005 // Sample program using the Watchdog
00006 // ---------------------------------
00007 //    * Three threads co-operate to flash two LEDs
00008 //    * A simple way to inject a fault, by pressing a button
00009 //    * The watchdog is configured with a 32ms timeout
00010 
00011 #define ON 1
00012 #define OFF 0
00013 DigitalOut led_red(LED_RED, ON);
00014 DigitalIn button(PTD0, PullUp);
00015 DigitalOut led1(PTC12, OFF);
00016 DigitalOut led2(PTC13, OFF);
00017 
00018 AnalogIn ain1(A0) ; // Analog input
00019 AnalogIn ain2(A1) ; // Analog input
00020 Serial pc(USBTX, USBRX); // tx, rx, for debugging
00021 
00022 
00023 // This ticker is used to feed the watch dog
00024 Ticker tick;
00025 
00026 // Threads
00027 Thread threadT(osPriorityNormal, 2000) ; // timer thread
00028 Thread threadLED1(osPriorityNormal, 2000) ; // thread LED1
00029 Thread threadLED2(osPriorityNormal, 2000) ; // thread LED2
00030 
00031 // ------------Fault Injection Button-------------
00032 //  Wait while the button is down
00033 //     Use this to simulate a STUCK fault
00034 // -----------------------------------------------
00035 void waitButton()
00036 {
00037     while (!button) ;
00038 }
00039 
00040 // Message type
00041 typedef struct {
00042     uint16_t analog; /* Analog input value */
00043 } message_t;
00044 
00045 // Mail box
00046 Mail<message_t, 2> mailbox_led1;
00047 
00048 // Function called every 10ms to read ADC
00049 // Low pass filter
00050 // Every 10th value is sent to mailbox
00051 volatile int samples_led1 = 0 ;
00052 volatile uint16_t smoothed_led1 = 0 ;
00053 void readA0()
00054 {
00055     smoothed_led1 = (smoothed_led1 >> 1) + (ain1.read_u16() >> 1) ; // divided by 2 - reduce the signal noise
00056     samples_led1++ ;
00057     if (samples_led1 == 10) {
00058         // send to thread
00059         message_t *mess = mailbox_led1.alloc() ; // may fail but does not block
00060         if (mess) {
00061             mess->analog = smoothed_led1;
00062             mailbox_led1.put(mess); // fails but does not block if full
00063         }
00064         samples_led1 = 0;
00065     }
00066 }
00067 
00068 // Mail box
00069 Mail<message_t, 2> mailbox_led2;
00070 
00071 // Function called every 10ms to read ADC
00072 // Low pass filter
00073 // Every 10th value is sent to mailbox
00074 volatile int samples_led2 = 0 ;
00075 volatile uint16_t smoothed_led2 = 0 ;
00076 void readA1()
00077 {
00078     smoothed_led2 = (smoothed_led2 >> 1) + (ain2.read_u16() >> 1) ; // divided by 2 - reduce the signal noise
00079     samples_led1++ ;
00080     if (samples_led2 == 10) {
00081         // send to thread
00082         message_t *mess = mailbox_led2.alloc() ; // may fail but does not block
00083         if (mess) {
00084             mess->analog = smoothed_led2;
00085             mailbox_led2.put(mess); // fails but does not block if full
00086         }
00087         samples_led2 = 0;
00088     }
00089 }
00090 
00091 
00092 
00093 // Write voltage digits
00094 //   v  Voltage as scale int, e.g. 3.30 is 330
00095 void vToString(int v, char* s)
00096 {
00097     s[3] = '0' + (v % 10) ;
00098     v = v / 10 ;
00099     s[2] = '0' + (v % 10) ;
00100     v = v / 10 ;
00101     s[0] = '0' + (v % 10) ;
00102 }
00103 
00104 // ---Thread for controlling LED 1----------------
00105 //   Turn LED1 on/off in response to signals
00106 // -----------------------------------------------
00107 void led1_thread()    // method to run in thread
00108 {
00109     osEvent evt ;
00110     while (true) {
00111         evt = Thread::signal_wait(0x0); // wait for any signal
00112         if (evt.status == osEventSignal) {
00113             if (evt.value.signals & 0x01) led1 = ON ;
00114             if (evt.value.signals & 0x02) led1 = OFF ;
00115         }
00116         waitButton() ;  // POSSIBLE FAULT HERE
00117         wdt_kickA();
00118     }
00119 }
00120 
00121 // ---Thread for controlling LED 2----------------
00122 //   Turn LED2 on/off in response to signals
00123 // -----------------------------------------------
00124 void led2_thread()    // method to run in thread
00125 {
00126     osEvent evt ;
00127     while (true) {
00128         evt = Thread::signal_wait(0x0); // wait for any signal
00129         if (evt.status == osEventSignal) {
00130             if (evt.value.signals & 0x01) led2 = ON ;
00131             if (evt.value.signals & 0x02) led2 = OFF ;
00132         }
00133         //waitButton() ; // POSSIBLE FAULT HERE
00134         wdt_kickB();
00135     }
00136 }
00137 
00138 // ---Thread for timing --------------------------
00139 //   Send signals to the other threads
00140 // -----------------------------------------------
00141 void timer_thread()    // method to run in thread
00142 {
00143     while (true) {
00144         Thread::wait(250) ;
00145         threadLED1.signal_set(0x1) ;
00146         threadLED2.signal_set(0x1) ;
00147         Thread::wait(250) ;
00148         threadLED1.signal_set(0x2) ;
00149         threadLED2.signal_set(0x2) ;
00150         //waitButton() ; // POSSIBLE FAULT HERE
00151     }
00152 }
00153 
00154 // -----------MAIN-------------------------------
00155 //    Configure watchdog. Start threads.
00156 //    Show start up with RED for 1sec
00157 //    Remember the watchdog is running
00158 //       - 1024ms to set it once
00159 //       - then must feed it every 32ms
00160 // ----------------------------------------------
00161 
00162 int main(void)
00163 {
00164     wdt_1sec() ; // initialise watchdog - 32ms timeout
00165     //tick.attach_us(callback(&wdt_kick_all), 20000); // ticks every 20ms
00166 
00167     // start threads
00168     threadT.start(&timer_thread) ; // start the timer thread
00169     threadLED1.start(&led1_thread) ; // start the LED1 control thread
00170     threadLED2.start(&led2_thread) ; // start the LED2 control thread
00171 
00172     int volts = 0 ;
00173     const int threshold = 100 ; // 1 vol
00174     int counter1 = 0 ;
00175     int counter2 = 0 ;
00176     char vstring[] = "X.XX\r\n" ;
00177 
00178     tick.attach_us(callback(&readA0), 10000); // ticks every 10ms -> 10000 micro second
00179 //    tick.attach_us(callback(&readA1), 10000); // ticks every 10ms -> 10000 micro second
00180 
00181     // show start-up
00182     led_red = OFF;
00183     Thread::wait(1000) ;
00184     led_red = ON;
00185 
00186     while (true) {
00187 
00188         // LED1 process
00189         osEvent evt1 = mailbox_led1.get(); // wait for mail
00190         // every 100 ms this loop operates
00191         if (evt1.status == osEventMail) {
00192             message_t* mess = (message_t*)evt1.value.p ;
00193             volts = (mess->analog * 330) / 0xffff ; // 2 ^ 16
00194             mailbox_led1.free(mess) ;  // free the message space
00195             counter1++;
00196 
00197 
00198 
00199             vToString(volts, vstring) ;
00200             // every 1 s this loop will operate
00201             if (counter1 == 10) {  // limit bandwidth of serial
00202                 pc.printf(vstring) ;
00203                  if(volts >= 150-threshold && volts <= 150+threshold) {
00204                     pc.printf("LED1 - Nomral \r\n\r\n") ;
00205                 } else if (volts == 0) {
00206                     pc.printf("LED1 - open circuit \r\n\r\n") ;
00207                 } else if(volts > 300) {
00208                     pc.printf("LED1 - short circuit \r\n\r\n") ;
00209                 }
00210                 counter1 = 0 ;
00211             }
00212         }
00213         
00214         // LED2 process
00215         if(false) {
00216         osEvent evt2 = mailbox_led2.get(); // wait for mail
00217         // every 100 ms this loop operates
00218         if (evt2.status == osEventMail) {
00219             message_t* mess = (message_t*)evt2.value.p ;
00220             volts = (mess->analog * 330) / 0xffff ; // 2 ^ 16
00221             mailbox_led1.free(mess) ;  // free the message space
00222             vToString(volts, vstring) ;
00223             counter2++;
00224 
00225             // every 1 s this loop will operate
00226             if (counter2 == 10) {  // limit bandwidth of serial
00227                 pc.printf(vstring) ;
00228                  if(volts >= 150-threshold && volts <= 150+threshold) {
00229                     pc.printf("LED2 - Nomral \r\n\r\n") ;
00230                 } else if (volts == 0) {
00231                     pc.printf("LED2 - open circuit \r\n\r\n" ) ;
00232                 } else if(volts > 300) {
00233                     pc.printf("LED2 - short circuit \r\n\r\n") ;
00234                 }
00235                 counter2 = 0 ;
00236             }
00237         }
00238         }
00239     }
00240 }