Compare commits

..

16 Commits

Author SHA1 Message Date
ed3d0087b0 modified: include/ModBusConfig.cpp
modified:   include/ModBusConfig.h
modified:   src/main.cpp
2024-11-02 21:11:07 +01:00
c0391afc25 File-Creation:
new file:   include/ModBusConfig.cpp
new file:   include/ModBusConfig.h
new file:   include/ModbusHandler.cpp
new file:   include/ModbusHandler.h
2024-11-02 20:50:59 +01:00
19f54dded9 Geändert: EEPROM.write to EEPROM.put
modified:   include/ModbusSlaveConfigToEEPROM.h
2024-11-02 20:18:01 +01:00
d94ba681fb Changes if (address > HoldingRegister_size ||
(address + length) > HoldingRegister_size) {
        return STATUS_ILLEGAL_DATA_ADDRESS;
    }
modified:   src/main.cpp
2024-11-02 20:03:13 +01:00
14b1d7079f Zeitbasierter Schreibschutz alle x-Minuten
modified:   include/ModbusSlaveConfigToEEPROM.h
2024-11-02 18:35:51 +01:00
ded26ae930 Added Switch Case in writeDigitalOut
modified:   src/main.cpp
2024-11-02 18:32:13 +01:00
e9a626df0a modified: src/main.cpp 2024-11-02 18:25:34 +01:00
ec1d6a644e Added Resetfunktionen
modified:   include/ModbusSlaveConfigToEEPROM.h
2024-11-02 18:24:46 +01:00
0e3024effb modified: include/ModbusSlaveConfigToEEPROM.h
Max BaudRate to 38400
2024-11-02 17:40:07 +01:00
16d109a71b new file: .vscode/settings.json
modified:   include/ModbusSlaveConfigToEEPROM.h
change  Baudrate = EEPROM.read(BAUD_RATE_ADDRESS);
2024-11-02 17:28:22 +01:00
4c0b8aaa74 modified: include/ModbusSlaveConfigToEEPROM.h
modified:   src/main.cpp

main.cpp read from eeprom_konfig
ModbusSlaveConfigToEEPROM.h write-Protection SetBaudRate
2024-11-02 17:24:05 +01:00
1c34032bc3 Holdingregister Write Funktion mit Write-ToEEprom ergänzt.
Holdingregister Read mit Funtion Read-EEPROM ergänzt
2024-11-02 16:56:41 +01:00
9bfedb97cb Ergänze Holding-Register /statt input-register für Write-Funktionen aus Modbus 2024-11-02 16:44:14 +01:00
c9e1e8b832 Vorbereitung für: uint8_t WriteSingleRegister 2024-11-02 16:33:24 +01:00
d50d66743f MAX_MODBUS_ID_ADDRESS 255 und SetModbusID(22); Standardwert gesetzt 2024-11-01 23:19:38 +01:00
960140e9db erste Implementierung zur EEPROM Speicherung 2024-11-01 23:16:10 +01:00
8 changed files with 395 additions and 136 deletions

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

@ -0,0 +1,3 @@
{
"CodeGPT.apiKey": "CodeGPT Plus Beta"
}

75
include/ModBusConfig.cpp Normal file
View File

@ -0,0 +1,75 @@
#include <ModBusConfig.h>
#include <EEPROM.h>
/*
Konstruktor: Der Konstruktor initialisiert die Modbus-ID und die Baudrate auf Standardwerte (1 und 9600),
falls die EEPROM-Werte nicht gesetzt sind (d.h. wenn sie 0xFF sind).
*/
ModBusConfig::ModBusConfig() {
// Optional: Initialisieren Sie die EEPROM-Werte, falls erforderlich
if (EEPROM.read(MODBUS_ID_ADDRESS) == 0xFF) {
SetModbusID(STANDARD_MODBUS_ID); // Setze Standard ID
}
if (EEPROM.read(BAUD_RATE_ADDRESS) == 0xFF) {
SetBaudRate(STANDARD_MODBUS_BAUDRATE); // Setze Standard Baudrate
}
}
void ModBusConfig::SetModbusID(int ID) {
if (ID >= 0 && ID <= MAX_MODBUS_ID_ADDRESS) { // Überprüfung, dass ID im gültigen Bereich liegt
unsigned long currentTime = millis();
if (currentTime - lastWriteTimeID >= WRITE_INTERVAL) { // Only write if enough time has passed
EEPROM.put(MODBUS_ID_ADDRESS, ID);
lastWriteTimeID = currentTime;
}
//EEPROM.write(MODBUS_ID_ADDRESS, ID);
} else {
Serial.println("Ungültige Modbus-ID. ID muss zwischen 0 und 255 liegen.");
}
}
void ModBusConfig::ResetModbusID() {
unsigned long currentTime = millis();
if (currentTime - lastWriteTimeID >= WRITE_INTERVAL) { // Only write if enough time has passed
SetModbusID(STANDARD_MODBUS_ID); // Reset to standard ID
lastWriteTimeID = currentTime;
}
}
void ModBusConfig::SetBaudRate(int BAUDRATE) {
int dividedBaudrate = BAUDRATE / 100;
unsigned long currentTime = millis();
// Überprüfung, dass Baudrate im gültigen Bereich liegt
if (BAUDRATE > 0 && BAUDRATE <= MAX_BAUD_RATE) {
if (dividedBaudrate != EEPROM.read(BAUD_RATE_ADDRESS)) {
if (currentTime - lastWriteTimeBaud >= WRITE_INTERVAL) {
EEPROM.put(BAUD_RATE_ADDRESS, dividedBaudrate);
lastWriteTimeBaud = currentTime;
}
}
} else {
Serial.println("Ungültige Baudrate. Baudrate muss zwischen 0 und 115200 liegen.");
}
}
void ModBusConfig::ResetBaudRate() {
unsigned long currentTime = millis();
if (currentTime - lastWriteTimeBaud >= WRITE_INTERVAL) {
SetBaudRate(STANDARD_MODBUS_BAUDRATE); // Reset to standard Baud rate
lastWriteTimeBaud = currentTime;
}
}
int ModBusConfig::GetModbusID() {
int MbID = EEPROM.read(MODBUS_ID_ADDRESS);
return MbID;
}
int ModBusConfig::GetBaudRate() {
int Baudrate = EEPROM.read(BAUD_RATE_ADDRESS);
return Baudrate;
}

37
include/ModBusConfig.h Normal file
View File

@ -0,0 +1,37 @@
#ifndef MODBUS_CONFIG_H
#define MODBUS_CONFIG_H
#include <Arduino.h>
class ModBusConfig {
public:
ModBusConfig(); // Konstruktor ohne Parameter
void SetModbusID(int ID);
void SetBaudRate(int BAUDRATE);
void ResetModbusID(); // Method to reset Modbus ID
void ResetBaudRate(); // Method to reset Baud Rate
int GetModbusID();
int GetBaudRate();
private:
/*
In diesem Beispiel wird Adresse 0 für die Modbus-ID und Adresse 2 für die Baudrate verwendet.
Diese Adressen sind willkürlich gewählt und sollten nicht mit anderen Daten im EEPROM überlappen.
*/
static const int MODBUS_ID_ADDRESS = 0; // Speicheradresse für Modbus-ID
static const int BAUD_RATE_ADDRESS = 2; // Speicheradresse für Baudrate
static const int MAX_BAUD_RATE = 38400; // Maximal unterstützte Baudrate
static const int MAX_MODBUS_ID_ADDRESS = 254; // Maximal unterstützte Baudrate
static const int STANDARD_MODBUS_ID = 22;
static const int STANDARD_MODBUS_BAUDRATE = 9600;
unsigned long lastWriteTimeID = 0; // Last write time for Modbus ID
unsigned long lastWriteTimeBaud = 0; // Last write time for Baud rate
const unsigned long WRITE_INTERVAL = 120000; // 2 minutes in milliseconds
};
#endif

View File

0
include/ModbusHandler.h Normal file
View File

View File

@ -0,0 +1,113 @@
/*
Insgesamt ermöglicht die ModBusConfig-Klasse das Speichern und Abrufen von Modbus-Konfigurationsdaten (ID und Baudrate) in einem EEPROM.
Dies ist besonders nützlich für Anwendungen, bei denen Konfigurationsdaten zwischen den Stromzyklen erhalten bleiben sollen.
Die Klasse abstrahiert die EEPROM-Operationen und bietet eine benutzerfreundliche Schnittstelle zur Verwaltung von Modbus-Konfigurationen.
*/
#ifndef ModbusSlaveConfigToEEPROM_H
#define ModbusSlaveConfigToEEPROM_H
#include <Arduino.h>
#include <EEPROM.h>
class ModBusConfig {
public:
ModBusConfig(); // Konstruktor ohne Parameter
void SetModbusID(int ID);
void SetBaudRate(int BAUDRATE);
void ResetModbusID(); // Method to reset Modbus ID
void ResetBaudRate(); // Method to reset Baud Rate
int GetModbusID();
int GetBaudRate();
private:
/*
In diesem Beispiel wird Adresse 0 für die Modbus-ID und Adresse 2 für die Baudrate verwendet.
Diese Adressen sind willkürlich gewählt und sollten nicht mit anderen Daten im EEPROM überlappen.
*/
static const int MODBUS_ID_ADDRESS = 0; // Speicheradresse für Modbus-ID
static const int BAUD_RATE_ADDRESS = 2; // Speicheradresse für Baudrate
static const int MAX_BAUD_RATE = 38400; // Maximal unterstützte Baudrate
static const int MAX_MODBUS_ID_ADDRESS = 254; // Maximal unterstützte Baudrate
static const int STANDARD_MODBUS_ID = 22;
static const int STANDARD_MODBUS_BAUDRATE = 9600;
unsigned long lastWriteTimeID = 0; // Last write time for Modbus ID
unsigned long lastWriteTimeBaud = 0; // Last write time for Baud rate
const unsigned long WRITE_INTERVAL = 120000; // 2 minutes in milliseconds
};
/*
Konstruktor: Der Konstruktor initialisiert die Modbus-ID und die Baudrate auf Standardwerte (1 und 9600),
falls die EEPROM-Werte nicht gesetzt sind (d.h. wenn sie 0xFF sind).
*/
ModBusConfig::ModBusConfig() {
// Optional: Initialisieren Sie die EEPROM-Werte, falls erforderlich
if (EEPROM.read(MODBUS_ID_ADDRESS) == 0xFF) {
SetModbusID(STANDARD_MODBUS_ID); // Setze Standard ID
}
if (EEPROM.read(BAUD_RATE_ADDRESS) == 0xFF) {
SetBaudRate(STANDARD_MODBUS_BAUDRATE); // Setze Standard Baudrate
}
}
void ModBusConfig::SetModbusID(int ID) {
if (ID >= 0 && ID <= MAX_MODBUS_ID_ADDRESS) { // Überprüfung, dass ID im gültigen Bereich liegt
unsigned long currentTime = millis();
if (currentTime - lastWriteTimeID >= WRITE_INTERVAL) { // Only write if enough time has passed
EEPROM.put(MODBUS_ID_ADDRESS, ID);
lastWriteTimeID = currentTime;
}
//EEPROM.write(MODBUS_ID_ADDRESS, ID);
} else {
Serial.println("Ungültige Modbus-ID. ID muss zwischen 0 und 255 liegen.");
}
}
void ModBusConfig::ResetModbusID() {
unsigned long currentTime = millis();
if (currentTime - lastWriteTimeID >= WRITE_INTERVAL) { // Only write if enough time has passed
SetModbusID(STANDARD_MODBUS_ID); // Reset to standard ID
lastWriteTimeID = currentTime;
}
}
void ModBusConfig::SetBaudRate(int BAUDRATE) {
int dividedBaudrate = BAUDRATE / 100;
unsigned long currentTime = millis();
// Überprüfung, dass Baudrate im gültigen Bereich liegt
if (BAUDRATE > 0 && BAUDRATE <= MAX_BAUD_RATE) {
if (dividedBaudrate != EEPROM.read(BAUD_RATE_ADDRESS)) {
if (currentTime - lastWriteTimeBaud >= WRITE_INTERVAL) {
EEPROM.put(BAUD_RATE_ADDRESS, dividedBaudrate);
lastWriteTimeBaud = currentTime;
}
}
} else {
Serial.println("Ungültige Baudrate. Baudrate muss zwischen 0 und 115200 liegen.");
}
}
void ModBusConfig::ResetBaudRate() {
unsigned long currentTime = millis();
if (currentTime - lastWriteTimeBaud >= WRITE_INTERVAL) {
SetBaudRate(STANDARD_MODBUS_BAUDRATE); // Reset to standard Baud rate
lastWriteTimeBaud = currentTime;
}
}
int ModBusConfig::GetModbusID() {
int MbID = EEPROM.read(MODBUS_ID_ADDRESS);
return MbID;
}
int ModBusConfig::GetBaudRate() {
int Baudrate = EEPROM.read(BAUD_RATE_ADDRESS);
return Baudrate;
}
#endif

View File

@ -1,66 +0,0 @@
/*
Insgesamt ermöglicht die ModBusConfig-Klasse das Speichern und Abrufen von Modbus-Konfigurationsdaten (ID und Baudrate) in einem EEPROM.
Dies ist besonders nützlich für Anwendungen, bei denen Konfigurationsdaten zwischen den Stromzyklen erhalten bleiben sollen.
Die Klasse abstrahiert die EEPROM-Operationen und bietet eine benutzerfreundliche Schnittstelle zur Verwaltung von Modbus-Konfigurationen.
*/
#ifndef ModbusSlaveConfigToEEPROM_H
#define ModbusSlaveConfigToEEPROM_H
#include <Arduino.h>
#include <EEPROM.h>
class ModBusConfig {
public:
ModBusConfig(); // Konstruktor ohne Parameter
void SetModbusID(int ID);
void SetBaudRate(int BAUDRATE);
int GetModbusID();
int GetBaudRate();
private:
static const int MODBUS_ID_ADDRESS = 0; // Speicheradresse für Modbus-ID
static const int BAUD_RATE_ADDRESS = 1; // Speicheradresse für Baudrate
static const int MAX_BAUD_RATE = 115200; // Maximal unterstützte Baudrate
};
ModBusConfig::ModBusConfig() {
// Optional: Initialisieren Sie die EEPROM-Werte, falls erforderlich
if (EEPROM.read(MODBUS_ID_ADDRESS) == 0xFF) {
SetModbusID(1); // Setze Standard ID
}
if (EEPROM.read(BAUD_RATE_ADDRESS) == 0xFF) {
SetBaudRate(9600); // Setze Standard Baudrate
}
}
void ModBusConfig::SetModbusID(int ID) {
if (ID >= 0 && ID <= 255) { // Überprüfung, dass ID im gültigen Bereich liegt
EEPROM.write(MODBUS_ID_ADDRESS, ID);
} else {
Serial.println("Ungültige Modbus-ID. ID muss zwischen 0 und 255 liegen.");
}
}
void ModBusConfig::SetBaudRate(int BAUDRATE) {
int dividedBaudrate = BAUDRATE / 100;
// Überprüfung, dass Baudrate im gültigen Bereich liegt
if (BAUDRATE > 0 && BAUDRATE <= MAX_BAUD_RATE) {
if (dividedBaudrate != EEPROM.read(BAUD_RATE_ADDRESS)) {
EEPROM.write(BAUD_RATE_ADDRESS, dividedBaudrate);
}
} else {
Serial.println("Ungültige Baudrate. Baudrate muss zwischen 0 und 115200 liegen.");
}
}
int ModBusConfig::GetModbusID() {
return EEPROM.read(MODBUS_ID_ADDRESS);
}
int ModBusConfig::GetBaudRate() {
int Baudrate = EEPROM.read(BAUD_RATE_ADDRESS) * 100;
return Baudrate;
}
#endif

View File

@ -1,144 +1,241 @@
#include <Arduino.h> // Einbindung der Arduino-Bibliothek für grundlegende Funktionen
#include <Wire.h> // Bibliothek für die I2C-Kommunikation
#include <ModbusSlave.h> // Modbus-Bibliothek für die Kommunikation als Slave
#include <SHT2x.h> // Bibliothek für den SHT2x-Sensor (Temperatur & Luftfeuchtigkeit)
#include <Arduino.h>
#include <Wire.h>
#include <ModbusSlave.h>
#include <SHT2x.h>
#include "ModbusSlaveConfigToEEPROM.h" // Inkludiere die Header-Datei für ModBusConfig
//include <ModBusConfig.h> wenn aktiviert wird, dann probleme
// -------------------------
// Definitions
// -------------------------
// Statische Definition von Modbus-ID und Baudrate
#define SLAVE_ID 8 // Modbus-Slave-Adresse (ID)
#define SERIAL_BAUDRATERS485 9600 // Baudrate für die serielle RS485-Kommunikation
#define SERIAL_PORTRS485 Serial // Serielle Schnittstelle für RS485
#define SLAVE_ID 8
#define SERIAL_BAUDRATERS485 9600
#define SERIAL_PORTRS485 Serial
// RS485-Konfiguration
#define RS485_CTRL_PIN 8 // Steuer-Pin für den RS485-Bus (Richtungskontrolle)
#define OutPutPin 9 // Pin für digitalen Ausgang
#define RS485_CTRL_PIN 8
#define OutPutPin 9
// Register-Arrays für Modbus
uint8_t ReadCoilRegister[] = {0, 1, 2}; // Coil-Register für digitale Werte (Lesen)
uint8_t output_pins[] = {0, 1}; // Liste der digitalen Ausgänge
uint8_t ReadInputRegister[] = {0, 1, 2, 3, 4, 5, 6, 7}; // Input-Register für analoge Werte (Lesen)
// -------------------------
// Global Variables
// -------------------------
// Register Arrays für Modbus
uint8_t ReadCoilRegister[] = {0, 1, 2};
uint8_t output_pins[] = {0,1,2,3};
uint8_t ReadInputRegister[] = {0,1,2,3,4,5,6,7};
uint8_t HoldingRegister[] = {0,1,2};
// Größen der Register-Arrays berechnen
uint8_t ReadCoilRegister_size = sizeof(ReadCoilRegister) / sizeof(ReadCoilRegister[0]);
uint8_t output_pins_size = sizeof(output_pins) / sizeof(output_pins[0]);
uint8_t ReadInputRegister_size = sizeof(ReadInputRegister) / sizeof(ReadInputRegister[0]);
uint8_t HoldingRegister_size = sizeof(HoldingRegister) / sizeof(HoldingRegister[0]);
int ValueInputOne = 0; // Variable zur Speicherung eines Eingabewertes
int ValueInputOne = 0;
// Modbus-Objekt initialisieren, abhängig von der RS485-Steuerleitung
#ifdef RS485_CTRL_PIN
Modbus slave(SERIAL_PORTRS485, SLAVE_ID, RS485_CTRL_PIN);
#else
Modbus slave(SERIAL_PORTRS485, SLAVE_ID);
#endif
// -------------------------
// Function Definitions
// -------------------------
/*
Instanz der ModBusConfig-Klasse
Aktuell keine Verwendung, eine Testimplementierung, nur Ausgabezwecke
*/
ModBusConfig modbusConfig;
// Funktion zur Steuerung der digitalen Ausgänge über Modbus
uint8_t writeDigitalOut(uint8_t fc, uint16_t address, uint16_t length) {
// Prüfen, ob die Adresse und Länge innerhalb des gültigen Bereichs liegen
if (address > output_pins_size || (address + length) > output_pins_size) {
return STATUS_ILLEGAL_DATA_ADDRESS; // Fehlercode zurückgeben
return STATUS_ILLEGAL_DATA_ADDRESS;
}
// Durchlaufen der angegebenen Register-Adressen
for (uint16_t i = 0; i < length; i++) {
// Lesen des Coil-Werts aus dem Modbus-Puffer und entsprechend den Ausgang setzen
if (slave.readCoilFromBuffer(i) == 1) {
digitalWrite(OutPutPin, HIGH); // Ausgang einschalten
} else {
digitalWrite(OutPutPin, LOW); // Ausgang ausschalten
}
switch (i) {
case 0:
digitalWrite(OutPutPin, slave.readCoilFromBuffer(i) == 0 ? HIGH : LOW);
break;
case 1:
if (slave.readCoilFromBuffer(i) == 1){
modbusConfig.ResetModbusID();
}
break;
case 2:
if (slave.readCoilFromBuffer(i) == 1) {
modbusConfig.ResetBaudRate();
}
break;
case 3:
digitalWrite(OutPutPin, slave.readCoilFromBuffer(i) == 1 ? HIGH : LOW);
break;
default:
// Optional: Handle cases where 'i' is greater than 3, if necessary
break;
}
return STATUS_OK; // Erfolgreiche Verarbeitung
}
return STATUS_OK;
}
// Funktion zum Lesen von Coil-Register-Werten (Digitale Eingänge)
// Funktion zum Lesen von Coil-Register-Werten
uint8_t fReadCoilRegister(uint8_t fc, uint16_t address, uint16_t length) {
// Prüfen, ob die Adresse und Länge innerhalb des gültigen Bereichs liegen
if (address > ReadCoilRegister_size || (address + length) > ReadCoilRegister_size) {
return STATUS_ILLEGAL_DATA_ADDRESS; // Fehlercode zurückgeben
return STATUS_ILLEGAL_DATA_ADDRESS;
}
// Durchlaufen der Register-Adressen und Werte setzen
for (uint16_t i = 0; i < length; i++) {
if (i == 0) {
slave.writeCoilToBuffer(i, digitalRead(OutPutPin)); // Wert des digitalen Ausgangs zurückgeben
slave.writeCoilToBuffer(i, digitalRead(OutPutPin));
} else if (i == 1) {
slave.writeCoilToBuffer(i, 0); // Platzhalterwert
slave.writeCoilToBuffer(i, 0);
} else if (i == 2) {
slave.writeCoilToBuffer(i, 1); // Platzhalterwert
slave.writeCoilToBuffer(i, 1);
}
}
return STATUS_OK; // Erfolgreiche Verarbeitung
return STATUS_OK;
}
// Funktion zum Lesen von Input-Register-Werten (Analoge Werte)
// Funktion zum Lesen von Input-Register-Werten
uint8_t fReadInputRegister(uint8_t fc, uint16_t address, uint16_t length) {
// Prüfen, ob die Adresse und Länge innerhalb des gültigen Bereichs liegen
if (address > ReadInputRegister_size || (address + length) > ReadInputRegister_size) {
return STATUS_ILLEGAL_DATA_ADDRESS; // Fehlercode zurückgeben
return STATUS_ILLEGAL_DATA_ADDRESS;
}
for (uint16_t i = 0; i < length; i++) {
// Dummy-Werte für Temperatur und Luftfeuchtigkeit
float temperatur = 21.21;
float humidity = 55.55;
float temperatur = 21.21; // Dummy-Wert für Temperatur
float humidity = 55.55; // Dummy-Wert für Luftfeuchtigkeit
switch (i) {
case 0:
slave.writeRegisterToBuffer(i, millis() / 1000); // Laufzeit des Systems in Sekunden
slave.writeRegisterToBuffer(i, millis() / 1000); // Zeit in Sekunden
break;
case 1:
slave.writeRegisterToBuffer(i, SERIAL_BAUDRATERS485); // Baudrate des Modbus
slave.writeRegisterToBuffer(i, modbusConfig.GetBaudRate()); // Baudrate aus der ModBusConfig-Klasse
break;
case 2:
slave.writeRegisterToBuffer(i, SLAVE_ID); // Slave-ID
slave.writeRegisterToBuffer(i, modbusConfig.GetModbusID()); // Slave-ID aus der ModBusConfig-Klasse
break;
case 3:
slave.writeRegisterToBuffer(i, static_cast<int>(temperatur * 100)); // Temperatur in 1/100 °C
case 3: {
slave.writeRegisterToBuffer(i, static_cast<int>(temperatur * 100));
break;
case 4:
slave.writeRegisterToBuffer(i, static_cast<int>(humidity * 100)); // Luftfeuchtigkeit in 1/100 %
}
case 4: {
slave.writeRegisterToBuffer(i, static_cast<int>(humidity * 100));
break;
case 5: {
// Berechnung der absoluten Luftfeuchtigkeit
const double UG = 8314.3; // J/(kmol*K), universelle Gaskonstante
const double mw = 18.016; // kg/kmol, Molekulargewicht von Wasserdampf
const double K = 273.15; // Konstante für Kelvin-Umrechnung
const double tp = 6.1078; // hPa, Triplettpunkt von Wasser
double absolutHumidity = (100000 * mw / UG * humidity / 100 * tp *
pow(10, ((7.5 * temperatur) / (239 + temperatur))) /
(temperatur + K)) * 100;
slave.writeRegisterToBuffer(i, static_cast<int>(absolutHumidity)); // Absolute Feuchtigkeit schreiben
}
case 5: {
const double UG = 8314.3; // J/(kmol*K), universelle Gaskonstante
const double mw = 18.016; // kg/kmol, Molekulargewicht des Wasserdampfes
const double K = 273.15; // Konstante für Kelvin-Umrechnung
const double tp = 6.1078; // hPa, Triplettpunkt von Wasser
double absolutHumidity = (100000 * mw / UG * humidity / 100 * tp * pow(10, ((7.5 * temperatur) / (239 + temperatur))) / (temperatur + K)) * 100;
slave.writeRegisterToBuffer(i, static_cast<int>(absolutHumidity));
break;
}
case 6:
slave.writeRegisterToBuffer(i, 5); // Platzhalterwert für Helligkeitssensor
slave.writeRegisterToBuffer(i, 5); // Platzhalter für Helligkeitswert
break;
case 7:
slave.writeRegisterToBuffer(i, digitalRead(OutPutPin)); // Status des digitalen Ausgangs
slave.writeRegisterToBuffer(i, digitalRead(OutPutPin)); // Zustand des Ausgangs
break;
}
}
return STATUS_OK; // Erfolgreiche Verarbeitung
return STATUS_OK;
}
// Write function for holding registers
uint8_t fWriteHoldingRegister(uint8_t fc, uint16_t address, uint16_t length) {
if (address > HoldingRegister_size || (address + length) > HoldingRegister_size) {
return STATUS_ILLEGAL_DATA_ADDRESS;
}
/*if (address >= sizeof(HoldingRegister) / sizeof(HoldingRegister[0]) || (address + length) > sizeof(HoldingRegister) / sizeof(HoldingRegister[0])) {
return STATUS_ILLEGAL_DATA_ADDRESS;
}*/
for (uint16_t i = 0; i < length; i++) {
int value = slave.readRegisterFromBuffer(i);
HoldingRegister[address + i] = value;
// Use switch-case for specific register addresses
switch (address + i) {
case 0:
modbusConfig.SetModbusID(value); // Update Modbus ID in EEPROM
break;
case 1:
modbusConfig.SetModbusID(value); // Update Modbus ID in EEPROM
break;
case 2:
modbusConfig.SetBaudRate(value); // Update Baud rate in EEPROM
break;
default:
// No specific action for other addresses
break;
}
}
return STATUS_OK;
}
// Optional: Read function for holding registers
uint8_t fReadHoldingRegister(uint8_t fc, uint16_t address, uint16_t length) {
if (address > HoldingRegister_size || (address + length) > HoldingRegister_size) {
return STATUS_ILLEGAL_DATA_ADDRESS;
}
/*if (address >= sizeof(HoldingRegister) / sizeof(HoldingRegister[0]) || (address + length) > sizeof(HoldingRegister) / sizeof(HoldingRegister[0])) {
return STATUS_ILLEGAL_DATA_ADDRESS;
}*/
for (uint16_t i = 0; i < length; i++) {
// Add specific data to holding registers
switch (address + i) {
case 0: // Modbus ID
slave.writeRegisterToBuffer(i, modbusConfig.GetModbusID());
break;
case 1: // Modbus ID
slave.writeRegisterToBuffer(i, modbusConfig.GetModbusID());
break;
case 2: // Baud rate
slave.writeRegisterToBuffer(i, modbusConfig.GetBaudRate());
break;
default: // Other data from HoldingRegister array
slave.writeRegisterToBuffer(i, HoldingRegister[address + i]);
break;
}
}
return STATUS_OK;
}
// -------------------------
// Setup and Loop Functions
// -------------------------
void setup() {
pinMode(RS485_CTRL_PIN, OUTPUT); // RS485-Steuerpin als Ausgang setzen
digitalWrite(RS485_CTRL_PIN, LOW); // RS485 auf Empfangsmodus setzen
pinMode(RS485_CTRL_PIN, OUTPUT);
digitalWrite(RS485_CTRL_PIN, LOW); // RS485-Empfang aktivieren
SERIAL_PORTRS485.begin(SERIAL_BAUDRATERS485); // Serielle Kommunikation starten
slave.begin(SERIAL_BAUDRATERS485); // Modbus initialisieren
SERIAL_PORTRS485.begin(SERIAL_BAUDRATERS485);
slave.begin(SERIAL_BAUDRATERS485);
// Modbus-Callback-Funktionen registrieren
// Modbus-Handler registrieren
slave.cbVector[CB_WRITE_COILS] = writeDigitalOut;
slave.cbVector[CB_READ_DISCRETE_INPUTS] = fReadCoilRegister;
slave.cbVector[CB_READ_INPUT_REGISTERS] = fReadInputRegister;
slave.cbVector[CB_WRITE_HOLDING_REGISTERS] = fWriteHoldingRegister;
slave.cbVector[CB_READ_HOLDING_REGISTERS] = fReadHoldingRegister;
//slave.cbVector[CB_WRITE_INPUT_REGISTERS] = fWriteInputRegister; // Registrierung der Schreib-Funktion
pinMode(OutPutPin, OUTPUT); // Digitalen Ausgangspin als Ausgang setzen
digitalWrite(OutPutPin, LOW); // Ausgang auf LOW setzen (Standardzustand)
pinMode(OutPutPin, OUTPUT);
digitalWrite(OutPutPin, LOW);
}
void loop() {
slave.poll(); // Modbus-Anfragen verarbeiten
slave.poll(); // Verarbeitet ankommende Modbus-Anfragen
}