Moin,
nachfolgend meine Lösung um eine Fröling PE1 über die COM2-Schnittstelle mit einem Arduino Uno via RS232 Modbus RTU auszulesen.
Verwendet habe ich einen Arduino Uno und ein Seeed RSR232 Shield.
Der Code basiert auf den Bibliotheken "SoftwareSerial" und "ModbusMaster" (beide in der Library der Arduino IDE verfügbar).
Das Shield sitzt piggyback auf dem Arduino und wird per 9-poligem SubD Kabel mit der PE1 Hauptplatine verbunden.
Die ausgelesenen Daten werden z. Zt. nur auf dem seriellen Monitor der Arduino IDE ausgegeben; andere Ausgaben (Display, Umwandlung in Modbus TCP, etc) wären natürlich auch möglich.
Nachfolgend der C-Code.
Gruß
Fabian
C
/////////////////////////////////////////////////////////////////////////////////////////////////////
//Modbus RTU RS232 communication between Arduino Uno and Fröling PE1
//
//Author: fabulous
//
//v0.01, April 2023
//
//Arduino Uno/Seeed RS232 Shield with female SubD9 connector: pin 2 = Tx, pin 3 = Rx
//Fröling PE1 main board (FRKEM29) with male SubD9 connector (aka "COM2"): pin 2 = Rx, pin 3 = Tx
//in "Idle", both Tx pins have a voltage level /against GND on pin 5) of about -9V
#include <SoftwareSerial.h>
#include <ModbusMaster.h>
SoftwareSerial mbSerial(7, 6); //Tx pin, Rx pin; both on Seeed RS232 shield
ModbusMaster mbMaster;
void setup() {
//initialize serial I/F for SerMon
Serial.begin(9600);
Serial.println("Start");
Serial.println("");
//initialize serial I/F for Modbus communication via RS232 shield
mbSerial.begin(57600);
//start Modbus master (Arduino Uno with RS232 shield); define Modbus slave address ("2", Fröling PE1 is slave) and the serial I/F to be used ("mbSerial")
mbMaster.begin(2, mbSerial);
}
void loop() {
uint8_t mbResult;
//The following function codes are understood by the PE1:
//readCoilStatus = FC01 (corresponds to "2.2 Digitale Ausgänge lesen" in Fröling Modbus documentation)
//readInputStatus = FC02 ("2.3 Digitale Eingänge lesen")
//readHoldingRegisters = FC03 ("2.5 Parameter lesen")
//readInputRegisters = FC04 ("2.4 Aktuelle Werte lesen")
//writeSingleRegister = FC06 ("2.5 Parameter schreiben")
//request 2 byte (UINT16) of data from slave @ register address 0 (corresponds to offset 0 and thus to ID 30001 in Fröling modbus documentation)
mbResult = mbMaster.readInputRegisters(0, 2); //Offset 0, Kesseltemperatur
delay(2000);
if(mbResult == mbMaster.ku8MBSuccess) {
//print received data on SerMon
Serial.print("Kesseltemperatur: ");
Serial.print(mbMaster.getResponseBuffer(0)/2); //has to be scaled with factor 2, "SKAL"
Serial.println(" °C"); //"MEH"
} else {
//error in Modbus communication, print error code
Serial.print("Error: ");
Serial.println(mbResult);
}
mbMaster.clearResponseBuffer();
mbResult = mbMaster.readInputRegisters(1, 2); //Offset 1, Abgastemperatur
delay(2000);
if(mbResult == mbMaster.ku8MBSuccess) {
Serial.print("Abgastemperatur: ");
Serial.print(mbMaster.getResponseBuffer(0));
Serial.println(" °C");
} else {
Serial.print("Error: ");
Serial.println(mbResult);
}
mbMaster.clearResponseBuffer();
mbResult = mbMaster.readInputRegisters(1000, 2); //Offset 1000, Außentemperatur
delay(2000);
if(mbResult == mbMaster.ku8MBSuccess) {
Serial.print("Außentemperatur: ");
Serial.print(mbMaster.getResponseBuffer(0)/2);
Serial.println(" °C");
} else {
Serial.print("Error: ");
Serial.println(mbResult);
}
mbMaster.clearResponseBuffer();
mbResult = mbMaster.readInputRegisters(2000, 2); //Offset 2000, Puffertemperatur oben
delay(2000);
if(mbResult == mbMaster.ku8MBSuccess) {
Serial.print("Puffertemperatur oben: ");
Serial.print(mbMaster.getResponseBuffer(0)/2);
Serial.println(" °C");
} else {
Serial.print("Error: ");
Serial.println(mbResult);
}
mbMaster.clearResponseBuffer();
mbResult = mbMaster.readInputRegisters(2001, 2); //Offset 2001, Puffertemperatur Mitte
delay(2000);
if(mbResult == mbMaster.ku8MBSuccess) {
Serial.print("Puffertemperatur Mitte: ");
Serial.print(mbMaster.getResponseBuffer(0)/2);
Serial.println(" °C");
} else {
Serial.print("Error: ");
Serial.println(mbResult);
}
mbMaster.clearResponseBuffer();
mbResult = mbMaster.readInputRegisters(2002, 2); //Offset 2002, Puffertemperatur unten
delay(2000);
if(mbResult == mbMaster.ku8MBSuccess) {
Serial.print("Puffertemperatur unten: ");
Serial.print(mbMaster.getResponseBuffer(0)/2);
Serial.println(" °C");
} else {
Serial.print("Error: ");
Serial.println(mbResult);
}
mbMaster.clearResponseBuffer();
mbResult = mbMaster.readInputRegisters(1630, 2); //Offset 163, Boilertemperatur
delay(2000);
if(mbResult == mbMaster.ku8MBSuccess) {
Serial.print("Boilertemperatur: ");
Serial.print(mbMaster.getResponseBuffer(0)/2);
Serial.println(" °C");
} else {
Serial.print("Error: ");
Serial.println(mbResult);
}
mbMaster.clearResponseBuffer();
mbResult = mbMaster.readInputRegisters(711, 2); //Offset 711, Rücklauftemperatur WW-Zirkulation
delay(2000);
if(mbResult == mbMaster.ku8MBSuccess) {
Serial.print("Rücklauftemperatur WW-Zirkulation: ");
Serial.print(mbMaster.getResponseBuffer(0)/2);
Serial.println(" °C");
} else {
Serial.print("Error: ");
Serial.println(mbResult);
}
mbMaster.clearResponseBuffer();
mbResult = mbMaster.readInputRegisters(1030, 2); //Offset 1030, HK Vorlauftemperatur
delay(2000);
if(mbResult == mbMaster.ku8MBSuccess) {
Serial.print("HK Vorlauftemperatur: ");
Serial.print(mbMaster.getResponseBuffer(0)/2);
Serial.println(" °C");
} else {
Serial.print("Error: ");
Serial.println(mbResult);
}
mbMaster.clearResponseBuffer();
mbResult = mbMaster.readInputRegisters(1032, 2); //Offset 1030, Raumtemperatur
delay(2000);
if(mbResult == mbMaster.ku8MBSuccess) {
Serial.print("Raumtemperatur: ");
Serial.print(mbMaster.getResponseBuffer(0)/2);
Serial.println(" °C");
} else {
Serial.print("Error: ");
Serial.println(mbResult);
}
mbMaster.clearResponseBuffer();
Serial.println("------------------------------------");
}
Display More