Modbus Starthindernisse...

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Antworten
Benutzeravatar
theo
Beiträge: 10697
Registriert: Mo 11. Sep 2006, 19:01

Modbus Starthindernisse...

Beitrag von theo »

Ich habe mir eine kleines Gerät von Shenzen FNIRSI namens "SG-003A" für CHF 40.- gekauft. Andreas kennt die Marke! :lol:
Sie nennen es "Signal Generator" weil sich unter "Process Calibrator" nur wenige etwas vorstellen können.
Das ist aber erst einmal egal.

Dieses Gerätchen kann man theoretisch via Modbus "fernsteuern" (über den USB Anschluss).

Nun habe ich echt überhaupt keine Ahnung von Modbus und glaube auch nicht, dass ich den ganzen Zauber verstehen will/muss.

Ich habe mal versucht, über QModBus eine Verbindung zu bekommen.
Das geht auch soweit. Ich denke, das Gerät ist "da". Es antwortet irgendwie, aber halt nur Fehlermeldungen.

qmodbus.png
qmodbus.png (115.24 KiB) 1369 mal betrachtet

Die Dokumentation legt nahe, dass hier keine Standard Codes verwendet werden. (z.B. Function code 101), soweit ich das verstehe (Anhang).

Bekanntlich ist jeder Anfang schwer, aber es wird echt mühsam, wenn beim ersten Mal schon alles eine Ausnahme ist.

Lohnt es sich überhaupt, hier weiter zu bohren?
Am Ende wäre natürlich eine Lazarus Anwendung schön, schlimmstenfalls auch über Linux Kommandoaufrufe.
Welche Möglichkeiten habe ich?

Danke.

P.S. Das "Modbus Diagnose Programm" von Corpsman habe ich mal ausprobiert sowie "mbpoll" auf der Shell, aber ich komme damit auch nicht direkt weiter.

P.S. Manual
Dateianhänge
SG-Series—modbus Use detailed instructions.pdf
(132.33 KiB) 113-mal heruntergeladen

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6512
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Modbus Starthindernisse...

Beitrag von af0815 »

Wie es der Zufall will, habe ich heute mit dem Fnirsi in einem Wurlitzer Fehler gesucht. Außerdem musste ich mich mit Modbus sehr intensiv in der Firma einarbeiten. Mal keine schlechte Kombination. Mal sehen was ich da herausfinde, wenn ich wieder zu Hause bin.

Ohne zu probieren aus den Stehgreif. Es sieght so aus, als wären damit die Reegister adressiert (40xxxxx) und nicht die Coils (Entsprechen Ein/Ausgängen auf SPS, Register sind den Merkern entsprechend). Die Doku beschreibt teilweise die Lowlevel Kommunikation. Entweder zur Erklärung oder weil das Modbus Protokoll nicht eingehalten wird. Kann ich jetzt ohne meine Unterlagen mal so nicht prüfen.

ich würde mit den Read 0x4 und Write 0x6 Befehlen da beginnen. 40001 bedeutet Read Register 0001, 4008 Read Register 0008. Wie gesagt, nach dem WE komme ich zu meinen Unterlagen.

@Theo, ich nehme an du arbeitest unter Linux. Der Name des seriellen Port verrät mir das. WIndows hätte mich bei dir verwundert.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
theo
Beiträge: 10697
Registriert: Mo 11. Sep 2006, 19:01

Re: Modbus Starthindernisse...

Beitrag von theo »

Danke erstmal! :D

Ich habe kaum Plan von der Theorie. Ich versuche nur mal mit den Tools die ich habe, ein "Hello World" hinzubekommen.
Fnirsi hat es ist in dem Beispiel "Firmware version" ja mal durchgespielt.

The command sent is: 01 64 9C 41 00 01 CF 86
01 is the slave address
64 is the function code //function code 100 becomes hexadecimal = 64
9C is the register address high byte
41 is the low byte of the register address
00 is the high byte of the number of registers
01 is the low byte of the number of registers
CF and 86 are CRC


Slave Address ist klar, dann kommt dieser ominöse Funktionscode (hier 101) der non-standard scheint und z.B. nicht in QModBus enthalten ist (Screenshot oben).
Danach kommt low und high von 40001 (9C41).
etc.

Kann man das eigentlich auch als einfach serielle Anfrage schicken, oder steckt für Modbus hier noch mehr dahinter?
Mit mbpoll habe ich es auch noch versucht, aber auch da steige ich nicht durch.
af0815 hat geschrieben: Sa 30. Nov 2024, 20:36 @Theo, ich nehme an du arbeitest unter Linux.
Ja.

Benutzeravatar
KoBraSoft
Beiträge: 114
Registriert: So 6. Jun 2021, 09:57
OS, Lazarus, FPC: die zu Zeit aktuellen Versionen, überwiegend Linux
CPU-Target: 64Bit 32 Bit
Kontaktdaten:

Re: Modbus Starthindernisse...

Beitrag von KoBraSoft »

theo hat geschrieben: Sa 30. Nov 2024, 20:58 Slave Address ist klar, dann kommt dieser ominöse Funktionscode (hier 101) der non-standard scheint und z.B. nicht in QModBus enthalten ist (Screenshot oben).
richtig
theo hat geschrieben: Sa 30. Nov 2024, 20:58 Kann man das eigentlich auch als einfach serielle Anfrage schicken, oder steckt für Modbus hier noch mehr dahinter?
Ja kann man, mache ich seit Jahren so. Ich verwende SendBuffer und RecvBufferEx von TBlockSerial von synaser von synapse.

Hier die Funktion ReadHoldingRegisters:

Code: Alles auswählen

function ReadHoldingRegisters(sPort: String; bSlave :byte; wStartAdr, wCount:word; var MyTabAntwort:TabAntwort): Boolean;
var
  ser         : TBlockSerial;
  abFrage     : array [0..7] of byte;
begin
  SetLength(myTabAntwort, wCount*2+5);
  abFrage[0] := bSlave;
  abFrage[1] := 3;						     // function code 
  abFrage[2] := hi(wStartAdr);                           // Startaddresse Hi Byte
  abFrage[3] := lo(wStartAdr);                           // Startaddresse Low Byte
  abFrage[4] := hi(wCount);                              // Anzahl Daten Hi Byte
  abFrage[5] := lo(wCount);                              // Anzahl Daten
  CalculateCRC16(abFrage);
  ser:=TBlockSerial.Create;

  try
    ser.LinuxLock:=False;
    ser.Connect(sPort);
    ser.config(19200,8,'N',2,false,true);
    ser.SendBuffer(@abFrage,8);
    ser.RecvBufferEx(@MyTabAntwort[0],Length(MyTabAntwort),150);
    Result := Test_crc(MyTabAntwort);
  finally
    ser.free;
  end;

und WriteHoldingRegisters:

Code: Alles auswählen

function WriteHoldingRegisters(sPort: String; const bSlave :byte; wStartAdr:word; awData: array of word;var abAntwort:TabAntwortWrite): Boolean;
var
  ser         : TBlockSerial;
  j           : integer;
  abTelegram  : array of byte;
  wCount      : word;

begin
  ser:=TBlockSerial.Create;
  ser.LinuxLock:=False;
  ser.config(19200,8,'N',2,false,true);
  ser.Connect(sPort);

  wCount := length(awData);
  SetLength(abTelegram,wCount*2+9);
  abTelegram[0] := bSlave;
  abTelegram[1] := 16;						// function code 
  abTelegram[2] := hi(wStartAdr);
  abTelegram[3] := lo(wStartAdr);
  abTelegram[4] := hi(wCount);
  abTelegram[5] := lo(wCount);
  abTelegram[6] := lo(wCount)*2;
  for j := 0 to wCount - 1 do begin
    abTelegram[j*2+7] := hi(awData[j]);
    abTelegram[j*2+8] := lo(awData[j]);
  end;
  abTelegram[j*2+9] := 0;
  abTelegram[j*2+10] := 0;
  CalculateCRC16(abTelegram);
  ser.SendBuffer(@abTelegram[0],wCount*2+9);                                 
  ser.RecvBufferEx(@abAntwort,SizeOf(abAntwort),120);
  Result := Test_crc(abAntwort);
  ser.free;

end;

dazu die Hilfsfunktionen CalculateCRC16:

Code: Alles auswählen

function CalculateCRC16(var Pkg:array of byte):Cardinal;
var
  crc,j,carry_flag,a:Cardinal;
  i,n:LongInt;
begin
  n:=Length(Pkg)-2;
  crc := $FFFF;
  i := 0;
  while (i<n) do begin
    crc :=crc xor Cardinal(pkg[i]);
    for j:=0 to 7 do begin
      a := crc;
      carry_flag := a and $0001;
      crc := crc shr 1;
      if (carry_flag=1) then
        crc := crc xor $A001;
    end;
    inc(i);
  end;
  pkg[n+1] := ((crc and $FF00) shr 8);
  pkg[n]   := (crc and 255);
  result := crc;
end;      

und Test_crc

Code: Alles auswählen

function Test_crc(const Pkg:array of byte):Boolean;
var
  crc,j,carry_flag,a:Cardinal;
  i,n:LongInt;
begin
  n := Length(Pkg)-2;
  crc := $FFFF;
  i := 0;
  while (i<n) do begin
    crc := crc xor Cardinal(pkg[i]);
    for j:=0 to 7 do begin
      a := crc;
      carry_flag := a and $0001;
      crc := crc shr 1;
      if (carry_flag=1) then
        crc := crc xor $A001;
    end;
    inc(i);
  end;

  Result := ((n+2)<=Length(Pkg)) and ((Cardinal(pkg[n+1])=(crc shr 8)) or (Cardinal(pkg[n])=(crc and 255)));

end;         
Du müsstest die function codes anpassen, dann sollte es gehen.

PS
Das ganze könnte man sicher eleganter programmieren, nur leider ich nicht. :D
Konrad

www.KoBraSoft.de

Benutzeravatar
theo
Beiträge: 10697
Registriert: Mo 11. Sep 2006, 19:01

Re: Modbus Starthindernisse...

Beitrag von theo »

@KoBraSoft: Danke!
Genau so gefällt mir das. Schön simpel... :D
Das "Hello World" (Versionsnummerabfrage) sieht schon mal gut aus!

Anfrage:
#01 (Dez:1)
#64 (Dez:100)
#9C (Dez:156)
#41 (Dez:65)
#00 (Dez:0)
#01 (Dez:1)
#CF (Dez:207)
#86 (Dez:134)

Antwort:
#01 (Dez:1)
#64 (Dez:100)
#02 (Dez:2)
#00 (Dez:0)
#40 (Dez:64)
#A6 (Dez:166)
#C0 (Dez:192)


Die Versionsnummer ist demnach 64 (#0040).
Klar, dass das noch nicht die ganze Geschichte ist, aber ein Anfang ist gemacht. :D

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6512
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Modbus Starthindernisse...

Beitrag von af0815 »

Ok, ich habe das mal Überlesen, das es um den SG-003A geht und nicht um das DSO-TC2. Das DSO hat zwar USB, wird aber nicht als Device richtig erkannt, mein Fehler.

KoBraSoft hat mit der einfachen Variante schon recht, man braucht manchmal den ganzen Overhead nicht, vor allen weil es sich ja um nur eine Handvoll Befehle handelt.

Ja , bei Modbus KANN mehr dahinter stecken, dann aber sollten auch die Spezifikationen eingehalten werden. Die einfache Lösung gefällt mir sogar sehr gut, die meisten Modbus Bibliotheken sind nicht so einfach aufgebaut, auch weil sie ja im Hintergrund laufen sollen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
theo
Beiträge: 10697
Registriert: Mo 11. Sep 2006, 19:01

Re: Modbus Starthindernisse...

Beitrag von theo »

@af0815: Kein Problem.

Aber die Doku ist ein Problem.
Die ist zu knapp, um zu verstehen wie das geht.
Ein Problem ist auch, dass sich die Doku wohl hauptsächlich auf die etwas leistungsfähigere Variante bezieht (SG-004A) und somit vieles gar nicht zutrifft für den SG-003A (Thermocouple, Resistance...).
Auch die Abkürzungen/Buchstaben verstehe ich nicht. z.B
Thermocouple is 1 is S, 2 is B, 3 is E, 4 is K, 5 is R, 6 is J, 7 is T, 8 is N,
Stochern im Nebel....

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6512
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Modbus Starthindernisse...

Beitrag von af0815 »

theo hat geschrieben: So 1. Dez 2024, 14:57 Auch die Abkürzungen/Buchstaben verstehe ich nicht. z.B
Thermocouple is 1 is S, 2 is B, 3 is E, 4 is K, 5 is R, 6 is J, 7 is T, 8 is N,
https://www.te.com/de/products/sensors/ ... types.html Vermutlich Type des Thermocouplelement. K und J sind häufig anzutreffen. Da geht es hauptsächlich darum, welche Materialien gepaart wurden und welche Kennlinie verwendet wird.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
theo
Beiträge: 10697
Registriert: Mo 11. Sep 2006, 19:01

Re: Modbus Starthindernisse...

Beitrag von theo »

Danke!

Gut, das kann ich schon mal vergessen. Dieses Feature besitzt meiner nicht, soweit ich weiss.
Im Prinzip wäre ich zufrieden, wenn ich bei dem Gerät vom PC aus mA und V auslesen sowie einstellen könnte (Vielleicht noch Frequenz).

Aber ich blicke aufgrund der Doku (noch) nicht wirklich durch, wie das funktioniert.

Spezifisch für mein Gerät gibt es noch diese Liste, sagt dir das etwas?

sg3modbus.png
sg3modbus.png (144.87 KiB) 1219 mal betrachtet

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6512
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Modbus Starthindernisse...

Beitrag von af0815 »

Man kann sich leider nur anhand der Beispiele durchprobieren. Die Werte aus den Beispielen kann man ja mit den Tabellen vergleichen, der Rest ist stures probieren.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
theo
Beiträge: 10697
Registriert: Mo 11. Sep 2006, 19:01

Re: Modbus Starthindernisse...

Beitrag von theo »

Es gibt ja kaum Beispiele, das ist das Problem.
Lazarusseitig funktioniert die Kommunikation schon, ich weiss nur nicht wie ich mit dem Gerät reden muss.

Wenn ich z.B. die Spannung (Ausgang) einstellen möchte, würde ich intuitiv einmal Fkt. 103 (Float write) nehmen, dann Adresse 40006
(Output Value).
Aber wie sage ich, dass ich V und nicht mA einstellen möchte?
Wie gebe ich den Wert mit?
Ist das ein zweistufiges Verfahren (Erst vllt. 40003 Output Signal, dann 40006)? Ist das üblich bei Modbus?
Ich weiss es nicht und aus der Doku werde ich nicht schlau.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6512
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Modbus Starthindernisse...

Beitrag von af0815 »

Das ist bei Modbus auch nicht festgelegt, du sagst nur welches Register oder Coil welchen Wert haben soll, der Rest ist auch Gerätespezifisch. Modbus ist nur der Datentransport, der Rest Anwendungsspezifisch.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Antworten