Mehrere Busteilnehmer mit einem CP340 ansprechen

poppycock

Level-1
Beiträge
253
Reaktionspunkte
21
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich habe mehrere selbstgebaute Busteilnehmer (RS485) über einen selbstgebauten RS232<->RS485-Wandler an einen CP340 (seriell / ASCII / 8N1, 9600) angeschlossen. Die Busteilnehmer sind alphabetisch benannt.

Nun möchte ich aus einem vorbereiteten DB (DB3) das erste Zeichen ('a') nehmen und dieses seriell mit dem CP340 verschicken. Die in der SPS ankommenden Zeichen werden analysiert und wenn ein 'a' zurückgekommen ist, soll in einem anderen DB (DB4) der verwertbare ASCII-Wert als INT gespeichert werden. Dann folgt das 'b' aus dem DB3 usw... Mit einem RS232-Teilnehmer habe ich das bereits gemacht. Nur wie "ticker" ich die Adressen in den DB's durch? Ja klar, indirekte Adressierung, aber wie?

Ablauf:
Lade DB3.'a'
Sende Inhalt.DB3.'a'
Empfange String.DB2
Verarbeite String.DB2
Wandle String.DB2.nach.INT
Speicher String.DB2.als.INT.im.DB4_Pos.'a'
---
Lade DB3.'b'
Sende Inhalt.DB3.'b'
Empfange String.DB2
Verarbeite String.DB2
Wandle String.DB2.nach.INT
Speicher String.DB2.als.INT.im.DB4_Pos.'b'
---
usw., bis man beim 'z' angekommen ist.
Dann soll das ganze wieder bei 'a' angfangen.

Es geht mir nicht um die Stringverarbeitung, sondern lediglich um das Laden der richtigen DB-Sendeposition und das Laden der dazugehörigen DB-Empfangsposition.

Anbei noch ein paar Screenshots, vielleicht wird es dann klarer.

Vielen Dank,
poppycock
 

Anhänge

  • db2-receive.JPG
    db2-receive.JPG
    63,9 KB · Aufrufe: 21
  • db3-send.JPG
    db3-send.JPG
    122,1 KB · Aufrufe: 24
  • db4-int.JPG
    db4-int.JPG
    137,6 KB · Aufrufe: 18
Hallo,
ich bin mir nicht sicher, ob ich dich richtig verstanden habe ...
Ich würde mir den "Pointer" für die Ziel-Adresse aus dem ASCII-Code des empfangenen Zeichens bilden. "a" hat z.B. den ASCII-Code 97 - die weiteren inkrementell folgend ...
ASCII-Code heißt in dem Fall der Byte-Wert des empfangenen Zeichens.
Der Pointer ist dann :
Code:
L #Zeichen
L 96
-I  // jetzt hast du 1 für a und 26 für z
L 2
*I  // weil du ja Worte adressieren möchtest
SLD 3  // und nun ist es ein Pointer auf ein Wort ...
T #myPointer   // Format DWORD
Hattest du das so gedacht ?

Gruß
LL
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Larry,

das hört sich gar nicht mal so schlecht an, so ähnlich könnte ich das aufbauen!

Ich schicke von der SPS ein 'a' raus, der selbstgebaute RS232<->RS485-Wandler schickt das 'a' sofort wieder zurück. Danach antwortet der Busteilnehmer 'a' und sendet seine Busadresse samt Daten und Stoppzeichen hinterher.
Der komplette String des Busteilnehmers 'a' könnte so aussehen: aa1023#
erstes a = das gesendete Zeichen von der SPS
zweites a = Busadresse vom Busteilnehmer
1023 = Messwert (verwertbarer Wert)
# = Stoppzeichen
Wenn das erste Zeichen gleich dem zweiten Zeichen ist, so soll der Messwert verwertet werden, ansonsten wird dieser verworfen.

Mal gucken, ob ich das Problem so (ähnlich) lösen kann, wie du es vorgeschlagen hast.
Das würde die Hürde für die Zeil-Adresse lösen, aber wie lasse ich das Alphabet automatisch für das Senden durchtickern?
Genau so? Oder gibt's eine bessere Lösung?

Gruß,
poppycock
 
Da ich meine Busteilnehmer alphabetisch anspreche, muss ich im CP340-Sendebaustein angeben, was gesendet werden soll.
Darum habe ich einen DB angelegt, in dem die Daten stehen, also 'a' bis 'z'.
In meinem ersten Posting sieht man den Aufbau des DB's. Es ist das mittlere Bild: DB3.
Ich habe jetzt erstmal einen Timer angelegt, der alle 20ms einen Sendevorgang anstößt. Das wird aber noch zeitunkritischer gelöst.
D.h. im Moment wird alle 20ms ein 'a' an die Busteilnehmer gesendet.
Nun möchte ich aber, dass nach dem 'a' das 'b' folgt usw., bis man bei 'z' angekommen ist. Danach soll das mit 'a' wieder von vorne beginnen.

Ich hoffe, das ist nun verständlicher beschrieben?!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
... klar ... verstanden ...

Ich würde das Ganze in einer Schleife lösen (bei mir wäre hier dann das Mittel der Umsetzung SCL - das war bei dir glaube ich kein Thema ?).
In der Schleife würde ich dann von 1 .. 26 hoch-inkrementrieren, aus der Index-variablen der Schleife dann das Sende-Zeichen bauen (umgekehrt wie oben schon beschrieben) und dann entsprechend verfahren.
Zu beachten ist hier, dass ein Schleifen-Durchlauf in einem SPS-Zyklus passiert, dann erstmal ein ganze Weile (mehrere Zyklen nichts in der Richtung) und dann (ggf. nach Erhalten der Anwort oder so) die Übertragung der Rest-Information. Danach kann/darf dann erst der Index erhöht werden - also so nebenher noch so eine Art Schrittkette ...
Soll der Index dann irgendwann auf 27 gesetzt werden, so setzt du ihn an Stelle dessen wieder auf 1.

Hast du es dir so gedacht ?

Gruß
LL
 
Hast du es dir so gedacht ?
Ja, in diese Richtung hatte ich gedacht!

Ich würde das Ganze in einer Schleife lösen (bei mir wäre hier dann das Mittel der Umsetzung SCL - das war bei dir glaube ich kein Thema ?).
Richtig, sollte schon in AWL bleiben!
Hatte ja schon mal so ein ähnliches Problem, bei dem du mir erfolgreich geholfen hattest! *danke*

In der Schleife würde ich dann von 1 .. 26 hoch-inkrementrieren, aus der Index-variablen der Schleife dann das Sende-Zeichen bauen (umgekehrt wie oben schon beschrieben) und dann entsprechend verfahren.
Zu beachten ist hier, dass ein Schleifen-Durchlauf in einem SPS-Zyklus passiert, dann erstmal ein ganze Weile (mehrere Zyklen nichts in der Richtung) und dann (ggf. nach Erhalten der Anwort oder so) die Übertragung der Rest-Information. Danach kann/darf dann erst der Index erhöht werden - also so nebenher noch so eine Art Schrittkette ...
Soll der Index dann irgendwann auf 27 gesetzt werden, so setzt du ihn an Stelle dessen wieder auf 1.
D.h. ich brauche eigentlich keinen DB für die Sendezeichen, sondern generiere mir aus einem Zählwert ein ASCII-Zeichen, das gesendet werden soll.
Dann könnte ich mir doch einen FB bauen, der das alles beinhaltet?!

Den Sendebefehl werde ich letztendlich so programmieren:
Beim Hochlauf der SPS wird ein Bit gesetzt und stößt den Sendevorgang an.
Wenn der CP erfolgreich etwas empfangen hat und die Umwandlung von ASCII nach INT durchgeführt wurde, wird der nächste Sendeauftrag eingeleitet. Somit stelle ich sicher, dass ich immer erst etwas sende, wenn ich erfolgreich etwas empfangen habe.
Dieses "Anstoßbit" könnte ich dann für den Zähler verwenden...

LG,
poppycock
 
Wie wärs bsw. so??

Aufbau DB1:
ZAEHLER: INT
res: 8 BYTE
SENDEDATEN[1..26] ARRAY of 100 BYTE, beginnend bei 10

Lokalvariablen:
SENDEZEICHEN : BYTE


Code:
L DB1.DBW0
L 'A'
+I
T SENDEZEICHEN

L DB1.DBW0
L 100 
*D
L 10
+D
SLD 3
LAR1

//NUN hasst du im AR1 die Adresse auf deine sendedaten...


//ZAEHLER erhöhen
L DB1.DBW 0
+ 1
T DB1.DBW 0
L 26
>I
SPBN ok

L 0
T DB1.DBW 0
ok: NOP 0


hab ich so richtig verstanden was du woltest???
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich habe jetzt ein wenig Zeit gefunden und habe mich wieder der Programmierung meiner Datenabfrage gekümmert.
Die DB's habe ich als Screenshot angehängt.
Nicht mit der Bezeichnung "Alphabet" irritieren lassen, ich habe nur Busteilnehmer a und b, darum ist bei 98 Schluss mit zählen.

Wenn ich Busteilnehmer a anspreche, bekomme ich folgenden String zurück aa1023#
Das erste a schickt der Buswandler sofort zurück, das a1023# kommt vom Busteilnehmer. So soll es auch sein!
Wenn ich Busteilnehmer b anspreche, bekomme ich b1023# zurück, also ohne das erste Zeichen (b).
Ich glaube, es liegt an meiner Zählweise, dass da irgendwas nicht stimmt.
Könnte sich das mal bitte einer angucken? Bin schon am Verzweifeln.

Code:
      L     254
      T     DB2.DBB    2
      T     DB2.DBB    3
      L     254
      T     DB2.DBB  270
      T     DB2.DBB  271

      L     1
      T     DB3.DBB    2
      T     DB3.DBB    3

// SENDEN
      CALL  "P_SEND_OLD" , "P_SEND_Instanz"
       REQ   :=M0.3
       R     :=
       LADDR :=256
       DB_NO :=3
       DBB_NO:=4
       LEN   :=1
       DONE  :="P_SEND_Data".SND_Done
       ERROR :="P_SEND_Data".SND_Error
       STATUS:=

// EMPFANGEN
      CALL  "P_RCV_OLD" , "P_RCV_Instanz"
       EN_R  :=M0.1
       R     :=
       LADDR :=256
       DB_NO :=2
       DBB_NO:=4
       NDR   :="P_RCV_Data".RCV_NDR
       ERROR :="P_RCV_Data".RCV_Error
       LEN   :=
       STATUS:=

      L     "P_RCV_Instanz".i_GESAMTLAE
      T     "P_RCV_Data".aktuelle_Laenge


// nutzbare Länge errechnen
      L     "P_RCV_Data".aktuelle_Laenge
      L     3
      -I    
      T     "P_RCV_Data".nutzbare_Laenge

// erstes Zeichen auslesen und speichern
      L     "P_RCV_Data".RCV_String[1]
      T     "P_RCV_Data".erstes_ASCII_Zeichen[1]

// zweites Zeichen auslesen und speichern
      L     "P_RCV_Data".RCV_String[2]
      T     "P_RCV_Data".zweites_ASCII_Zeichen[1]

// verwertbare ASCII-Daten heraussuchen
      CALL  "MID"
       IN     :="P_RCV_Data".RCV_String
       L      :="P_RCV_Data".nutzbare_Laenge
       P      :=3
       RET_VAL:="P_RCV_Data".ASCII_Daten

// empfangenen ASCII-String nach INT wandeln
      CALL  "STRNG_I"
       S      :="P_RCV_Data".ASCII_Daten
       RET_VAL:="P_RCV_Data".INT_Daten

      U     "P_RCV_Data".RCV_NDR
      SPBN  nop1                        // Mache nichts, wenn keine neue Daten empfangen wurden

// Im DB die Speicherstelle generieren
      L     "P_SEND_Data".SND_ASCII[1]
      L     97
      -I    
      L     2
      *I    
      SLW   3
      LAR1  
      L     "P_RCV_Data".INT_Daten
      T     #Werte
      AUF   "P_INT_Data"
      L     #Werte
      T     DBW [AR1,P#0.0]

// Alphabet durchzählen
      L     "P_SEND_Data".SND_ASCII[1]
      L     1
      +I    
      T     "P_SEND_Data".SND_ASCII[1]
      L     98
      >I    
      SPBN  ende                        // Alphabet-Ende erreicht, wieder bei 'a' anfangen
      L     97
      T     "P_SEND_Data".SND_ASCII[1]
ende: NOP   0

nop1: NOP   0


Danke, poppycock
 

Anhänge

  • db2.JPG
    db2.JPG
    65,5 KB · Aufrufe: 6
  • db3.JPG
    db3.JPG
    44,5 KB · Aufrufe: 3
Hallo Poppycock,
ich kann erstmal keinen Fehler erkennen ... bis auf :
Wenn du mit den S7-Strings_Wandlungs-FC's (MID , STRING_I, etc.) arbeitest dann muß zwingend sichergestellt sein, dass ALLE beteiligten Strings initialisiert sind (String-Länge und -Größe in den Header-Bytes eingetragen). Ich habe davon jetzt in deinem Code nichts gefunden - hast du das gemacht ? Wenn nein, dann hol das doch bitte noch nach ...

Gruß
LL
 
Wenn du mit den S7-Strings_Wandlungs-FC's (MID , STRING_I, etc.) arbeitest dann muß zwingend sichergestellt sein, dass ALLE beteiligten Strings initialisiert sind (String-Länge und -Größe in den Header-Bytes eingetragen). Ich habe davon jetzt in deinem Code nichts gefunden - hast du das gemacht ?

Hallo Larry,

ich habe folgendes so initialisiert (Auszug aus Programm):

Code:
    [FONT=Verdana][COLOR=Red]L     254
      T     DB2.DBB    2
      T     DB2.DBB    3[/COLOR][/FONT][FONT=Verdana]
[/FONT] [FONT=Verdana][COLOR=Teal]     L     254
      T     DB2.DBB  270
      T     DB2.DBB  271[/COLOR][/FONT][FONT=Verdana]

// verwertbare ASCII-Daten heraussuchen
      CALL  "MID"
       IN     := [/FONT][FONT=Verdana][COLOR=Red]"P_RCV_Data".RCV_String[/COLOR][/FONT][FONT=Verdana]
       L      :="P_RCV_Data".nutzbare_Laenge
       P      :=3
       RET_VAL:=[COLOR=Teal]"P_RCV_Data".ASCII_Daten[/COLOR]

// empfangenen ASCII-String nach INT wandeln
      CALL  "STRNG_I"
       S      := [/FONT][FONT=Verdana][COLOR=Teal]"P_RCV_Data".ASCII_Daten[/COLOR][/FONT][FONT=Verdana]
       RET_VAL:="P_RCV_Data".INT_Daten[/FONT]


Sehr komisch ist folgendes:
Wenn ich 97 ( a ) zu meinen Busteilnehmern sende, antwortet der Teilnehmer a samt Daten. Teilnehmer a sendet übrigens die Umdrehungszahl eines Lüfters.
Wenn der Lüfter steht, bekomme ich aa0# zurück, also 4 Zeichen.
Der CP340-Empfangsbaustein gibt auch eine Stringlänge von 4 aus. Sendet der Teilnehmer bei drehendem Lüfter aa85#, gibt der
CP340-Empfangsbaustein eine Stringlänge von 5 aus. Das passt soweit!
Ganz anders verhält sich Teilnehmer b ( 98 ).
Teilnehmer b gibt eine Temperatur aus. Sende ich ein b an den Teilnehmer, bekomme ich nur b21# zurück und der
CP340-Empfangsbaustein hat eine Stringlänge von 4. Das ist falsch, denn ich will ja den String bb21# einlesen, also 5 Zeichen.
Wenn ich im
CP340-Sendebaustein DBB_NO von 4 auf 5 ändere, verschiebt sich der empfangene String.
Also da muss der Fehler sein?! Ich weiß aber nicht mehr weiter.

Hat jemand noch eine Idee, wie ich die korrekten Daten vom Busteilnehmer b bekomme?

Gruß,
poppycock

 
Zuviel Werbung?
-> Hier kostenlos registrieren
... 2 Sachen noch ...

1.) Schreib doch bei der Initialisierung des Strings in die Bytes 3 und 271 mal bitte eine 0 hinein - du hast ja zum Zeitpunkt der initialisierung schließlich noch keine Zeichen (oder sinnvoll Informationen drin stehen). Dein String ist also mit einer Breite von 254 deklariert (Byte 2 und 270), du nutzt davon aktuell aber nichts (Byte 3 und 271).

2.) Woher weißt du, dass deine Routine den "Fehler" macht ? Kann es nicht auch der anderen Teilnehmer ("b") sein ?

Gruß
LL
 
1.) Schreib doch bei der Initialisierung des Strings in die Bytes 3 und 271 mal bitte eine 0 hinein - du hast ja zum Zeitpunkt der initialisierung schließlich noch keine Zeichen (oder sinnvoll Informationen drin stehen). Dein String ist also mit einer Breite von 254 deklariert (Byte 2 und 270), du nutzt davon aktuell aber nichts (Byte 3 und 271).
Ich initialisiere momentan alles am Anfang des selben FC's.
Wenn ich 0 eingeben, sind meine ganzen Werte 0.
Schreibe ich
Code:
      L     254
      T     DB2.DBB    2
      L     5
      T     DB2.DBB    3
      L     254
      T     DB2.DBB  270
      L     5
      T     DB2.DBB  271
bleibt alles beim alten, mir fehlt die Zehnerstelle bei der Temperatur.

2.) Woher weißt du, dass deine Routine den "Fehler" macht ? Kann es nicht auch der anderen Teilnehmer ("b") sein ?
Teilnehmer b funktioniert. Siehe angehängen Screenshot...
Im unteren Bildschirmausschnitt sind die Sendedaten an die Teilnehmer (ababab...), analog dazu stehen im oberen Bildschirmausschnitt die Messwerte (aa0# = Drehzahl 0 U/sec, bb18# = Temperatur 18°C).

Gruß,
poppycock
 

Anhänge

  • ab.JPG
    ab.JPG
    70,2 KB · Aufrufe: 8
... aufgrund deines letzten Beitrages habe ich nun noch einen ... :rolleyes:

Du brauchst deine Strings natürlich nicht dauern initialisieren ... im Falle des Receive-FB wäre das sogar ein Fehler.
Ich würde das so machen :
Einmal beim Start der SPS alle Strings initialisieren - alternativ als Flanke für den 1. Aufruf und noch kein Init durchgeführt. Hier schreibst du die totale Länge des Strings (254) in Byte 0 und die aktuelle Länge (0) in Byte 1.
Danach nur wieder wenn du den String zurücksetzen möchtest (myString = "").

Du hattest doch geschrieben, das Teilnehme "a" dir den String "aa1223#" zurücksendet und das Teilnehmer "b" dir "nur" "b1223#" antwortet, seine Kennung also nicht noch einmal wiederholt. Darauf bezog ich mich mit dem Hinweis "Fehler".
Dazu noch einmal die Frage :
Was sind das für Teilnehmer und ist sicher´gestellt, dass beide Teilnehmer intern das gleiche machen ?

...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Einmal beim Start der SPS alle Strings initialisieren - alternativ als Flanke für den 1. Aufruf und noch kein Init durchgeführt. Hier schreibst du die totale Länge des Strings (254) in Byte 0 und die aktuelle Länge (0) in Byte 1.
Da ich sowieso irgendwann für die Kommunikation den Anlauf-OB OB100 brauche, habe ich folgendes in den OB100 geschrieben:
Code:
// "P_RCV_Data".RCV_String initialisieren  
      L     254
      T     DB2.DBB    2
      L     0
      T     DB2.DBB    3

// "P_RCV_Data".ASCII_Daten initialisieren
      L     254
      T     DB2.DBB  270
      L     0
      T     DB2.DBB  271

// "P_SEND_Data".SND_ASCII initialisieren
      L     1
      T     DB3.DBB    2
      L     0
      T     DB3.DBB    3
Wenn ich das so mache, bekomme ich keinen anderen Wert außer 0.
Schreibe ich statt der L0 bspw. L100, so funktioniert das ganze wieder genau so falsch wie vorher.

Danach nur wieder wenn du den String zurücksetzen möchtest (myString = "").
Ja, daran habe ich auch gedacht, nur wie mache ich das in AWL?

Du hattest doch geschrieben, das Teilnehme "a" dir den String "aa1223#" zurücksendet und das Teilnehmer "b" dir "nur" "b1223#" antwortet, seine Kennung also nicht noch einmal wiederholt. Darauf bezog ich mich mit dem Hinweis "Fehler".
Dazu noch einmal die Frage :
Was sind das für Teilnehmer und ist sicher´gestellt, dass beide Teilnehmer intern das gleiche machen ?
Noch mal zum Verständnis, kam wohl nicht so sauber rüber.
Die Werte, die ich für den Busteilnehmer b einlese, kommen ALLE vom Busteilnehmer. Mir fehlt das erste Zeichen, das die SPS rausschickt und sofort wieder einliest.
Die beiden Busteilnehmer sind selbstgebaut und vom Aufbau her identisch.
Nur das Programm entscheidet sich geringfügig, denn der eine ruft die Funktion drehzahl() auf und der andere temperatur().
Ansonsten sind die Programme identisch!

Mir kommt es so vor, dass sich der Empfangsstring verschiebt.
Den Teilnehmer c gibt es nicht, aber vom Gefühl her würde ich sagen, dass dann die SPS statt cc1023# nur 1023# einlesen würde, ohne die zwei ersten Zeichen.

Gruß,
poppycock
 
... was passiert, wenn du nur den Tln.B einliest und gar nicht den Tln.A ?
oder
... was passiert, wenn du 2 mal hintereinander nur Tln.A einliest - oder 2 mal Tln.B ?

Das resetten eines String a la myString = "" machst du in AWL in dem du die benutzte Länge auf 0 setzt. Wenn du auf Nummer sicher gehen möchtest, dann könntest du dir zusätzlich auch bei den Nutzdaten auch noch Nullen hineinschreiben ...

Gruß
LL
 
was passiert, wenn du nur den Tln.B einliest und gar nicht den Tln.A ?
Der Teilnehmer b wird von der SPS angesprochen und es kommt nur b18# zurück. Habe im Mikrocontroller das b zum c geändert, damit man sieht, ob nun das von der SPS geschickte b zurückkommt oder nicht. Siehe da, es fehlt das vom CP gesendete Zeichen.
Wenn ich das a schicke, ist das erste Zeichen auch wieder da.

was passiert, wenn du 2 mal hintereinander nur Tln.A einliest - oder 2 mal Tln.B ?
Es funktioniert noch immer genau so falsch wie vorher.
Teilnehmer a funktioniert ohne Probleme, Teilnehmer b antwortet auch munter, aber das b von der SPS wird nicht wieder eingelesen, nur der String vom Teilnehmer b.

Ich bin noch immer ratlos...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Teilerfolg

So, ich habe ein wenig weiter geforscht.

Der Fehler liegt im Mikrocontroller-Programm! Denn irgendwie verschiebt sich etwas im Programm, wenn ich den errechneten Wert der Temperatur ausgebe.
Bei Drahtbruch gebe ich 999 aus, und das kommt wunderbar mit allen Zeichen im CP an.
Find ich schon komisch, denn die Ausgabe-Funktion sind bei beiden Busteilnehmern gleich!

Wenn ich den Fehler im Mikrocontroller-Programm bereinigt habe, schreibe ich hier wieder.
Mein Programm für den CP340 funktioniert demnach tadellos!

Sorry LL, dass ich dich damit aufgehalten habe. Du hast recht gehabt! Danke!

Gruß,
poppycock
 
Zuletzt bearbeitet:
:confused::confused::confused: wie bist du denn drauf ?
Wenn ich keine Lust habe zu helfen, dann tue ich es auch nicht ... ergo ... du hast mich nicht damit genervt und ich habe gerne mitgearbeitet ... :)
Vielen Dank, Larry!
Naja, das eigentliche Problem lag nicht an der Programmierung mit Step7, sondern die Umrechnung des Wertes innerhalb des Busteilnehmers b. :cry:
Den Temperaturwert habe ich als double im AtMega8 angegeben, aber so wie es aussieht, kann ich damit nicht wie normale Gleitkommazahlen rechnen.
Habe nun alles als unsigned int und passe mir den Rechenwert an.

Nun noch mal was zu meinem Programm.
Ich will nun erreichen, dass die SPS einen Kommunikationsfehler erkennt.
Also, ich möchte das erste Zeichen mit dem zweiten Zeichen vergleichen.
Wenn innerhalb einer bestimmten Zeit das zweite Zeichen entweder nicht gekommen ist oder gar ein falscher Teilnehmer antwortet, soll das Durchzählen des Alphabets wieder bei a beginnen.
Ich bin nicht so firm in Sachen Sprünge innerhalb des Programms, aber es sollte doch machbar sein, oder?
Meine Versuche sind kläglich gescheitert.
Als "Timer-Starter" kann ich das Bit für Daten gesendet ("P_SEND_Data".SND_Done) nehmen.
Zur Info: Der Busteilnehmer a hat den dezimalen Wert 97, Teilnehmer b hat 98. Mehr Teilnehmer sind nicht vorhanden.

Hier das Programm:

Code:
[B]OB100[/B]

// "P_RCV_Data".RCV_String initialisieren  
      L     254
      T     DB2.DBB    2
      L     254
      T     DB2.DBB    3

// "P_RCV_Data".ASCII_Daten initialisieren
      L     254
      T     DB2.DBB  270
      L     254
      T     DB2.DBB  271

// "P_SEND_Data".SND_ASCII initialisieren
      L     1
      T     DB3.DBB    2
      L     1
      T     DB3.DBB    3

// Senden anstoßen
      SET   
      =     "P_SEND_Data".SND_Anstoss

Code:
[B]FC3[/B]

// SENDEN
      CALL  "P_SEND_OLD" , "P_SEND_Instanz"
       REQ   :="P_SEND_Data".SND_Anstoss
       R     :=
       LADDR :=256
       DB_NO :=3
       DBB_NO:=4
       LEN   :=1
       DONE  :="P_SEND_Data".SND_Done
       ERROR :="P_SEND_Data".SND_Error
       STATUS:=

// EMPFANGEN
      CALL  "P_RCV_OLD" , "P_RCV_Instanz"
       EN_R  :=M0.1
       R     :=
       LADDR :=256
       DB_NO :=2
       DBB_NO:=4
       NDR   :="P_RCV_Data".RCV_NDR
       ERROR :="P_RCV_Data".RCV_Error
       LEN   :=
       STATUS:=

      L     "P_RCV_Instanz".i_GESAMTLAE
      T     "P_RCV_Data".aktuelle_Laenge

// Sende-Anstoß blockieren
      CLR   
      =     "P_SEND_Data".SND_Anstoss

// nutzbare Länge errechnen
      L     "P_RCV_Data".aktuelle_Laenge
      L     3
      -I    
      T     "P_RCV_Data".nutzbare_Laenge

// erstes Zeichen auslesen und speichern
      L     "P_RCV_Data".RCV_String[1]
      T     "P_RCV_Data".erstes_ASCII_Zeichen[1]

// zweites Zeichen auslesen und speichern
      L     "P_RCV_Data".RCV_String[2]
      T     "P_RCV_Data".zweites_ASCII_Zeichen[1]

[COLOR="Red"]// die ersten beiden Zeichen vergleichen
      L     "P_RCV_Data".RCV_String[1]
      L     "P_RCV_Data".RCV_String[2]
      ==I 
[B]// hier soll nun der Sprung durchgeführt werden:[/B]
// wenn"P_RCV_Data".RCV_String[1] == "P_RCV_Data".RCV_String[2]
// --> mache nichts und gehe weiter im Programm
// wenn"P_RCV_Data".RCV_String[1] != "P_RCV_Data".RCV_String[2]
// --> setze a wieder als erstes Sende-Zeichen
[/COLOR]
// verwertbare ASCII-Daten heraussuchen
      CALL  "MID"
       IN     :="P_RCV_Data".RCV_String
       L      :="P_RCV_Data".nutzbare_Laenge
       P      :=3
       RET_VAL:="P_RCV_Data".ASCII_Daten

// empfangenen ASCII-String nach INT wandeln
      CALL  "STRNG_I"
       S      :="P_RCV_Data".ASCII_Daten
       RET_VAL:="P_RCV_Data".INT_Daten

      U     "P_RCV_Data".RCV_NDR
      SPBN  nop0                        // Mache nichts, wenn keine neue Daten empfangen wurden

// Im DB die Speicherstelle generieren
      L     "P_SEND_Data".SND_ASCII[1]
      L     97
      -I    
      L     2
      *I    
      SLW   3
      LAR1  
      L     "P_RCV_Data".INT_Daten
      T     #Werte
      AUF   "P_INT_Data"
      L     #Werte
      T     DBW [AR1,P#0.0]

// Alphabet durchzählen
      L     "P_SEND_Data".SND_ASCII[1]
      L     1                           // lade nächstes Zeichen
      +I    
      T     "P_SEND_Data".SND_ASCII[1]
      L     98
      >I                                // Alphabet-Ende erreicht...
      SPBN  ende
      L     97                          // ... wieder bei 'a' anfangen
      T     "P_SEND_Data".SND_ASCII[1]
ende: NOP   0

// alle Daten da, Senden wieder anstoßen
      SET   
      =     "P_SEND_Data".SND_Anstoss

nop0: NOP   0

Ansonsten bin ich mit meiner Programmierung sehr zufrieden!

Gruß,
poppycock
 
Zurück
Oben