2025-03-2505

This commit is contained in:
2025-03-25 18:52:17 +01:00
commit cf0d29ba2c
19 changed files with 1706 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"
]
}

4
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,4 @@
{
"C_Cpp.errorSquiggles": "Disabled",
"cmake.configureOnOpen": true
}

View File

@ -0,0 +1,9 @@
{
"folders": [
{
"name": "Gross_Display",
"path": "."
}
],
"settings": {}
}

1
data/error.dat Normal file
View File

@ -0,0 +1 @@
0

96
include/CO2.h Normal file
View File

@ -0,0 +1,96 @@
#include <Arduino.h>
#include <HardwareSerial.h>
HardwareSerial Co2Port(1); // use UART2
// co2 Grenzwerte
/* #define CO2_WARN_1 650
#define CO2_WARN_2 950
#define CO2_WARN_3 1250
#define CO2_WARN_4 1500
#define CO2_CRITICAL_PPM 1850 */
#define CO2_WARN_1 600
#define CO2_WARN_2 800
#define CO2_WARN_3 1000
#define CO2_WARN_4 1500
#define CO2_WARN_5 2000
#define CO2_CRITICAL_PPM 1850
int CO2Wert = -99;
char antwort[100] = {0xFF};
int range =2000;
bool readCo2Flag;
char getCheckSum(char *packet)
{
char i, checksum;
for (i = 1; i < 8; i++)
{
checksum += packet[i];
}
checksum = 0xFF - checksum;
return checksum +1;
}
int readCO2() {
char cmd[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
Co2Port.write(cmd,9);
if(Co2Port.available()) {
Co2Port.readBytes(antwort, 9);
}
#ifdef DebugCO2
for (int a=0; a<9; a++){
Serial.printf(" BufferRead [%d] = 0x%02X \n", a, antwort[a]);
}
Serial.println();
#endif
if (antwort[0] != 0xFF) return -1;
if (antwort[1] != 0x86) return -2;
int antwortHigh = (int) antwort[2]; // CO2 High Byte
int antwortLow = (int) antwort[3]; // CO2 Low Byte
int ppm = (256 * antwortHigh) + antwortLow;
Co2Port.flush();
return ppm;
}
void calibrationCo2() {
char cmd[9] = {0xFF, 0x01, 0x79, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00};
cmd[8] = getCheckSum(cmd);
Serial.printf("Checksumme = 0x%02X\n", cmd[8]);
Co2Port.write(cmd,9);
#ifdef DebugCO2
for (int a=0; a<9; a++){
Serial.printf(" BufferCalibration [%d] = 0x%02X \n", a, cmd[a]);
}
Serial.println();
#endif
}
void setRange()
{
char cmd[9] = {0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
cmd[6] = range >> 8;
cmd[7] = range & 0xFF;
cmd[8] = getCheckSum(cmd);
Serial.printf("Checksumme = 0x%02X\n", cmd[8]);
Co2Port.write(cmd,9);
#ifdef DebugCO2
for (int a=0; a<9; a++){
Serial.printf(" BufferRange [%d] = 0x%02X \n", a, cmd[a]);
}
Serial.println();
#endif
}
void beginC02()
{
Co2Port.begin(9600, SERIAL_8N1, 32, 33);
readCo2Flag = false;
delay(100);
calibrationCo2();
delay(100);
setRange();
delay(100);
}

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

31
include/error.h Normal file
View File

@ -0,0 +1,31 @@
#include <Arduino.h>
#include <EEPROM.h>
#define AkkuLeer 0x80
#define ADS1115noReady 0x01
#define HTU21noReady 0x02
#define BMP280noReady 0x04
#define MCP9808noReady 0x08
byte SystemStatus;
void writeSystemStatus()
{
EEPROM.begin(512);
EEPROM.put(0,SystemStatus);
EEPROM.commit();
EEPROM.end();
}
void readSystemStatus()
{
EEPROM.begin(512);
EEPROM.get(0,SystemStatus);
EEPROM.commit();
EEPROM.end();
}

77
include/mcp9808.h Normal file
View File

@ -0,0 +1,77 @@
#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();
bool F_MCP9808;
char Temperature[15] = {0};
void init_MCP9808(){
F_MCP9808 = true;
// 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("MCP9808 not connected!");
SystemStatus = SystemStatus | MCP9808noReady;
F_MCP9808 = false;
}
//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,7,1,Temperature);
Serial.print("Temperatur (MCP9808):\t");
Serial.print(Temperature);
Serial.print(" °C\t");
Serial.println(temperature,4);
tempsensor.shutdown_wake(1); // shutdown MSP9808 - power consumption ~0.1 mikro Ampere, stops temperature sampling
return temperature;
}
void M2M_Temperatur_MCP9808(String deviceId = "4711") {
char topic[100];
dtostrf(valTemp,7,1,Temperature);
sprintf(topic, "%s%s%s", "hjk/devices/", deviceId.c_str(), "/telemetry/temperature_MCP9808");
client.publish(topic, Temperature, true);
}
void Clear_MCP9808(String deviceId = "4711") {
char topic[100];
char test[1] = "";
sprintf(topic, "%s%s%s", "hjk/devices/", deviceId.c_str(), "/telemetry/temperature_MCP9808");
client.publish(topic, test, false);
delay(100);
}

155
include/messADS1115.h Normal file
View File

@ -0,0 +1,155 @@
/***************************************************************************
* Example sketch for the ADS1115_WE library
*
* This sketch shows how to use the ADS1115 in single shot mode.
*
* Further information can be found on:
* https://wolles-elektronikkiste.de/ads1115 (German)
* https://wolles-elektronikkiste.de/en/ads1115-a-d-converter-with-amplifier (English)
*
***************************************************************************/
#include <Arduino.h>
#include<ADS1115_WE.h>
#include<Wire.h>
#define I2C_ADDRESS 0x48
/* There are several ways to create your ADS1115_WE object:
* ADS1115_WE adc = ADS1115_WE(); -> uses Wire / I2C Address = 0x48
* ADS1115_WE adc = ADS1115_WE(I2C_ADDRESS); -> uses Wire / I2C_ADDRESS
* ADS1115_WE adc = ADS1115_WE(&Wire); -> you can pass any TwoWire object / I2C Address = 0x48
* ADS1115_WE adc = ADS1115_WE(&Wire, I2C_ADDRESS); -> all together
*/
ADS1115_WE adc = ADS1115_WE(I2C_ADDRESS);
bool F_ADS1115;
struct {
char Akku[15] = {0};
char Solar[15] = {0};
} ADSData;
void initADS() {
Wire.begin();
F_ADS1115 = true;
if(!adc.init()){
Serial.println("ADS1115 not connected!");
SystemStatus = (SystemStatus | ADS1115noReady);
F_ADS1115 = false;
}
/* Set the voltage range of the ADC to adjust the gain
* Please note that you must not apply more than VDD + 0.3V to the input pins!
*
* ADS1115_RANGE_6144 -> +/- 6144 mV
* ADS1115_RANGE_4096 -> +/- 4096 mV
* ADS1115_RANGE_2048 -> +/- 2048 mV (default)
* ADS1115_RANGE_1024 -> +/- 1024 mV
* ADS1115_RANGE_0512 -> +/- 512 mV
* ADS1115_RANGE_0256 -> +/- 256 mV
*/
adc.setVoltageRange_mV(ADS1115_RANGE_4096); //comment line/change parameter to change range
/* Set the inputs to be compared
*
* ADS1115_COMP_0_1 -> compares 0 with 1 (default)
* ADS1115_COMP_0_3 -> compares 0 with 3
* ADS1115_COMP_1_3 -> compares 1 with 3
* ADS1115_COMP_2_3 -> compares 2 with 3
* ADS1115_COMP_0_GND -> compares 0 with GND
* ADS1115_COMP_1_GND -> compares 1 with GND
* ADS1115_COMP_2_GND -> compares 2 with GND
* ADS1115_COMP_3_GND -> compares 3 with GND
*/
//adc.setCompareChannels(ADS1115_COMP_0_GND); //uncomment if you want to change the default
/* Set number of conversions after which the alert pin will assert
* - or you can disable the alert
*
* ADS1115_ASSERT_AFTER_1 -> after 1 conversion
* ADS1115_ASSERT_AFTER_2 -> after 2 conversions
* ADS1115_ASSERT_AFTER_4 -> after 4 conversions
* ADS1115_DISABLE_ALERT -> disable comparator / alert pin (default)
*/
//adc.setAlertPinMode(ADS1115_ASSERT_AFTER_1); //uncomment if you want to change the default
/* Set the conversion rate in SPS (samples per second)
* Options should be self-explaining:
*
* ADS1115_8_SPS
* ADS1115_16_SPS
* ADS1115_32_SPS
* ADS1115_64_SPS
* ADS1115_128_SPS (default)
* ADS1115_250_SPS
* ADS1115_475_SPS
* ADS1115_860_SPS
*/
//adc.setConvRate(ADS1115_128_SPS); //uncomment if you want to change the default
/* Set continuous or single shot mode:
*
* ADS1115_CONTINUOUS -> continuous mode
* ADS1115_SINGLE -> single shot mode (default)
*/
//adc.setMeasureMode(ADS1115_CONTINUOUS); //uncomment if you want to change the default
/* Choose maximum limit or maximum and minimum alert limit (window) in volts - alert pin will
* assert when measured values are beyond the maximum limit or outside the window
* Upper limit first: setAlertLimit_V(MODE, maximum, minimum)
* In max limit mode the minimum value is the limit where the alert pin assertion will be
* be cleared (if not latched)
*
* ADS1115_MAX_LIMIT
* ADS1115_WINDOW
*
*/
//adc.setAlertModeAndLimit_V(ADS1115_MAX_LIMIT, 3.0, 1.5); //uncomment if you want to change the default
/* Enable or disable latch. If latch is enabled the alert pin will assert until the
* conversion register is read (getResult functions). If disabled the alert pin assertion
* will be cleared with next value within limits.
*
* ADS1115_LATCH_DISABLED (default)
* ADS1115_LATCH_ENABLED
*/
//adc.setAlertLatch(ADS1115_LATCH_ENABLED); //uncomment if you want to change the default
/* Sets the alert pin polarity if active:
*
* ADS1115_ACT_LOW -> active low (default)
* ADS1115_ACT_HIGH -> active high
*/
//adc.setAlertPol(ADS1115_ACT_LOW); //uncomment if you want to change the default
/* With this function the alert pin will assert, when a conversion is ready.
* In order to deactivate, use the setAlertLimit_V function
*/
//adc.setAlertPinToConversionReady(); //uncomment if you want to change the default
}
float readChannel(ADS1115_MUX channel) {
float voltage = 0.0;
adc.setCompareChannels(channel);
adc.startSingleMeasurement();
while(adc.isBusy()){}
voltage = adc.getResult_V(); // alternative: getResult_mV for Millivolt
return voltage;
}
void MessungADS() {
float voltage = 0.0;
voltage = readChannel(ADS1115_COMP_0_GND);
dtostrf(voltage,8,2,ADSData.Akku);
Serial.print("Akku:\t\t\t");
Serial.print(ADSData.Akku);
Serial.println(" V");
voltage = readChannel(ADS1115_COMP_1_GND);
voltage = voltage *2;
dtostrf(voltage,8,2,ADSData.Solar);
Serial.print("Solar:\t\t\t");
Serial.print(ADSData.Solar);
Serial.println(" V");
}

108
include/mess_BME280.h Executable file
View File

@ -0,0 +1,108 @@
#include "Wire.h"
#define Anzahl_Sensoren_BME280 1 // Mögliche Werte: '0','1','2'
//#define Korrektur_Luftdruck KorrekturLuftdruck // Korrekturwert um Abweichungen zu offiziellen Wetterstationen auszugleichen
//----------------------------------------------------------------
// Konfiguration BME280 - Temperatur und Luftfeuchte
//----------------------------------------------------------------
#include "Adafruit_Sensor.h"
#include "Adafruit_BME280.h"
uint8_t BME280_adresse[2] = {0x76, 0x76};
#ifndef SEALEVELPRESSURE_HPA
#define SEALEVELPRESSURE_HPA (1013.25f)
#endif
//----------------------------------------------------------------
bool F_BME280 = true;
const float No_Val = 999.99;
float Temp[2] = {No_Val, No_Val};
float Feuchte[2] = {No_Val, No_Val};
float L_Druck[2] = {No_Val, No_Val};
struct {
char temperature[15] = {0};
char pressure[15] = {0};
char approx_altitud[15] = {0};
char humity[15] = {0};
} BME280Data;
void Sensor_BME280() {
if (Anzahl_Sensoren_BME280 > 0) {
float Temperatur_BME;
float Luftfeuchte_BME;
float Luftdruck_BME;
boolean check;
Adafruit_BME280 my_bme;
for (byte i = 0; i < Anzahl_Sensoren_BME280; i++) {
check = my_bme.begin(BME280_adresse[i]); // I2C Adresse
delay (100); // time to get system ready
if (check) { // if bme ok
Temperatur_BME = my_bme.readTemperature();
Temperatur_BME += KorrekturTemperaturBME;
Luftfeuchte_BME = my_bme.readHumidity();
Luftdruck_BME = my_bme.readPressure();
Luftdruck_BME = (Luftdruck_BME/100) + KorrekturLuftdruck;
//Luftdruck_BME = 220;
Serial.print("Temperature (BME280):\t\t");
Serial.print(Temperatur_BME);
Serial.println(" °C");
Serial.print("Luftfeuchtigkeit (BME280):\t");
Serial.print(Luftfeuchte_BME);
Serial.println(" %");
Serial.print("Luftdruck (BME280):\t\t");
Serial.print(Luftdruck_BME);
Serial.println(" hPa");
}
else {
Temperatur_BME = No_Val;
Luftfeuchte_BME = No_Val;
Luftdruck_BME = No_Val;
Serial.println("BME280 not connected!");
F_BME280 = false;
}
if (i == 0) { // erster BME
Temp[0] = Temperatur_BME; // Hier kann die Zuordnung der Sensoren geändert werden
Feuchte[0] = Luftfeuchte_BME; // Hier kann die Zuordnung der Sensoren geändert werden
L_Druck[0] = Luftdruck_BME;
}
if (i == 1) { // zweiter BME
Temp[1] = Temperatur_BME; // Hier kann die Zuordnung der Sensoren geändert werden
Feuchte[1] = Luftfeuchte_BME; // Hier kann die Zuordnung der Sensoren geändert werden
L_Druck[1] = Luftdruck_BME;
}
}
}
}
void M2M_BME280(String deviceId = "4711") {
char topic[100];
dtostrf(Temp[0],7,1,BME280Data.temperature);
sprintf(topic, "%s%s%s", "hjk/devices/", deviceId.c_str(), "/telemetry/temperature_BME_280" );
client.publish(topic, BME280Data.temperature, true);
dtostrf(Feuchte[0],7,1,BME280Data.humity);
sprintf(topic, "%s%s%s", "hjk/devices/", deviceId.c_str(), "/telemetry/humity_BME280" );
client.publish(topic, BME280Data.humity, true);
dtostrf(L_Druck[0],7,1,BME280Data.pressure);
sprintf(topic, "%s%s%s", "hjk/devices/", deviceId.c_str(), "/telemetry/pressure" );
client.publish(topic, BME280Data.pressure, true);
}
void Clear_BME280(String deviceId = "4711"){
char topic[100];
char test[1] = "";
sprintf(topic, "%s%s%s", "hjk/devices/", deviceId.c_str(), "/telemetry/temperature_BME_280" );
client.publish(topic,test, false);
delay(100);
sprintf(topic, "%s%s%s", "hjk/devices/", deviceId.c_str(), "/telemetry/humity_BME280" );
client.publish(topic,test, false);
delay(100);
sprintf(topic, "%s%s%s", "hjk/devices/", deviceId.c_str(), "/telemetry/pressure" );
client.publish(topic,test, false);
delay(100);
}

95
include/mess_BMP280.h Normal file
View File

@ -0,0 +1,95 @@
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
#ifndef SEALEVELPRESSURE_HPA
#define SEALEVELPRESSURE_HPA (1013.25f)
#endif
// Richen 219 m über NN
// Eppingem 195 m über NN
Adafruit_BMP280 bmp; // I2C
bool F_BMP280;
struct {
char temperature[15] = {0};
char pressure[15] = {0};
char approx_altitud[15] = {0};
char humity[15] = {0};
} BMP280Data;
void Init_BMP280(){
bool status = bmp.begin(0x76);
F_BMP280 = true;
if (!status) {
Serial.println("BMP280 not connected!");
F_BMP280 = false;
SystemStatus = SystemStatus | BMP280noReady;
Serial.print("SensorID was: 0x"); Serial.println(bmp.sensorID(),16);
//delay(5000);
} else{
/* Default settings from datasheet. */
bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */
Adafruit_BMP280::SAMPLING_X2, /* Temp. oversampling */
Adafruit_BMP280::SAMPLING_X16, /* Pressure oversampling */
Adafruit_BMP280::FILTER_X16, /* Filtering. */
Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
//bmp_temp->printSensorDetails();
Serial.println("BMP280 gefunden");
}
}
void read_BMP_280() {
Serial.print("Temperature (BMP280):\t");
float t = bmp.readTemperature();
t = t + KorrekturTemperaturBMP;
dtostrf(t,7,1,BMP280Data.temperature);
Serial.print(BMP280Data.temperature);
Serial.println(" °C");
Serial.print("Pressure:\t\t");
float p = bmp.readPressure() / 100.0F;
p = p + KorrekturLuftdruck;
dtostrf(p,7,1,BMP280Data.pressure);
Serial.print(BMP280Data.pressure);
Serial.println(" hPa");
Serial.print("Approx. Altitude:\t");
float a = bmp.readAltitude(SEALEVELPRESSURE_HPA);
dtostrf(a,7,1,BMP280Data.approx_altitud);
Serial.print(BMP280Data.approx_altitud);
Serial.println(" m über NN");
Serial.println();
}
void M2M_BMP280(String deviceId = "4711") {
char topic[100];
sprintf(topic, "%s%s%s", "hjk/devices/", deviceId.c_str(), "/telemetry/temperature_BMP_280" );
client.publish(topic, BMP280Data.temperature, true);
sprintf(topic, "%s%s%s", "hjk/devices/", deviceId.c_str(), "/telemetry/pressure" );
client.publish(topic, BMP280Data.pressure, true);
sprintf(topic, "%s%s%s", "hjk/devices/", deviceId.c_str(), "/telemetry/approx_altitude" );
client.publish(topic, BMP280Data.approx_altitud);
}
void Clear_BMP280(String deviceId = "4711"){
char topic[100];
char test[1] = "";
sprintf(topic, "%s%s%s", "hjk/devices/", deviceId.c_str(), "/telemetry/temperature_BMP_280" );
client.publish(topic,test, false);
delay(100);
sprintf(topic, "%s%s%s", "hjk/devices/", deviceId.c_str(), "/telemetry/approx_altitude" );
client.publish(topic,test, false);
delay(100);
sprintf(topic, "%s%s%s", "hjk/devices/", deviceId.c_str(), "/telemetry/pressure" );
client.publish(topic,test, false);
delay(100);
}

22
include/mess_Ub.h Normal file
View File

@ -0,0 +1,22 @@
#include <Arduino.h>
ADC_MODE(ADC_VDD);
const float MinimalSpannung = 2.60;
float korectur = 0.000913242;
char floatString[15] = {0};
float AKKU;
float getBattery()
{
#if (NOBATT == 1)
Serial.print("Batterie:\t\t 3.05 V\n");
return 3.05;
#endif
int Vcc = ESP.getVcc();
float VCC = Vcc * korectur ;
Serial.printf("Rohdaten: %d, ", Vcc);
dtostrf(VCC,8,2,floatString);
Serial.printf("Vcc: \t%s V\n", floatString);
return VCC;
}

28
include/mess_Ub_old.h Normal file
View File

@ -0,0 +1,28 @@
#include <Arduino.h>
float korectur = 0.90021322;
char floatString[15] = {0};
float AKKU;
float getBattery(float kor = 1.000)
{
#if (NOBATT == 1)
Serial.print("Batterie:\t\t 3.05 V\n");
return 3.05;
#endif
float valA0 = analogRead(A0);
#ifdef Spannungsteiler
valA0 = valA0 * Spannungsteiler;
#else
valA0 = valA0 * 5.4;
#endif
// (R1 + r1 + r2) / r2
// r1 und r2 Spannungsteiler
// r1 = 270k, r2 = 100k
// Spannungsbereich = 5.2 Volt
valA0= valA0 / 1024;
valA0 = valA0 * kor;
dtostrf(valA0,7,2,floatString);
Serial.printf("Akku:\t\t\t%s V\n", floatString);
return valA0;
}

53
include/mess_htu21.h Normal file
View File

@ -0,0 +1,53 @@
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_I2CDevice.h>
#include <Adafruit_HTU21DF.h>
Adafruit_HTU21DF htu = Adafruit_HTU21DF();
bool F_HTU_21D;
float K_HTU= -0.00;
struct {
char temperature[15] = {0};
char humity[15] = {0};
} htuData;
void init_HTU21(){
F_HTU_21D = false;
if (!htu.begin()) {
Serial.println("Couldn't find sensor HUT21D!");
SystemStatus = SystemStatus | HTU21noReady;
}else{
F_HTU_21D = true;
Serial.println("HUT21D gefunden");
}
}
void read_HTU21D() {
float t = htu.readTemperature();
t = t + KorrekturTemperaturHTU;
dtostrf(t,7,1,htuData.temperature);
float h = htu.readHumidity();
dtostrf(h,7,1,htuData.humity);
Serial.print("Temperature (HTU21D):\t");
Serial.print(htuData.temperature);
Serial.print(" °C\t");
Serial.println(t,4);
Serial.print("Luftfeuchtigkeit:\t");
Serial.print(htuData.humity);
Serial.println(" %");
}
void M2M_HTU21D(String deviceId = "4711") {
char topic[100];
sprintf(topic, "%s%s%s", "hjk/devices/", deviceId.c_str(), "/telemetry/temperature_Htu_21" );
client.publish(topic, htuData.temperature, true);
sprintf(topic, "%s%s%s", "hjk/devices/", deviceId.c_str(), "/telemetry/humity" );
client.publish(topic, htuData.humity, true);
/* Serial.printf("HTU21:\t\t %s °C\n", htuData.temperature);
Serial.printf("HTU21:\t\t %s %%\n", htuData.humity); */
}

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

69
platformio.ini Normal file
View File

@ -0,0 +1,69 @@
; 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]
platform = espressif32
board = nodemcu-32s
framework = arduino
monitor_speed = 115200
monitor_port = COM3
monitor_filters = time
upload_port = COM3
lib_deps =
knolleary/PubSubClient @ 2.8
adafruit/Adafruit GFX Library @ 1.11.3
2dom/PxMatrix LED MATRIX library @ 1.8.2
adafruit/Adafruit BusIO @ 1.7.2
build_flags =
-DSCAN=32
[env:debug] ; Entwicklungssystem
build_flags = ${env.build_flags}
-DDEBUG=1
-DGRENZWERT=3.70
-DSTASSID=\"MagentaWLAN-RGDO\"
-DSTAPSK=\"93329248424922704583\"
-DGATEWAY=\"192.168.127.1\"
-DDNS=\"192.168.127.1\"
-DSECONDARDNS=\"8.8.8.8\"
-DMYIP=\"192.168.127.48\"
-DSUBNET=\"255.255.255.0\"
-Dmqtt_server=\"hjkmqtt.dedyn.io\"
-Dmqtt_port=61883
-DINNEN=\"hjk/devices/TEMPWOHNZIM/telemetry/temperature\"
-DFLUR=\"hjk/devices/TEMPFLUR/telemetry/temperature\"
-DCO2=\"hjk/devices/257923/telemetry/co2\"
-DAKKU=\"hjk/devices/WETTERSTATION/telemetry/battery\"
-DWETTER=\"hjk/devices/WETTERSTATION/telemetry/temperature_Htu_21\"
-DLUFTDRUCK=\"hjk/devices/WETTERSTATION/telemetry/pressure\"
-DFEUCHTIGKEIT=\"hjk/devices/WETTERSTATION/telemetry/humity\"
-DHELLIGKEIT=\"hjk/devices/WETTERSTATION/telemetry/Lux\"
[env:boris]
build_flags = ${env.build_flags}
-DDEBUG=1
-DGRENZWERT=2.80
-DSTASSID=\"FRITZ!Box7362SL\"
-DSTAPSK=\"BorisundEva2007\"
-DGATEWAY=\"192.168.2.1\"
-DDNS=\"192.168.2.1\"
-DMYIP=\"192.168.2.40\"
-DSUBNET=\"255.255.255.0\"
-DSECONDARDNS=\"8.8.8.8\"
-Dmqtt_server=\"hjkmqtt.dedyn.io\"
-Dmqtt_port=61883
-DINNEN=\"hjk/devices/MESSUNITTEMPBORIS/telemetry/temperature_Htu_21\"
-DAKKU=\"hjk/devices/WETTERSTATIONBORIS/telemetry/battery\"
-DWETTER=\"hjk/devices/WETTERSTATIONBORIS/telemetry/temperature_Htu_21\"
-DLUFTDRUCK=\"hjk/devices/WETTERSTATIONBORIS/telemetry/pressure\"
-DFEUCHTIGKEIT=\"hjk/devices/WETTERSTATIONBORIS/telemetry/humity\"
-DHELLIGKEIT=\"hjk/devices/WETTERSTATIONBORIS/telemetry/Lux\"

847
src/main.cpp Normal file
View File

@ -0,0 +1,847 @@
#include <Arduino.h>
// This is how many color levels the display shows - the more the slower the update
//#define PxMATRIX_COLOR_DEPTH 4
// Defines the speed of the SPI bus (reducing this may help if you experience noisy images)
//#define PxMATRIX_SPI_FREQUENCY 20000000
// Creates a second buffer for backround drawing (doubles the required RAM)
//#define PxMATRIX_double_buffer true
#include <Adafruit_GFX.h>
#include <Fonts/FreeMonoBold12pt7b.h>
#include <Fonts/FreeMono12pt7b.h>
#include <Fonts/FreeMono9pt7b.h>
#include <Fonts/Picopixel.h>
#include <PxMatrix.h>
// Pins for LED MATRIX
#ifdef ESP32
#define P_LAT 22
#define P_A 19
#define P_B 23
#define P_C 18
#define P_D 5
#define P_E 15
#define P_OE 16
hw_timer_t * timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
#endif
#ifdef ESP8266
#include <Ticker.h>
Ticker display_ticker;
#define P_LAT 16
#define P_A 5
#define P_B 4
#define P_C 15
#define P_D 12
#define P_E 0
#define P_OE 2
#endif
#define MaxErrCount 30
const unsigned long stoerung = 15 * 60000000UL; // Minuten * Mikrosekunden für Sleep Mode
unsigned long startTime;
unsigned long endTime;
#include <Wire.h>
#include <WiFi.h>
#include <PubSubClient.h>
WiFiClient espClient;
PubSubClient client(espClient);
// co2 Werte
#define CO2_WARN_1 650
#define CO2_WARN_2 950
#define CO2_WARN_3 1250
#define CO2_WARN_4 1500
#define CO2_CRITICAL_PPM 1850
#define matrix_width 64
#define matrix_height 64
// This defines the 'on' time of the display is us. The larger this number,
// the brighter the display. If too large the ESP will crash
uint8_t display_draw_time=10; //30-70 is usually fine
//PxMATRIX display(32,16,P_LAT, P_OE,P_A,P_B,P_C);
//PxMATRIX display(64,32,P_LAT, P_OE,P_A,P_B,P_C,P_D);
PxMATRIX display(64,64,P_LAT, P_OE,P_A,P_B,P_C,P_D,P_E);
// Some standard colors
uint16_t myRED = display.color565(255, 0, 0);
uint16_t myGREEN = display.color565(0, 255, 0);
uint16_t myBLUE = display.color565(0, 0, 255);
uint16_t myWHITE = display.color565(255, 255, 255);
uint16_t myYELLOW = display.color565(255, 255, 0);
uint16_t myCYAN = display.color565(0, 255, 255);
uint16_t myMAGENTA = display.color565(255, 0, 255);
uint16_t myBLACK = display.color565(0, 0, 0);
uint16_t myDATUM = display.color565(64, 64, 64);
uint16_t myTEMP = display.color565(255, 255, 255);
uint16_t myCo = display.color565(0, 64, 0);
uint16_t myTEST = display.color565(30, 30, 0);
uint16_t myCOLORS[8]={myRED,myGREEN,myBLUE,myWHITE,myYELLOW,myCYAN,myMAGENTA,myBLACK};
// Wifi
char ssid[] = STASSID; // your network SSID (name)
char pass[] = STAPSK; // your network password
IPAddress ip;
IPAddress gateway;
IPAddress subnet;
IPAddress dns; // DNS-Server
IPAddress secondarDNS;
String hostname = "GROSSZEICHBORIS";
int status = WL_IDLE_STATUS;
const char* NTP_SERVER = "de.pool.ntp.org";
const char* TZ_INFO = "CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00"; // enter your time zone (https://remotemonitoringsystems.ca/time-zone-abbreviations.php)
tm timeinfo;
time_t now;
long unsigned lastNTPtime;
unsigned long lastEntryTime;
const int TimeY = 20;
const int TimeX = 1;
const int WetterY = 32;
const int WetterX = 18;
const int CoY = 43;
int Co2 = 0.00;
float Covid19 = 0.00;
float Aussentemp = -99.90;
int Pressure = 0;
float TempWohn = -99.90;
float TempFlur = -99.99;
float Luftfeuchtigkeit = 0.00;
float Akku = -99.00;
int Helligkeit = 255;
const char* const PROGMEM DAY_NAMES[] = {"Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag"};
const char* const PROGMEM DAY_SHORT[] = {"So", "Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"};
//MQTT
//define mqtt_port mqtt_port
//const char* mqtt_server = mqtt_server;
char topic_0[50];
char msg[20];
char clientName[30];
const char* topic_Innen = INNEN;
const char* topic_Akku = AKKU;
#ifdef CO2
const char* topic_Co2 = CO2;
#endif
const char* topic_Wetter = WETTER;
const char* topic_Pressure = LUFTDRUCK;
const char* topic_Luftfeuchtigkeit = FEUCHTIGKEIT;
const char* topic_Helligkeit = HELLIGKEIT;
#ifdef FLUR
const char* topic_Flur = FLUR;
#endif
void callback(char* topic1, byte* payload, unsigned int length);
void scroll_text(uint8_t ypos, unsigned long scroll_delay, String text, uint8_t colorR, uint8_t colorG, uint8_t colorB, boolean blink);
void scroll_text2(uint8_t ypos, unsigned long scroll_delay, String text, uint8_t colorR, uint8_t colorG, uint8_t colorB, boolean blink);
void scroll_Grad(uint8_t ypos, unsigned long scroll_delay, String text, uint8_t colorR, uint8_t colorG, uint8_t colorB, boolean blink);
bool getNTPtime(int sec);
void showTime(tm localTime);
static uint32_t lastTime = 0; // millis() memory
static void setup_wifi();
#ifdef ESP8266
// ISR for display refresh
void display_updater()
{
display.display(display_draw_time);
}
#endif
#ifdef ESP32
void IRAM_ATTR display_updater(){
// Increment the counter and set the time of ISR
portENTER_CRITICAL_ISR(&timerMux);
display.display(display_draw_time);
portEXIT_CRITICAL_ISR(&timerMux);
}
#endif
void print_wifi_status() {
// SSID des WiFi Netzwerkes ausgeben:
/* Serial.print("SSID: ");
Serial.println(WiFi.SSID()); */
// WiFi IP Adresse des ESP32 ausgeben:
/* IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip); */
// WiFi Signalstärke ausgeben:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
display.clearDisplay();
scroll_text(64-16,40,"IP Adress: " + WiFi.localIP().toString()+ " signal strength (RSSI): " + String(rssi, DEC) + " dBm", 96,96,0, false);
}
void display_update_enable(bool is_enable)
{
#ifdef ESP8266
if (is_enable)
display_ticker.attach(0.004, display_updater);
else
display_ticker.detach();
#endif
#ifdef ESP32
if (is_enable)
{
timer = timerBegin(0, 80, true);
timerAttachInterrupt(timer, &display_updater, true);
timerAlarmWrite(timer, 4000, true);
timerAlarmEnable(timer);
}
else
{
timerDetachInterrupt(timer);
timerAlarmDisable(timer);
}
#endif
}
String TimeOld = "";
int MinuteOld = 99;
static bool blinkSek = false; // seconds passing flasher
void callback(char* topic1, byte* payload, unsigned int length) {
// float wert;
// int st; // Hilfsvariable zum ansteuern der Page zum einstellen der Solltemperatur
Serial.print("Message arrived [");
Serial.print(topic1);
Serial.print("] ");
for (int i = 0; i < length; i++) {
msg[i] = (char)payload[i];
}
msg[length] = '\0';
//Serial.println(msg);
#ifdef CO2
// CO2 Wert vom Sensor
if(strcmp(topic1, topic_Co2)== 0){
Serial.print("Co2 Sensor !!!: ");
Serial.print(msg);
Serial.println();
Co2 = atoi(msg);
}
#endif
// Covid19 Wert
/* if(strcmp(topic1, topic_Covid)== 0){
Serial.print("Covid: ");
Serial.print(msg);
Serial.println();
Covid19 = atof(msg);
} */
// Wetter Wert
if(strcmp(topic1, topic_Wetter)== 0){
Serial.print("Aussentemperatur: ");
Serial.print(msg);
Serial.println(" °C");
Aussentemp = atof(msg);
}
if(strcmp(topic1, topic_Pressure)== 0){
Serial.print("Luftdruck: ");
Serial.print(msg);
Serial.println(" hPa");
Pressure = atoi(msg);
}
if(strcmp(topic1, topic_Innen)== 0){
Serial.print("Temperatur Innen: ");
Serial.print(msg);
Serial.println(" °C");
TempWohn = atof(msg);
}
#ifdef FLUR
if(strcmp(topic1, topic_Flur)== 0){
Serial.print("Temperatur Flur: ");
Serial.print(msg);
Serial.println(" °C");
TempFlur = atof(msg);
}
#endif
if(strcmp(topic1, topic_Luftfeuchtigkeit)== 0){
Serial.print("Luftfeuchtigkeit: ");
Serial.print(msg);
Serial.println(" %");
Luftfeuchtigkeit = atof(msg);
}
if(strcmp(topic1, topic_Akku)== 0){
Serial.print("Wetterstation Akku: ");
Serial.print(msg);
Serial.println(" V");
Akku = atof(msg);
}
if(strcmp(topic1, topic_Helligkeit)== 0){
Serial.print("Helligkeit: ");
Serial.print(msg);
Serial.println(" Lux");
Helligkeit = atoi(msg);
if (Helligkeit > 255) Helligkeit = 255;
if (Helligkeit < 0) Helligkeit = 0;
display.setBrightness(Helligkeit);
}
}
void reconnect() {
sprintf(clientName, "%s%s", "Uhr", "Zentrale4" );
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
if (client.connect(clientName)) {
/* MQTTStatus.setPic(3); */
Serial.println("connected");
#ifdef CO2
client.subscribe(topic_Co2);
#endif
//client.subscribe(topic_Covid);Ja
client.subscribe(topic_Wetter);
client.subscribe(topic_Pressure);
client.subscribe(topic_Innen);
#ifdef FLUR
client.subscribe(topic_Flur);
#endif
client.subscribe(topic_Luftfeuchtigkeit);
client.subscribe(topic_Akku);
client.subscribe(topic_Helligkeit);
//client.subscribe("hjk/devices/WETTERSTATIONBORIS/telemetry/#");
//client.subscribe("hjk/devices/MESSUNITTEMPBORIS/telemetry/#");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void ZeigeZeit(tm localTime, int xPos = 2, int yPos = 8)
{
if (xPos < 4) xPos = 4;
if (yPos < 4) yPos = 4;
//Serial.print(timeClient.getFormattedTime()); Serial.println();
char szTime[4];
sprintf(szTime, "%02d", localTime.tm_hour);
display.setCursor(xPos-1, yPos);
display.setFont(&FreeMonoBold12pt7b);
display.setTextColor(myMAGENTA);
display.fillRect(xPos, yPos - 8, 27, 15, myBLACK);
display.print(szTime);
display.setFont();
// Doppelpunkt zeichnen
display.fillRect(xPos + 27, yPos -8, 2, 15, myBLACK);
if (blinkSek == true) {
display.fillRect(xPos + 27, yPos - 3, 2, 2, myMAGENTA);
display.fillRect(xPos + 27, yPos + 1, 2, 2, myMAGENTA);
}
/* display.fillRect(xPos + 27, yPos - 3, 2, 2, myMAGENTA);
display.fillRect(xPos + 27, yPos + 1, 2, 2, myMAGENTA); */
sprintf(szTime, "%02d", localTime.tm_min);
display.setCursor(xPos + 29, yPos);
display.setFont(&FreeMonoBold12pt7b);
display.setTextColor(myMAGENTA);
display.fillRect(xPos + 29, yPos - 8, 27, 15, myBLACK);
display.print(szTime);
display.setFont();
}
void ZeigeCO(int xPos = 1, int yPos = 19)
{
if (xPos < 1) xPos = 1;
if (yPos < 19) yPos = 19;
if (Co2 > 300.00){
char szCO[10];
sprintf(szCO, "%4d", Co2);
//Serial.print("CO = "); Serial.println(szCO);
display.setCursor(xPos, yPos);
display.setFont();
switch (Co2){
case 0 ... CO2_WARN_3 -1: {
display.setTextColor(myCo); // green
break;
}
case CO2_WARN_3 ... CO2_WARN_4 -1: {
display.setTextColor(myYELLOW);
break;
}
case CO2_WARN_4 ... CO2_CRITICAL_PPM: {
display.setTextColor(myRED);
break;
}
default: {
display.setTextColor(myBLUE);
break;
}
}
//display.setTextColor(myGREEN);
display.fillRect(xPos, yPos-2, 64-xPos, 8+2, (myBLACK));
display.print("CO :");
display.print(szCO);
// Hochzeichen zeichen CO²
display.setFont(&Picopixel);
display.setCursor(xPos+12, yPos+2);
display.print("2");
display.setCursor(xPos+48, yPos+6);
display.print("ppm");
display.setFont();
}
}
void ZeigeDatum(tm localTime, int xPos = 2, int yPos = 1)
{
//if (xPos < 2) xPos = 2;
if (yPos < 0) yPos = 0;
char szDATUM[20];
/* sprintf(szDATUM, "%s%2d.%02d.%02d", DAY_SHORT[(localTime.tm_wday > 0 ? localTime.tm_wday : 7 )],
localTime.tm_mday,
localTime.tm_mon + 1,
(localTime.tm_year+1900)-2000); */
display.setCursor(xPos, yPos);
display.fillRect(xPos, yPos-2, 64-xPos, 8+2, (myBLACK));
sprintf(szDATUM, "%s", DAY_SHORT[(localTime.tm_wday > 0 ? localTime.tm_wday : 7 )]);
// display.setFont(&Picopixel);
display.setTextColor(myDATUM);
display.print(szDATUM); // Tag
display.setCursor(xPos+15, yPos);
sprintf(szDATUM, "%2d.%02d.%02d",
localTime.tm_mday,
localTime.tm_mon + 1,
(localTime.tm_year+1900)-2000);
display.print(szDATUM); // Zeit
display.setFont();
}
void ZeigeWetter(double Wetter1, int yPos = 2, int xPos = 1)
{
if (xPos < 2) xPos = 2;
if (yPos < 0) yPos = 0;
if (Wetter1 > -99.9){
char szWetter[10];
//Serial.print("Aussentemperatur: "); Serial.println(Wetter1,3);
dtostrf(Wetter1, 4, 1, szWetter);
display.setCursor(xPos, yPos);
display.fillRect(xPos, yPos-2, 64-xPos, 8+2, (myBLACK));
display.setTextColor(myWHITE);
display.print(szWetter);
// Erzeuge Grad Zeichen ......
display.setCursor(xPos+24, yPos-5);
display.setFont(&Picopixel);
display.print("o");
display.setCursor(xPos+28, yPos+6);
display.setFont();
// ...........
display.print("C");
}
}
void Test()
{
display.setCursor(1, 40);
display.print("Hallo");
display.setFont(&Picopixel);
display.print("0o");
display.setFont();
}
void setup() {
startTime = millis();
Serial.begin(115200);
//WiFi.mode( WIFI_OFF );
delay( 10 );
Serial.println("Start");
// initialise_wifi();
setup_wifi();
// Define your display layout here, e.g. 1/8 step, and optional SPI pins begin(row_pattern, CLK, MOSI, MISO, SS)
display.begin(SCAN); // Rows-scan pattern 1/32
//display.begin(8, 14, 13, 12, 4);
// Define multiplex implemention here {BINARY, STRAIGHT} (default is BINARY)
display.setMuxPattern(BINARY);
// Set the multiplex pattern {LINE, ZIGZAG,ZZAGG, ZAGGIZ, WZAGZIG, VZAG, ZAGZIG} (default is LINE)
display.setScanPattern(LINE);
// Rotate display
//display.setRotate(true);
// Flip display
//display.setFlip(true);
// Control the minimum color values that result in an active pixel
//display.setColorOffset(5, 5,5);
// Set the multiplex implemention {BINARY, STRAIGHT} (default is BINARY)
display.setMuxPattern(BINARY);
// Set the color order {RRGGBB, RRBBGG, GGRRBB, GGBBRR, BBRRGG, BBGGRR} (default is RRGGBB)
display.setColorOrder(BBRRGG);
// Set the time in microseconds that we pause after selecting each mux channel
// (May help if some rows are missing / the mux chip is too slow)
//display.setMuxDelay(0,1,0,0,0);
// Set the number of panels that make up the display area width (default is 1)
//display.setPanelsWidth(2);
// Set the brightness of the panels (default is 255)
display.setBrightness(Helligkeit);
display_update_enable(true);
display.clearDisplay();
display.setTextColor(myRED);
display.setCursor(0,0);
display.print("Pixel");
display.setTextColor(myGREEN);
display.setCursor(30,0);
display.print("Time");
//----------------------
display.setTextColor(myBLUE);
display.setCursor(2,50);
display.print("Pixel");
display.setTextColor(myYELLOW);
display.setCursor(30,50);
display.print("1234");
//--------------------------------------------------
//--------------------------------------------------
delay(1000);
print_wifi_status();
configTime(0, 0, NTP_SERVER);
// See https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv for Timezone codes for your region
setenv("TZ", TZ_INFO, 1);
if (getNTPtime(10)) { // wait up to 10sec to sync
} else {
Serial.println("Time not set");
delay(5000);
ESP.restart();
}
lastNTPtime = time(&now);
lastEntryTime = millis();
}
union single_double{
uint8_t two[2];
uint16_t one;
} this_single_double;
unsigned long last_draw=0;
void scroll_text(uint8_t ypos, unsigned long scroll_delay, String text, uint8_t colorR, uint8_t colorG, uint8_t colorB, boolean blink)
{
uint16_t text_length = text.length();
display.setTextWrap(false); // we don't wrap text so it scrolls nicely
display.setTextSize(1);
display.setRotation(0);
display.setTextColor(display.color565(colorR,colorG,colorB));
// Asuming 5 pixel average character width
for (int xpos=matrix_width; xpos>-(matrix_width+text_length*5); xpos--)
{
if (millis() - lastTime >= 1000)
{
lastTime = millis();
blinkSek = !blinkSek;
}
if (blink){
if (blinkSek) {
display.fillRect(TimeX + 30, TimeY - 3, 2, 2, myMAGENTA);
display.fillRect(TimeX + 30, TimeY + 1, 2, 2, myMAGENTA);
}else{
display.fillRect(TimeX + 30, TimeY - 8, 2, 15, myBLACK);
}
}
display.setTextColor(display.color565(colorR,colorG,colorB));
//display.clearDisplay();
display.fillRect(xpos, ypos, 64-xpos, 8, (myBLACK));
display.setCursor(xpos,ypos);
display.println(text);
delay(scroll_delay);
yield();
// This might smooth the transition a bit if we go slow
// Dies könnte den Übergang etwas glätten, wenn wir langsam vorgehen
/* display.setTextColor(display.color565(colorR/4,colorG/4,colorB/4));
display.setCursor(xpos-1,ypos);
display.println(text);
delay(scroll_delay/5);
yield(); */
}
}
void scroll_text2(uint8_t ypos, unsigned long scroll_delay, String text, uint8_t colorR, uint8_t colorG, uint8_t colorB, boolean blink)
{
uint16_t text_length = text.length();
display.setTextWrap(false); // we don't wrap text so it scrolls nicely
display.setTextSize(2);
display.setRotation(0);
display.setTextColor(display.color565(colorR,colorG,colorB));
// Asuming 5 pixel average character width
for (int xpos=matrix_width; xpos>-(matrix_width+text_length*10); xpos--)
{
if (millis() - lastTime >= 1000)
{
lastTime = millis();
blinkSek = !blinkSek;
}
if (blinkSek && blink) {
display.fillRect(4 + 27, 20 - 3, 2, 2, myMAGENTA);
display.fillRect(4 + 27, 20 + 1, 2, 2, myMAGENTA);
}else{
display.fillRect(4 + 27, 20 - 3, 2, 2, myBLACK);
display.fillRect(4 + 27, 20 + 1, 2, 2, myBLACK);
}
display.setTextColor(display.color565(colorR,colorG,colorB));
//display.clearDisplay();
display.fillRect(xpos, ypos, 64-xpos, 16, (myBLACK));
display.setCursor(xpos,ypos);
display.println(text);
delay(scroll_delay);
yield();
}
display.setTextSize(1);
}
void scroll_Grad(uint8_t ypos, unsigned long scroll_delay, String text, uint8_t colorR, uint8_t colorG, uint8_t colorB, boolean blink)
{
uint16_t text_length = text.length() +2;
display.setTextWrap(false); // we don't wrap text so it scrolls nicely
display.setTextSize(1);
display.setRotation(0);
display.setTextColor(display.color565(colorR,colorG,colorB));
// Asuming 5 pixel average character width
for (int xpos=matrix_width; xpos>-(matrix_width+text_length*5); xpos--)
{
if (millis() - lastTime >= 1000)
{
lastTime = millis();
blinkSek = !blinkSek;
}
if (blink){
if (blinkSek) {
display.fillRect(TimeX + 30, TimeY - 3, 2, 2, myMAGENTA);
display.fillRect(TimeX + 30, TimeY + 1, 2, 2, myMAGENTA);
}else{
display.fillRect(TimeX + 30, TimeY - 8, 2, 15, myBLACK);
}
}
display.setTextColor(display.color565(colorR,colorG,colorB));
display.fillRect(xpos, ypos-1, 64-xpos, 9, (myBLACK));
display.setCursor(xpos,ypos);
display.print(text);
display.setCursor(xpos+132, ypos-5);
display.setFont(&Picopixel);
display.print("o");
display.setCursor(xpos+136, ypos+6);
display.setFont();
// ...........
display.println("C");
delay(scroll_delay);
yield();
}
}
uint8_t icon_index=0;
static void setup_wifi() {
long ErrCount = 0;
delay(10);
// We start by connecting to a WiFi network
if (!ip.fromString(MYIP)) { // try to parse into the IPAddress
Serial.println("UnParsable IP");
}
if (!dns.fromString(DNS)) { // try to parse into the IPAddress
Serial.println("UnParsable DNS");
}
if (!gateway.fromString(GATEWAY)) { // try to parse into the IPAddress
Serial.println("UnParsable GATEWAY");
}
if (!secondarDNS.fromString(SECONDARDNS)) { // try to parse into the IPAddress
Serial.println("UnParsable GATEWAY");
}
if (!subnet.fromString(SUBNET)) { // try to parse into the IPAddress
Serial.println("UnParsable GATEWAY");
}
if (!WiFi.config(ip, gateway, subnet, dns, secondarDNS))
{
Serial.println("STA Failed to configure");
}
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
ErrCount ++;
if (ErrCount >= MaxErrCount){
endTime = millis();
unsigned long Pause = stoerung -((endTime - startTime) * 1000); // Pause
ESP.deepSleep(Pause); // Pause
delay(100);
}
}
Serial.println(" WiFi connected");
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
Serial.print("IP Address: \t");
Serial.println(WiFi.localIP());
}
void loop() {
getNTPtime(10);
if (!client.connected()) {
reconnect();
}
client.loop();
if (millis() - lastTime >= 1000)
{
lastTime = millis();
blinkSek = !blinkSek;
ZeigeDatum(timeinfo, 1, 1);
ZeigeZeit(timeinfo, TimeX, TimeY);
//ZeigeZeit(timeinfo, 1,40);
ZeigeCO(1,CoY);
/* if ((timeinfo.tm_min % 10) == 0){
/* if (Covid19 != 0){
scroll_text(matrix_height-8,20,"Landkreis Heilbronn", 30,30,30, true);
if (Covid19 <= 500){
// ------------------------------------ \204 für ä
scroll_text(matrix_height-8,25,"Covid 19 F\204lle in den letzte 7 Tage pro 100000 EW: " + String(Covid19, 1), 40,40,40, true);
} else if (Covid19 <= 1000){
// ------------------------------------ \204 für ä
scroll_text(matrix_height-8,25,"Covid 19 F\204lle in den letzte 7 Tage pro 100000 EW: " + String(Covid19, 1), 64,64,0, true);
} else {
// ------------------------------------ \204 für ä
scroll_text(matrix_height-8,25,"Covid 19 F\204lle in den letzte 7 Tage pro 100000 EW: " + String(Covid19, 1), 64,0,0, true);
}
}
} else {
if (Aussentemp > -99.9){
scroll_text(matrix_height-8,30,"Luftdruck: " + String(Pressure) + " hPa", 255,255,255, true);
char szWetter[10];
dtostrf(Aussentemp, 4, 1, szWetter);
//Serial.print(Aussentemp); Serial.print(" "); Serial.println(szWetter);
scroll_Grad(matrix_height-8,30,"Aussentemperatur: " + String(szWetter), 64,64,64, true);
dtostrf(Luftfeuchtigkeit, 4, 1, szWetter);
scroll_text(matrix_height-8,30,"Luftfeuchtigkeit: " + String(szWetter) + " %", 48,48,48, true);
}
} */
//scroll_text(matrix_height-16,20,"Temperatur: " + String(Wetter,1) +" °C", 128,30,30, true);
/* scroll_text2(matrix_height-24,20,"Liebe Frunde, liebe Nachbarn,", 128,128,0, true);
scroll_text2(matrix_height-24,20,"ich w\201nsche Euch allen ein", 128,128,0, true);
scroll_text2(matrix_height-24,20,"Frohes neues Jahr 2022.", 128,255,0, true); */
ZeigeWetter(double(TempWohn), WetterY,WetterX);
//Serial.println("START");
if (Aussentemp > -99.9){
char szWetter[10];
dtostrf(TempFlur, 4, 1, szWetter);
//Serial.print(Aussentemp); Serial.print(" "); Serial.println(szWetter);
scroll_Grad(matrix_height-8,30," Flur: " + String(szWetter), 64,64,64, true);
/* Achtung sehr wichtig,
wenn das gesamt Laufschrift mehr
als 30 Sekunden Dauert muss ein .... */
client.loop();
/* eingeführt werden, sonst kommt es zu
einen Socket Fehler !!!! */
scroll_text(matrix_height-8,30,"Luftdruck: " + String(Pressure) + " hPa", 255,255,255, true);
dtostrf(Aussentemp, 4, 1, szWetter);
//Serial.print(Aussentemp); Serial.print(" "); Serial.println(szWetter);
/* Achtung sehr wichtig,
wenn das gesamt Laufschrift mehr
als 30 Sekunden Dauert muss ein .... */
client.loop();
/* eingeführt werden, sonst kommt es zu
einen Socket Fehler !!!! */
scroll_Grad(matrix_height-8,30,"Aussentemperatur: " + String(szWetter), 64,64,64, true);
/* Achtung sehr wichtig,
wenn das gesamt Laufschrift mehr
als 30 Sekunden Dauert muss ein .... */
client.loop();
/* eingeführt werden, sonst kommt es zu
einen Socket Fehler !!!! */
dtostrf(Luftfeuchtigkeit, 4, 1, szWetter);
scroll_text(matrix_height-8,30,"Luftfeuchtigkeit: " + String(szWetter) + " %", 64,64,64, true);
}
if ((Akku <= GRENZWERT) && (Akku > 0)){
scroll_text(matrix_height-8,40,"Akku: " + String(Akku) + " Volt", 255, 0, 0, true);
scroll_text(matrix_height-8,40,"Akku aufladen!", 255, 0, 0, true);
}
//Serial.println("STOP");
}
}
bool getNTPtime(int sec) {
{
uint32_t start = millis();
do {
time(&now);
localtime_r(&now, &timeinfo);
//Serial.print(".");
delay(10);
} while (((millis() - start) <= (1000 * sec)) && (timeinfo.tm_year < (2016 - 1900)));
if (timeinfo.tm_year <= (2016 - 1900)) return false; // the NTP call was not successful
//Serial.print("now "); Serial.println(now);
/* char time_output[30];
strftime(time_output, 30, "%a %d-%m-%y %T", localtime(&now));
Serial.println(time_output);
Serial.println(12); */
}
return true;
}
void showTime(tm localTime) {
Serial.printf(
"%04d-%02d-%02d %02d:%02d:%02d, day %d, %s time\n",
localTime.tm_year + 1900,
localTime.tm_mon + 1,
localTime.tm_mday,
localTime.tm_hour,
localTime.tm_min,
localTime.tm_sec,
(localTime.tm_wday > 0 ? localTime.tm_wday : 7 ),
(localTime.tm_isdst == 1 ? "summer" : "standard")
);
}

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