From 975ba1cd34a6d12b52799a57662da6fee43b7707 Mon Sep 17 00:00:00 2001 From: schinken Date: Tue, 15 Mar 2022 16:29:17 +0100 Subject: [PATCH] Reverted to 6dc7b63a55cf743eea58d5e3cec0df0468b1fe41 --- README.md | 20 +-- configFileHandling.ino | 37 ----- esp8266-geigercounter.ino | 280 +++++++++++++++----------------------- serialCommunication.ino | 81 ----------- settings.h.example | 29 ++++ wifi.h | 4 - 6 files changed, 144 insertions(+), 307 deletions(-) delete mode 100644 configFileHandling.ino delete mode 100644 serialCommunication.ino create mode 100644 settings.h.example delete mode 100644 wifi.h diff --git a/README.md b/README.md index 7e428cd..b97ad96 100644 --- a/README.md +++ b/README.md @@ -8,27 +8,11 @@ Here's some code and schematic to connect your mightyohm.com geiger counter to t ## compile -The firmware can be built and flashed using the Arduino IDE. - -For this, you will need to add ESP8266 support to it by [using the Boards Manager](https://github.com/esp8266/Arduino#installing-with-boards-manager). - -Furthermore, you will also need to install the following libraries using the Library Manager: - -* ArduinoJSON 6.10.1 -* PubSubClient 2.8.0 -* WiFiManager 0.15.0 +To compile this code, just clone or download the master branch as a zip and ramp up your arduino library. For this code to work, you need the SimpleTimer-library (http://playground.arduino.cc/Code/SimpleTimer#Download) and the ESP8266 added to your Arduino-IDE as a board (https://github.com/esp8266/Arduino, see install instructions) ## settings -Since this project is using the WifiManager library, the ESP8266 will open up a WiFi Access Point for its initial configuration -or if it is unable to connect to the previously configured WiFi. - -The library pretends that said WiFi AP requires a captive portal which triggers a notification on recent android phones. -Simply connect to the AP with your phone, tap the "Login required"-notification and you should be able to configure everything. - -## usage - -Since we're using the Home Assistant Autodiscovery feature, everything should just work™. +You need to adjust the settings in the settings.h file. ## license and credits diff --git a/configFileHandling.ino b/configFileHandling.ino deleted file mode 100644 index 193807b..0000000 --- a/configFileHandling.ino +++ /dev/null @@ -1,37 +0,0 @@ -void saveConfig() { - DynamicJsonDocument json(512); - json["mqtt_server"] = mqtt_server; - json["username"] = username; - json["password"] = password; - - File configFile = SPIFFS.open("/config.json", "w"); - if (!configFile) { - return; - } - - serializeJson(json, configFile); - configFile.close(); -} - -void loadConfig() { - if (SPIFFS.begin()) { - - if (SPIFFS.exists("/config.json")) { - File configFile = SPIFFS.open("/config.json", "r"); - - if (configFile) { - const size_t size = configFile.size(); - std::unique_ptr buf(new char[size]); - - configFile.readBytes(buf.get(), size); - DynamicJsonDocument json(512); - - if (DeserializationError::Ok == deserializeJson(json, buf.get())) { - strcpy(mqtt_server, json["mqtt_server"]); - strcpy(username, json["username"]); - strcpy(password, json["password"]); - } - } - } - } -} diff --git a/esp8266-geigercounter.ino b/esp8266-geigercounter.ino index 5323a82..ee2e021 100644 --- a/esp8266-geigercounter.ino +++ b/esp8266-geigercounter.ino @@ -1,207 +1,153 @@ -#include "wifi.h" - #include -#include -#include -#include -#include #include #include +#include +#include #include "settings.h" -uint8_t mqttRetryCounter = 0; - - -WiFiManager wifiManager; WiFiClient wifiClient; PubSubClient mqttClient; - -WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, sizeof(mqtt_server)); -WiFiManagerParameter custom_mqtt_user("user", "MQTT username", username, sizeof(username)); -WiFiManagerParameter custom_mqtt_pass("pass", "MQTT password", password, sizeof(password)); - -unsigned long lastMqttConnectionAttempt = millis(); -const long mqttConnectionInterval = 60000; - -unsigned long statusPublishPreviousMillis = millis(); -const long statusPublishInterval = 30000; - -char identifier[24]; -#define FIRMWARE_PREFIX "esp8266-geigercounter" -#define AVAILABILITY_ONLINE "online" -#define AVAILABILITY_OFFLINE "offline" -char MQTT_TOPIC_AVAILABILITY[128]; -char MQTT_TOPIC_CPM[128]; -char MQTT_TOPIC_USV[128]; - -char MQTT_TOPIC_AUTOCONF_CPM[128]; -char MQTT_TOPIC_AUTOCONF_USV[128]; - SoftwareSerial geigerCounterSerial(PIN_UART_RX, PIN_UART_TX); +SimpleTimer timer; +String serialInput = ""; +char serialInputHelper[RECV_LINE_SIZE]; -bool shouldSaveConfig = false; - -void saveConfigCallback () { - shouldSaveConfig = true; -} +int lastCPM = 0, currentCPM = 0; +float lastuSv = 0, currentuSv = 0; void setup() { + +// power up wait delay(3000); - Serial.begin(9600); - delay(2000); - Serial.println("\n"); - Serial.println("Hello from esp8266-geigercounter"); - Serial.printf("Core Version: %s\n", ESP.getCoreVersion().c_str()); - Serial.printf("Boot Version: %u\n", ESP.getBootVersion()); - Serial.printf("Boot Mode: %u\n", ESP.getBootMode()); - Serial.printf("CPU Frequency: %u MHz\n", ESP.getCpuFreqMHz()); - Serial.printf("Reset reason: %s\n", ESP.getResetReason().c_str()); - - geigerCounterSerial.begin(9600); - - snprintf(identifier, sizeof(identifier), "GEIGERCTR-%X", ESP.getChipId()); - snprintf(MQTT_TOPIC_AVAILABILITY, 127, "%s/%s/status", FIRMWARE_PREFIX, identifier); - snprintf(MQTT_TOPIC_CPM, 127, "%s/%s_cpm/state", FIRMWARE_PREFIX, identifier); - snprintf(MQTT_TOPIC_USV, 127, "%s/%s_usv/state", FIRMWARE_PREFIX, identifier); - - snprintf(MQTT_TOPIC_AUTOCONF_CPM, 127, "homeassistant/sensor/%s/%s_cpm/config", FIRMWARE_PREFIX, identifier); - snprintf(MQTT_TOPIC_AUTOCONF_USV, 127, "homeassistant/sensor/%s/%s_usv/config", FIRMWARE_PREFIX, identifier); - - - - WiFi.hostname(identifier); - - loadConfig(); - setupWifi(); - mqttClient.setServer(mqtt_server, 1883); - mqttClient.setKeepAlive(10); - mqttClient.setBufferSize(2048); - - Serial.print("Hostname: "); - Serial.println(identifier); - Serial.print("\nIP: "); - Serial.println(WiFi.localIP()); - - Serial.println("-- Current GPIO Configuration --"); - Serial.print("PIN_UART_RX: "); - Serial.println(PIN_UART_RX); - - //Disable blue LED - pinMode(LED_BUILTIN, OUTPUT); - digitalWrite(LED_BUILTIN, HIGH); - - mqttReconnect(); -} - - -void loop() { - mqttClient.loop(); - - handleUart(); - if (statusPublishInterval <= (millis() - statusPublishPreviousMillis)) { - statusPublishPreviousMillis = millis(); - updateRadiationValues(); + Serial.begin(115200); + geigerCounterSerial.begin(BAUD_GEIGERCOUNTER); + delay(10); + + WiFi.hostname(WIFI_HOSTNAME); + WiFi.mode(WIFI_STA); + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); + + while (WiFi.status() != WL_CONNECTED) { + Serial.print("."); + delay(500); } - if (!mqttClient.connected() && (mqttConnectionInterval <= (millis() - lastMqttConnectionAttempt)) ) { - lastMqttConnectionAttempt = millis(); - mqttReconnect(); - } -} - -void setupWifi() { - wifiManager.setDebugOutput(false); - wifiManager.setSaveConfigCallback(saveConfigCallback); - - wifiManager.addParameter(&custom_mqtt_server); - wifiManager.addParameter(&custom_mqtt_user); - wifiManager.addParameter(&custom_mqtt_pass); - - WiFi.hostname(identifier); - wifiManager.autoConnect(identifier); mqttClient.setClient(wifiClient); + mqttClient.setServer(MQTT_HOST, 1883); + + ArduinoOTA.setHostname(WIFI_HOSTNAME); + ArduinoOTA.setPassword(OTA_PASSWORD); + ArduinoOTA.begin(); - strcpy(mqtt_server, custom_mqtt_server.getValue()); - strcpy(username, custom_mqtt_user.getValue()); - strcpy(password, custom_mqtt_pass.getValue()); + timer.setInterval(UPDATE_INTERVAL_SECONDS * 1000L, updateRadiationValues); +} - if (shouldSaveConfig) { - saveConfig(); - } else { - //For some reason, the read values get overwritten in this function - //To combat this, we just reload the config - //This is most likely a logic error which could be fixed otherwise - loadConfig(); +void updateRadiationValues() { + + + char tmp[8]; + + if (currentCPM != lastCPM) { + String(currentCPM).toCharArray(tmp, 8); + Serial.print("Sending CPM"); + Serial.println(tmp); + mqttClient.publish(MQTT_TOPIC_CPM, tmp, true); } + + if (currentuSv != lastuSv) { + String(currentuSv).toCharArray(tmp, 8); + Serial.print("Sending uSv"); + Serial.println(tmp); + mqttClient.publish(MQTT_TOPIC_USV, tmp, true); + } + + lastCPM = currentCPM; + lastuSv = currentuSv; } -void resetWifiSettingsAndReboot() { - wifiManager.resetSettings(); - delay(3000); - ESP.restart(); -} +void connectMqtt() { -void mqttReconnect() { - for (int attempt = 0; attempt < 3; ++attempt) { - if (mqttClient.connect(identifier, username, password, MQTT_TOPIC_AVAILABILITY, 1, true, AVAILABILITY_OFFLINE)) { - mqttClient.publish(MQTT_TOPIC_AVAILABILITY, AVAILABILITY_ONLINE, true); - - Serial.println("Connected to MQTT Server"); - - publishAutoConfig(); - break; + while (!mqttClient.connected()) { + if (mqttClient.connect(WIFI_HOSTNAME, MQTT_TOPIC_LAST_WILL, 1, true, "disconnected")) { + mqttClient.publish(MQTT_TOPIC_LAST_WILL, "connected", true); } else { - Serial.println("Failed to connect to MQTT Server :("); - delay(5000); + delay(1000); } } + } -boolean isMqttConnected() { - return mqttClient.connected(); +void parseReceivedLine(char* input) { + + char segment = 0; + char *token; + + float uSv = 0; + float cpm = 0; + + token = strtok(input, delimiter); + + while (token != NULL) { + + switch (segment) { + + // This is just for validation + case IDX_CPS_KEY: if (strcmp(token, "CPS") != 0) return; break; + case IDX_CPM_KEY: if (strcmp(token, "CPM") != 0) return; break; + case IDX_uSv_KEY: if (strcmp(token, "uSv/hr") != 0) return; break; + + case IDX_CPM: + Serial.printf("Current CPM: %s\n", token); + cpm = String(token).toInt(); + break; + + case IDX_uSv: + Serial.printf("Current uSv/hr: %s\n", token); + uSv = String(token).toFloat(); + break; + } + + if (segment > 7) { + // Invalid! There should be no more than 7 segments + return; + } + + token = strtok(NULL, delimiter); + segment++; + } + + currentuSv = uSv; + currentCPM = cpm; } -void publishAutoConfig() { - char mqttPayload[2048]; - DynamicJsonDocument device(256); - StaticJsonDocument<64> identifiersDoc; - JsonArray identifiers = identifiersDoc.to(); +void loop() { - identifiers.add(identifier); + connectMqtt(); + timer.run(); + mqttClient.loop(); - device["identifiers"] = identifiers; - device["manufacturer"] = "MightyOhm LLC"; - device["model"] = "Geiger Counter"; - device["name"] = identifier; - device["sw_version"] = "0.0.1"; + if (geigerCounterSerial.available()) { + char in = (char) geigerCounterSerial.read(); + serialInput += in; - DynamicJsonDocument cpmSensorPayload(512); + if (in == '\n') { + serialInput.toCharArray(serialInputHelper, RECV_LINE_SIZE); + parseReceivedLine(serialInputHelper); - cpmSensorPayload["device"] = device.as(); - cpmSensorPayload["availability_topic"] = MQTT_TOPIC_AVAILABILITY; - cpmSensorPayload["state_topic"] = MQTT_TOPIC_CPM; - cpmSensorPayload["name"] = identifier + String(" CPM"); - cpmSensorPayload["unit_of_measurement"] = "CPM"; - cpmSensorPayload["unique_id"] = identifier + String("_cpm"); + serialInput = ""; + } - serializeJson(cpmSensorPayload, mqttPayload); - mqttClient.publish(MQTT_TOPIC_AUTOCONF_CPM, mqttPayload, true); + // Just in case the buffer gets to big, start from scratch + if (serialInput.length() > RECV_LINE_SIZE + 10) { + serialInput = ""; + } - DynamicJsonDocument usvSensorPayload(512); + Serial.write(in); + } - usvSensorPayload["device"] = device.as(); - usvSensorPayload["availability_topic"] = MQTT_TOPIC_AVAILABILITY; - usvSensorPayload["state_topic"] = MQTT_TOPIC_USV; - usvSensorPayload["name"] = identifier + String(" uSv"); - usvSensorPayload["unit_of_measurement"] = "µSv/h"; - usvSensorPayload["unique_id"] = identifier + String("_uSv"); - - serializeJson(usvSensorPayload, mqttPayload); - mqttClient.publish(MQTT_TOPIC_AUTOCONF_USV, mqttPayload, true); - - Serial.println("Published MQTT Autoconf"); + ArduinoOTA.handle(); } diff --git a/serialCommunication.ino b/serialCommunication.ino deleted file mode 100644 index 1115a73..0000000 --- a/serialCommunication.ino +++ /dev/null @@ -1,81 +0,0 @@ - -const char* delimiter = ", "; -int lastCPM = 0, currentCPM = 0; -float lastuSv = 0, currentuSv = 0; - -byte serialRxBuf[255]; - - - -void handleUart() { - if (geigerCounterSerial.available()) { - geigerCounterSerial.readBytesUntil('\n', serialRxBuf, 250); - - parseReceivedLine((char*)serialRxBuf); - } -} - -void parseReceivedLine(char* input) { - Serial.println(input); - - char segment = 0; - char *token; - - float uSv = 0; - float cpm = 0; - - token = strtok(input, delimiter); - - while (token != NULL) { - - switch (segment) { - - // This is just for validation - case IDX_CPS_KEY: if (strcmp(token, "CPS") != 0) return; break; - case IDX_CPM_KEY: if (strcmp(token, "CPM") != 0) return; break; - case IDX_uSv_KEY: if (strcmp(token, "uSv/hr") != 0) return; break; - - case IDX_CPM: - //Serial.printf("\nCurrent CPM: %s\n", token); - cpm = String(token).toInt(); - break; - - case IDX_uSv: - //Serial.printf("Current uSv/hr: %s\n", token); - uSv = String(token).toFloat(); - break; - } - - if (segment > 7) { - // Invalid! There should be no more than 7 segments - return; - } - - token = strtok(NULL, delimiter); - segment++; - } - - currentuSv = uSv; - currentCPM = cpm; -} - -void updateRadiationValues() { - char tmp[8]; - - if (currentCPM != lastCPM) { - String(currentCPM).toCharArray(tmp, 8); - Serial.print("Sending CPM: "); - Serial.println(tmp); - mqttClient.publish(MQTT_TOPIC_CPM, tmp, true); - } - - if (currentuSv != lastuSv) { - String(currentuSv).toCharArray(tmp, 8); - Serial.print("Sending uSv: "); - Serial.println(tmp); - mqttClient.publish(MQTT_TOPIC_USV, tmp, true); - } - - lastCPM = currentCPM; - lastuSv = currentuSv; -} diff --git a/settings.h.example b/settings.h.example new file mode 100644 index 0000000..5ea0d47 --- /dev/null +++ b/settings.h.example @@ -0,0 +1,29 @@ +#define IDX_CPS_KEY 0 +#define IDX_CPM_KEY 2 +#define IDX_uSv_KEY 4 + +#define IDX_CPM 3 +#define IDX_uSv 5 +#define IDX_MODE 6 + +#define RECV_LINE_SIZE 37 + +#define PIN_UART_RX 0 // 4 +#define PIN_UART_TX 13 // UNUSED + +#define UPDATE_INTERVAL_SECONDS 300L + +#define BAUD_GEIGERCOUNTER 9600 + +const char* HOSTNAME = "ESP-GeigerCounter"; +const char* WIFI_SSID = "----"; +const char* WIFI_PASSWORD = "----"; + +const char* OTA_PASSWORD = "foobar"; + +#define MQTT_TOPIC_CPM "sensor/radiation/cpm" +#define MQTT_TOPIC_USV "sensor/radiation/uSv" +#define MQTT_TOPIC_LAST_WILL "state/sensor/geigercounter" + +const char* mqttHost = "mqtt.core.bckspc.de"; +const char* delimiter = ", "; diff --git a/wifi.h b/wifi.h deleted file mode 100644 index ee33cb3..0000000 --- a/wifi.h +++ /dev/null @@ -1,4 +0,0 @@ -char mqtt_server[80] = "example.tld"; - -char username[24] = ""; -char password[24] = "";