Hello, please take a look at this code. I want to read from danfoss vlt 6000 parameter 511. according to the manual, the address should look like 511 * 10 - 1, that is 5109 decimal.
when I try to read the parameter I get error 226. I try twist A and B, use other pins on wemos, use another modbus libraries. I want only know, that this code is fine. then i can buy another one max485 and try again.
i have connected DI to D6 and RO to D5, RE and DE to D3. A - 68 (danfoss) B- 69 (danfoss)
other things like webserial and arduino ota are there because the converter is already mounted and working.
danfoss vlt 6000 manual
Modbus RTU danfoss manual
full code here, shortest code is in third post
#include <ModbusMaster.h>
#include <SoftwareSerial.h>
#include <ESP8266WiFi.h>
#include <map>
#include <ESPAsyncWebServer.h>
#include <WebSerial.h>
#include <ArduinoOTA.h>
#define SLAVE_ID 1
#define FIRST_REG 0
#define REG_COUNT 2
#define MAX485_DE D3 // D5
#define MAX485_RE D3 // D6
// Nastavenie Wi-Fi
const char* ssid = "WiFi"; // Zmeň na svoje SSID
const char* password = "pass"; // Zmeň na svoje heslo
uint16_t holdingRegisterAddress = 511; // Predvolená hodnota
uint16_t data = 0;
// Inicializácia SoftwareSerial
SoftwareSerial S(D5, D6); // RX, TX
AsyncWebServer server(80);
ModbusMaster mb;
// IP adresa a subnet pre ESP8266
IPAddress localIP(192, 168, 1, 11);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
// Mapa pre faktory konverzie
std::map<int, float> faktor_konverzie = {
{500, 1.0}, {501, 1.0}, {502, 1.0}, {503, 1.0},
{504, 1.0}, {505, 1.0}, {506, 1.0}, {507, 1.0},
{508, 1.0}, {509, 0.1}, {510, 0.001}, {511, 0.001},
{512, 0.1}, {513, 0.01}, {514, 0.01}, {515, 1.0},
{516, 0.01}, {517, 0.1}, {518, 1.0}, {519, 1.0},
{520, 1.0}, {521, 1.0}, {522, 0.1}, {523, 0.1},
{524, 0.0001}, {525, 0.1}, {526, 0.1}
};
// Funkcia pre vykreslenie stránky
void handleRoot(AsyncWebServerRequest *request) {
String html = "<!DOCTYPE html><html><head><title>Modbus Hodnota</title>";
html += "<script src='https://code.jquery.com/jquery-3.6.0.min.js'></script>";
html += "<script src='https://cdn.jsdelivr.net/npm/chart.js'></script>";
html += "<style>canvas { width: 100% !important; height: 300px !important; }</style>";
html += "</head><body>";
html += "<h1>Hodnota z registra:</h1>";
// Formulár na zadávanie adresy holding registra
html += "<form id='registerForm'>";
html += "Zadaj adresu holding registra: <input type='number' id='registerAddress' value='" + String(holdingRegisterAddress) + "' min='0'>";
html += "<input type='submit' value='Načítať'>";
html += "</form>";
// Canvas pre graf
html += "<canvas id='myChart'></canvas>";
html += "<script>";
html += "var ctx = document.getElementById('myChart').getContext('2d');";
html += "var myChart = new Chart(ctx, {";
html += "type: 'line',";
html += "data: { labels: [], datasets: [{ label: 'Hodnota registra', data: [], borderColor: 'rgba(75, 192, 192, 1)', borderWidth: 1 }] },";
html += "options: { scales: { y: { beginAtZero: true } } }";
html += "});";
// AJAX na aktualizáciu grafu
html += "function fetchValue(address) {";
html += "$.ajax({";
html += "url: '/getValue?address=' + address,";
html += "success: function(data) {";
html += "data = parseInt(data);"; // Prevod na celé číslo
html += "if (myChart.data.labels.length >= 10) {";
html += "myChart.data.labels.shift();"; // Odstránenie najstaršej hodnoty
html += "myChart.data.datasets[0].data.shift();"; // Odstránenie najstaršej hodnoty
html += "}";
html += "myChart.data.labels.push(new Date().toLocaleTimeString());"; // Pridanie časovej značky
html += "myChart.data.datasets[0].data.push(data);"; // Pridanie novej hodnoty
html += "myChart.update();"; // Aktualizácia grafu
html += "}";
html += "});";
html += "}";
// Obsluha formulára
html += "$('#registerForm').submit(function(event) {";
html += "event.preventDefault();"; // Zastavenie predvoleného správania formulára
html += "var address = $('#registerAddress').val();";
html += "fetchValue(address);"; // Volanie funkcie fetchValue s zadanou adresou
html += "});";
html += "</script>";
html += "</body></html>";
request->send(200, "text/html", html);
WebSerial.println("request send");
}
// Funkcia pre získanie hodnoty registra
void handleGetValue(AsyncWebServerRequest *request) {
uint8_t result;
WebSerial.println("handleGetValue");
// Získanie adresy z požiadavky
if (request->hasParam("address")) {
holdingRegisterAddress = request->getParam("address")->value().toInt();
}
// Prepočet adresy na hexadecimálnu formu pre Danfoss
int modbusAddress = holdingRegisterAddress * 10 - 1;
WebSerial.println(modbusAddress);
digitalWrite(MAX485_DE, HIGH);
digitalWrite(MAX485_RE, HIGH);
// Inicializácia výsledku
result = mb.readHoldingRegisters(modbusAddress, 2); // Pokus o čítanie
digitalWrite(MAX485_DE, LOW);
digitalWrite(MAX485_RE, LOW);
// Spracovanie výsledku
if (result == mb.ku8MBSuccess) {
float faktor = faktor_konverzie[holdingRegisterAddress];
float processedValue = mb.getResponseBuffer(0) * faktor;
request->send(200, "text/plain", String(processedValue));
WebSerial.println(processedValue);
} else {
request->send(500, "text/plain", "Chyba: " + String(result));
WebSerial.println("result chyba " + String(result));
}
}
void setup() {
S.begin(9600); // Spustenie SoftwareSerial
mb.begin(SLAVE_ID, S); // Inicializácia Modbus s ID a prenosom
// Nastavenie Wi-Fi
WiFi.config(localIP, gateway, subnet);
WiFi.begin(ssid, password);
// Čakanie na pripojenie k Wi-Fi
while (WiFi.status() != WL_CONNECTED) {
delay(2000);
}
// Nastavenie WebSerial pre výstup logov
WebSerial.begin(&server);
// Nastavenie rout pre server
server.on("/", HTTP_GET, handleRoot);
server.on("/getValue", HTTP_GET, handleGetValue);
// Spustenie webového servera
server.begin();
// Inicializácia OTA
ArduinoOTA.onStart([]() {
String type;
if (ArduinoOTA.getCommand() == U_FLASH) {
type = "sketch"; // je to nahratie sketchu
} else { // U_SPIFFS
type = "filesystem"; // je to nahratie SPIFFS
}
// Uložení názvu pre použitie pri debugovaní
WebSerial.print("Start updating " + type);
});
ArduinoOTA.onEnd([]() {
WebSerial.println("\nEnd");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
WebSerial.printf("Progress: %u%%\r", (progress / total) * 100); // Opravená chyba tu
});
ArduinoOTA.onError([](ota_error_t error) {
WebSerial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) {
WebSerial.println("Auth Failed");
} else if (error == OTA_BEGIN_ERROR) {
WebSerial.println("Begin Failed");
} else if (error == OTA_CONNECT_ERROR) {
WebSerial.println("Connect Failed");
} else if (error == OTA_RECEIVE_ERROR) {
WebSerial.println("Receive Failed");
} else if (error == OTA_END_ERROR) {
WebSerial.println("End Failed");
}
});
ArduinoOTA.begin();
pinMode(MAX485_DE, OUTPUT);
pinMode(MAX485_RE, OUTPUT);
digitalWrite(MAX485_RE, LOW);
digitalWrite(MAX485_DE, LOW);
}
void loop() {
WebSerial.loop(); // Spracovanie WebSerial
ArduinoOTA.handle(); // Spracovanie OTA
delay(10); // Krátka oneskorenie pre stabilitu
}