2025-12-1205

This commit is contained in:
2025-12-11 01:19:39 +01:00
parent d57d91e83e
commit c2af9db648
11 changed files with 628 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

10
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,10 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}

39
include/README Normal file
View File

@@ -0,0 +1,39 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

34
include/mess_Ub.h Normal file
View File

@@ -0,0 +1,34 @@
const float MinimalSpannung = 3.20;
float korectur = 1;
float getBattery(float ref = 0.00945)
{
float valA0 = analogRead(A0) * ref;
Serial.print("Batterie:\t");
Serial.print(valA0,4);
Serial.print(" V\n");
return valA0;
}
float readKorectur(){
float korectur;
File k = LittleFS.open("/kor.txt", "r");
if(!k){
//Serial.println("file open failed");
korectur = 0.01;
}else{
String data = k.readString();
korectur = data.toFloat();
k.close();
}
return korectur;
}
void saveKorektur(){
File k = LittleFS.open("/kor.txt", "w");
if(!k){
Serial.println("file open failed");
}else{
k.println(String(korectur,8));
k.close();
}
}

69
include/mess_bme280.h Normal file
View File

@@ -0,0 +1,69 @@
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme; // I2C
struct {
char temperature[15] = {0};
char pressure[15] = {0};
char approx_altitud[15] = {0};
char humity[15] = {0};
} BME280Data;
void Init_BME280(){
bool status = bme.begin();
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
}
void read_BME_280() {
Serial.print("Temperature:\t\t");
float t = bme.readTemperature();
dtostrf(t,10,4,BME280Data.temperature);
Serial.print(BME280Data.temperature);
Serial.println(" °C");
//Serial.print("Diff zu DS1820 \t\t");Serial.print(t-valTemp,4); Serial.println(" °C");
Serial.print("Humidity:\t\t");
float h = bme.readHumidity();
dtostrf(h,8,2,BME280Data.humity);
Serial.print(BME280Data.humity);
Serial.println(" %");
Serial.print("Pressure:\t\t");
float p = bme.readPressure() / 100.0F;
p = p + 22;
dtostrf(p,5,0,BME280Data.pressure);
Serial.print(BME280Data.pressure);
Serial.println(" hPa");
Serial.print("Approx. Altitude:\t");
float a = bme.readAltitude(SEALEVELPRESSURE_HPA);
dtostrf(a,5,0,BME280Data.approx_altitud);
Serial.print(BME280Data.approx_altitud);
Serial.println(" m über NN");
Serial.println();
}
void M2M_BME280(long deviceId = 4711) {
char topic[100];
sprintf(topic, "%s%ld%s", "hjk/devices/", deviceId, "/telemetry/temperature_BME_280" );
client.publish(topic, BME280Data.temperature, true);
sprintf(topic, "%s%ld%s", "hjk/devices/", deviceId, "/telemetry/pressure" );
client.publish(topic, BME280Data.pressure, true);
sprintf(topic, "%s%ld%s", "hjk/devices/", deviceId, "/telemetry/humity" );
client.publish(topic, BME280Data.humity, true);
sprintf(topic, "%s%ld%s", "hjk/devices/", deviceId, "/telemetry/approx_altitude" );
client.publish(topic, BME280Data.approx_altitud);
//
//delay(500);
}

29
include/mess_htu21.h Normal file
View File

@@ -0,0 +1,29 @@
#include "Adafruit_HTU21DF.h"
const float No_Valhtu = 999.99;
struct {
char temperature[15] = {0};
char humity[15] = {0};
float Temp = No_Valhtu;
float Feuchte = No_Valhtu;
} htu21Data;
Adafruit_HTU21DF htu = Adafruit_HTU21DF();
void init_HTU21(){
if (!htu.begin()) {
Serial.println("Couldn't find sensor HUT21D!");
while (1);
}
Serial.println("HUT21D gefunden");
}
void read_HTU21D() {
htu21Data.Temp = htu.readTemperature();
htu21Data.Feuchte = htu.readHumidity();
//htu21Data.Temp = htu21Data.Temp + HTU_Korrectur;
//htu21Data.Feuchte = htu21Data.Feuchte + HTUKorrekturFeuchte;
Serial.printf("HTU21D: Temperarur Innen %3.2f °C und\n Luftfeuchtigkeit %3.2f %%\n\n", htu21Data.Temp, htu21Data.Feuchte );
}

64
include/mess_mcp9808.h Normal file
View File

@@ -0,0 +1,64 @@
#include <Arduino.h>
/* Daten:
* Temperaturbereich -40 bis 125°C
* Genauigkeit: ± 0,25°C
* Auflösung: 0,0625°C
*/
#include <Wire.h>
#include "Adafruit_MCP9808.h"
float valTemp;
// Create MCP9808 temperature sensor object
Adafruit_MCP9808 tempsensor = Adafruit_MCP9808();
char Temperature[15] = {0};
void init_MCP9808(){
// Make sure the sensor is found, you can also pass in a different i2c
// address with tempsensor.begin(0x19) for example, also can be left in blank for default address use
// Also there is a table with all addres possible for this sensor, you can connect multiple sensors
// to the same i2c bus, just configure each sensor with a different address and define multiple objects for that
// A2 A1 A0 address
// 0 0 0 0x18 this is the default address
// 0 0 1 0x19
// 0 1 0 0x1A
// 0 1 1 0x1B
// 1 0 0 0x1C
// 1 0 1 0x1D
// 1 1 0 0x1E
// 1 1 1 0x1F
if (!tempsensor.begin(0x18)) {
Serial.println("Couldn't find MCP9808! Check your connections and verify the address is correct.");
datenSave(-20);
while (1);
}
Serial.println("Found MCP9808!");
tempsensor.setResolution(3); // sets the resolution mode of reading, the modes are defined in the table bellow:
// Mode Resolution SampleTime
// 0 0.5°C 30 ms
// 1 0.25°C 65 ms
// 2 0.125°C 130 ms
// 3 0.0625°C 250 ms
}
float getTemperature_MCP9808(){
// Wake up MSP9808 - power consumption ~200 mikro Ampere
tempsensor.wake();
float temperature = tempsensor.readTempC();
tempsensor.shutdown();
dtostrf(temperature,10,4,Temperature);
Serial.print("Temperatur:\t\t");
Serial.print(Temperature);
Serial.println(" °C");
tempsensor.shutdown_wake(1); // shutdown MSP9808 - power consumption ~0.1 mikro Ampere, stops temperature sampling
return temperature;
}
void M2M_Temperatur_MCP9808(long deviceId = 4711) {
char topic[100];
dtostrf(valTemp,10,4,Temperature);
sprintf(topic, "%s%ld%s", "hjk/devices/", deviceId, "/telemetry/temperature" );
client.publish(topic, Temperature, true);
//delay(500);
}

46
lib/README Normal file
View File

@@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.
The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

32
platformio.ini Normal file
View File

@@ -0,0 +1,32 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:nodemcuv2]
platform = espressif8266
board = nodemcuv2
framework = arduino
monitor_speed = 115200
monitor_port = /dev/ttyUSB0
upload_port = /dev/ttyUSB0
monitor_filters = time
lib_deps =
knolleary/PubSubClient @ 2.8
adafruit/Adafruit MCP9808 Library @ 1.1.2
adafruit/Adafruit BME280 Library @ 2.1.2
adafruit/Adafruit HTU21DF Library @ 1.0.5
build_flags =
-DHTU_Korrectur=-0.55
-DBME_Korrectur=-0.00
-DKorrekturLuftdruck=0.00
-DHTUKorrekturFeuchte=0.00
-DBME_KorrekturFeuchte=0.00
-DAKKU_GREZWERT=2.950

289
src/main.cpp Normal file
View File

@@ -0,0 +1,289 @@
#include <Arduino.h>
#include <FS.h> //this needs to be first, or it all crashes and burns...
#include <LittleFS.h>
#define TEST
#define MaxErrCount 30
#define I2C_SCL D1 // I2C BMP 180
#define I2C_SDA D2 // WeMOS D1 Mini D1 --> 4, D2 --> 5
#define BUILTIN_LED D4
#include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino
#include <PubSubClient.h>
#include <Ticker.h>
void flip();
void reconnect();
void setup_wifi();
void datenSave(int wert);
int readDaten();
WiFiClient espClient;
PubSubClient client(espClient);
Ticker blink;
void callback(char* topic1, byte* payload, unsigned int length);
#include "mess_htu21.h"
#include "mess_Ub.h"
const char* ssid = "MagentaWLAN-RGDO";
const char* password = "93329248424922704583";
//boris
//13.April13
//const char* mqtt_server = "192.168.2.87";
/* const char* mqtt_server = "91.36.199.250";
const char* mqtt_user = "boris";
const char* mqtt_password = "13.April13"; */
const char* mqtt_server = "hjkmqtt.dedyn.io";
#ifdef TEST
//onst char* ssid = "FRITZ!Box7362SL";
//const char* ssid = "Redmi-Note-11";
//const char* password = "BorisundEva2007";
//const char* password = "51Fische#";
IPAddress ip( 192, 168, 2, 199 );
IPAddress gateway( 192, 168, 2, 1 );
IPAddress subnet( 255, 255, 255, 0 );
IPAddress dns(192, 168, 2, 1); // DNS-Server
#else
const char* ssid = "WLAN-7QHHAK";
const char* password = "3557919930817586";
IPAddress ip( 192, 168, 127, 212 );
IPAddress gateway( 192, 168, 127, 1 );
IPAddress subnet( 255, 255, 255, 0 );
IPAddress dns(192, 168, 127, 1); // DNS-Server
#endif
const unsigned long interval = 1 * 60000000UL; // Minuten * Mikrosekunden für Sleep Mode
const unsigned long intervalLowBatt = 10 * 60000000UL; // Minuten * Mikrosekunden für Sleep Mode, Akku entladen
const unsigned long stoerung = 1 * 60000000UL; // Minuten * Mikrosekunden für Sleep Mode
unsigned long previousMillis = 0;
long deviceId;
char sID[16];
char clientName[30];
unsigned long startTime;
unsigned long endTime;
char topic[100];
char topic_1[50];
char topicWert[20];
char msg[20];
int SystemStatus;
void flip(){
int state = digitalRead(LED_BUILTIN);
digitalWrite(LED_BUILTIN, !state);
}
void setup() {
startTime = millis();
String Error;
Serial.begin(115200);
WiFi.mode( WIFI_OFF );
WiFi.forceSleepBegin();
delay( 10 );
if (!LittleFS.begin()) {
Serial.println("LittleFS mount failed");
return;
}
Serial.println(); Serial.println(); Serial.println();
korectur = readKorectur();
Serial.print("Korektur:\t"); Serial.println(korectur,8);
pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an output
digitalWrite(BUILTIN_LED, LOW);
Serial.print("STATUS (Systemmeldung): "); Serial.println(SystemStatus);
//init_MCP9808();
//Init_BME280();
init_HTU21();
Serial.println(" "); Serial.println(" "); Serial.println(" ");
//read_BME_280();
//valTemp = getTemperature_MCP9808();
setup_wifi();
// ---------------------------------
// Status ändern !!! 0
datenSave(0);
// ---------------------------------
digitalWrite(BUILTIN_LED, HIGH);
deviceId = ESP.getChipId();
sprintf(sID, "%010ld", deviceId);
Serial.print("ID: \t\t"); Serial.println(deviceId);
client.setServer(mqtt_server, 61883);
client.setCallback(callback);
}
void callback(char* topic1, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic1);
Serial.print("] ");
for (unsigned int i = 0; i < length; i++) {
msg[i] = (char)payload[i];
}
msg[length] = '\0';
Serial.println(msg);
if(strcmp(topic1, topic_1)== 0){
// Serial.print(msg); Serial.println();
korectur = atof(msg);
Serial.print("Korektur:\t");Serial.println(korectur, 4);
saveKorektur();
}
}
void reconnect() {
unsigned long Pause = 0;
unsigned long ErrLoop = 0;
sprintf(clientName, "%s%s", "ESP8266Client", sID );
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
// If you do not want to use a username and password, change next line to
// if (client.connect("ESP8266Client")) {
//if (client.connect(clientName, mqtt_user, mqtt_pass)) {
if (client.connect(clientName)) {
Serial.println("connected");
sprintf(topic_1, "%s%ld%s", "hjk/devices/", deviceId, "/telemetry/korektur" );
client.subscribe(topic_1);
blink.detach();
digitalWrite(LED_BUILTIN, HIGH);
// sprintf(topic, "%s%ld%s", "hjk/devices/", deviceId, "/telemetry/ID" );
// client.publish(topic, sID);
} else {
ErrLoop ++;
blink.attach(0.8, flip);
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
if (ErrLoop >= 10){
// ---------------------------------
// Status ändern !!! -3
datenSave(-3);
// ---------------------------------
endTime = millis();
Pause = stoerung -((endTime - startTime) * 1000); // Pause ca. 15 Minuten
Serial.print("Ich gehe für "); Serial.print(Pause); Serial.println( " µs schlafen.");
ESP.deepSleep(Pause, WAKE_RF_DISABLED); // Pause
delay(500);
}
}
}
}
void setup_wifi() {
long ErrCount = 0;
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.print(ssid);
Serial.print(" ");
WiFi.forceSleepWake();
delay( 1 );
WiFi.persistent( false );
WiFi.mode( WIFI_STA );
//WiFi.config( ip, dns, gateway, subnet );
//WiFi.begin( WLAN_SSID, WLAN_PASSWD );
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
ErrCount ++;
if (ErrCount >= MaxErrCount){
// ---------------------------------
// Status ändern !!! -1
datenSave(-1);
// ---------------------------------
endTime = millis();
unsigned long Pause = stoerung -((endTime - startTime) * 1000); // Pause
ESP.deepSleep(Pause); // Pause
delay(100);
}
}
Serial.println(" WiFi connected");
Serial.print("IP address: \t");
Serial.println(WiFi.localIP());
}
void loop() {
// put your main code here, to run repeatedly:
unsigned long Pause = 0;
if (!client.connected()) {
reconnect();
}
client.loop();
int currentMillis = millis();
if (currentMillis - previousMillis >= 10000) {
previousMillis = currentMillis;
float valA00 = getBattery(korectur);
read_HTU21D();
valA00 = htu21Data.Temp;
dtostrf(valA00, 8, 2, msg);
sprintf(topic, "%s%ld%s", "hjk/devices/", deviceId, "/telemetry/battery" );
client.publish(topic, msg, true);
//sprintf(topic, "%s%ld%s", "hjk/devices/", deviceId, "/telemetry/status" );
sprintf(topic, "%s%ld%s", "hjk/devices/", deviceId, "/telemetry/temp" );
dtostrf(htu21Data.Temp, 8, 2, htu21Data.temperature);
client.publish(topic, htu21Data.temperature, true);
Serial.printf("R1 %3.3f R2 %s\n", htu21Data.Temp, htu21Data.temperature);
// sprintf(topic, "%s%ld%s", "hjk/devices/", deviceId, "/telemetry/status" );
// sprintf(topicWert,"%d",SystemStatus);
// client.publish(topic, topicWert, true);
//M2M_Temperatur_MCP9808(deviceId);
//M2M_BME280(deviceId);
delay(5000);
endTime = millis();
if(Pause <=0){
Pause = 1;
}
delay(5000);
Pause = interval;
Serial.print("Ich gehe für ca."); Serial.print(Pause/1000/1000); Serial.println( " sek schlafen.");
ESP.deepSleep(Pause, WAKE_RF_DISABLED); // Pause
delay(500);
}
}
void datenSave(int wert){
File k = LittleFS.open("/status.txt", "w");
if(!k){
Serial.println("file open failed");
}
k.println(wert);
k.close();
}
int readDaten()
{
int Error;
File k = LittleFS.open("/status.txt", "r");
if(!k){
Serial.println("file open failed");
Error = -10;
}else{
String data = k.readString();
Error = data.toInt();
k.close();
}
return Error;
}

11
test/README Normal file
View File

@@ -0,0 +1,11 @@
This directory is intended for PlatformIO Unit Testing and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/page/plus/unit-testing.html