Modbus

Hallo,

ich hätte mal eine Frage zum Modbus. Ich möchte einen PID Regler ansteuern. Messen kann ich auf dem Bus aber der Regler hat keinerlei Regung gezeigt. Vielleicht kann mir jemand helfen.
Danke schon im Voraus. ModbusMaster.h hab ich verwendet.

#define Heiz_REG_Ausg (0x0021)
...
ModbusMaster Heiz (serialModbus, 1)
...
Int Serial Modbus = 3
...
Heiz.begin(9600);
...
Heiz.writesingleregister(Heiz_REG_Ausg, 1) // Relais 1- 0 ist aus 1 ist an
...
Das müsste doch eigentlich reichen. Oder was mach ich falsch.

Diggsn:
Hallo,

ich hätte mal eine Frage zum Modbus. Ich möchte einen PID Regler ansteuern. Messen kann ich auf dem Bus aber der Regler hat keinerlei Regung gezeigt. Vielleicht kann mir jemand helfen.
Danke schon im Voraus. ModbusMaster.h hab ich verwendet.

#define Heiz_REG_Ausg (0x0021)
...
ModbusMaster Heiz (serialModbus, 1)
...
Int Serial Modbus = 3
...
Heiz.begin(9600);
...
Heiz.writesingleregister(Heiz_REG_Ausg, 1) // Relais 1- 0 ist aus 1 ist an
...
Das müsste doch eigentlich reichen. Oder was mach ich falsch.

Was soll das sein? Ein Sketch, dann kann es nicht funktionieren.

Bitte den kompletten Sketch in Code-Tags (</>) setzen, dann können wir auch was erkennen und helfen.

Schau ins Datenblatt, wie du den PID Regler ansteuern musst. Es handelt sich hier ja scheinbar um ein externes Gerät.

Welche Heizung?
Wie sieht die Ansteuerung aus?
BaudRate Richtig?
Du schreibst Register willst aber nur 1 Coil ansteuern muss das bei der Heizung so sein?
Ist die Baudrate Korrekt?
Welche Adresse hat dein Modbus Slave? Ist die 1 Korrekt?
ASCII Modbus oder RTU?

Den ganzen Sketch bitte posten evtl auch eine Beschreibung deiner Heizung bzw der Adressen

=> 42 <=

Gruß
DerDani

Es fehlen viele Informationen.

Und den Link zu der Modbus Library nicht vvergessen.

Konfiguration des Reglers hab ich gemacht. 9600Baud, 8 datenbits, 1 Stoppbit, keine Parität,
Slave 1.

Jumo cControl 08
Adresse ist 0x0021
Datentyp ist Int / Bit0
Signalbezeichnung ist Ausgang K1Relais (0=0x0001) Binärausgang 1 / 0=aus 1 = an

Da ist alles was ich habe oder was im Datenblatt steht. ModbusMaster ist die hier von der Arduino Seite. Code kann ich nicht in Tags setzten da der Browser hier veraltet ist und nicht alles richtig anzeigt.

http://playground.arduino.cc/Code/ModbusMaster

#include <ModbusMaster.h>

#define Heiz_REG_Ausg (0x0021)

int SerialModbus=3;

ModbusMaster Heiz(SerialModbus, 1);

void setup()
{

Heiz.begin(9600);

void loop()
{

Heiz.writeSingleRegister(Heiz_REG_Ausg, 1);

}

Sorry geht grad leider nur so.

Wenn die Gegenstelle nur ein Relais ist, dann musst du den PID Regler selber machen in deinem Arduino Programm.

Das ist ein PID Regler. Der 4 Relais intern hat.

Ich habe mit das mal angeschaut in der DOKU und deine Adresse 0x0021 ist nur Read Only da kannst du nix schreiben du kannst nur den Zustand lesen:

Was willst du denn machen?
Schreiben der Ausgänge an Adresse 0x0025
hier:

Achtung zwei Bits musst du setzten.

Gruß
DerDani

Oh cool danke. Wer lesen kann ist klar im Vorteil. >:( da kann das ja nicht gehen.
Wie schreibe ich die 2 bits?

int send = 0;

send |= (1<<BIT0) | (1<<BIT8); // K1 ON
transmitFunc(send);
send &= ~((1<<BIT0) | (1<<BIT8)); // K1 OFF
transmitFunc(send);

#include <ModbusMaster.h>

#define Heiz_REG_Ausg (0x0025)

int SerialModbus=3;
int Send1=0;
int Send2=0;

ModbusMaster Heiz(SerialModbus, 1);

void setup()
{

send1 |= (1<<BIT0) | (1<<BIT8); // K1 ON
transmitFunc(send1);
send2 &= ~((1<<BIT0) | (1<<BIT8)); // K1 OFF
transmitFunc(send2);

Heiz.begin(9600);

void loop()

{

Heiz.writeSingleRegister(Heiz_REG_Ausg, send1); //k1 an
delay(1000);
Heiz.writeSingleRegister(Heiz_REG_Ausg, send2); //k1 aus
delay(1000);

}

Quasi so? Kann es leider grad nicht testen.

Im Prinzip ja, denke aber das transmitFunc nur eine Pseudofunktion ist.

Du solltest dir auf jedenfall mal "Bitmanipulation in C" anschauen.

Steht ja auch schon in der Beschreibung
BIN HEX DEZ
K1= 0000 0001 0000 0001 = 0x0101 = 257
K2= 0000 0010 0000 0010 = 0x0202 = 514
K3= 0000 0100 0000 0100 = 0x0404 = 1028
K4= 0000 1000 0000 1000 = 0x0808 = 2056

Kann man ja fest hinterlegen dann brauchst du die Bits ja Manipulieren

Gruß
DerDani

Danke, also das geht schonmal ohne Bitverschiebung. Wenn ich dem Ctron einfach ne 257 für K1 schicke.

XXX.writeSingleRegister(XXXX, 257);

Wenn ich in das 0x0037 Register einen float schreiben will geht das aber nicht. Zumindestens übernimmt er das nicht.

XXX.writeSingleRegister(XXXXX, 0x42c80000); // Dez=100 = IEEE 754 Hex = 0x42c80000
oder
XXX.writeSingleRegister(XXXXX, 100); //geht auch nicht.
Wo liegt hier noch der Hund begraben?

Evtl muss du einen Float definieren und den dann senden. Sicher bin ich mir nicht
also.
float sendfloat=10.0;
und dann den hier machen
XXX.writeSingleRegister(XXXXX, sendfloat);
Probier das mal so Float ist auch ein 4Byte Wert.
^Mangels wissen falsch ^

Korrektur siehe unten
Gruß
DerDani

uint8_t writeSingleRegister(uint16_t, uint16_t);

Einen Float zu schicken scheint hier nicht möglich zu sein, das senden von Werte größer 2Byte ist nicht vorgesehen. float hat 4Byte.

Warum aber er die 100 nicht nimmt, weiß ich nicht. Ich habe mich mit der IEEE754 Norm zur Umwandlung von Zahlen noch nicht beschäftigt.

Habe nochma nachgelesen
Modbus hat kein 32Bit(4Bytes) float. Hier gibt es Infos dazu:

>Klick1<
>Klick2<
Das ist ein bisschen Arbeit.
Gruß
DerDani

Jetzt komm ich nicht mehr mit...
Hab es jetzt nochmal so versucht aber das geht auch nicht.

XXX.writeSingleRegister(Heiz_REG_Temp, lowbyte (100); oder lowWord
XXX.writeSingleRegister(Heiz_REG_Temp+1, highbyte (100); oder lowWord

das geht nicht und

XXX.writeSingleRegister(Heiz_REG_Temp, lowbyte (0x42c80000)); oder lowWord
XXX.writeSingleRegister(Heiz_REG_Temp+1, highbyte (0x42c80000)); oder lowWord

geht auch nicht... und dann steh ich am Bahnhof.

Schau mal im zweiten Link man muss den 4byte Float auseinander nehmen und dann verdrehen (SWAP) und dann übertragen nicht zweimal das gleiche.
Highbyte und Lowbyte beziehen sich auf ein Word (2Bytes).

union float2word{
  float f;
  word words[2];
}Test;



void setup(){
}

void loop(){
  Test.f=1.234;
XXX.writeSingleRegister(Heiz_REG_Temp,Test.words[0] );    // oder die [0] zu [1]
XXX.writeSingleRegister(Heiz_REG_Temp+1,Test.words[1]); // anderums
}

Sowas in der Richtung müsste laufen