Hallo,
Anbei sende ich nochmals den aktuelle code der bei mir einwandfrei läuft. es stimmt schon das beim alten code wild kopiert wurde und dadurch vielleicht einige fehler entstanden sind..
Also bei dem Code kommen aktuelle Messdaten die Stimmen und im
Codesys wird der Modbus-Slave durchaus grün angezeigt. Es gehen keine Counter verloren...
Ich hab zuletzt nur irgendwie herum probiert plötzlich war es das richtige.
Zum Code:
/* Einbindung von Libraries:
mit <LIBRARYNAME> sucht der Präprozessor nach den libraries nur libraries-Ordner (wo sie beim Installieren über den Library Manager abgespeichert werden)
mit "LIBRARYNAME" sucht der Präprozessor nach den libraries zuerst im Ordner, wo das aktuell konmpilierte Programm abgespeichert ist.
Findet er da nichts, sucht er auch im Standard-libraries-Ordner (Libraries im Ordner des aktuellen Programms haben also Priorität,
falls bestimmte Libraries dort und im Standardordner existieren!)
*/
#include <ESP8266WiFi.h> // für ESP8266
//#include <WiFi.h> // ESP32
#include <DHT.h>
const char *ssid = "---";
const char *password = "---";
int ModbusTCP_port = 502;
//DEF Output ESP8266
const int DOutput1 = 14; // d5 pin board
const int DOutput2 = 0; // d6 pin board
const int DOutput3 = 2; // d7 pin board
//DEF Output ESP32
//const int DOutput1 = 14; // d5 pin board
//const int DOutput2 = 12; // d6 pin board
//const int DOutput3 = 13; // d7 pin board
unsigned long previousMillis = 0; // will store last time DHT was updated
unsigned long currentMillis = 0;
const long interval = 3000; // update interval DHT sensor data
#define DHTPIN 5 // Digital PIN D1 ESP8266!!!!!!!
//#define DHTPIN 27 // Digital PIN D1 ESP32!!!!!!!
#define DHTTYPE DHT11 // DHT 11
DHT dht(DHTPIN, DHTTYPE);
float temp = 0.0;
float hum = 0.0;
float T_max = -100.0;
float T_min = 100.0;
//////// Required for Modbus TCP / IP
const byte clientAddress = 1;
const byte maxInputRegister = 20;
const byte maxHoldingRegister = 20;
// Functions: 03/06/16 are 16 bit (analog) input/output registers, 0 is a broadcast to all bus members
const byte MB_FC_NONE = 0;
const byte MB_FC_READ_REGISTERS = 3; //implemented
const byte MB_FC_WRITE_REGISTER = 6; //implemented
const byte MB_FC_WRITE_MULTIPLE_REGISTERS = 16; //implemented
// MODBUS Error Codes (not imlemented here!)
//#define MB_EC_NONE 0
//#define MB_EC_ILLEGAL_FUNCTION 1
//#define MB_EC_ILLEGAL_DATA_ADDRESS 2
//#define MB_EC_ILLEGAL_DATA_VALUE 3
//#define MB_EC_SLAVE_DEVICE_FAILURE 4
// MODBUS MBAP offsets
//const byte MB_TCP_TID = 0; // transaction number, bytes 0+1, not used
//const byte MB_TCP_PID = 2; // protocoll ID (always 0x0000), bytes 2+3, not used
//const byte MB_TCP_LEN = 4; // number of bytes to follow + 2, bytes 4+5, not used here
const byte MB_TCP_UID = 6; // address of the client the message is send to, byte 6
const byte MB_TCP_FUNC = 7; // function, byte 7
const byte MB_TCP_REGISTER_START = 8; // data, 2 bytes (8+9), i.e. 16 bit
const byte MB_TCP_REGISTER_NUMBER = 10; // register, byte 10
int MBHoldingRegister[maxHoldingRegister]; // must not be unsigned if we want to store negative temperature values in here!
WiFiServer MBServer(ModbusTCP_port);
void connectWiFi() {
Serial.println(F("Connecting to WiFi"));
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
MBServer.begin();
Serial.println(F("connected!"));
Serial.print(F("ESP8266 Slave Modbus TCP/IP "));
Serial.print(WiFi.localIP());
Serial.print(":");
Serial.println(String(ModbusTCP_port));
Serial.println(F("Modbus TCP/IP Online"));
}
void setDOutputs() {
digitalWrite(DOutput1, MBHoldingRegister[3]);
digitalWrite(DOutput2, MBHoldingRegister[4]);
digitalWrite(DOutput3, MBHoldingRegister[5]);
}
void readDHT() {
temp = dht.readTemperature();
if (isnan(temp)) {
Serial.println(F("Failed to read temperature from DHT sensor!"));
} else {
if (T_max < temp) {
T_max = temp;
}
if (temp < T_min) {
T_min = temp;
}
MBHoldingRegister[0] = temp * 10;
Serial.print("akt. Temperatur: ");
Serial.print(temp);
Serial.print("\t[Max.: ");
Serial.print(T_max);
Serial.print(" degC\tMin.: ");
Serial.print(T_min);
Serial.println(" degC]");
}
// Read Humidity
hum = dht.readHumidity();
// if humidity read failed, don't change h value
if (isnan(hum)) {
Serial.println(F("Failed to read humidity from DHT sensor!"));
} else {
MBHoldingRegister[1] = hum * 10;
Serial.print("akt. Luftfeuchte: ");
Serial.print(hum);
Serial.println(" %");
}
}
void setup() {
pinMode(DOutput1, OUTPUT);
pinMode(DOutput2, OUTPUT);
pinMode(DOutput3, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT); // LED als Output definieren
digitalWrite(LED_BUILTIN, HIGH); // Switch onboard LED off
Serial.begin(115200);
delay(100);
dht.begin();
connectWiFi();
}
void loop() {
if (WiFi.status() != WL_CONNECTED) {
connectWiFi(); // reconnect to WiFi in case connection has been lost
}
/* Check if a client has connected / Modbus TCP/IP
server.available() gets a client that is connected to the server and has data available for reading.
The connection persists when the returned client object goes out of scope; you can close it by calling client.stop().
*/
WiFiClient client = MBServer.available();
if (!client) {
return; // no client connection available
}
// Modbus TCP/IP
while (client.connected()) {
// read temp and humidity sensor at a predefined interval
currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time you updated the DHT values
previousMillis = currentMillis;
readDHT();
}
byte ByteArray[260];
byte commandByte = MB_FC_NONE;
int Start;
int WordDataLength;
int ByteDataLength;
int MessageLength;
int i = 0;
while (client.available()) {
if (i > 259) {
Serial.println(F("Error: Client data does not fit into ByteArray variable!\n"));
return;
}
ByteArray
= client.read();
i++;
}
if (i == 0) { // got no data from PLC, skip rest of loop
continue;
}
// Ausgabe MB-Register, die benuetzt wurden (optional, kann weggelassen werden)
// Serial.print("Modbus register: ");
// for (int i = 0; i < 10; i++) {
// Serial.print("[");
// Serial.print(i);
// Serial.print("] ");
// Serial.print(MBHoldingRegister);
// }
// Serial.println();
//// routine Modbus TCP
if (ByteArray[MB_TCP_UID] == clientAddress) {
digitalWrite(LED_BUILTIN, LOW); // turn onboard LED on
Serial.print("Got commands addressed to me...");
commandByte = ByteArray[MB_TCP_FUNC]; // this byte tells the ESP what the Beckhoff wants it to do
Start = word(ByteArray[MB_TCP_REGISTER_START], ByteArray[MB_TCP_REGISTER_START + 1]);
WordDataLength = word(ByteArray[MB_TCP_REGISTER_NUMBER], ByteArray[MB_TCP_REGISTER_NUMBER + 1]);
// Handle request
switch (commandByte) {
case MB_FC_NONE: // do nothing
Serial.println("Nothing to do.");
break;
case MB_FC_READ_REGISTERS: // 03 Read Holding Registers
Serial.println("Read holding registers.");
ByteDataLength = WordDataLength * 2;
ByteArray[5] = ByteDataLength + 3; //Number of bytes after this one.
ByteArray[8] = ByteDataLength; //Number of bytes after this one (or number of bytes of data).
for (int i = 0; i < WordDataLength; i++) {
ByteArray[9 + i * 2] = highByte(MBHoldingRegister[Start + i]);
ByteArray[10 + i * 2] = lowByte(MBHoldingRegister[Start + i]);
}
MessageLength = ByteDataLength + 9;
client.write((const uint8_t *)ByteArray, MessageLength);
commandByte = MB_FC_NONE;
break;
case MB_FC_WRITE_REGISTER: // 06 Write Holding Register
Serial.println("Write holding registers.");
MBHoldingRegister[Start] = word(ByteArray[MB_TCP_REGISTER_NUMBER], ByteArray[MB_TCP_REGISTER_NUMBER + 1]);
ByteArray[5] = 6; //Number of bytes after this one.
MessageLength = 12;
client.write((const uint8_t *)ByteArray, MessageLength);
commandByte = MB_FC_NONE;
setDOutputs();
break;
case MB_FC_WRITE_MULTIPLE_REGISTERS: //16 Write Holding Registers
Serial.println("Write multiple holding registers.");
ByteDataLength = WordDataLength * 2;
ByteArray[5] = ByteDataLength + 3; //Number of bytes after this one.
for (int i = 0; i < WordDataLength; i++) {
MBHoldingRegister[Start + i] = word(ByteArray[13 + i * 2], ByteArray[14 + i * 2]);
}
MessageLength = 12;
client.write((const uint8_t *)ByteArray, MessageLength);
commandByte = MB_FC_NONE;
setDOutputs();
break;
}
digitalWrite(LED_BUILTIN, HIGH); // turn onboard LED off
}
Serial.println();
}
}