Hi,
bisher hatte ich immer einen Raspberry + Relaiskarte für die Steuerung von Relais zur Schaltung von Lasten verwendet. Hat funktioniert.
Da ich immer mal neu Projekte benötige, hab ich für ca. 200€ eine Kleinsteuerung Finder Opta Advanced gekauft.
Sicher geht auch der kleinere Typ vom Opta, nur RS485 sollte er haben.
Damit kann man, da ein Arduino verbaut ist, schön seine Software schreiben und aktuell einen Growatt per RS485 - Modbus RTU abfragen.
Hier meine erster Code.
//Solarsteuerung mit Opta RS485 Modbus RTU
#include <ArduinoModbus.h>
#include <ArduinoRS485.h>
//Modbus RS485
constexpr auto baudrate { 9600 };
constexpr auto bitduration { 1.f / baudrate };
constexpr auto preDelayBR { bitduration * 9.6f * 3.5f * 1e6 };
constexpr auto postDelayBR { bitduration * 9.6f * 3.5f * 1e6 };
//LED
const int StatusLed[] = {LED_D0, LED_D1, LED_D2, LED_D3};
const int NUM_LED_and_Relais = 4;
// Relais
int relais[] = {D0, D1, D2, D3};
int soc = 0;
void setup() {
Serial.begin(9600);
while (!Serial);
// Initialize LED_BUILTIN as an output
pinMode(LED_RESET, OUTPUT);
pinMode(LED_USER, OUTPUT);
// Initialize LED_D0-D3 as an output
for (int i = 0; i < NUM_LED_and_Relais; i++) {
pinMode(StatusLed[i], OUTPUT);
pinMode(relais[i], OUTPUT);
}
pinMode(BTN_USER, INPUT);
RS485.setDelays(preDelayBR, postDelayBR);
// Start the Modbus RTU client
if (!ModbusRTUClient.begin(baudrate, SERIAL_8N1)) {
Serial.println("Failed to start Modbus RTU Client!");
while (1);
}
}
void loop() {
// ModbusRTUClient.inputRegisterRead
// Read 10 discrete input values from (server) id 42,
if (!ModbusRTUClient.inputRegisterRead(1,1014)) {
Serial.print("ERROR: ");
Serial.println(ModbusRTUClient.lastError());
digitalWrite(LED_RESET, LOW);
soc = 0;
} else {
digitalWrite(LED_RESET, HIGH);
soc = ModbusRTUClient.inputRegisterRead(1,1014);
Serial.println(soc);
}
//Warmwasser
if (soc >= 10){digitalWrite(relais[0], HIGH); digitalWrite(StatusLed[0],HIGH);}
else{digitalWrite(relais[0], LOW);digitalWrite(StatusLed[0],LOW);}
//Warmwasser 2
if (soc >= 20){digitalWrite(relais[1], HIGH); digitalWrite(StatusLed[1],HIGH);}
else{digitalWrite(relais[1], LOW);digitalWrite(StatusLed[1],LOW);}
//Frei
if (soc >= 30){digitalWrite(relais[2], HIGH); digitalWrite(StatusLed[2],HIGH);}
else{digitalWrite(relais[2], LOW);digitalWrite(StatusLed[2],LOW);}
//Frei
if (soc >= 40){digitalWrite(relais[1], HIGH); digitalWrite(StatusLed[3],HIGH);}
else{digitalWrite(relais[3], LOW);digitalWrite(StatusLed[3],LOW);}
delay(1000);
}