Central Heating controller using the real time clock, PHY module for internet, 1-wire interface for temperature sensors, a system log and a configuration file

Dependencies:   net 1-wire lpc1768 crypto clock web fram log

/media/uploads/andrewboyson/heating.sch

/media/uploads/andrewboyson/heating.brd

/media/uploads/andrewboyson/eagle.epf

Committer:
andrewboyson
Date:
Tue Apr 23 18:47:47 2019 +0000
Revision:
47:229338b3adcb
Parent:
20:904a4f043f2c
Child:
48:6eac12df3ad5
Provided individual scripts per page and moved most inputs to ajax.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 0:3c04f4b47041 1 #include <stdint.h>
andrewboyson 0:3c04f4b47041 2 #include <stdlib.h>
andrewboyson 0:3c04f4b47041 3 #include <stdbool.h>
andrewboyson 0:3c04f4b47041 4
andrewboyson 20:904a4f043f2c 5 #include "rtc.h"
andrewboyson 20:904a4f043f2c 6 #include "clktime.h"
andrewboyson 20:904a4f043f2c 7 #include "clk.h"
andrewboyson 20:904a4f043f2c 8 #include "log.h"
andrewboyson 20:904a4f043f2c 9 #include "fram.h"
andrewboyson 47:229338b3adcb 10 #include "program.h"
andrewboyson 0:3c04f4b47041 11
andrewboyson 47:229338b3adcb 12 #define PROGRAMS_COUNT 3
andrewboyson 47:229338b3adcb 13 #define TRANSITIONS_COUNT 4
andrewboyson 47:229338b3adcb 14 static int16_t programs[PROGRAMS_COUNT][TRANSITIONS_COUNT]; static int iPrograms;
andrewboyson 47:229338b3adcb 15 static char programDay[7]; static int iDay;
andrewboyson 47:229338b3adcb 16 static char programNewDayHour; static int iNewDayHour;
andrewboyson 0:3c04f4b47041 17
andrewboyson 0:3c04f4b47041 18 int ProgramGetDay (int i) { return (int) programDay[i]; }
andrewboyson 0:3c04f4b47041 19 int ProgramGetNewDayHour() { return (int) programNewDayHour;}
andrewboyson 0:3c04f4b47041 20
andrewboyson 0:3c04f4b47041 21 void ProgramSetDay (int i, int value) { programDay [i] = (char)value; FramWrite(iDay + i, 1, &programDay [i]); }
andrewboyson 0:3c04f4b47041 22 void ProgramSetNewDayHour( int value) { programNewDayHour = (char)value; FramWrite(iNewDayHour, 1, &programNewDayHour ); }
andrewboyson 0:3c04f4b47041 23
andrewboyson 0:3c04f4b47041 24 int ProgramInit()
andrewboyson 0:3c04f4b47041 25 {
andrewboyson 0:3c04f4b47041 26 char def1;
andrewboyson 0:3c04f4b47041 27 int address;
andrewboyson 47:229338b3adcb 28 int programSize = PROGRAMS_COUNT * TRANSITIONS_COUNT * sizeof(int16_t);
andrewboyson 0:3c04f4b47041 29 address = FramLoad(7, programDay, NULL); if (address < 0) return -1; iDay = address;
andrewboyson 0:3c04f4b47041 30 address = FramLoad(programSize, programs, NULL); if (address < 0) return -1; iPrograms = address; //3 x 4 x 2
andrewboyson 0:3c04f4b47041 31 def1 = 2; address = FramLoad(1, &programNewDayHour, &def1); if (address < 0) return -1; iNewDayHour = address;
andrewboyson 0:3c04f4b47041 32 return 0;
andrewboyson 0:3c04f4b47041 33 }
andrewboyson 0:3c04f4b47041 34
andrewboyson 0:3c04f4b47041 35 /*
andrewboyson 0:3c04f4b47041 36 There are three programs available [0|1|2]; any of which can be allocated to a given day [0-6].
andrewboyson 0:3c04f4b47041 37 Each program contains four transitions with an index [0|1|2|3].
andrewboyson 0:3c04f4b47041 38 A transition is defined to be a short (16 bit) and consists of:
andrewboyson 0:3c04f4b47041 39 +---------+--------+--------+---------+
andrewboyson 0:3c04f4b47041 40 | 15 - 13 | 12 | 11 | 10 - 00 |
andrewboyson 0:3c04f4b47041 41 +---------+--------+--------+---------+
andrewboyson 0:3c04f4b47041 42 | | in use | switch | minute |
andrewboyson 0:3c04f4b47041 43 | | yes/no | on/off | in day |
andrewboyson 0:3c04f4b47041 44 | | 1/0 | 1/0 | 0-1439 |
andrewboyson 0:3c04f4b47041 45 +---------+--------+--------+---------+
andrewboyson 0:3c04f4b47041 46 */
andrewboyson 0:3c04f4b47041 47 static int16_t encodeTransition(bool inuse, bool onoff, int minutes)
andrewboyson 0:3c04f4b47041 48 {
andrewboyson 0:3c04f4b47041 49 int16_t transition = minutes;
andrewboyson 0:3c04f4b47041 50 transition &= 0x07FF;
andrewboyson 0:3c04f4b47041 51 if (onoff) transition |= 0x0800;
andrewboyson 0:3c04f4b47041 52 if (inuse) transition |= 0x1000;
andrewboyson 0:3c04f4b47041 53 return transition;
andrewboyson 0:3c04f4b47041 54 }
andrewboyson 0:3c04f4b47041 55 static void decodeTransition(int16_t transition, bool* pinuse, bool* ponoff, int* pminutes)
andrewboyson 0:3c04f4b47041 56 {
andrewboyson 0:3c04f4b47041 57 *pinuse = transition & 0x1000;
andrewboyson 0:3c04f4b47041 58 *ponoff = transition & 0x0800;
andrewboyson 0:3c04f4b47041 59 *pminutes = transition & 0x07FF;
andrewboyson 0:3c04f4b47041 60 }
andrewboyson 0:3c04f4b47041 61
andrewboyson 0:3c04f4b47041 62 static int compareTransition (const void * a, const void * b) //-ve a goes before b; 0 same; +ve a goes after b
andrewboyson 0:3c04f4b47041 63 {
andrewboyson 0:3c04f4b47041 64 bool inUseA, inUseB;
andrewboyson 0:3c04f4b47041 65 bool onA, onB;
andrewboyson 0:3c04f4b47041 66 int minutesA, minutesB;
andrewboyson 0:3c04f4b47041 67 decodeTransition(*(int16_t*)a, &inUseA, &onA, &minutesA);
andrewboyson 0:3c04f4b47041 68 decodeTransition(*(int16_t*)b, &inUseB, &onB, &minutesB);
andrewboyson 0:3c04f4b47041 69
andrewboyson 0:3c04f4b47041 70 if (!inUseA && !inUseB) return 0;
andrewboyson 0:3c04f4b47041 71 if (!inUseA) return +1;
andrewboyson 0:3c04f4b47041 72 if (!inUseB) return -1;
andrewboyson 0:3c04f4b47041 73
andrewboyson 0:3c04f4b47041 74 if (minutesA < programNewDayHour * 60) minutesA += 1440;
andrewboyson 0:3c04f4b47041 75 if (minutesB < programNewDayHour * 60) minutesB += 1440;
andrewboyson 0:3c04f4b47041 76
andrewboyson 0:3c04f4b47041 77 if (minutesA < minutesB) return -1;
andrewboyson 0:3c04f4b47041 78 if (minutesA > minutesB) return +1;
andrewboyson 0:3c04f4b47041 79 return 0;
andrewboyson 0:3c04f4b47041 80 }
andrewboyson 0:3c04f4b47041 81 static void sort(int16_t* pProgram)
andrewboyson 0:3c04f4b47041 82 {
andrewboyson 0:3c04f4b47041 83 qsort (pProgram, 4, sizeof(int16_t), compareTransition);
andrewboyson 0:3c04f4b47041 84 }
andrewboyson 0:3c04f4b47041 85
andrewboyson 0:3c04f4b47041 86 //[+|-][00-23][00-59];
andrewboyson 0:3c04f4b47041 87 void ProgramToString(int program, int buflen, char* buffer)
andrewboyson 0:3c04f4b47041 88 {
andrewboyson 0:3c04f4b47041 89 if (buflen < 25) return;
andrewboyson 0:3c04f4b47041 90 char* p = buffer;
andrewboyson 47:229338b3adcb 91 for (int i = 0; i < TRANSITIONS_COUNT; i++)
andrewboyson 0:3c04f4b47041 92 {
andrewboyson 0:3c04f4b47041 93 int16_t transition = programs[program][i];
andrewboyson 0:3c04f4b47041 94 bool inuse;
andrewboyson 0:3c04f4b47041 95 bool on;
andrewboyson 0:3c04f4b47041 96 int minuteUnits;
andrewboyson 0:3c04f4b47041 97 decodeTransition(transition, &inuse, &on, &minuteUnits);
andrewboyson 0:3c04f4b47041 98 if (!inuse) continue;
andrewboyson 0:3c04f4b47041 99
andrewboyson 0:3c04f4b47041 100 int minuteTens = minuteUnits / 10; minuteUnits %= 10;
andrewboyson 0:3c04f4b47041 101 int hourUnits = minuteTens / 6; minuteTens %= 6;
andrewboyson 0:3c04f4b47041 102 int hourTens = hourUnits / 10; hourUnits %= 10;
andrewboyson 0:3c04f4b47041 103
andrewboyson 0:3c04f4b47041 104 if (p > buffer) *p++ = ' ';
andrewboyson 0:3c04f4b47041 105 *p++ = on ? '+' : '-';
andrewboyson 0:3c04f4b47041 106 *p++ = hourTens + '0';
andrewboyson 0:3c04f4b47041 107 *p++ = hourUnits + '0';
andrewboyson 0:3c04f4b47041 108 *p++ = minuteTens + '0';
andrewboyson 0:3c04f4b47041 109 *p++ = minuteUnits + '0';
andrewboyson 0:3c04f4b47041 110 }
andrewboyson 0:3c04f4b47041 111 *p = 0;
andrewboyson 0:3c04f4b47041 112 }
andrewboyson 0:3c04f4b47041 113 static void handleParseDelim(int program, int* pIndex, bool* pInUse, bool* pOn, int* pHourTens, int* pHourUnits, int* pMinuteTens, int* pMinuteUnits)
andrewboyson 0:3c04f4b47041 114 {
andrewboyson 0:3c04f4b47041 115 int hour = *pHourTens * 10 + *pHourUnits;
andrewboyson 0:3c04f4b47041 116 if (hour < 0) *pInUse = false;
andrewboyson 0:3c04f4b47041 117 if (hour > 23) *pInUse = false;
andrewboyson 0:3c04f4b47041 118
andrewboyson 0:3c04f4b47041 119 int minute = *pMinuteTens * 10 + *pMinuteUnits;
andrewboyson 0:3c04f4b47041 120 if (minute < 0) *pInUse = false;
andrewboyson 0:3c04f4b47041 121 if (minute > 59) *pInUse = false;
andrewboyson 0:3c04f4b47041 122
andrewboyson 0:3c04f4b47041 123 int minutes = hour * 60 + minute;
andrewboyson 0:3c04f4b47041 124
andrewboyson 0:3c04f4b47041 125 int16_t transition = encodeTransition(*pInUse, *pOn, minutes);
andrewboyson 0:3c04f4b47041 126 programs[program][*pIndex] = transition;
andrewboyson 0:3c04f4b47041 127
andrewboyson 0:3c04f4b47041 128 *pIndex += 1;
andrewboyson 0:3c04f4b47041 129 *pInUse = 0;
andrewboyson 0:3c04f4b47041 130 *pOn = 0;
andrewboyson 0:3c04f4b47041 131 *pHourTens = 0;
andrewboyson 0:3c04f4b47041 132 *pHourUnits = 0;
andrewboyson 0:3c04f4b47041 133 *pMinuteTens = 0;
andrewboyson 0:3c04f4b47041 134 *pMinuteUnits = 0;
andrewboyson 0:3c04f4b47041 135
andrewboyson 0:3c04f4b47041 136 }
andrewboyson 0:3c04f4b47041 137 void ProgramParse(int program, char* p)
andrewboyson 0:3c04f4b47041 138 {
andrewboyson 0:3c04f4b47041 139 int i = 0;
andrewboyson 0:3c04f4b47041 140 bool inUse = 0; bool on = 0;
andrewboyson 0:3c04f4b47041 141 int hourUnits = 0; int hourTens = 0;
andrewboyson 0:3c04f4b47041 142 int minuteUnits = 0; int minuteTens = 0;
andrewboyson 47:229338b3adcb 143 while (*p && i < TRANSITIONS_COUNT)
andrewboyson 0:3c04f4b47041 144 {
andrewboyson 0:3c04f4b47041 145 if (*p == '+') { on = true ; }
andrewboyson 0:3c04f4b47041 146 else if (*p == '-') { on = false; }
andrewboyson 0:3c04f4b47041 147 else if (*p >= '0' && *p <= '9') { inUse = true; hourTens = hourUnits; hourUnits = minuteTens; minuteTens = minuteUnits; minuteUnits = *p - '0'; }
andrewboyson 0:3c04f4b47041 148 else if (*p == ' ') { handleParseDelim(program, &i, &inUse, &on, &hourTens, &hourUnits, &minuteTens, &minuteUnits); }
andrewboyson 0:3c04f4b47041 149 p++;
andrewboyson 0:3c04f4b47041 150 }
andrewboyson 47:229338b3adcb 151 while (i < TRANSITIONS_COUNT) handleParseDelim(program, &i, &inUse, &on, &hourTens, &hourUnits, &minuteTens, &minuteUnits);
andrewboyson 0:3c04f4b47041 152 sort(&programs[program][0]);
andrewboyson 0:3c04f4b47041 153 FramWrite(iPrograms + program * 8, 8, &programs[program]);
andrewboyson 0:3c04f4b47041 154 }
andrewboyson 0:3c04f4b47041 155
andrewboyson 0:3c04f4b47041 156 static bool readProgramTimerOutput()
andrewboyson 0:3c04f4b47041 157 {
andrewboyson 0:3c04f4b47041 158
andrewboyson 20:904a4f043f2c 159 if (!ClkTimeIsSet()) return 0;
andrewboyson 0:3c04f4b47041 160
andrewboyson 0:3c04f4b47041 161 struct tm tm;
andrewboyson 20:904a4f043f2c 162 ClkNowTmLocal(&tm);
andrewboyson 0:3c04f4b47041 163
andrewboyson 0:3c04f4b47041 164 int dayOfWeek = tm.tm_wday;
andrewboyson 0:3c04f4b47041 165 int minutesNow = tm.tm_hour * 60 + tm.tm_min;
andrewboyson 0:3c04f4b47041 166 if (tm.tm_hour < programNewDayHour) //Before 2am should be matched against yesterday's program.
andrewboyson 0:3c04f4b47041 167 {
andrewboyson 0:3c04f4b47041 168 dayOfWeek--;
andrewboyson 0:3c04f4b47041 169 if (dayOfWeek < 0) dayOfWeek = 6;
andrewboyson 0:3c04f4b47041 170 }
andrewboyson 0:3c04f4b47041 171
andrewboyson 0:3c04f4b47041 172 int program = programDay[dayOfWeek];
andrewboyson 0:3c04f4b47041 173
andrewboyson 0:3c04f4b47041 174 bool calling = 0;
andrewboyson 47:229338b3adcb 175 for (int i = 0; i < TRANSITIONS_COUNT; i++)
andrewboyson 0:3c04f4b47041 176 {
andrewboyson 0:3c04f4b47041 177 int16_t transition = programs[program][i];
andrewboyson 0:3c04f4b47041 178 bool inuse;
andrewboyson 0:3c04f4b47041 179 bool on;
andrewboyson 0:3c04f4b47041 180 int minutes;
andrewboyson 0:3c04f4b47041 181 decodeTransition(transition, &inuse, &on, &minutes);
andrewboyson 0:3c04f4b47041 182 if (!inuse) continue;
andrewboyson 0:3c04f4b47041 183 if (minutes <= minutesNow) calling = on;
andrewboyson 0:3c04f4b47041 184 }
andrewboyson 0:3c04f4b47041 185
andrewboyson 0:3c04f4b47041 186 return calling;
andrewboyson 0:3c04f4b47041 187 }
andrewboyson 0:3c04f4b47041 188
andrewboyson 0:3c04f4b47041 189 bool ProgramTimerOutput;
andrewboyson 0:3c04f4b47041 190
andrewboyson 0:3c04f4b47041 191 int ProgramMain()
andrewboyson 0:3c04f4b47041 192 {
andrewboyson 0:3c04f4b47041 193 ProgramTimerOutput = readProgramTimerOutput();
andrewboyson 0:3c04f4b47041 194 return 0;
andrewboyson 0:3c04f4b47041 195 }