Configuration extended and some more LED code improvements

This commit is contained in:
2026-02-03 21:16:51 +01:00
parent 3b6b97011b
commit dcac1f70df
9 changed files with 138 additions and 23 deletions

View File

@@ -41,7 +41,7 @@
"arduino",
"espidf"
],
"name": "OBPkb61 ESP32-S3-N16R8 16 MB QD, 8 MB PSRAM)",
"name": "OBPkp61 ESP32-S3-N16R8 16 MB QD, 8 MB PSRAM)",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 327680,

View File

@@ -35,6 +35,7 @@ struct ConfigDef {
static const ConfigDef configdefs[] = {
{"systemName", ConfigType::STRING, String("OBPkp61")},
{"systemMode", ConfigType::CHAR, 'K'},
{"nightMode", ConfigType::BOOL, false},
{"logLevel", ConfigType::BYTE, uint8_t(4)},
{"adminPassword", ConfigType::STRING, String("obpkp61")},
{"useAdminPass", ConfigType::BOOL, true},
@@ -49,6 +50,8 @@ static const ConfigDef configdefs[] = {
{"cpuSpeed", ConfigType::SHORT, int16_t(160)},
{"ledBrightness", ConfigType::SHORT, int16_t(96)},
{"rgbBrightness", ConfigType::SHORT, int16_t(96)},
{"buzEnable", ConfigType::BOOL, false},
{"buzPower", ConfigType::BYTE, uint8_t(50)},
{"tempFormat", ConfigType::CHAR, 'C'},
{"switchBank", ConfigType::BYTE, uint8_t(0)},
{"key1", ConfigType::BYTE, uint8_t(1)},
@@ -63,6 +66,8 @@ static const ConfigDef configdefs[] = {
{"key5long", ConfigType::BYTE, uint8_t(15)},
{"key6", ConfigType::BYTE, uint8_t(6)},
{"key6long", ConfigType::BYTE, uint8_t(16)},
{"n2kSysInst", ConfigType::BYTE, uint8_t(0)},
{"n2kDevInst", ConfigType::BYTE, uint8_t(0)},
{"n2kDestA", ConfigType::STRING, String("none")},
{"n2kDestB", ConfigType::STRING, String("none")},
{"n2kDestC", ConfigType::STRING, String("none")},

View File

@@ -6,3 +6,4 @@ extern int16_t rgb_brightness;
void led_init();
void led_test();
void led_blink(uint8_t channel, uint8_t count, int16_t brightness, uint32_t interval_ms);
void led_set_mode();

View File

@@ -129,18 +129,24 @@ struct ButtonEvent {
ButtonPressType pressType;
};
extern uint8_t loglevel;
extern Nmea2kTwai &NMEA2000;
extern tN2kDeviceList *pN2kDeviceList;
extern char globalmode;
extern uint8_t loglevel;
extern char mode;
extern char ledmode;
extern char audiomode;
extern char destination;
extern uint64_t chipid;
extern int16_t led_brightness;
extern int16_t rgb_brightness;
// extern int16_t led_brightness;
// extern int16_t rgb_brightness;
extern bool ap_enabled;
extern bool buz_enabled;
extern uint8_t keycode[6];
extern uint8_t longcode[6];
extern float temp;
extern float hum;

View File

@@ -93,3 +93,15 @@ void led_blink(uint8_t channel, uint8_t count, int16_t brightness, uint32_t inte
}
delay(interval_ms);
}
void led_set_mode() {
if (mode == 'C') {
ledcWrite(LEDC_LED_A, ledmode == 'N' ? led_brightness : 0); // Nightmode
ledcWrite(LEDC_LED_B, audiomode == 'D' ? led_brightness : 0); // Silence
ledcWrite(LEDC_LED_C, ap_enabled ? led_brightness : 0); // Accesspoint
} else {
ledcWrite(LEDC_LED_A, destination == 'A' ? led_brightness : 0);
ledcWrite(LEDC_LED_B, destination == 'B' ? led_brightness : 0);
ledcWrite(LEDC_LED_C, destination == 'C' ? led_brightness : 0);
}
}

View File

@@ -39,13 +39,15 @@ uint8_t loglevel = 5;
const char* wifi_ssid = "OBPKP61";
const char* wifi_pass = "keypad61";
bool ap_enabled = false;
bool ap_hidden = false;
bool ap_enabled = true;
unsigned long firstStart = 0;
unsigned long lastSensor = 0;
unsigned long lastPrint = 0;
unsigned long env_interval = 2000;
bool rgb_r = false;
bool rgb_g = false;
bool rgb_b = false;
@@ -58,7 +60,8 @@ RTC_DATA_ATTR char ledmode = 'D'; // (D)ay | (N)ight
RTC_DATA_ATTR char audiomode = 'E'; // (E)nabled | (D)isabled
RTC_DATA_ATTR char destination = 'A'; // A | B | C im RTC-Speicher überlebt deep sleep
uint buzzerpower = 50; // TBD make use of this
bool buz_enabled = true;
uint buzzerpower = 50; // TBD make use of this 0 .. 100%
uint8_t keycode[6]; // configurable keycodes
uint8_t longcode[6]; // configurable keycodes for long pressed keys
@@ -71,6 +74,7 @@ float hum = 0.0;
uint8_t nodeid; // NMEA2000 id on bus
Nmea2kTwai &NMEA2000=*(new Nmea2kTwai(CAN_TX, CAN_RX, CAN_RECOVERY_PERIOD));
tN2kDeviceList *pN2kDeviceList;
uint8_t n2k_id[3] = { 254, 254, 254 }; // aktuelle IDs für dest A, B, C
String processor(const String& var) {
// dummy for now
@@ -261,6 +265,8 @@ void setup() {
String apip = config.getString("apIp");
String apmask = config.getString("apMask");
env_interval = config.getShort("envInterval") * 1000;
// Setup webserver
WiFi.persistent(false);
WiFi.mode(WIFI_MODE_AP);
@@ -293,6 +299,15 @@ void setup() {
// NMEA2000 configuration
// Destinations setup, refresh in loop later
if (config.getString("n2kDestA") == "all") {
// broadcast
} else if (config.getString("n2kDestA") == "none") {
// disabled
} else {
// NAME
}
NMEA2000.SetN2kCANMsgBufSize(8);
NMEA2000.SetN2kCANReceiveFrameBufSize(250);
NMEA2000.SetN2kCANSendFrameBufSize(250);
@@ -492,6 +507,7 @@ void print_n2k_devicelist() {
}
// rename to: void sendSwitchBank()
// later: void send_switchbank(uint8_t keycode, uint8_t dest_id) {
void send_switchbank(uint8_t keycode) {
tN2kMsg N2kMsg;
tN2kBinaryStatus bankstatus;
@@ -505,9 +521,7 @@ void send_switchbank(uint8_t keycode) {
SetN2kPGN127502(N2kMsg, 0, bankstatus);
NMEA2000.SendMsg(N2kMsg);
Serial.print("PGN127502 sent: Switch=");
Serial.print(keycode);
Serial.println(" Action=On");
LOGI(TAG, "PGN127502 sent: Switch=%d", keycode);
}
void send_sensor_temphum(float temp_k, float hum_perc) {
@@ -546,7 +560,7 @@ void loop() {
ledcWrite(LEDC_LED_C, 0);
ledcWrite(LEDC_LED_A, led_brightness);
}
LOGI(TAG, "New destination=%s", destination);
LOGI(TAG, "New destination=%c", destination);
}
} else if (event.pressType == ButtonPressType::LONG) {
shortBeep();
@@ -560,6 +574,7 @@ void loop() {
ledcWrite(LEDC_RGBLED_B, 0);
LOGI(TAG, "Leaving config mode");
}
led_set_mode();
}
} else {
// normal button
@@ -584,29 +599,35 @@ void loop() {
if (ledmode == 'D') {
LOGI(TAG, "Night mode enabled");
ledmode = 'N';
ledcWrite(LEDC_LED_A, led_brightness);
} else {
LOGI(TAG, "Day mode enabled");
ledmode = 'D';
ledcWrite(LEDC_LED_A, 0);
}
break;
case BUTTON_2: // switch audio on/off
if (audiomode == 'E') {
LOGI(TAG, "Disabled audio");
audiomode = 'D';
ledcWrite(LEDC_LED_B, led_brightness);
} else {
LOGI(TAG, "Enabled audio");
audiomode = 'E';
ledcWrite(LEDC_LED_B, 0);
}
break;
case BUTTON_3: // switch accesspoint on/off
if (ap_enabled) {
ESP_LOGI(TAG, "Disable Accesspoint");
LOGI(TAG, "Disable Accesspoint");
WiFi.softAPdisconnect(true);
ap_enabled = false;
ledcWrite(LEDC_LED_C, 0);
} else {
Serial.println("Enable Accesspoint");
LOGI(TAG, "Enable Accesspoint");
WiFi.softAP(wifi_ssid, wifi_pass, WIFI_CHANNEL, ap_hidden, WIFI_MAX_STA);
ap_enabled = true;
ledcWrite(LEDC_LED_C, led_brightness);
}
break;
case BUTTON_4: // reserved
@@ -633,7 +654,7 @@ void loop() {
// NMEA2000.loop(); // not implemented yet
NMEA2000.ParseMessages();
if ((millis() - lastSensor >= 5000) and sht_available) {
if ((millis() - lastSensor >= env_interval) and sht_available) {
lastSensor = millis();
sht.read();
temp = sht.getTemperature(); // °C

View File

@@ -1,10 +1,12 @@
#include "main.h"
#include "config.h"
#include "webserver.h"
#include "led.h"
#include <map>
#include <AsyncTCP.h>
#include <ArduinoJson.h>
#include <esp32/clk.h> // for cpu frequency
#include "esp_rom_uart.h" // for uart wait idle
#include <Update.h>
// Logging
@@ -105,6 +107,7 @@ void webserver_init() {
StaticJsonDocument<1024> doc;
doc["systemName"] = config.getString("systemName");
doc["systemMode"] = String(config.getChar("systemMode"));
doc["nightMode"] = config.getBool("nightMode") ? "true" : "false";
doc["instDesc1"] = config.getString("instDesc1");
doc["instDesc2"] = config.getString("instDesc2");
doc["logLevel"] = loglevel;
@@ -119,10 +122,12 @@ void webserver_init() {
doc["apPassword"] = "********";
doc["stopApTime"] = config.getShort("stopApTime");
doc["apHidden"] = config.getBool("apHidden") ? "true" : "false";
doc["cpuSpeed"] = 160;
doc["cpuSpeed"] = config.getShort("cpuSpeed");
doc["tempFormat"] = String(config.getChar("tempFormat"));
doc["ledBrightness"] = led_brightness;
doc["rgbBrightness"] = rgb_brightness;
doc["ledBrightness"] = config.getShort("ledBrightness");
doc["rgbBrightness"] = config.getShort("rgbBrightness");
doc["buzEnable"] = config.getBool("buzEnable") ? "true" : "false";
doc["buzPower"] = config.getByte("buzPower");
doc["switchBank"] = config.getByte("switchBank");
doc["key1"] = keycode[BUTTON_1];
doc["key2"] = keycode[BUTTON_2];
@@ -136,6 +141,8 @@ void webserver_init() {
doc["key4long"] = longcode[BUTTON_4];
doc["key5long"] = longcode[BUTTON_5];
doc["key6long"] = longcode[BUTTON_6];
doc["n2kSysInst"] = config.getByte("n2kSysInst");
doc["n2kDevInst"] = config.getByte("n2kDevInst");
doc["n2kDestA"] = config.getString("n2kDestA");
doc["n2kDestB"] = config.getString("n2kDestB");
doc["n2kDestC"] = config.getString("n2kDestC");
@@ -145,6 +152,18 @@ void webserver_init() {
request->send(200, "application/json", out);
});
server.on("/api/reset", HTTP_GET, [](AsyncWebServerRequest *request) {
LOGD(TAG, "reset called");
StaticJsonDocument<100> doc;
doc["status"] = "OK";
String out;
serializeJson(doc, out);
request->send(200, "application/json", out);
led_blink(LEDC_RGBLED_G, 3, 4095, 500);
esp_rom_uart_tx_wait_idle(0);
ESP.restart();
});
server.on("/api/resetconfig", HTTP_GET, [](AsyncWebServerRequest *request) {
LOGD(TAG, "resetconfig called");
StaticJsonDocument<100> doc;
@@ -155,7 +174,7 @@ void webserver_init() {
});
server.on("/api/status", HTTP_GET, [](AsyncWebServerRequest *request) {
StaticJsonDocument<200> doc;
StaticJsonDocument<512> doc;
doc["version"] = VERSION;
int cpu_freq = esp_clk_cpu_freq() / 1000000;
doc["cpuspeed"] = String(cpu_freq) + "MHz";
@@ -179,6 +198,9 @@ void webserver_init() {
default:
doc["mode"] = "*unknown*";
}
doc["n2kDestA"] = config.getString("n2kDestA");
doc["n2kDestB"] = config.getString("n2kDestB");
doc["n2kDestC"] = config.getString("n2kDestC");
doc["status"] = "OK";
String out;
serializeJson(doc, out);

View File

@@ -22,6 +22,13 @@
"category": "System"
},
{
"name": "nightMode",
"label": "Night mode",
"type": "boolean",
"default": "false",
"description": "Enable night mode for minimal lighting",
"category": "System"
},{
"name": "logLevel",
"label": "Log level",
"type": "list",
@@ -156,6 +163,27 @@
"description": "The brightness of the rgb status led (0..4095).",
"category": "Hardware"
},
{
"name": "buzEnable",
"label": "Enable buzzer",
"type": "boolean",
"default": "true",
"description": "Enable audio feedback with internal buzzer",
"category": "Hardware"
},
{
"name": "buzPower",
"label": "Buzzer power",
"type": "number",
"default": 50,
"min": 0,
"max": 100,
"description": "The loudness of the buzzer (0..100%)",
"category": "Hardware",
"condition": {
"buzEnable": "true"
}
},
{
"name": "tempFormat",
"label": "Temperature Format",
@@ -336,5 +364,25 @@
"max": 300,
"description": "interval in seconds to send environment data [1..300]",
"category": "NMEA2000"
},
{
"name": "n2kSysInst",
"label": "System instance",
"type": "number",
"default": 0,
"min": 0,
"max": 255,
"description": "The NMEA2000 system instance the device belongs to\nRange [0 .. 255] default 0",
"category": "NMEA2000"
},
{
"name": "n2kDevInst",
"label": "Device instance",
"type": "number",
"default": 0,
"min": 0,
"max": 255,
"description": "The instance number of this device\nRange [0 .. 255] default 0",
"category": "NMEA2000"
}
]

View File

@@ -2,7 +2,7 @@
<html><head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>OBPkeyboard 6/1</title>
<title>OBPkeypad 6/1</title>
<link rel="icon" href="data:,">
<script>
if (!window.isSecureContext) {
@@ -17,7 +17,7 @@ if (!window.isSecureContext) {
</head>
<body>
<div class="main">
<h1 id="headline">OBPkb61</h1>
<h1 id="headline">OBPkp61</h1>
<div class="row">
<span class="label" id="conn_label">disconnected</span>
<span class="value" id="connected"></span>
@@ -66,15 +66,15 @@ if (!window.isSecureContext) {
<div class="row even">
<span class="label">Dest A</span>
<span class="value" id="destA">---</span>
<span class="value" id="n2kDestA">---</span>
</div>
<div class="row">
<span class="label">Dest B</span>
<span class="value" id="destB">---</span>
<span class="value" id="n2kDestB">---</span>
</div>
<div class="row even">
<span class="label">Dest C</span>
<span class="value" id="destC">---</span>
<span class="value" id="n2kDestC">---</span>
</div>
<div class="row">