Energy Manager App

Dependencies:   C12832_lcd LM75B mbed-rtos mbed

Fork of rtos_mutex by avnish aggarwal

Committer:
jesstvaldez
Date:
Fri Sep 20 04:12:04 2013 +0000
Revision:
6:3b2a6cb895a9
Parent:
1:0f886ffbe0c1
EM100 V1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jesstvaldez 6:3b2a6cb895a9 1 /* ============================================================================
jesstvaldez 6:3b2a6cb895a9 2 JESS VALDEZ
jesstvaldez 6:3b2a6cb895a9 3 Class 5381
jesstvaldez 6:3b2a6cb895a9 4 Homework : Final Project
jesstvaldez 6:3b2a6cb895a9 5 Instructor: AVNISH AGGARWAL
jesstvaldez 6:3b2a6cb895a9 6
jesstvaldez 6:3b2a6cb895a9 7 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
jesstvaldez 6:3b2a6cb895a9 8 OFF THE GRID ENERGY MANAGER
jesstvaldez 6:3b2a6cb895a9 9 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
jesstvaldez 6:3b2a6cb895a9 10
jesstvaldez 6:3b2a6cb895a9 11 OTHER Resource:
jesstvaldez 6:3b2a6cb895a9 12 p27,p28 i2c pins connected to LM75B thermometer;
jesstvaldez 6:3b2a6cb895a9 13 tick interrupt uses TIMER0
jesstvaldez 6:3b2a6cb895a9 14
jesstvaldez 6:3b2a6cb895a9 15 OUTPUT MAPPING
jesstvaldez 6:3b2a6cb895a9 16 - led1 - blinks = running
jesstvaldez 6:3b2a6cb895a9 17 - led2 - source1 or Solar
jesstvaldez 6:3b2a6cb895a9 18 - led3 - source2 or battery
jesstvaldez 6:3b2a6cb895a9 19 - led4 - generator
jesstvaldez 6:3b2a6cb895a9 20 - p22 general control pin
jesstvaldez 6:3b2a6cb895a9 21 - display - LCD (SPI)
jesstvaldez 6:3b2a6cb895a9 22
jesstvaldez 6:3b2a6cb895a9 23 ADC
jesstvaldez 6:3b2a6cb895a9 24 p18 - S1 (Solar prescaled input)
jesstvaldez 6:3b2a6cb895a9 25 p19 - S2 (raw scale battery)
jesstvaldez 6:3b2a6cb895a9 26
jesstvaldez 6:3b2a6cb895a9 27 JOYSTICK CONTROL
jesstvaldez 6:3b2a6cb895a9 28 UP - Start
jesstvaldez 6:3b2a6cb895a9 29 RIGHT - Force change source
jesstvaldez 6:3b2a6cb895a9 30 DOWN - System down system to OUT - No source selected, used as turn off sequence.
jesstvaldez 6:3b2a6cb895a9 31
jesstvaldez 6:3b2a6cb895a9 32 Added: Power saving mode 9-12-2013
jesstvaldez 6:3b2a6cb895a9 33
jesstvaldez 6:3b2a6cb895a9 34 ==============================================================================*/
jesstvaldez 6:3b2a6cb895a9 35
emilmont 1:0f886ffbe0c1 36 #include "mbed.h"
emilmont 1:0f886ffbe0c1 37 #include "rtos.h"
jesstvaldez 6:3b2a6cb895a9 38 #include "C12832_lcd.h"
jesstvaldez 6:3b2a6cb895a9 39 #include "LM75B.h"
emilmont 1:0f886ffbe0c1 40
jesstvaldez 6:3b2a6cb895a9 41 Serial pc(USBTX, USBRX);
jesstvaldez 6:3b2a6cb895a9 42 AnalogIn a_PD[] = {(p16),(p17),(p18),(p19),(p20)};
jesstvaldez 6:3b2a6cb895a9 43
jesstvaldez 6:3b2a6cb895a9 44 //p19, p20 are pots used for solar + battery simulation - USE_POT=1
jesstvaldez 6:3b2a6cb895a9 45 //p17 true solar sense
jesstvaldez 6:3b2a6cb895a9 46 //p18 true batt sense
jesstvaldez 6:3b2a6cb895a9 47 #define USE_POT 0
jesstvaldez 6:3b2a6cb895a9 48
jesstvaldez 6:3b2a6cb895a9 49 #define OUT 0
jesstvaldez 6:3b2a6cb895a9 50 #define RUNNING 1
jesstvaldez 6:3b2a6cb895a9 51 #define FAULT 2
emilmont 1:0f886ffbe0c1 52
jesstvaldez 6:3b2a6cb895a9 53 //Defined or available sources of energy
jesstvaldez 6:3b2a6cb895a9 54 #define SOLAR 0
jesstvaldez 6:3b2a6cb895a9 55 #define BATTERY 1
jesstvaldez 6:3b2a6cb895a9 56 #define GENERATOR 2
jesstvaldez 6:3b2a6cb895a9 57
jesstvaldez 6:3b2a6cb895a9 58 #define maxSource 3 //adjust to number of sources ablove
jesstvaldez 6:3b2a6cb895a9 59
jesstvaldez 6:3b2a6cb895a9 60 float solar_threshold = 0.10; //10 percent
jesstvaldez 6:3b2a6cb895a9 61 float battery_threshold = 0.20; //20 percent
jesstvaldez 6:3b2a6cb895a9 62
jesstvaldez 6:3b2a6cb895a9 63
jesstvaldez 6:3b2a6cb895a9 64 #include "PowerControl.h"
jesstvaldez 6:3b2a6cb895a9 65 //#include "EthernetPowerControl.h"
jesstvaldez 6:3b2a6cb895a9 66 // Need PowerControl *.h files from this URL
jesstvaldez 6:3b2a6cb895a9 67 // http://mbed.org/users/no2chem/notebook/mbed-power-controlconsumption/
jesstvaldez 6:3b2a6cb895a9 68
jesstvaldez 6:3b2a6cb895a9 69 // Function to power down magic USB interface chip with new firmware
jesstvaldez 6:3b2a6cb895a9 70 #define USR_POWERDOWN (0x104)
jesstvaldez 6:3b2a6cb895a9 71 int semihost_powerdown()
jesstvaldez 6:3b2a6cb895a9 72 {
jesstvaldez 6:3b2a6cb895a9 73 uint32_t arg;
jesstvaldez 6:3b2a6cb895a9 74 return __semihost(USR_POWERDOWN, &arg);
emilmont 1:0f886ffbe0c1 75 }
emilmont 1:0f886ffbe0c1 76
jesstvaldez 6:3b2a6cb895a9 77 char statStr[3][50] = {"OFF","RUNNING","FAULT"};
jesstvaldez 6:3b2a6cb895a9 78 char sourceStr[3][50] = {"SOLAR","BATTERY","GENERATOR"};
jesstvaldez 6:3b2a6cb895a9 79 float sourceLev[20]; /* AD result of measured voltage */
jesstvaldez 6:3b2a6cb895a9 80 C12832_LCD lcd;
jesstvaldez 6:3b2a6cb895a9 81 LM75B tmp(p28,p27);
jesstvaldez 6:3b2a6cb895a9 82 DigitalOut led1(LED1);
jesstvaldez 6:3b2a6cb895a9 83 DigitalOut led2(LED2);
jesstvaldez 6:3b2a6cb895a9 84 DigitalOut led3(LED3);
jesstvaldez 6:3b2a6cb895a9 85 DigitalOut led4(LED4);
jesstvaldez 6:3b2a6cb895a9 86
jesstvaldez 6:3b2a6cb895a9 87 DigitalOut generator_control(p22);
jesstvaldez 6:3b2a6cb895a9 88
jesstvaldez 6:3b2a6cb895a9 89
jesstvaldez 6:3b2a6cb895a9 90 void running_thread(void const *);
jesstvaldez 6:3b2a6cb895a9 91 void get_levels_thread(void const *);
jesstvaldez 6:3b2a6cb895a9 92 void temperature_thread(void const *);
jesstvaldez 6:3b2a6cb895a9 93
jesstvaldez 6:3b2a6cb895a9 94 // GLOBALS
jesstvaldez 6:3b2a6cb895a9 95 int mainSource;
jesstvaldez 6:3b2a6cb895a9 96 int prioritySource;
jesstvaldez 6:3b2a6cb895a9 97 int mainStatus;
jesstvaldez 6:3b2a6cb895a9 98 short int update;
jesstvaldez 6:3b2a6cb895a9 99
jesstvaldez 6:3b2a6cb895a9 100 unsigned int tsec, tsec2, seconds, minutes, hours, days;
jesstvaldez 6:3b2a6cb895a9 101 //unsigned int setTime, setTime_min; //default cooktime
jesstvaldez 6:3b2a6cb895a9 102 double controller_temp;
jesstvaldez 6:3b2a6cb895a9 103 Mutex status_mutex;
jesstvaldez 6:3b2a6cb895a9 104
jesstvaldez 6:3b2a6cb895a9 105 // Watchdog code from
jesstvaldez 6:3b2a6cb895a9 106 // http://mbed.org/forum/mbed/topic/508/
jesstvaldez 6:3b2a6cb895a9 107 class Watchdog
jesstvaldez 6:3b2a6cb895a9 108 {
jesstvaldez 6:3b2a6cb895a9 109 public:
jesstvaldez 6:3b2a6cb895a9 110 // Load timeout value in watchdog timer and enable
jesstvaldez 6:3b2a6cb895a9 111 void kick(float s) {
jesstvaldez 6:3b2a6cb895a9 112 LPC_WDT->WDCLKSEL = 0x1; // Set CLK src to PCLK
jesstvaldez 6:3b2a6cb895a9 113 uint32_t clk = SystemCoreClock / 16; // WD has a fixed /4 prescaler, PCLK default is /4
jesstvaldez 6:3b2a6cb895a9 114 LPC_WDT->WDTC = s * (float)clk;
jesstvaldez 6:3b2a6cb895a9 115 LPC_WDT->WDMOD = 0x3; // Enabled and Reset
jesstvaldez 6:3b2a6cb895a9 116 kick();
jesstvaldez 6:3b2a6cb895a9 117 }
jesstvaldez 6:3b2a6cb895a9 118 // "kick" or "feed" the dog - reset the watchdog timer
jesstvaldez 6:3b2a6cb895a9 119 // by writing this required bit pattern
jesstvaldez 6:3b2a6cb895a9 120 void kick() {
jesstvaldez 6:3b2a6cb895a9 121 LPC_WDT->WDFEED = 0xAA;
jesstvaldez 6:3b2a6cb895a9 122 LPC_WDT->WDFEED = 0x55;
jesstvaldez 6:3b2a6cb895a9 123 }
jesstvaldez 6:3b2a6cb895a9 124 };
jesstvaldez 6:3b2a6cb895a9 125
jesstvaldez 6:3b2a6cb895a9 126 // Setup the watchdog timer
jesstvaldez 6:3b2a6cb895a9 127 Watchdog wdt;
jesstvaldez 6:3b2a6cb895a9 128
jesstvaldez 6:3b2a6cb895a9 129 /*==============================
jesstvaldez 6:3b2a6cb895a9 130 Start INTERRUPT
jesstvaldez 6:3b2a6cb895a9 131 ================================*/
jesstvaldez 6:3b2a6cb895a9 132 class Control_start
jesstvaldez 6:3b2a6cb895a9 133 {
jesstvaldez 6:3b2a6cb895a9 134 public:
jesstvaldez 6:3b2a6cb895a9 135 Control_start(PinName pin) : start_interrupt(pin) {
jesstvaldez 6:3b2a6cb895a9 136 start_interrupt.rise(this, &Control_start::start_system);
jesstvaldez 6:3b2a6cb895a9 137 }
jesstvaldez 6:3b2a6cb895a9 138 void start_system() {
jesstvaldez 6:3b2a6cb895a9 139 status_mutex.lock();
jesstvaldez 6:3b2a6cb895a9 140 mainStatus = RUNNING;
jesstvaldez 6:3b2a6cb895a9 141 mainSource = SOLAR;
jesstvaldez 6:3b2a6cb895a9 142
jesstvaldez 6:3b2a6cb895a9 143 lcd.cls();
jesstvaldez 6:3b2a6cb895a9 144 seconds=0;
jesstvaldez 6:3b2a6cb895a9 145 minutes=0;
jesstvaldez 6:3b2a6cb895a9 146 hours=0;
jesstvaldez 6:3b2a6cb895a9 147 days=0;
jesstvaldez 6:3b2a6cb895a9 148 status_mutex.unlock();
jesstvaldez 6:3b2a6cb895a9 149 }
jesstvaldez 6:3b2a6cb895a9 150 private:
jesstvaldez 6:3b2a6cb895a9 151 InterruptIn start_interrupt;
jesstvaldez 6:3b2a6cb895a9 152 };
jesstvaldez 6:3b2a6cb895a9 153 /*==============================
jesstvaldez 6:3b2a6cb895a9 154 Stop INTERRUPT
jesstvaldez 6:3b2a6cb895a9 155 ================================*/
jesstvaldez 6:3b2a6cb895a9 156 class Control_stop
jesstvaldez 6:3b2a6cb895a9 157 {
jesstvaldez 6:3b2a6cb895a9 158 public:
jesstvaldez 6:3b2a6cb895a9 159 Control_stop(PinName pin) : stop_interrupt(pin) {
jesstvaldez 6:3b2a6cb895a9 160 stop_interrupt.rise(this, &Control_stop::stop_system);
jesstvaldez 6:3b2a6cb895a9 161 }
jesstvaldez 6:3b2a6cb895a9 162 void stop_system() {
jesstvaldez 6:3b2a6cb895a9 163 status_mutex.lock();
jesstvaldez 6:3b2a6cb895a9 164 mainStatus = OUT;
jesstvaldez 6:3b2a6cb895a9 165
jesstvaldez 6:3b2a6cb895a9 166 seconds=0;
jesstvaldez 6:3b2a6cb895a9 167 minutes=0;
jesstvaldez 6:3b2a6cb895a9 168 hours=0;
jesstvaldez 6:3b2a6cb895a9 169 days=0;
jesstvaldez 6:3b2a6cb895a9 170
jesstvaldez 6:3b2a6cb895a9 171 led1 = 0;
jesstvaldez 6:3b2a6cb895a9 172 led2 = 0;
jesstvaldez 6:3b2a6cb895a9 173 led3 = 0;
jesstvaldez 6:3b2a6cb895a9 174 led4 = 0;
jesstvaldez 6:3b2a6cb895a9 175 lcd.cls();
jesstvaldez 6:3b2a6cb895a9 176 status_mutex.unlock();
jesstvaldez 6:3b2a6cb895a9 177 }
jesstvaldez 6:3b2a6cb895a9 178 private:
jesstvaldez 6:3b2a6cb895a9 179 InterruptIn stop_interrupt;
jesstvaldez 6:3b2a6cb895a9 180 };
jesstvaldez 6:3b2a6cb895a9 181
jesstvaldez 6:3b2a6cb895a9 182 /*==============================
jesstvaldez 6:3b2a6cb895a9 183 Force next Source INTERRUPT
jesstvaldez 6:3b2a6cb895a9 184 ================================*/
jesstvaldez 6:3b2a6cb895a9 185 class Control_next
jesstvaldez 6:3b2a6cb895a9 186 {
jesstvaldez 6:3b2a6cb895a9 187 public:
jesstvaldez 6:3b2a6cb895a9 188 Control_next(PinName pin) : next_interrupt(pin) {
jesstvaldez 6:3b2a6cb895a9 189 next_interrupt.rise(this, &Control_next::switch_to_next_source);
jesstvaldez 6:3b2a6cb895a9 190 }
jesstvaldez 6:3b2a6cb895a9 191 void switch_to_next_source() {
jesstvaldez 6:3b2a6cb895a9 192 status_mutex.lock();
jesstvaldez 6:3b2a6cb895a9 193 if (mainStatus == RUNNING) {
jesstvaldez 6:3b2a6cb895a9 194 mainSource++;
jesstvaldez 6:3b2a6cb895a9 195 if (mainSource>(maxSource-1)) mainSource=0;
jesstvaldez 6:3b2a6cb895a9 196
jesstvaldez 6:3b2a6cb895a9 197 }
jesstvaldez 6:3b2a6cb895a9 198 lcd.cls();
jesstvaldez 6:3b2a6cb895a9 199 seconds=0;
jesstvaldez 6:3b2a6cb895a9 200 minutes=0;
jesstvaldez 6:3b2a6cb895a9 201 hours=0;
jesstvaldez 6:3b2a6cb895a9 202 days=0;
jesstvaldez 6:3b2a6cb895a9 203 status_mutex.unlock();
jesstvaldez 6:3b2a6cb895a9 204 }
jesstvaldez 6:3b2a6cb895a9 205 private:
jesstvaldez 6:3b2a6cb895a9 206 InterruptIn next_interrupt;
jesstvaldez 6:3b2a6cb895a9 207 };
jesstvaldez 6:3b2a6cb895a9 208
jesstvaldez 6:3b2a6cb895a9 209 Control_next next(p16);
jesstvaldez 6:3b2a6cb895a9 210 Control_start start(p15);
jesstvaldez 6:3b2a6cb895a9 211 Control_stop stop(p12);
jesstvaldez 6:3b2a6cb895a9 212
jesstvaldez 6:3b2a6cb895a9 213 unsigned short timer_count, clear_count;
jesstvaldez 6:3b2a6cb895a9 214
jesstvaldez 6:3b2a6cb895a9 215 //======================================================
jesstvaldez 6:3b2a6cb895a9 216 // TIMER0 IRQ Handler
jesstvaldez 6:3b2a6cb895a9 217 //=======================================================
jesstvaldez 6:3b2a6cb895a9 218 extern "C" void TIMER0_IRQHandler (void)
jesstvaldez 6:3b2a6cb895a9 219 {
jesstvaldez 6:3b2a6cb895a9 220 if((LPC_TIM0->IR & 0x01) == 0x01) { // if MR0 interrupt, proceed
jesstvaldez 6:3b2a6cb895a9 221 LPC_TIM0->IR |= 1 << 0; // Clear MR0 interrupt flag
jesstvaldez 6:3b2a6cb895a9 222 timer_count++; //increment timer_count
jesstvaldez 6:3b2a6cb895a9 223 clear_count++;
jesstvaldez 6:3b2a6cb895a9 224 }
jesstvaldez 6:3b2a6cb895a9 225 }
jesstvaldez 6:3b2a6cb895a9 226 //======================================================
jesstvaldez 6:3b2a6cb895a9 227 // timer0 initialization
jesstvaldez 6:3b2a6cb895a9 228 //=======================================================
jesstvaldez 6:3b2a6cb895a9 229 void timer0_init(void)
jesstvaldez 6:3b2a6cb895a9 230 {
jesstvaldez 6:3b2a6cb895a9 231 LPC_SC->PCONP |=1<1; //timer0 power on
jesstvaldez 6:3b2a6cb895a9 232 LPC_TIM0->MR0 = 2398000; //100 msec
jesstvaldez 6:3b2a6cb895a9 233 LPC_TIM0->MCR = 3; //interrupt and reset control
jesstvaldez 6:3b2a6cb895a9 234 //3 = Interrupt & reset timer0 on match
jesstvaldez 6:3b2a6cb895a9 235 //1 = Interrupt only, no reset of timer0
jesstvaldez 6:3b2a6cb895a9 236 NVIC_EnableIRQ(TIMER0_IRQn); //enable timer0 interrupt
jesstvaldez 6:3b2a6cb895a9 237 LPC_TIM0->TCR = 1; //enable Timer0
jesstvaldez 6:3b2a6cb895a9 238 // pc.printf("Done timer_init\n\r");
jesstvaldez 6:3b2a6cb895a9 239 }
jesstvaldez 6:3b2a6cb895a9 240
jesstvaldez 6:3b2a6cb895a9 241 /* ==========================================
jesstvaldez 6:3b2a6cb895a9 242 main()
jesstvaldez 6:3b2a6cb895a9 243 - Entry point.
jesstvaldez 6:3b2a6cb895a9 244 ============================================*/
jesstvaldez 6:3b2a6cb895a9 245 int main()
jesstvaldez 6:3b2a6cb895a9 246 {
jesstvaldez 6:3b2a6cb895a9 247 float s_p[2], volts; //calculated levels in percent
jesstvaldez 6:3b2a6cb895a9 248 timer0_init();
jesstvaldez 6:3b2a6cb895a9 249 timer_count = 0;
jesstvaldez 6:3b2a6cb895a9 250 clear_count = 0;
jesstvaldez 6:3b2a6cb895a9 251 generator_control = 0;
jesstvaldez 6:3b2a6cb895a9 252 mainStatus = OUT;
jesstvaldez 6:3b2a6cb895a9 253 mainSource = SOLAR;
jesstvaldez 6:3b2a6cb895a9 254 s_p[0] = 5.0; //give this a value to prevent glitch to generator at startup
jesstvaldez 6:3b2a6cb895a9 255 s_p[1] = 5.0;
jesstvaldez 6:3b2a6cb895a9 256
jesstvaldez 6:3b2a6cb895a9 257 #ifdef NOETHER
jesstvaldez 6:3b2a6cb895a9 258 // Normal mbed power level for this setup is around 690mW
jesstvaldez 6:3b2a6cb895a9 259 // assuming 5V used on Vin pin
jesstvaldez 6:3b2a6cb895a9 260 // If you don't need networking...
jesstvaldez 6:3b2a6cb895a9 261 // Power down Ethernet interface - saves around 175mW
jesstvaldez 6:3b2a6cb895a9 262 // Also need to unplug network cable - just a cable sucks power
jesstvaldez 6:3b2a6cb895a9 263 PHY_PowerDown();
jesstvaldez 6:3b2a6cb895a9 264 #endif
jesstvaldez 6:3b2a6cb895a9 265
jesstvaldez 6:3b2a6cb895a9 266 // On reset, indicate a watchdog reset or a pushbutton reset on LED 4 or 3
jesstvaldez 6:3b2a6cb895a9 267 if ((LPC_WDT->WDMOD >> 2) & 1)
jesstvaldez 6:3b2a6cb895a9 268 led4 = 1;
jesstvaldez 6:3b2a6cb895a9 269 else led3 = 1;
jesstvaldez 6:3b2a6cb895a9 270
jesstvaldez 6:3b2a6cb895a9 271
jesstvaldez 6:3b2a6cb895a9 272 //running thread
jesstvaldez 6:3b2a6cb895a9 273 Thread thread1(running_thread, NULL, osPriorityHigh, DEFAULT_STACK_SIZE, NULL);
jesstvaldez 6:3b2a6cb895a9 274
jesstvaldez 6:3b2a6cb895a9 275 //measurements
jesstvaldez 6:3b2a6cb895a9 276 Thread thread2(get_levels_thread);
jesstvaldez 6:3b2a6cb895a9 277
jesstvaldez 6:3b2a6cb895a9 278 //fault monitor thread (temperature)
jesstvaldez 6:3b2a6cb895a9 279 Thread thread3(temperature_thread, NULL, osPriorityLow, DEFAULT_STACK_SIZE, NULL);
jesstvaldez 6:3b2a6cb895a9 280
jesstvaldez 6:3b2a6cb895a9 281 //main status threads
emilmont 1:0f886ffbe0c1 282 while (true) {
jesstvaldez 6:3b2a6cb895a9 283 lcd.locate(0,1);
jesstvaldez 6:3b2a6cb895a9 284 lcd.printf("%s, %s", statStr[mainStatus], sourceStr[mainSource]);
jesstvaldez 6:3b2a6cb895a9 285
jesstvaldez 6:3b2a6cb895a9 286 volts = (sourceLev[0] / 3.04) * 10.0;
jesstvaldez 6:3b2a6cb895a9 287 volts = volts * 4.0; //scale to voltage divider of solar sense
jesstvaldez 6:3b2a6cb895a9 288 s_p[0] = (volts / 21.0) * 100.0; //percentage of solar current single panel.
jesstvaldez 6:3b2a6cb895a9 289
jesstvaldez 6:3b2a6cb895a9 290 s_p[1] = (sourceLev[1] / 3.04) * 10.0; // voltage, sourceLev[1] has no scaling
jesstvaldez 6:3b2a6cb895a9 291 s_p[1] = (s_p[1] / 3.3) * 100.0; //percent
jesstvaldez 6:3b2a6cb895a9 292 lcd.locate(0,11);
jesstvaldez 6:3b2a6cb895a9 293 lcd.printf("S1= %.2f %%, S2= %.2f %%", s_p[0], s_p[1]);
jesstvaldez 6:3b2a6cb895a9 294
jesstvaldez 6:3b2a6cb895a9 295 lcd.locate(0,21);
jesstvaldez 6:3b2a6cb895a9 296 lcd.printf("Time= %d days, %.2d:%.2d:%.2d", days, hours, minutes, seconds%60);
jesstvaldez 6:3b2a6cb895a9 297
jesstvaldez 6:3b2a6cb895a9 298 //refresh lcd every 100 seconds
jesstvaldez 6:3b2a6cb895a9 299 if (clear_count > 1000) {
jesstvaldez 6:3b2a6cb895a9 300 // Clear LCD Screen
jesstvaldez 6:3b2a6cb895a9 301 lcd.cls();
jesstvaldez 6:3b2a6cb895a9 302 clear_count = 0;
jesstvaldez 6:3b2a6cb895a9 303 }
jesstvaldez 6:3b2a6cb895a9 304 pc.printf("S1= %.2f %%, S2= %.2f %%, %d, %d\n\r", s_p[0], s_p[1], mainStatus, mainSource);
jesstvaldez 6:3b2a6cb895a9 305 Thread::wait(500);
emilmont 1:0f886ffbe0c1 306 }
emilmont 1:0f886ffbe0c1 307 }
emilmont 1:0f886ffbe0c1 308
jesstvaldez 6:3b2a6cb895a9 309 //======================================================
jesstvaldez 6:3b2a6cb895a9 310 // thread that displays the time elapsed while running on a source
jesstvaldez 6:3b2a6cb895a9 311 // also links led1
jesstvaldez 6:3b2a6cb895a9 312 //=======================================================
jesstvaldez 6:3b2a6cb895a9 313 void running_thread(void const *args)
jesstvaldez 6:3b2a6cb895a9 314 {
jesstvaldez 6:3b2a6cb895a9 315
jesstvaldez 6:3b2a6cb895a9 316 while (true) {
jesstvaldez 6:3b2a6cb895a9 317 status_mutex.lock();
jesstvaldez 6:3b2a6cb895a9 318 update=0;
jesstvaldez 6:3b2a6cb895a9 319 if (mainStatus == RUNNING) {
jesstvaldez 6:3b2a6cb895a9 320 led1 = !led1;
jesstvaldez 6:3b2a6cb895a9 321
jesstvaldez 6:3b2a6cb895a9 322 if (timer_count > 9) {
jesstvaldez 6:3b2a6cb895a9 323 /* timer_count is 10 per second (so 0-9)*/
jesstvaldez 6:3b2a6cb895a9 324 seconds++;
jesstvaldez 6:3b2a6cb895a9 325 minutes = seconds/60.0;
jesstvaldez 6:3b2a6cb895a9 326 hours = minutes/60.0;
jesstvaldez 6:3b2a6cb895a9 327 days = hours/24.0;
jesstvaldez 6:3b2a6cb895a9 328 timer_count=0;
jesstvaldez 6:3b2a6cb895a9 329 }
jesstvaldez 6:3b2a6cb895a9 330 //led update OK, but not a reliable way to set a power switch
jesstvaldez 6:3b2a6cb895a9 331 switch(mainSource) {
jesstvaldez 6:3b2a6cb895a9 332 case 0:
jesstvaldez 6:3b2a6cb895a9 333 led2=1;
jesstvaldez 6:3b2a6cb895a9 334 led3=0;
jesstvaldez 6:3b2a6cb895a9 335 led4=0;
jesstvaldez 6:3b2a6cb895a9 336 break;
jesstvaldez 6:3b2a6cb895a9 337 case 1:
jesstvaldez 6:3b2a6cb895a9 338 led2=0;
jesstvaldez 6:3b2a6cb895a9 339 led3=1;
jesstvaldez 6:3b2a6cb895a9 340 led4=0;
jesstvaldez 6:3b2a6cb895a9 341 break;
jesstvaldez 6:3b2a6cb895a9 342 case 2:
jesstvaldez 6:3b2a6cb895a9 343 led2=0;
jesstvaldez 6:3b2a6cb895a9 344 led3=0;
jesstvaldez 6:3b2a6cb895a9 345 led4=1;
jesstvaldez 6:3b2a6cb895a9 346 break;
jesstvaldez 6:3b2a6cb895a9 347 }
jesstvaldez 6:3b2a6cb895a9 348 }
jesstvaldez 6:3b2a6cb895a9 349
jesstvaldez 6:3b2a6cb895a9 350 if ((mainStatus == OUT)|| (mainStatus == FAULT)) {
jesstvaldez 6:3b2a6cb895a9 351 led1 = 0;
jesstvaldez 6:3b2a6cb895a9 352 led2 = 0;
jesstvaldez 6:3b2a6cb895a9 353 led3 = 0;
jesstvaldez 6:3b2a6cb895a9 354 led4 = 0;
jesstvaldez 6:3b2a6cb895a9 355 Sleep(); //Save Power
jesstvaldez 6:3b2a6cb895a9 356 }
jesstvaldez 6:3b2a6cb895a9 357
jesstvaldez 6:3b2a6cb895a9 358
jesstvaldez 6:3b2a6cb895a9 359 //OK decide which source is available as mainSource
jesstvaldez 6:3b2a6cb895a9 360 switch(mainSource) {
jesstvaldez 6:3b2a6cb895a9 361 case SOLAR:
jesstvaldez 6:3b2a6cb895a9 362 if ((sourceLev[0] < solar_threshold) && (sourceLev[1] > battery_threshold)) {
jesstvaldez 6:3b2a6cb895a9 363 mainSource++;
jesstvaldez 6:3b2a6cb895a9 364 update=1;
jesstvaldez 6:3b2a6cb895a9 365 }
jesstvaldez 6:3b2a6cb895a9 366 if ((sourceLev[0] < solar_threshold) && (sourceLev[1] < battery_threshold)) {
jesstvaldez 6:3b2a6cb895a9 367 mainSource=GENERATOR; //if both solar and battery are down
jesstvaldez 6:3b2a6cb895a9 368 generator_control=1;
jesstvaldez 6:3b2a6cb895a9 369 update=1;
jesstvaldez 6:3b2a6cb895a9 370 }
jesstvaldez 6:3b2a6cb895a9 371 break;
jesstvaldez 6:3b2a6cb895a9 372
jesstvaldez 6:3b2a6cb895a9 373 case BATTERY:
jesstvaldez 6:3b2a6cb895a9 374 if (sourceLev[0] > solar_threshold) {
jesstvaldez 6:3b2a6cb895a9 375 mainSource=SOLAR; //if solar comes to life
jesstvaldez 6:3b2a6cb895a9 376 update=1;
jesstvaldez 6:3b2a6cb895a9 377 }
jesstvaldez 6:3b2a6cb895a9 378 if ((sourceLev[0] < solar_threshold) && (sourceLev[1] < battery_threshold)) {
jesstvaldez 6:3b2a6cb895a9 379 mainSource=GENERATOR; //solar or batt are low
jesstvaldez 6:3b2a6cb895a9 380 generator_control=1;
jesstvaldez 6:3b2a6cb895a9 381 update=1;
jesstvaldez 6:3b2a6cb895a9 382 }
jesstvaldez 6:3b2a6cb895a9 383 break;
jesstvaldez 6:3b2a6cb895a9 384
jesstvaldez 6:3b2a6cb895a9 385 case GENERATOR:
jesstvaldez 6:3b2a6cb895a9 386 if (sourceLev[1] > battery_threshold) {
jesstvaldez 6:3b2a6cb895a9 387 mainSource=BATTERY; //check if we can switch to battery
jesstvaldez 6:3b2a6cb895a9 388 generator_control=0;
jesstvaldez 6:3b2a6cb895a9 389 update=1;
jesstvaldez 6:3b2a6cb895a9 390 }
jesstvaldez 6:3b2a6cb895a9 391 if (sourceLev[0] > solar_threshold) {
jesstvaldez 6:3b2a6cb895a9 392 mainSource=SOLAR; //switch to solar if ever possible
jesstvaldez 6:3b2a6cb895a9 393 generator_control=0;
jesstvaldez 6:3b2a6cb895a9 394 update=1;
jesstvaldez 6:3b2a6cb895a9 395 }
jesstvaldez 6:3b2a6cb895a9 396 break;
jesstvaldez 6:3b2a6cb895a9 397 default:
jesstvaldez 6:3b2a6cb895a9 398 mainStatus = OUT;
jesstvaldez 6:3b2a6cb895a9 399 update=1;
jesstvaldez 6:3b2a6cb895a9 400 break;
jesstvaldez 6:3b2a6cb895a9 401 }
jesstvaldez 6:3b2a6cb895a9 402
jesstvaldez 6:3b2a6cb895a9 403 if (update==1) {
jesstvaldez 6:3b2a6cb895a9 404 //if update occurred
jesstvaldez 6:3b2a6cb895a9 405 lcd.cls();
jesstvaldez 6:3b2a6cb895a9 406 seconds=0;
jesstvaldez 6:3b2a6cb895a9 407 minutes=0;
jesstvaldez 6:3b2a6cb895a9 408 hours=0;
jesstvaldez 6:3b2a6cb895a9 409 days=0;
jesstvaldez 6:3b2a6cb895a9 410 update=0;
jesstvaldez 6:3b2a6cb895a9 411 }
jesstvaldez 6:3b2a6cb895a9 412 status_mutex.unlock();
jesstvaldez 6:3b2a6cb895a9 413 Thread::wait(500);
jesstvaldez 6:3b2a6cb895a9 414 }
emilmont 1:0f886ffbe0c1 415 }
jesstvaldez 6:3b2a6cb895a9 416 //======================================================
jesstvaldez 6:3b2a6cb895a9 417 //get levels thread
jesstvaldez 6:3b2a6cb895a9 418 //======================================================
jesstvaldez 6:3b2a6cb895a9 419 void get_levels_thread(void const *args)
jesstvaldez 6:3b2a6cb895a9 420 {
jesstvaldez 6:3b2a6cb895a9 421 while (true) {
jesstvaldez 6:3b2a6cb895a9 422 status_mutex.lock();
jesstvaldez 6:3b2a6cb895a9 423 if (mainStatus == RUNNING) {
jesstvaldez 6:3b2a6cb895a9 424 #if USE_POT
jesstvaldez 6:3b2a6cb895a9 425 //using pots during development
jesstvaldez 6:3b2a6cb895a9 426 sourceLev[0]=a_PD[3]; //pot1
jesstvaldez 6:3b2a6cb895a9 427 sourceLev[1]=a_PD[4]; //pot2
jesstvaldez 6:3b2a6cb895a9 428 #else
jesstvaldez 6:3b2a6cb895a9 429 //using actual solar + battery
jesstvaldez 6:3b2a6cb895a9 430 sourceLev[0]=a_PD[2]; //p18 of mbed
jesstvaldez 6:3b2a6cb895a9 431 sourceLev[1]=a_PD[1]; //p17 of mbed
jesstvaldez 6:3b2a6cb895a9 432
jesstvaldez 6:3b2a6cb895a9 433 #endif
jesstvaldez 6:3b2a6cb895a9 434 }
jesstvaldez 6:3b2a6cb895a9 435
jesstvaldez 6:3b2a6cb895a9 436 status_mutex.unlock();
jesstvaldez 6:3b2a6cb895a9 437 Thread::wait(500);
jesstvaldez 6:3b2a6cb895a9 438 }
jesstvaldez 6:3b2a6cb895a9 439 }
jesstvaldez 6:3b2a6cb895a9 440
jesstvaldez 6:3b2a6cb895a9 441 //======================================================
jesstvaldez 6:3b2a6cb895a9 442 // thread that monitors temperature of the controller PCB
jesstvaldez 6:3b2a6cb895a9 443 // generates fault or error when temp reaches threshold 100C
jesstvaldez 6:3b2a6cb895a9 444 //=======================================================
jesstvaldez 6:3b2a6cb895a9 445 void temperature_thread(void const *args)
jesstvaldez 6:3b2a6cb895a9 446 {
jesstvaldez 6:3b2a6cb895a9 447 while (true) {
jesstvaldez 6:3b2a6cb895a9 448 status_mutex.lock();
jesstvaldez 6:3b2a6cb895a9 449
jesstvaldez 6:3b2a6cb895a9 450 controller_temp = tmp.read();
jesstvaldez 6:3b2a6cb895a9 451 if (controller_temp > 100) {
jesstvaldez 6:3b2a6cb895a9 452 mainStatus = FAULT;
jesstvaldez 6:3b2a6cb895a9 453 generator_control = 0;
jesstvaldez 6:3b2a6cb895a9 454 wdt.kick();
jesstvaldez 6:3b2a6cb895a9 455 }
jesstvaldez 6:3b2a6cb895a9 456 status_mutex.unlock();
jesstvaldez 6:3b2a6cb895a9 457 Thread::wait(500);
jesstvaldez 6:3b2a6cb895a9 458 }
jesstvaldez 6:3b2a6cb895a9 459 }