Lab 6 - Step 3: Add Detection of Hardware Failure
Fork of ADCandticker_sample by
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 }
Generated on Fri Aug 5 2022 02:59:24 by
1.7.2
