From aa0cd89d4e91b90c5baaccd4385e0cfb89f0b9ea Mon Sep 17 00:00:00 2001 From: Leon Krieg Date: Wed, 25 Sep 2024 17:16:20 +0200 Subject: [PATCH] Update documentation and do some basic housekeeping --- .gitmodules | 12 +-- Makefile | 7 +- docs/CHANGELOG.md | 73 ++++++++++++++++++ docs/README.md | 50 +++++++++--- docs/{ => external}/ADS1115.pdf | Bin docs/{ => external}/AHT20.pdf | Bin .../ATMEGA1284P.pdf} | Bin docs/{ => external}/ATMEGA32A.pdf | Bin docs/{ => external}/BMP280.pdf | Bin docs/{ => external}/PCA9546-01.pdf | Bin docs/{ => external}/PCA9546-02.pdf | Bin docs/{ => external}/PWM-NOCTUA.pdf | Bin docs/{ => external}/USART-01.pdf | Bin docs/{ => external}/USART-02.pdf | Bin docs/{ => external}/USART-03.pdf | Bin opt/webgui | 2 +- src/common.h | 8 +- src/common/memory.c | 6 +- src/common/memory.h | 4 +- src/main.c | 62 +++++++-------- 20 files changed, 167 insertions(+), 57 deletions(-) create mode 100644 docs/CHANGELOG.md rename docs/{ => external}/ADS1115.pdf (100%) rename docs/{ => external}/AHT20.pdf (100%) rename docs/{ATMEGA1284PPU.pdf => external/ATMEGA1284P.pdf} (100%) rename docs/{ => external}/ATMEGA32A.pdf (100%) rename docs/{ => external}/BMP280.pdf (100%) rename docs/{ => external}/PCA9546-01.pdf (100%) rename docs/{ => external}/PCA9546-02.pdf (100%) rename docs/{ => external}/PWM-NOCTUA.pdf (100%) rename docs/{ => external}/USART-01.pdf (100%) rename docs/{ => external}/USART-02.pdf (100%) rename docs/{ => external}/USART-03.pdf (100%) diff --git a/.gitmodules b/.gitmodules index afd666e..3ea9946 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,7 @@ -[submodule "opt/tools"] - path = opt/tools - url = git@github.com:madcow/drybox-tools.git +[submodule "tools"] +path = opt/tools +url = git@github.com:madcow/drybox-tools.git -[submodule "opt/webgui"] - path = opt/webgui - url = git@github.com:madcow/drybox-webgui.git +[submodule "webgui"] +path = opt/webgui +url = git@github.com:madcow/drybox-webgui.git diff --git a/Makefile b/Makefile index 35b82c1..cced8de 100644 --- a/Makefile +++ b/Makefile @@ -62,7 +62,7 @@ flash: $(TARGET) -c $(ASP) -p $(ARCH) \ -U lfuse:w:0xff:m \ -U hfuse:w:0x91:m \ - -U flash:w:$(TARGET) + -U flash:w:$< .PHONY: clean clean: @@ -85,6 +85,11 @@ listen: ./opt/tools/serial-listen.py $(E) "[PY3] $<" $(Q) ./$< +.PHONY: listen-web +listen-web: ./opt/webgui/Makefile + $(E) "[MAK] $( + ./opt/tools/serial-send.py Issue the SET command to update the target settings: @@ -50,3 +66,19 @@ Settings are stored in EEPROM and are persistent until a new SET command is issued. Keywords are not case-sensitive. Both arguments may contain a decimal point followed by a sequence of digits. + +### Webinterface Example + +There is an example Python web server utilizing websockets you +can check out in `opt/webgui`. It should give you a basis for +writing a custom network bridge and integrating the device into +your home automation system. + +You must generate a self-signed certificate before you run the +server. The configuration script will take care of it: + + ./opt/webgui/configure + +See the README file in the webgui/ directory for prerequisites +and more information. Please be aware that development for the +web server has paused until the core has reached version v1.0. diff --git a/docs/ADS1115.pdf b/docs/external/ADS1115.pdf similarity index 100% rename from docs/ADS1115.pdf rename to docs/external/ADS1115.pdf diff --git a/docs/AHT20.pdf b/docs/external/AHT20.pdf similarity index 100% rename from docs/AHT20.pdf rename to docs/external/AHT20.pdf diff --git a/docs/ATMEGA1284PPU.pdf b/docs/external/ATMEGA1284P.pdf similarity index 100% rename from docs/ATMEGA1284PPU.pdf rename to docs/external/ATMEGA1284P.pdf diff --git a/docs/ATMEGA32A.pdf b/docs/external/ATMEGA32A.pdf similarity index 100% rename from docs/ATMEGA32A.pdf rename to docs/external/ATMEGA32A.pdf diff --git a/docs/BMP280.pdf b/docs/external/BMP280.pdf similarity index 100% rename from docs/BMP280.pdf rename to docs/external/BMP280.pdf diff --git a/docs/PCA9546-01.pdf b/docs/external/PCA9546-01.pdf similarity index 100% rename from docs/PCA9546-01.pdf rename to docs/external/PCA9546-01.pdf diff --git a/docs/PCA9546-02.pdf b/docs/external/PCA9546-02.pdf similarity index 100% rename from docs/PCA9546-02.pdf rename to docs/external/PCA9546-02.pdf diff --git a/docs/PWM-NOCTUA.pdf b/docs/external/PWM-NOCTUA.pdf similarity index 100% rename from docs/PWM-NOCTUA.pdf rename to docs/external/PWM-NOCTUA.pdf diff --git a/docs/USART-01.pdf b/docs/external/USART-01.pdf similarity index 100% rename from docs/USART-01.pdf rename to docs/external/USART-01.pdf diff --git a/docs/USART-02.pdf b/docs/external/USART-02.pdf similarity index 100% rename from docs/USART-02.pdf rename to docs/external/USART-02.pdf diff --git a/docs/USART-03.pdf b/docs/external/USART-03.pdf similarity index 100% rename from docs/USART-03.pdf rename to docs/external/USART-03.pdf diff --git a/opt/webgui b/opt/webgui index b616559..bd60c0e 160000 --- a/opt/webgui +++ b/opt/webgui @@ -1 +1 @@ -Subproject commit b616559a362c020f5f98f65b42548d784f1a03dd +Subproject commit bd60c0e13dce8210262fa0899f640b0a022b5085 diff --git a/src/common.h b/src/common.h index 85e3556..9971a59 100644 --- a/src/common.h +++ b/src/common.h @@ -12,13 +12,13 @@ #define UNUSED(s) (void)(s) #define BIT(n) (0x1U << (n)) -#define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) #define CLAMP(n, hi, lo) (MIN((hi), MAX((n), (lo)))) -void Info(const char *fmt, ...); -void Error(const char *fmt, ...); -void Print(const char *fmt, ...); +void Info(const char *fmt, ...); +void Error(const char *fmt, ...); +void Print(const char *fmt, ...); #include #define Sleep(ms) _delay_ms(ms) diff --git a/src/common/memory.c b/src/common/memory.c index f46e752..a691c1a 100644 --- a/src/common/memory.c +++ b/src/common/memory.c @@ -62,19 +62,19 @@ void MEM_Write(mem_block_t *in) WriteBlock(head, in); } -int MEM_Read(mem_block_t *out) +bool MEM_Read(mem_block_t *out) { int head; head = GetUsedBlock(); if (head < 0) { // Empty? - return -1; + return false; } ReadBlock(head, out); - return 0; + return true; } void MEM_Free(void) diff --git a/src/common/memory.h b/src/common/memory.h index feeed22..9184aff 100644 --- a/src/common/memory.h +++ b/src/common/memory.h @@ -1,6 +1,8 @@ #ifndef MAD_CORE_COMMON_MEMORY_H #define MAD_CORE_COMMON_MEMORY_H +#include "common/types.h" + typedef struct mem_block_s mem_block_t; // Important: Must reset EEPROM memory when the size of @@ -13,7 +15,7 @@ struct mem_block_s { } __attribute__((packed)); void MEM_Write(mem_block_t *in); -int MEM_Read(mem_block_t *out); +bool MEM_Read(mem_block_t *out); void MEM_Free(void); void MEM_Dump(void); diff --git a/src/main.c b/src/main.c index 204b233..4f36a12 100644 --- a/src/main.c +++ b/src/main.c @@ -76,17 +76,11 @@ static int Init(void) WDT_Enable(); WDT_SetTimeoutFlag(WDT2000); // 2 seconds - // Test persistent settings from EEPROM. There must - // be some sanity checking before these values are - // used. + // See if there are persistent target settings + // stored in EEPROM and load them. Some sanity + // checking must be done before using those. - // mem.temp = 20.50f; - // mem.dewp = 10.25f; - // MEM_Write(&mem); - // MEM_Dump(); - // MEM_Free(); - - if (MEM_Read(&mem) == 0) { + if (MEM_Read(&mem)) { // Any valid blocks found? Info("Found persistent configuration in EEPROM!"); Info("Using targets TEMP=%.2fC, DEWP=%.2fC.", mem.temp, mem.dewp); @@ -95,6 +89,12 @@ static int Init(void) dewp_target = mem.dewp; } + // mem.temp = 20.50f; + // mem.dewp = 10.25f; + // MEM_Write(&mem); + // MEM_Dump(); + // MEM_Free(); + // There is a possiblity to use interrupt signals // for I2C communication but only as one large // branching routine for the whole I2C system. @@ -103,9 +103,9 @@ static int Init(void) I2C_Init(); PWM_Init(); - MOS_Enable(MOS03); // Lights - // MOS_Enable(MOS01); // Peltier - // MOS_Disable(MOS02); // Heating + MOS_Enable(MOS03); // Lights + // MOS_Enable(MOS01); // Peltier + // MOS_Disable(MOS02); // Heating // Only FAN01 and FAN02 are receiving the correct // frequency (25 KHz) right now. The 16-bit timer on @@ -117,9 +117,9 @@ static int Init(void) // complicated so it might be worth it to switch to // something like an ATmega328PB. - PWM_SetValue(FAN01, 50); // Fan Peltier Hot side - PWM_SetValue(FAN02, 50); // Fan Peltier Cold Side - // PWM_SetValue(FAN03, 20); // Fan Heating + PWM_SetValue(FAN01, 50); // Fan Peltier Hot side + PWM_SetValue(FAN02, 50); // Fan Peltier Cold Side + // PWM_SetValue(FAN03, 20); // Fan Heating // The I2C_SetChannel command changes the channel // setting of the PCA9546 I2C multiplexer. Any @@ -156,7 +156,7 @@ static void Update(void) } } - // Get sensor values + // Get latest sensor values FetchSensorValues(); // Handle state @@ -179,23 +179,25 @@ static void SetTarget(float t, float td) Print("\r\n"); Info("Updating target configuration:"); Info("Setting temperature to %.2fC.", t); - Info("Setting new dewpoint to %.2fC.", td); + Info("Setting dewpoint to %.2fC.", td); - if (MEM_Read(&mem) == 0) { + // Even with level wearing there is a finite number + // of EEPROM write cycles so we should always check + // for redundant values. This could be handled by + // the underlying memory implementation. + + if (MEM_Read(&mem)) { if (t == mem.temp && td == mem.dewp) { return; // Nothing to do } } - mem.temp = t; - mem.dewp = td; + // Update current targets + mem.temp = temp_target = t; + mem.dewp = dewp_target = td; - // Keep in EEPROM + // Store in EEPROM MEM_Write(&mem); - - // Update state - temp_target = t; - dewp_target = td; } static void FetchSensorValues(void) @@ -204,23 +206,19 @@ static void FetchSensorValues(void) float t[6], rh[3], td[3]; Print("\r\n"); - Info("Reading sensor values..."); + Info("Fetching sensor values..."); I2C_SetChannel(AHT01); I2C_AHT20_Read(&t[0], &rh[0]); - I2C_SetChannel(AHT02); I2C_AHT20_Read(&t[1], &rh[1]); - I2C_SetChannel(AHT03); I2C_AHT20_Read(&t[2], &rh[2]); raw = I2C_ADS1115_ReadRaw(ADS01); t[3] = SteinhartHart(Resistance(raw)); - raw = I2C_ADS1115_ReadRaw(ADS02); t[4] = SteinhartHart(Resistance(raw)); - raw = I2C_ADS1115_ReadRaw(ADS03); t[5] = SteinhartHart(Resistance(raw)); @@ -230,7 +228,7 @@ static void FetchSensorValues(void) temp = (t[0] + t[1] + t[2]) / 3; rhum = (rh[0] + rh[1] + rh[2]) / 3; - dewp = Dewpoint(temp, rhum); + dewp = (td[0] + td[1] + td[2]) / 3; Info("T1=%.2fC, TD1=%.2fC, RH1=%.2f%%, NT1=%.2fC", t[0], td[0], rh[0], t[3]); Info("T2=%.2fC, TD2=%.2fC, RH2=%.2f%%, NT2=%.2fC", t[1], td[1], rh[1], t[4]);