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:
Fri Apr 23 08:36:42 2021 +0000
Revision:
106:41ed3ea0bbba
Parent:
95:97621bfbedfa
Not working, crashes.

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 95:97621bfbedfa 5 #include "rtc.h"
andrewboyson 20:904a4f043f2c 6 #include "clktime.h"
andrewboyson 95:97621bfbedfa 7 #include "clk.h"
andrewboyson 95:97621bfbedfa 8 #include "log.h"
andrewboyson 20:904a4f043f2c 9 #include "fram.h"
andrewboyson 48:6eac12df3ad5 10 #include "http.h"
andrewboyson 0:3c04f4b47041 11
andrewboyson 48:6eac12df3ad5 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 48:6eac12df3ad5 113 void ProgramSendAjax()
andrewboyson 48:6eac12df3ad5 114 {
andrewboyson 48:6eac12df3ad5 115 for (int program = 0; program < PROGRAMS_COUNT; program++)
andrewboyson 48:6eac12df3ad5 116 {
andrewboyson 48:6eac12df3ad5 117 for (int transition = 0; transition < TRANSITIONS_COUNT; transition++)
andrewboyson 48:6eac12df3ad5 118 {
andrewboyson 48:6eac12df3ad5 119 bool inuse;
andrewboyson 48:6eac12df3ad5 120 bool on;
andrewboyson 48:6eac12df3ad5 121 int minuteUnits;
andrewboyson 48:6eac12df3ad5 122 decodeTransition(programs[program][transition], &inuse, &on, &minuteUnits);
andrewboyson 48:6eac12df3ad5 123 if (!inuse) continue;
andrewboyson 48:6eac12df3ad5 124
andrewboyson 48:6eac12df3ad5 125 int minuteTens = minuteUnits / 10; minuteUnits %= 10;
andrewboyson 48:6eac12df3ad5 126 int hourUnits = minuteTens / 6; minuteTens %= 6;
andrewboyson 48:6eac12df3ad5 127 int hourTens = hourUnits / 10; hourUnits %= 10;
andrewboyson 48:6eac12df3ad5 128
andrewboyson 48:6eac12df3ad5 129 if (transition) HttpAddChar(' ');
andrewboyson 48:6eac12df3ad5 130 HttpAddChar(on ? '+' : '-');
andrewboyson 48:6eac12df3ad5 131 HttpAddChar(hourTens + '0');
andrewboyson 48:6eac12df3ad5 132 HttpAddChar(hourUnits + '0');
andrewboyson 48:6eac12df3ad5 133 HttpAddChar(minuteTens + '0');
andrewboyson 48:6eac12df3ad5 134 HttpAddChar(minuteUnits + '0');
andrewboyson 48:6eac12df3ad5 135 }
andrewboyson 48:6eac12df3ad5 136 HttpAddChar('\n');
andrewboyson 48:6eac12df3ad5 137 }
andrewboyson 48:6eac12df3ad5 138 }
andrewboyson 0:3c04f4b47041 139 static void handleParseDelim(int program, int* pIndex, bool* pInUse, bool* pOn, int* pHourTens, int* pHourUnits, int* pMinuteTens, int* pMinuteUnits)
andrewboyson 0:3c04f4b47041 140 {
andrewboyson 0:3c04f4b47041 141 int hour = *pHourTens * 10 + *pHourUnits;
andrewboyson 0:3c04f4b47041 142 if (hour < 0) *pInUse = false;
andrewboyson 0:3c04f4b47041 143 if (hour > 23) *pInUse = false;
andrewboyson 0:3c04f4b47041 144
andrewboyson 0:3c04f4b47041 145 int minute = *pMinuteTens * 10 + *pMinuteUnits;
andrewboyson 0:3c04f4b47041 146 if (minute < 0) *pInUse = false;
andrewboyson 0:3c04f4b47041 147 if (minute > 59) *pInUse = false;
andrewboyson 0:3c04f4b47041 148
andrewboyson 0:3c04f4b47041 149 int minutes = hour * 60 + minute;
andrewboyson 0:3c04f4b47041 150
andrewboyson 0:3c04f4b47041 151 int16_t transition = encodeTransition(*pInUse, *pOn, minutes);
andrewboyson 0:3c04f4b47041 152 programs[program][*pIndex] = transition;
andrewboyson 0:3c04f4b47041 153
andrewboyson 0:3c04f4b47041 154 *pIndex += 1;
andrewboyson 0:3c04f4b47041 155 *pInUse = 0;
andrewboyson 0:3c04f4b47041 156 *pOn = 0;
andrewboyson 0:3c04f4b47041 157 *pHourTens = 0;
andrewboyson 0:3c04f4b47041 158 *pHourUnits = 0;
andrewboyson 0:3c04f4b47041 159 *pMinuteTens = 0;
andrewboyson 0:3c04f4b47041 160 *pMinuteUnits = 0;
andrewboyson 0:3c04f4b47041 161
andrewboyson 0:3c04f4b47041 162 }
andrewboyson 0:3c04f4b47041 163 void ProgramParse(int program, char* p)
andrewboyson 0:3c04f4b47041 164 {
andrewboyson 0:3c04f4b47041 165 int i = 0;
andrewboyson 0:3c04f4b47041 166 bool inUse = 0; bool on = 0;
andrewboyson 0:3c04f4b47041 167 int hourUnits = 0; int hourTens = 0;
andrewboyson 0:3c04f4b47041 168 int minuteUnits = 0; int minuteTens = 0;
andrewboyson 47:229338b3adcb 169 while (*p && i < TRANSITIONS_COUNT)
andrewboyson 0:3c04f4b47041 170 {
andrewboyson 0:3c04f4b47041 171 if (*p == '+') { on = true ; }
andrewboyson 0:3c04f4b47041 172 else if (*p == '-') { on = false; }
andrewboyson 0:3c04f4b47041 173 else if (*p >= '0' && *p <= '9') { inUse = true; hourTens = hourUnits; hourUnits = minuteTens; minuteTens = minuteUnits; minuteUnits = *p - '0'; }
andrewboyson 0:3c04f4b47041 174 else if (*p == ' ') { handleParseDelim(program, &i, &inUse, &on, &hourTens, &hourUnits, &minuteTens, &minuteUnits); }
andrewboyson 0:3c04f4b47041 175 p++;
andrewboyson 0:3c04f4b47041 176 }
andrewboyson 47:229338b3adcb 177 while (i < TRANSITIONS_COUNT) handleParseDelim(program, &i, &inUse, &on, &hourTens, &hourUnits, &minuteTens, &minuteUnits);
andrewboyson 0:3c04f4b47041 178 sort(&programs[program][0]);
andrewboyson 0:3c04f4b47041 179 FramWrite(iPrograms + program * 8, 8, &programs[program]);
andrewboyson 0:3c04f4b47041 180 }
andrewboyson 0:3c04f4b47041 181
andrewboyson 0:3c04f4b47041 182 static bool readProgramTimerOutput()
andrewboyson 0:3c04f4b47041 183 {
andrewboyson 0:3c04f4b47041 184
andrewboyson 20:904a4f043f2c 185 if (!ClkTimeIsSet()) return 0;
andrewboyson 0:3c04f4b47041 186
andrewboyson 0:3c04f4b47041 187 struct tm tm;
andrewboyson 20:904a4f043f2c 188 ClkNowTmLocal(&tm);
andrewboyson 0:3c04f4b47041 189
andrewboyson 0:3c04f4b47041 190 int dayOfWeek = tm.tm_wday;
andrewboyson 0:3c04f4b47041 191 int minutesNow = tm.tm_hour * 60 + tm.tm_min;
andrewboyson 0:3c04f4b47041 192 if (tm.tm_hour < programNewDayHour) //Before 2am should be matched against yesterday's program.
andrewboyson 0:3c04f4b47041 193 {
andrewboyson 0:3c04f4b47041 194 dayOfWeek--;
andrewboyson 0:3c04f4b47041 195 if (dayOfWeek < 0) dayOfWeek = 6;
andrewboyson 0:3c04f4b47041 196 }
andrewboyson 0:3c04f4b47041 197
andrewboyson 0:3c04f4b47041 198 int program = programDay[dayOfWeek];
andrewboyson 0:3c04f4b47041 199
andrewboyson 0:3c04f4b47041 200 bool calling = 0;
andrewboyson 47:229338b3adcb 201 for (int i = 0; i < TRANSITIONS_COUNT; i++)
andrewboyson 0:3c04f4b47041 202 {
andrewboyson 0:3c04f4b47041 203 int16_t transition = programs[program][i];
andrewboyson 0:3c04f4b47041 204 bool inuse;
andrewboyson 0:3c04f4b47041 205 bool on;
andrewboyson 0:3c04f4b47041 206 int minutes;
andrewboyson 0:3c04f4b47041 207 decodeTransition(transition, &inuse, &on, &minutes);
andrewboyson 0:3c04f4b47041 208 if (!inuse) continue;
andrewboyson 0:3c04f4b47041 209 if (minutes <= minutesNow) calling = on;
andrewboyson 0:3c04f4b47041 210 }
andrewboyson 0:3c04f4b47041 211
andrewboyson 0:3c04f4b47041 212 return calling;
andrewboyson 0:3c04f4b47041 213 }
andrewboyson 0:3c04f4b47041 214
andrewboyson 0:3c04f4b47041 215 bool ProgramTimerOutput;
andrewboyson 0:3c04f4b47041 216
andrewboyson 0:3c04f4b47041 217 int ProgramMain()
andrewboyson 0:3c04f4b47041 218 {
andrewboyson 0:3c04f4b47041 219 ProgramTimerOutput = readProgramTimerOutput();
andrewboyson 0:3c04f4b47041 220 return 0;
andrewboyson 0:3c04f4b47041 221 }