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 Jan 08 14:08:33 2019 +0000
Revision:
20:904a4f043f2c
Parent:
0:3c04f4b47041
Child:
47:229338b3adcb
Updated clock library

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