diff --git a/boards/esp32_s3_nano.json b/boards/esp32_s3_nano.json index 8dcd3e6..415b397 100644 --- a/boards/esp32_s3_nano.json +++ b/boards/esp32_s3_nano.json @@ -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, diff --git a/include/config.h b/include/config.h index edb19c2..b2286a1 100644 --- a/include/config.h +++ b/include/config.h @@ -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")}, diff --git a/include/led.h b/include/led.h index 1a57cfa..21556df 100644 --- a/include/led.h +++ b/include/led.h @@ -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(); diff --git a/include/main.h b/include/main.h index 3fe59e2..5b4c993 100644 --- a/include/main.h +++ b/include/main.h @@ -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; - diff --git a/src/led.cpp b/src/led.cpp index 963d18e..e25f45f 100644 --- a/src/led.cpp +++ b/src/led.cpp @@ -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); + } +} diff --git a/src/main.cpp b/src/main.cpp index 1dec41b..e498d2b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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 diff --git a/src/webserver.cpp b/src/webserver.cpp index c102f61..cf67842 100644 --- a/src/webserver.cpp +++ b/src/webserver.cpp @@ -1,10 +1,12 @@ #include "main.h" #include "config.h" #include "webserver.h" +#include "led.h" #include #include #include #include // for cpu frequency +#include "esp_rom_uart.h" // for uart wait idle #include // 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); diff --git a/web/config.json b/web/config.json index 8070120..a2d618f 100644 --- a/web/config.json +++ b/web/config.json @@ -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" } ] diff --git a/web/index.html b/web/index.html index 6b595c9..cd445f5 100644 --- a/web/index.html +++ b/web/index.html @@ -2,7 +2,7 @@ -OBPkeyboard 6/1 +OBPkeypad 6/1