Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Seite 2 von 4 ErsteErste 1234 LetzteLetzte
Ergebnis 11 bis 20 von 31

Thema: Auslesen eines Temperatursensors über MODBUS an WAGO SPS

  1. #11
    SPS_A ist offline Benutzer
    Themenstarter
    Registriert seit
    15.05.2013
    Beiträge
    58
    Danke
    4
    Erhielt 7 Danke für 7 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Ok, vorhin hatte ich das testweise auch einfach mal mit der 2 im Request eingegeben. Da kamen dann auch 2 Werte in den Anfangsbereich des Array. Ich probier das morgen früh dann direkt weiter. Weiterhin will ich dann probieren die Systematik einzubauen, dass der Zyklus wiederholt wird.

    Könntest du mir das mit dem POINTER_TO_REAL noch genauer beschreiben? Ich hab grade keine CoDeSys Software vor mir, aber wird die Variable genauso über F2 definiert und ist dann dort irgendwo hinterlegt? Oder reicht es einfach zu schreiben "pTemperatur: POINTER TO REAL;" in den lokalen Variablen? Und wie würde ich dann den Wert "ADR(Wert)" zuweisen?

    Vielen Dank nochmals für deine Hilfe, viele Grüße

  2. #12
    Registriert seit
    12.07.2011
    Beiträge
    19
    Danke
    0
    Erhielt 4 Danke für 4 Beiträge

    Standard

    Hintergrundinfo:

    Alle Datentypen sind im tiefsten Kern nichts anderes als eine Aneinandereihung von Bytes. Bei INT sind es 2, bei REAL sind es 4 etc. Der Datentyp gibt lediglich an, wie die Ansammlung von Bytes zu interpretieren ist. Die in CoDeSys zur Verfügung stehenden Funktionen erlauben meist nur eine Konvertierung auf der "bereits interpretierten" Ebene. So kann man aus einem REAL mit Wert 21.4 einen INT mit Wert 21 machen. Was nicht so ohne weiteres geht, ist die Neuinterpretation der Bytes, d.h. man kann nicht aus 2 Worten (4 Bytes) einen REAL (ebenfalls 4 Bytes) erschaffen. Schön wäre ja eine Funktion, die ich mit 2 Worten füttere und hinten kommt ein REAL heraus. So etwas muss man sich selbst schreiben, nachdem man verstanden hat, wie das geht.

    Auf die schnelle gibt es aber folgende Lösung:

    Du nagelst dein Wert-Array an eine feste Adresse im Speicher, z.B.:

    Code:
    Wert AT %MD0: ARRAY[0..124] OF WORD;
    Dann nagelst du auch deine Temperatur-Variable an die gleiche Adresse im Speicher, z.B.:

    Code:
    Temperatur AT %MD0: REAL;
    Damit stehen die Daten aus der RESPONSE einerseits als WORD-Array zur Verfügung. Andererseits werden die ersten beiden Worte dieses Array aber auch über die Variable Temperatur als REAL interpretiert. Das wäre eine vorläufige, halbwegs elegante Typkonvertierung.


    Eine zweite Lösung:

    Du definierst dir im lokalen Variablenteil (oberes Fenster) eine Variable vom Typ "Zeiger auf REAL" und eine REAL-Variable Temperatur:

    Code:
    pTemperatur: POINTER TO REAL;
    Temperatur: REAL;
    Im Programmteil schreibst du zwei Zuweisungen:
    1. Adresse von Wert[0] (Baustein "Eingang") auf den Zeiger pTemperatur (Baustein "Ausgang")
    2. Inhalt von pTemperatur (Baustein "Eingang") auf Temperatur (Baustein "Ausgang")

    [ ADR(Wert[0]) ]-----[ pTemperatur ]
    [ pTemperatur^ ]-----[ Temperatur ]

    Wichtig ist der Inhaltsoperator "^" hinter pTemperatur. Er gibt an, auf welchen Wert der Zeiger pTemperatur zeigt. Er ist das Gegenstück zu "ADR()".

    Beide Varianten funktionieren nur dann richtig, wenn die Reihenfolge der beiden Worte, die den REAL-Wert beschreiben, korrekt ist. Ist das nicht der Fall, muss die oben bereits erwähnte eigene Funkton her. Dazu mehr, wenn es nötig wird.

  3. #13
    SPS_A ist offline Benutzer
    Themenstarter
    Registriert seit
    15.05.2013
    Beiträge
    58
    Danke
    4
    Erhielt 7 Danke für 7 Beiträge

    Standard

    Hallo Snert,

    vielen Dank wieder für deine schnelle Antwort und auch den "Exkurs" zu den Datentypen. Ich hatte die letzten 3 Tage leider kaum Zeit um mich mit der Materie zu beschäftigen, aber ab morgen kanns hoffentlich wieder weitergehen. Ich müsste mir dann bei Gelegenheit sicherlich mal die einzelnen Datentypen anschauen, aber ich denke das ist im Moment noch nicht ganz so dringend.

    Ich werde dann zuerst deine beiden beschriebenen Möglichkeiten testen, an den Wert bzw. die Werte zu kommen. Dazu habe ich überlegt, eine Abfrage einzubauen, die zB. alle 5 Sekunden einen Wert abfragt. Also nach 5 Sekunden CO2, dann wieder nach 5 Sekunden die Temperatur und dann nach weiteren 5 Sekunden die rel. Feuchte. Dazu würde ich analog dem Vorgehen bisher 2 weitere Abfrageblöcke reinsetzen mit dem zugehörigen Registerwert. Dies würde ich probieren über den Timer zu realiseren. Dein beschriebenes Vorgehen würde ich dann analog für die 3 Werte durchführen, dazu müsste ich mir dann wahrscheinlich die Speicheradressierung anschauen, oder? Also welche Speicherblöcke es noch außer "%MD0" gibt. Die Deklaration des Array und der Wert-Variablen würde dann auch oben in dem Bereich für die lokalen Varibalen erfolgen, analog zu der zweiten Methode?
    Wenn beide Methoden nicht klappen sollten (Also weiter keine "richtigen" Messwerte rauskommen sollten), stände ich sicherlich ziemlich auf dem Schlauch wie man das zustande bringt. Da würd ich mich natürlich über ein wenig Hilfe sehr freuen. Aber vielen Dank natürlich nochmals für deine bisherige Hilfe und Lösungsvorschläge, ich mach mich morgen früh direkt dran. Ich würde parallel dazu auch gerne probieren, einen zweiten Sensor vom gleichen Typ ins System zu bringen. Da hab ich überlegt, dass man diesen ja erstmal adressieren müsste, da die Default-ID "1" ja schon von dem ersten Slave belegt ist. Mein geplantes Vorgehen wäre dann wie folgt:
    1) Der Sensor, der ID Nummer 2 bekommen soll wird an 24V/0V/RS485-Klemme angeschlossen
    2) Die Funktion, die eine ID zuweist, wird irgendwie definiert. ("6 - Write Single Register")
    3) Der Sensor bekommt dann die ID 2
    4) Der Sensor mit der ID 1 wird wieder wie folgt angeschlossen: Klemme1/Klemme5<->A/B Sensor 1<->A/B Sensor 2<->(Abschlusswiderstand?), beide jeweils mit Spannungsversorgung

    Ich melde mich sicherlich morgen mittag direkt wieder, entweder mit Verzweiflung oder dem nächsten kleinen Fortschritt!

    Viele Grüße

  4. #14
    Registriert seit
    12.07.2011
    Beiträge
    19
    Danke
    0
    Erhielt 4 Danke für 4 Beiträge

    Standard

    Bevor du dir die Mühe machst, alle Bausteine zu vervielfachen, um alle Werte aus allen Slaves zu bekommen, solltest du mal ausprobieren, ob durch Erhöhen der READ_QUANTITY von 2 auf 6 (READ_ADDRESS=0) alle drei Werte des Sensors fehlerfrei gelesen werden (Wert[0] - Wert[5]). Dann würde ich Variante 2 zum Umwandeln in REAL-Werte favorisieren.

    Für den zweiten Sensor brauchst du dann nur die Slave-Address zyklisch wechseln. Da du nur eine serielle Klemme hast, brauchst du keinen weiteren Masterbaustein. Die würden sich nur gegenseitig behindern...

    Das Vorgehen für den zweiten Sensor ist ok.

    Tip:
    Vielleicht wäre ein Umstellen beider Slave-Adressen weg von der standardmäßigen 1 zu überlegen. Denn dann kannst du weitere Slaves einbinden, ohne einen der bestehenden abzuklemmen.

  5. #15
    SPS_A ist offline Benutzer
    Themenstarter
    Registriert seit
    15.05.2013
    Beiträge
    58
    Danke
    4
    Erhielt 7 Danke für 7 Beiträge

    Standard

    Hallo Snert,

    vielen Dank für die Antwort. Ich habe gerade ein wenig nach deinem Ratschlag rumgebastelt. Die Anzahl der gelesenen Werte auf 6 erhöhen klappt, bei 7 oder noch mehr würde dann eine Fehlermeldung kommen. Ich habe einmal einen Screenshort von dem "laufenden" Modell erstellt, eingeloggt und gestartet (noch mit der force-Funktion, das mit dem Timer scheint noch nicht ganz zu klappen).

    Screen_MODBUS.jpg

    Der angezeigte CO2-Wert (1290) entspricht auch genau dem was auf dem Display angezeigt wird, bei Temperatur und rel. Feuchte scheint es noch nicht zu klappen. Aber morgen gehts dann erst einmal ans testen eines zweiten Slaves. Dass mit dem Master hatte ich auch so aufgefasst, also ein Master für (in meinem Fall werdens max. 20 Sensoren) "beliebig" viele Sensoren. Als Abschlusswiderstand würde ich einfach die beiden kabelenden (A und B) an einen Widerstand mit 220 Ohm klemmen, da ich gerade nichts anderes zur Verfügung habe. Oder ist das bei 2 Slaves mit nur kurzer Kabellänge so nicht in Ordnung?

    Viele Grüße und danke nochmals

  6. #16
    Registriert seit
    12.07.2011
    Beiträge
    19
    Danke
    0
    Erhielt 4 Danke für 4 Beiträge

    Standard

    Für die Umwandlung der Worte in REAL sind natürlich die Adressen von Wert[0] (CO2), Wert[2] (Temp.) und Wert[4] (Hum.) zu nehmen, da REAL jweils 2 Worte benötigt. In Summe also 6 Worte, die du ja auch eingestellt hast als READ_QUANTITY.

    Sind die Variablen Temperatur, CO2 und RH vom Typ REAL? Poste doch bitte mal die 6 Werte von Wert[0] - Wert[5]. Dann kann man erkennen, ob die Worte paarweise zu drehen sind, damit ein ordentlicher REAL herauskommt.

    Ob und welchen Abschlusswiderstand man nehmen sollte, hängt von vielen Dingen ab. Hier im Forum gibt es entsprechend Beiträge dazu, z.B. Abschlusswiderstaende fuer Modbus (RS485).

    Wenn man einen Abschlusswiderstand verwendet, so sind in der Tat Leitung A und B über diesen Widerstand zu verbinden, und zwar hinter dem letzten Slave.

  7. #17
    SPS_A ist offline Benutzer
    Themenstarter
    Registriert seit
    15.05.2013
    Beiträge
    58
    Danke
    4
    Erhielt 7 Danke für 7 Beiträge

    Standard

    Hallo,

    vielen Dank für den Hinweis. Klar, das mit den Adressen ist ja logisch. Hier sind die 6 Werte der 3 Messdaten im laufenden Betrieb:

    Screen_MODBUS_2.jpg


    Wie kann man denn aus den 6 Array-Werten erkennen, wie daraus 3 REAL-Werte "entstehen"? Also z.B. "17463" und "49152" zu dem Wert Tempertur werden? (Hier merk ich gerade, dass ich die ersten beiden Variablen verdreht hab, aber das dürfte für die Rechnung ja erstmal egal ein)
    Die Variablen sind vom Typ REAL, hier noch mal ein Screenshot im ausgeloggten Zustand:

    Screen_MODBUS_3.jpg

    Danke auch für den Hinweis zum Abschlusswiderstand. Dort scheint es ja verschiedene Ansichten zu geben. Wenn ich soweit komme, mus ich mich da wohl noch ein wenig detaillierter informieren.

    Viele Grüße

    edit:

    Ein kleiner Nachtrag: ich habe gerade einmal für die Werte der Adresse 1,3 und 5 eingegeben. Jetzt kommen auf einmal "richtige" Werte raus, also so wie sie auch auf dem Display angezeigt werden:

    Screen_MODBUS_4.jpg

    Interpretiert die CoDeSys dann sozusagen selbstständig den eingegebenen Wert und den vorherigen als Messwert und wanelt diesen in REAL um?
    Geändert von SPS_A (18.06.2013 um 10:06 Uhr)

  8. #18
    Registriert seit
    12.07.2011
    Beiträge
    19
    Danke
    0
    Erhielt 4 Danke für 4 Beiträge

    Standard

    Dass das Ergebnis bei Verwendung der Adressen 1, 3 und 5 korrekt zu sein scheint, hängt mit der Gleichartigkeit der Real-Werte zusammen. Zu sehen daran, dass die Werte 0, 2 und 4 ungefähr gleich sind. Wenn man also das Haupt-WORD statt mit dem Nach-WORD mit dem Vor-WORD kombiniert, ist das zunächst nicht auffällig, aber dennoch falsch. Auffällig wird es, wenn die Zehnerpotenzen der Zahlen stark variieren, z.B. 0.1 / 2.4e-12 / 4.5e14.

    Somit ist auch deutlich, dass die WORDs zu drehen sind, damit ein ordentlicher REAL herauskommt. Was du benötigst, ist folgende Funktion "DW_TO_R" (geschrieben in ST), die zwei WORD in einen REAL verwandelt. Dabei kann man die WORDs als Eingangsparameter beliebig setzen. In deinem Fall ist die Reihenfolge der Werte jeweils 1-0, 3-2 und 5-4. Das Ergebnis der Funktion ist schon der REAL-Wert und kann direkt den Variablen CO2, Temperatur und Feuchtigkeit zugewiesen werden.

    Code:
    FUNCTION DW_TO_R : REAL
    VAR_INPUT
    	w1: WORD; (* erstes  Wort, z.B. Wert[1] von aussen angelegt *)
    	w2: WORD; (* zweites Wort, z.B. Wert[0] von aussen angelegt *)
    END_VAR
    VAR
    	w: ARRAY[0..1] OF WORD;
    	pR: POINTER TO REAL;
    END_VAR
    
    
    (* Worte in das 2er-Array schreiben *)
    w[0] := w1;
    w[1] := w2;
    
    (* POINTER TO REAL auf die Adresse des 2er-Array setzen *)
    pR := ADR(w);
    
    (* Inhalt des Pointers übergeben an Funktion *)
    DW_TO_R := pR^;
    Die Funktion nutzt die Tatsache, dass ein POINTER TO REAL die beiden Worte, auf die er zeigt, als REAL deutet. Dass sie ursprunglich von einem 2-Wort-Array stammen, ist der Kunstgriff.

  9. #19
    SPS_A ist offline Benutzer
    Themenstarter
    Registriert seit
    15.05.2013
    Beiträge
    58
    Danke
    4
    Erhielt 7 Danke für 7 Beiträge

    Standard

    Hallo, vielen Dank wieder für deine Antwort. Jetzt bin ich leider ein wenig verwirrt, da ich doch zumindest nach meiner Einschätzung richtige Messwerte hatte, die auch synchron mit der Anzeige auf dem Display des Sensors sind. Ich hatte mir das so erklärt, dass durch die "force" Abfrage alle paar ms ein Wert abgefragt und geschrieben wird, also parallel zu der Anzeige im Display.

    Jetzt habe ich deine beschriebene Abfrage einmal versucht zu integrieren. Dazu habe ich einen neuen Baustein (Typ Funktion, ST, REAL) eingefügt. Bei diesem habe ich oben dann die loklen Variablen definiert und unten den Code reinkopiert. Einloggen klappt auch ohne Probleme und in dem Hauptbaustein PLC_RPG die Werte wie vorher angezeigt. In dem Baustein DW_TO_R steht überall ein "?":

    Screen_MODBUS_5.jpg

    Dies wird dann ja daran liegen, dass die Variablen lokal sind und nicht in den Bblock übertragen werden. war es überhaupt richtig dafür eine neue Funktion anzulegen? Ich steht aber gerade zugegebenermaßen noch ein wenig auf dem Schlauch, warum und vor allem was genau in dem Programm gemacht wird. Also die beiden Werte "w1" und "w2" werden in das 2er-Array "w"geschrieben. Auf dieses Arry wird wieder der Pointer gesetzt und an die Funktion übergeben. Das kann ich soweit nachvollziehen. Aber es hapert noch wenig an dem Verständnis des "Zwecks" des ganzen, wahrscheinlich bin ich gerade nur froh endlich Messwerte zu sehen

    Hoffe du kannst meinen Horizont da ein wenig erweitern, viele Grüße bei dem sonnigen Wetter

  10. #20
    Registriert seit
    12.07.2011
    Beiträge
    19
    Danke
    0
    Erhielt 4 Danke für 4 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Im Baustein muss alles "?" sein, weil es eine Funktion ist. Der Geltungsbereich einer Funktion reicht nicht, um nach Zyklusende noch Werte anzeigen zu können. Welche denn auch? Der Baustein ist im laufenden Programm nur 1x definiert, wird aber 3x aufgerufen! Das geht also nicht. Bei Funktionsblöcken sieht das anders aus. Die haben einen reservierten, eigenen Speicherbereich, so dass man zwischendurch auch mal reinschauen kann.

    Zur Erklärung der Datenkonvertierung:

    Der Modbus-Masterbaustein füllt dein RESP.Data und damit letzendlich dein Array "Wert". Der Speicher der WAGO ist grundsätzlich wortweise arrangiert, wobei jedes Wort aus dem High- und dem Low-Byte besteht. Die Reihenfolge, in der die Worte aus dem Sensor sortiert sind, entspricht dem Datentyp "FLOAT INVERS" (laut Datenblatt). Diesen gibt es auf der WAGO nicht. Dreht man allerdings die Worte paarweise um, so entsteht der Datentyp REAL. Den kennt WAGO sehr gut. Man könnte auch sagen, dass man die beiden Worte des jeweiligen Wertes "rückwärts" lesen muss, um sie korrekt zu deuten. "Rückwärts" geht aber nicht, daher müssen die Worte umgedreht werden in ihrer Reihenfolge. Aus Wert[0]/Wert[1] wird Wert[1]/Wert[0] usw. Wenn man dann einen REAL-Pointer auf den Beginn eines "gedrehten" WORD-Pärchens zeigen läßt, dann ist der Inhalt des Pointers ein REAL-Wert. Und nichts anderes macht die Funktion. Das folgende Bild versucht das etwas zu verdeutlichen.
    Forum_Speicheraufteilung.png

Ähnliche Themen

  1. Energiezähler über Modbus auslesen
    Von arkeq im Forum CODESYS und IEC61131
    Antworten: 5
    Letzter Beitrag: 16.01.2017, 09:01
  2. Antworten: 10
    Letzter Beitrag: 30.10.2012, 13:06
  3. WAGO-SPS und Modbus-Protokoll?
    Von Oxy im Forum Sonstige Steuerungen
    Antworten: 6
    Letzter Beitrag: 22.08.2011, 02:09
  4. Anbindung KBR-Multimess WAGO über Modbus
    Von fraggle-m im Forum CODESYS und IEC61131
    Antworten: 1
    Letzter Beitrag: 29.06.2011, 15:57
  5. Antworten: 0
    Letzter Beitrag: 05.08.2010, 08:14

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •