Merge branch 'v2'
This commit is contained in:
@@ -31,6 +31,8 @@ add_executable(zavlaha
|
||||
src/screens/screen_kompenzace_tlaku.c
|
||||
src/screens/screen_program_prehled.c
|
||||
src/screens/screen_program_edit.c
|
||||
src/screens/screen_suche_dny.c
|
||||
src/screens/screen_manual_control.c
|
||||
src/app_io.c
|
||||
src/app_config.c)
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
kompilovano s SDK ver 3352ccf5de3a704e74355f72aa61143fb36cfec9
|
||||
|
||||
+12
-3
@@ -9,10 +9,10 @@
|
||||
|
||||
#define APPCONFIG_EE_BASE_ADDR 0
|
||||
|
||||
// TODO sensible defaults, loading and saving to/from EE
|
||||
struct AppConfig app_config;
|
||||
|
||||
static const struct AppConfig DEFAULTS = {
|
||||
.magic_version = APPCONFIG_MAGIC1,
|
||||
.circuit_base_time_s = 300, // for a test
|
||||
.circuit_time_percent = {100, 100, 100, 100}, // for a test
|
||||
.scheduler_enable = true,
|
||||
@@ -26,6 +26,8 @@ static const struct AppConfig DEFAULTS = {
|
||||
.moisture_dry = 2800,
|
||||
.moisture_wet = 1600,
|
||||
.moisture_threshold_percent = 70,
|
||||
.magic2 = APPCONFIG_MAGIC2,
|
||||
.scheduler_dry_days = 0,
|
||||
};
|
||||
|
||||
static void load_fallback_config() {
|
||||
@@ -36,7 +38,7 @@ static void load_fallback_config() {
|
||||
void appconfig_load()
|
||||
{
|
||||
uint8_t magic = 0;
|
||||
if (0 > ee_read(APPCONFIG_EE_BASE_ADDR, &magic, 1) || magic != APPCONFIG_VERSION) {
|
||||
if (0 > ee_read(APPCONFIG_EE_BASE_ADDR, &magic, 1) || magic != APPCONFIG_MAGIC1) {
|
||||
printf("Couldn't read EE to check magic!\r\n");
|
||||
load_fallback_config();
|
||||
return;
|
||||
@@ -45,6 +47,12 @@ void appconfig_load()
|
||||
if (0 > ee_read(APPCONFIG_EE_BASE_ADDR, (uint8_t *) &app_config, APPCONFIG_SIZE)) {
|
||||
printf("Couldn't read EE to load config!\r\n");
|
||||
load_fallback_config();
|
||||
return;
|
||||
}
|
||||
|
||||
if (app_config.magic2 != APPCONFIG_MAGIC2) {
|
||||
app_config.magic2 = APPCONFIG_MAGIC2;
|
||||
app_config.scheduler_dry_days = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +61,8 @@ void appconfig_save()
|
||||
// printf("PERSISTENCE DISABLED - NOT SAVING\r\n");
|
||||
// return; // FIXME - when all GUIs are finished, add persistence
|
||||
// whatever, just write everything
|
||||
app_config.magic_version = APPCONFIG_VERSION;
|
||||
app_config.magic_version = APPCONFIG_MAGIC1;
|
||||
app_config.magic2 = APPCONFIG_MAGIC2;
|
||||
if (0 > ee_write(APPCONFIG_EE_BASE_ADDR, (const uint8_t *) &app_config, APPCONFIG_SIZE)) {
|
||||
printf("Couldn't write EE!");
|
||||
}
|
||||
|
||||
+16
-13
@@ -13,26 +13,29 @@
|
||||
#define MENU_AUTOEXIT_TIME_S 120
|
||||
|
||||
struct __attribute__((packed)) ScheduleTime {
|
||||
bool enable;
|
||||
uint8_t h;
|
||||
uint8_t m;
|
||||
bool enable; /// True if the schedule time is enabled
|
||||
uint8_t h; /// Hour
|
||||
uint8_t m; /// Minute
|
||||
};
|
||||
|
||||
struct __attribute__((packed)) AppConfig {
|
||||
uint8_t magic_version;
|
||||
uint16_t circuit_base_time_s;
|
||||
uint16_t circuit_time_percent[CIRCUIT_COUNT]; // 0% can be used to disable a branch
|
||||
bool scheduler_enable;
|
||||
struct ScheduleTime schedules[SCHEDULE_COUNT];
|
||||
bool moisture_enable;
|
||||
uint16_t moisture_dry;
|
||||
uint16_t moisture_wet;
|
||||
uint8_t moisture_threshold_percent;
|
||||
uint8_t magic_version; /// Magic (byte reserved)
|
||||
uint16_t circuit_base_time_s; /// Base time for each branch (scaled by percent)
|
||||
uint16_t circuit_time_percent[CIRCUIT_COUNT]; /// Relative time of each branch 0% can be used to disable a branch
|
||||
bool scheduler_enable; /// Enable automatic watering
|
||||
struct ScheduleTime schedules[SCHEDULE_COUNT]; /// Scheduled times in a day
|
||||
bool moisture_enable; /// Enable blocking watering by high soil humidity
|
||||
uint16_t moisture_dry; /// Saved humidity value as 0%
|
||||
uint16_t moisture_wet; /// Saved humidity value as 100%
|
||||
uint8_t moisture_threshold_percent; /// % of soil humidity that deactivates watering
|
||||
uint8_t magic2;
|
||||
uint8_t scheduler_dry_days; /// Days to skip between watering
|
||||
};
|
||||
|
||||
#define APPCONFIG_SIZE sizeof(struct AppConfig)
|
||||
|
||||
#define APPCONFIG_VERSION 0b11100001
|
||||
#define APPCONFIG_MAGIC1 0b11100001
|
||||
#define APPCONFIG_MAGIC2 0b00111001
|
||||
|
||||
extern struct AppConfig app_config;
|
||||
|
||||
|
||||
+14
-6
@@ -9,21 +9,29 @@
|
||||
#include "pinout.h"
|
||||
#include "app_config.h"
|
||||
|
||||
|
||||
void set_relays(bool one, bool two, bool three, bool four)
|
||||
{
|
||||
gpio_put(PIN_RE1, one);
|
||||
gpio_put(PIN_RE2, two);
|
||||
gpio_put(PIN_RE3, three);
|
||||
gpio_put(PIN_RE1, four);
|
||||
gpio_put(PIN_RE4, four);
|
||||
}
|
||||
|
||||
void open_valve(uint8_t num)
|
||||
{
|
||||
gpio_put(PIN_RE1, num == 1);
|
||||
gpio_put(PIN_RE2, num == 2);
|
||||
gpio_put(PIN_RE3, num == 3);
|
||||
gpio_put(PIN_RE4, num == 4);
|
||||
set_relays(num == 1, num == 2, num == 3, num == 4);
|
||||
}
|
||||
|
||||
void set_one_relay(uint8_t num, bool on)
|
||||
{
|
||||
if (num < 1 || num > 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (num == 1) { gpio_put(PIN_RE1, on); }
|
||||
if (num == 2) { gpio_put(PIN_RE2, on); }
|
||||
if (num == 3) { gpio_put(PIN_RE3, on); }
|
||||
if (num == 4) { gpio_put(PIN_RE4, on); }
|
||||
}
|
||||
|
||||
uint16_t moisture_read()
|
||||
|
||||
@@ -13,6 +13,8 @@ void set_relays(bool one, bool two, bool three, bool four);
|
||||
/** Open valve, 1,2,3,4; 0=close all */
|
||||
void open_valve(uint8_t num);
|
||||
|
||||
void set_one_relay(uint8_t num, bool on);
|
||||
|
||||
uint16_t moisture_read();
|
||||
|
||||
uint16_t moisture_convert(uint16_t moisture);
|
||||
|
||||
+6
-3
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* TODO file description
|
||||
* Functions to access the RTC (DS3231)
|
||||
*/
|
||||
|
||||
#include <pico/stdlib.h>
|
||||
@@ -35,11 +35,13 @@ static int rtc_write(uint8_t start, const uint8_t *data, size_t len) {
|
||||
|
||||
int rtc_get_time(struct rtc_time *dest) {
|
||||
int rv;
|
||||
uint8_t buf[3];
|
||||
TRY(rtc_read(0x00, buf, 3));
|
||||
uint8_t buf[4];
|
||||
TRY(rtc_read(0x00, buf, 4));
|
||||
|
||||
dest->second = (buf[0] & 15) + (buf[0] >> 4) * 10;
|
||||
dest->minute = (buf[1] & 15) + (buf[1] >> 4) * 10;
|
||||
dest->weekday = buf[3] & 7;
|
||||
if (dest->weekday > 0) dest->weekday -= 1; // Normalize to 0-6, with failsafe in case we got zero, should not happen.
|
||||
|
||||
if (buf[2] & 0x40) {
|
||||
// 12h time?
|
||||
@@ -60,5 +62,6 @@ int rtc_set_time(const struct rtc_time *time) {
|
||||
buf[2] = (time->hour % 10) + ((time->hour / 10) << 4);
|
||||
|
||||
TRY(rtc_write(0x00, buf, 3));
|
||||
// just let the week counter go on its own - we only care about it incrementing
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ struct rtc_time {
|
||||
uint8_t hour;
|
||||
uint8_t minute;
|
||||
uint8_t second;
|
||||
uint8_t weekday; // 0-6, We use this as a counter for dry days
|
||||
};
|
||||
|
||||
int rtc_get_time(struct rtc_time *dest);
|
||||
|
||||
+81
-5
@@ -28,12 +28,54 @@ static void draw_common_overlay();
|
||||
//stratch string buffer
|
||||
char sbuf[100];
|
||||
|
||||
void gui_read_moisture() {
|
||||
void gui_read_moisture()
|
||||
{
|
||||
s_app.moisture_pt = moisture_convert(s_app.moisture_raw = moisture_read());
|
||||
}
|
||||
|
||||
static void read_time_and_moisture() {
|
||||
/**
|
||||
* Get days remaining to next watering day
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
uint8_t days_to_next_watering()
|
||||
{
|
||||
if (app_config.scheduler_dry_days == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t wd = s_app.rtc_time.weekday;
|
||||
uint8_t last_wd = s_app.last_watering_day_wd;
|
||||
uint8_t normalized_next = (last_wd + 1 + app_config.scheduler_dry_days) % 7;
|
||||
if (wd > normalized_next) {
|
||||
normalized_next += 7;
|
||||
}
|
||||
return normalized_next - wd;
|
||||
}
|
||||
|
||||
static void read_time_and_moisture()
|
||||
{
|
||||
uint8_t prev_wd = s_app.rtc_time.weekday;
|
||||
rtc_get_time(&s_app.rtc_time); // now is a good time to update timestamp - we could just increment it though
|
||||
|
||||
// decide if today is a watering day
|
||||
if (app_config.scheduler_dry_days == 0) {
|
||||
s_app.today_is_watering_day = true;
|
||||
s_app.last_watering_day_wd = s_app.rtc_time.weekday;
|
||||
} else {
|
||||
uint8_t cur_wd = s_app.rtc_time.weekday;
|
||||
if (cur_wd != prev_wd) {
|
||||
// Weekday change, decide now
|
||||
s_app.today_is_watering_day = false;
|
||||
uint8_t now_normalized = cur_wd + (cur_wd < s_app.last_watering_day_wd ? 7 : 0);
|
||||
uint8_t elapsed_days = now_normalized - s_app.last_watering_day_wd;
|
||||
if (elapsed_days >= app_config.scheduler_dry_days) {
|
||||
s_app.today_is_watering_day = true;
|
||||
s_app.last_watering_day_wd = cur_wd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gui_read_moisture();
|
||||
}
|
||||
|
||||
@@ -44,11 +86,19 @@ void gui_init()
|
||||
|
||||
read_time_and_moisture();
|
||||
|
||||
s_app.today_is_watering_day = true;
|
||||
s_app.last_watering_day_wd = s_app.rtc_time.weekday;
|
||||
|
||||
LcdBuffer_Init(&lcd, CGROM_A00, CGRAM_CZ);
|
||||
}
|
||||
|
||||
static bool blink_state = 0;
|
||||
|
||||
bool is_valve_control_screen()
|
||||
{
|
||||
return s_app.screen == screen_cyklus || s_app.screen == screen_manual_control;
|
||||
}
|
||||
|
||||
void gui_loop_iter(GuiEvent message)
|
||||
{
|
||||
uint32_t tickNow = timestamp_ms();
|
||||
@@ -56,7 +106,7 @@ void gui_loop_iter(GuiEvent message)
|
||||
// Time program logic - since this runs very often, we are guaranteed not to miss a cycle - unless there is a power outage
|
||||
// exactly in the scheduled watering time
|
||||
|
||||
if (s_app.screen != screen_cyklus && app_config.scheduler_enable) {
|
||||
if (!is_valve_control_screen() && app_config.scheduler_enable && (s_app.today_is_watering_day || app_config.scheduler_dry_days == 0)) { // if dry days=0, is_wd should always be true, but making sure here
|
||||
if (s_app.cycle_time_checking) {
|
||||
if (s_app.rtc_time.hour != s_app.last_cycle_time.hour
|
||||
|| s_app.rtc_time.minute != s_app.last_cycle_time.minute) {
|
||||
@@ -88,12 +138,19 @@ void gui_loop_iter(GuiEvent message)
|
||||
}
|
||||
|
||||
// screen auto-close
|
||||
if (s_app.screen != screen_home && s_app.screen != screen_cyklus) {
|
||||
if (s_app.screen != screen_home && !is_valve_control_screen()) {
|
||||
if ((tickNow - s_app.screen_open_time) >= (MENU_AUTOEXIT_TIME_S * 1000)) {
|
||||
switch_screen(screen_home, true);
|
||||
}
|
||||
}
|
||||
|
||||
// exit manual mode after long time
|
||||
if (s_app.screen == screen_manual_control) {
|
||||
if ((tickNow - s_app.screen_open_time) >= (3600 * 1000)) {
|
||||
switch_screen(screen_home, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Read RTC every second
|
||||
if (tickNow - s_app.last_1s_time >= 1000) {
|
||||
s_app.screen(GUI_EVENT_SCREEN_TICK_1S);
|
||||
@@ -154,13 +211,17 @@ void gui_loop_iter(GuiEvent message)
|
||||
|
||||
/** Switch to a different screen handler.
|
||||
* If "init" is true, immediately call it with the init event. */
|
||||
void switch_screen(screen_t pScreen, bool init)
|
||||
static void switch_screen_ex(screen_t pScreen, bool init, bool deinit_current)
|
||||
{
|
||||
if (s_app.screen == pScreen) {
|
||||
// already, no op
|
||||
return;
|
||||
}
|
||||
|
||||
if (s_app.screen && deinit_current) {
|
||||
s_app.screen(GUI_EVENT_SCREEN_DEINIT);
|
||||
}
|
||||
|
||||
s_app.screen_open_time = timestamp_ms();
|
||||
s_app.screen = pScreen;
|
||||
|
||||
@@ -178,6 +239,21 @@ void switch_screen(screen_t pScreen, bool init)
|
||||
}
|
||||
}
|
||||
|
||||
void switch_screen(screen_t pScreen, bool init)
|
||||
{
|
||||
switch_screen_ex(pScreen, init, true);
|
||||
}
|
||||
|
||||
void switch_to_subscreen(screen_t pScreen)
|
||||
{
|
||||
switch_screen_ex(pScreen, true, false);
|
||||
}
|
||||
|
||||
void switch_to_parent_screen(screen_t pScreen)
|
||||
{
|
||||
switch_screen_ex(pScreen, false, true);
|
||||
}
|
||||
|
||||
/** Draw GUI common to all screens */
|
||||
static void draw_common_overlay()
|
||||
{
|
||||
|
||||
+12
-1
@@ -45,6 +45,9 @@ void gui_init();
|
||||
*/
|
||||
void switch_screen(screen_t pScreen, bool init);
|
||||
|
||||
void switch_to_subscreen(screen_t pScreen);
|
||||
void switch_to_parent_screen(screen_t pScreen);
|
||||
|
||||
void request_paint();
|
||||
|
||||
// prototypes for screen handlers
|
||||
@@ -59,6 +62,10 @@ void screen_moisture_calib(GuiEvent event);
|
||||
void screen_delka_zalivky(GuiEvent event);
|
||||
void screen_kompenzace_tlaku(GuiEvent event);
|
||||
void screen_program_prehled(GuiEvent event);
|
||||
void screen_suche_dny(GuiEvent event);
|
||||
void screen_manual_control(GuiEvent event);
|
||||
|
||||
uint8_t days_to_next_watering();
|
||||
|
||||
extern int pgm_edit_slot;
|
||||
void screen_program_edit(GuiEvent event);
|
||||
@@ -66,12 +73,13 @@ void screen_program_edit(GuiEvent event);
|
||||
|
||||
void gui_read_moisture();
|
||||
|
||||
// This is actually the global app state!
|
||||
struct State {
|
||||
struct rtc_time rtc_time;
|
||||
uint16_t moisture_raw;
|
||||
uint16_t moisture_pt;
|
||||
struct rtc_time last_cycle_time;
|
||||
bool cycle_time_checking;
|
||||
bool cycle_time_checking; // This is used to prevent cycle being started again and again during the same minute - it is cleared once the HH:MM time changes.
|
||||
|
||||
/// Repaint was requested from the screen code
|
||||
bool paint_needed;
|
||||
@@ -85,6 +93,9 @@ struct State {
|
||||
|
||||
|
||||
uint32_t screen_open_time;
|
||||
|
||||
bool today_is_watering_day;
|
||||
uint8_t last_watering_day_wd;
|
||||
};
|
||||
|
||||
extern struct State s_app;
|
||||
|
||||
@@ -13,6 +13,8 @@ typedef enum GuiEvent {
|
||||
GUI_EVENT_PAINT,
|
||||
/// Used as the argument when initing a screen
|
||||
GUI_EVENT_SCREEN_INIT,
|
||||
/// Screen is about to close (this will NOT be called for middle pages when auto-closing a multi-level hierarchy!)
|
||||
GUI_EVENT_SCREEN_DEINIT,
|
||||
/// Time tick, used to carry timing to the screen functions.
|
||||
/// This tick has 10ms interval
|
||||
GUI_EVENT_SCREEN_TICK_10MS,
|
||||
|
||||
@@ -82,6 +82,10 @@ void screen_cyklus(GuiEvent event)
|
||||
case GUI_EVENT_KEY_D:
|
||||
end_cycle();
|
||||
switch_screen(screen_home, true);
|
||||
return;
|
||||
break;
|
||||
|
||||
case GUI_EVENT_SCREEN_DEINIT:
|
||||
open_valve(0); // close all - this should not be needed here, this screen does not autoclose.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,12 +38,12 @@ void screen_delka_zalivky(GuiEvent event)
|
||||
case GUI_EVENT_KEY_A: // Confirm
|
||||
if (cursor > 0) {
|
||||
settings_scratch.circuit_base_time_s = value;
|
||||
switch_screen(screen_settings, false);
|
||||
switch_to_parent_screen(screen_settings);
|
||||
}
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_D: // CANCEL
|
||||
switch_screen(screen_settings, false);
|
||||
switch_to_parent_screen(screen_settings);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -49,6 +49,7 @@ void screen_home(GuiEvent event)
|
||||
} else {
|
||||
int found = -1;
|
||||
int first = -1;
|
||||
bool wrapped_around = false;
|
||||
uint16_t m_now = s_app.rtc_time.hour * 60 + s_app.rtc_time.minute;
|
||||
for (int i = 0; i < SCHEDULE_COUNT; i++) {
|
||||
if (!app_config.schedules[i].enable) {
|
||||
@@ -68,27 +69,37 @@ void screen_home(GuiEvent event)
|
||||
|
||||
if (found == -1) {
|
||||
found = first;
|
||||
wrapped_around = true;
|
||||
}
|
||||
|
||||
if (found == -1) {
|
||||
LcdBuffer_Write(&lcd, 1, 0, "Program nenastaven!");
|
||||
LcdBuffer_Write(&lcd, 1, 0, "Program nenastaven! ");
|
||||
} else {
|
||||
snprintf(sbuf, sbuf_len, "Další závlaha %d:%02d ",
|
||||
app_config.schedules[found].h, app_config.schedules[found].m);
|
||||
uint8_t days = days_to_next_watering();
|
||||
if (days > 0 && (!s_app.today_is_watering_day || wrapped_around)) {
|
||||
snprintf(sbuf, sbuf_len, "Další závlaha za %d d", days);
|
||||
} else {
|
||||
snprintf(sbuf, sbuf_len, "Další závlaha %d:%02d ",
|
||||
app_config.schedules[found].h, app_config.schedules[found].m);
|
||||
}
|
||||
LcdBuffer_Write(&lcd, 1, 0, sbuf);
|
||||
}
|
||||
}
|
||||
|
||||
LcdBuffer_Write(&lcd, 2, 0, "🅰Spustit cyklus");
|
||||
LcdBuffer_Write(&lcd, 3, 0, "🅱Nastavení");
|
||||
LcdBuffer_Write(&lcd, 3, 0, "🅱Nastavení 🅳Test");
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_A:
|
||||
switch_screen(screen_cyklus, true); // fake cycle
|
||||
switch_screen(screen_cyklus, true); // manually started cycle
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_B:
|
||||
switch_screen(screen_settings, true);
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_D:
|
||||
switch_screen(screen_manual_control, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,11 +46,11 @@ void screen_kompenzace_tlaku(GuiEvent event)
|
||||
|
||||
case GUI_EVENT_KEY_A: // Confirm
|
||||
memcpy(settings_scratch.circuit_time_percent, ratios, sizeof(settings_scratch.circuit_time_percent));
|
||||
switch_screen(screen_settings, false);
|
||||
switch_to_parent_screen(screen_settings);
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_D: // CANCEL
|
||||
switch_screen(screen_settings, false);
|
||||
switch_to_parent_screen(screen_settings);
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_1:
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
#include <stdio.h>
|
||||
#include "app_gui.h"
|
||||
#include "gui_event.h"
|
||||
#include "app_io.h"
|
||||
#include "lcd.h"
|
||||
|
||||
static int cur_valve = 0;
|
||||
|
||||
void screen_manual_control(GuiEvent event)
|
||||
{
|
||||
int num = 0;
|
||||
switch (event) {
|
||||
case GUI_EVENT_SCREEN_INIT:
|
||||
open_valve(0); // make sure all are closed
|
||||
cur_valve = 0;
|
||||
break;
|
||||
|
||||
case GUI_EVENT_PAINT:
|
||||
LcdBuffer_Write(&lcd, 0, 0, "== MANUÁLNÍ REŽIM ==");
|
||||
LcdBuffer_Write(&lcd, 1, 0, "1-4 ventil,0 vyp.vše");
|
||||
|
||||
//LcdBuffer_SetCursor(&lcd, 2, 0, CURSOR_BOTH);
|
||||
|
||||
snprintf(sbuf, sbuf_len, " %s %s %s %s ",
|
||||
(cur_valve == 1) ? "█1█" : " 1 ",
|
||||
(cur_valve == 2) ? "█2█" : " 2 ",
|
||||
(cur_valve == 3) ? "█3█" : " 3 ",
|
||||
(cur_valve == 4) ? "█4█" : " 4 ");
|
||||
LcdBuffer_Write(&lcd, 2, 0, sbuf);
|
||||
|
||||
LcdBuffer_Write(&lcd, 3, 0, "🅳Konec");
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_D: // CANCEL
|
||||
open_valve(0);
|
||||
switch_screen(screen_home, true);
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_0:
|
||||
cur_valve = 0;
|
||||
open_valve(0);
|
||||
request_paint();
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_1:
|
||||
case GUI_EVENT_KEY_2:
|
||||
case GUI_EVENT_KEY_3:
|
||||
case GUI_EVENT_KEY_4:
|
||||
num = (int) (event - '0');
|
||||
if (cur_valve == num) {
|
||||
cur_valve = 0;
|
||||
open_valve(0);
|
||||
} else {
|
||||
cur_valve = num;
|
||||
open_valve(num);
|
||||
}
|
||||
request_paint();
|
||||
break;
|
||||
|
||||
case GUI_EVENT_SCREEN_DEINIT:
|
||||
open_valve(0); // close all
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -42,12 +42,12 @@ void screen_moisture_calib(GuiEvent event)
|
||||
} else {
|
||||
settings_scratch.moisture_dry = sample_dry;
|
||||
settings_scratch.moisture_wet = s_app.moisture_raw;
|
||||
switch_screen(screen_settings, false);
|
||||
switch_to_parent_screen(screen_settings);
|
||||
}
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_D: // CANCEL
|
||||
switch_screen(screen_settings, false);
|
||||
switch_to_parent_screen(screen_settings);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ void screen_program_edit(GuiEvent event)
|
||||
case GUI_EVENT_KEY_A: // Confirm
|
||||
if (!time.enable || cursor == 4) {
|
||||
memcpy(&settings_scratch.schedules[pgm_edit_slot], &time, sizeof(time));
|
||||
switch_screen(screen_program_prehled, false);
|
||||
switch_to_parent_screen(screen_program_prehled);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -54,7 +54,7 @@ void screen_program_edit(GuiEvent event)
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_D: // CANCEL
|
||||
switch_screen(screen_program_prehled, false);
|
||||
switch_to_parent_screen(screen_program_prehled);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -44,7 +44,7 @@ void screen_program_prehled(GuiEvent event)
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_D: // CANCEL
|
||||
switch_screen(screen_settings, false);
|
||||
switch_to_parent_screen(screen_settings);
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_1:
|
||||
@@ -52,7 +52,7 @@ void screen_program_prehled(GuiEvent event)
|
||||
case GUI_EVENT_KEY_3:
|
||||
case GUI_EVENT_KEY_4:
|
||||
pgm_edit_slot = event - '1'; // 0-3
|
||||
switch_screen(screen_program_edit, true);
|
||||
switch_to_subscreen(screen_program_edit);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,12 +37,12 @@ void screen_set_moisture_threshold(GuiEvent event)
|
||||
case GUI_EVENT_KEY_A: // Confirm
|
||||
if (cursor > 0) {
|
||||
settings_scratch.moisture_threshold_percent = threshold;
|
||||
switch_screen(screen_settings, false);
|
||||
switch_to_parent_screen(screen_settings);
|
||||
}
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_D: // CANCEL
|
||||
switch_screen(screen_settings, false);
|
||||
switch_to_parent_screen(screen_settings);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -32,12 +32,12 @@ void screen_set_time(GuiEvent event)
|
||||
case GUI_EVENT_KEY_A: // Confirm
|
||||
if (cursor == 4) {
|
||||
rtc_set_time(&time);
|
||||
switch_screen(screen_settings, false);
|
||||
switch_to_parent_screen(screen_settings);
|
||||
}
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_D: // CANCEL
|
||||
switch_screen(screen_settings, false);
|
||||
switch_to_parent_screen(screen_settings);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -43,6 +43,8 @@ void screen_settings(GuiEvent event)
|
||||
case 2:
|
||||
LcdBuffer_Write(&lcd, 0, 0, "1. Délka zálivky");
|
||||
LcdBuffer_Write(&lcd, 1, 0, "2. Kompenzace tlaku");
|
||||
snprintf(sbuf, sbuf_len, "3. Suché dny (%d)", settings_scratch.scheduler_dry_days);
|
||||
LcdBuffer_Write(&lcd, 2, 0, sbuf);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
@@ -96,11 +98,11 @@ void screen_settings(GuiEvent event)
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_2: // Upravit program
|
||||
switch_screen(screen_program_prehled, true);
|
||||
switch_to_subscreen(screen_program_prehled);
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_3: // Nastavit cas
|
||||
switch_screen(screen_set_time, true);
|
||||
switch_to_subscreen(screen_set_time);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -108,11 +110,15 @@ void screen_settings(GuiEvent event)
|
||||
case 2:
|
||||
switch (event) {
|
||||
case GUI_EVENT_KEY_1: // Délka zálivky
|
||||
switch_screen(screen_delka_zalivky, true);
|
||||
switch_to_subscreen(screen_delka_zalivky);
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_2: // Kompenzace tlaku
|
||||
switch_screen(screen_kompenzace_tlaku, true);
|
||||
switch_to_subscreen(screen_kompenzace_tlaku);
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_3: // Nastavit suche dny
|
||||
switch_to_subscreen(screen_suche_dny);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -125,11 +131,11 @@ void screen_settings(GuiEvent event)
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_2: // Kalibrace vlhkomeru
|
||||
switch_screen(screen_moisture_calib, true);
|
||||
switch_to_subscreen(screen_moisture_calib);
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_3: // Nastavit prah
|
||||
switch_screen(screen_set_moisture_threshold, true);
|
||||
switch_to_subscreen(screen_set_moisture_threshold);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
#include <stdio.h>
|
||||
#include "app_gui.h"
|
||||
#include "gui_event.h"
|
||||
#include "app_io.h"
|
||||
#include "lcd.h"
|
||||
#include "app_config.h"
|
||||
|
||||
static int value;
|
||||
|
||||
void screen_suche_dny(GuiEvent event)
|
||||
{
|
||||
switch (event) {
|
||||
case GUI_EVENT_SCREEN_INIT:
|
||||
value = settings_scratch.scheduler_dry_days;
|
||||
break;
|
||||
|
||||
case GUI_EVENT_PAINT:
|
||||
LcdBuffer_Write(&lcd, 0, 0, "Vynechat dny mezi");
|
||||
LcdBuffer_Write(&lcd, 1, 0, "auto. zálivkou (0-5)");
|
||||
|
||||
LcdBuffer_SetCursor(&lcd, 2, 0, CURSOR_BOTH);
|
||||
|
||||
snprintf(sbuf, sbuf_len, "%d d", value);
|
||||
LcdBuffer_Write(&lcd, 2, 0, sbuf);
|
||||
|
||||
LcdBuffer_Write(&lcd, 3, 0, "🅳Zrušit 🅰OK");
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_A: // Confirm
|
||||
settings_scratch.scheduler_dry_days = value;
|
||||
switch_to_parent_screen(screen_settings);
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_D: // CANCEL
|
||||
switch_to_parent_screen(screen_settings);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (event >= '0' && event <= '5') {
|
||||
value = (uint8_t) (event - '0');
|
||||
request_paint();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user