Problem bei einer Such-Schleife

Imker

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

ich bin Neuling in Sachen S7-Programmierung und stehe jetzt vor einem Problem.
Ich habe ein Regal mit 7x3 Plätzen, 7 fächer mit 3 etagen. Dafür will ich jetzt eine Art suche für den nächsten freien Platz machen.
Es ist mir ansich egal ob er zuerst eine Etage vollmacht oder zuerst ein Fach.
Anschließend soll diese Position in einen anderen DB samt eines weiteren MB zu einem Word zusammengefasst werden.
Ich wollte das ganze jetzt so lösen, indem ich einen DB, in meinem Fall DB11 anlege und da die Verwaltung mache.
Den DB hab ich so angelegt: zuerst habe ich mir einen "suchzeiger" angelegt: das DBD 0. Doppelwort, weil in den bits 0.0 bis 1.7 kann die "suche" stattfinden, in den bits 2.0 bis 3,7 können infos zum typ reingeschrieben werden (siehe weiter unten) Die einzelnen Positionen dann DBX 4.0 (entspricht dem 1. Platz), DBX 4.1 dem 2. usw... bis DBX 6.4

Nun zu meinem Problem:
Ich will in einem FC eine Schleife laufen lassen. Diese schleife soll von dbx 4.0 an durchlaufen, bis ein freier platz gefunden wurde.
Findet er einen, setzt er das DBX = 1 (leer bedeutet also 0).
Code:
            AUF DB 11

            L # 4.0       
            T DBD 0
//Abbruchbedingung

FIND: U     M     50.0                    // Mein Merker, damit das ganze starten kann, ist eine positiver Flankenmerker
             U
            (
            L     DB11.DBD    0                 // Lade Suchzeiger       
            L     52                                // ist der kleiner als DBX 6.4?
           <D        
            )       
           SPBN  ENDE                          // wenn ja mache weiter, wenn nein = voll, also ende

          UN    DBX [DBD 0]                  // Hier läuft er durch, beginnend ab dbx 4.0... wie bekomme ich hier die 4.0?
          SPB   ELGN

           L     DB11.DBD    0
           L     1
          +D    
           T     DB11.DBD    0
           SPA   FIND

ELGN: S     DB11.DBX [DBD 0]         // Setze das DBX, auf dass der Zeiger zeigt.


Nun solls aber noch weitergehen. Ich benötige die Info (x und y-position), wo eingelagert wird, sowie die jeweilige artikelnummer (zur identifikation)
Ich dachte mir, dass es sinnvoll wäre für die x und y-position ein DBD anzulegen um dann beim anfahren in der Schrittkette darauf zugreifen zu können...

Code:
      L     DBW2  // Weiß ich noch nicht. Kann ich den Teil vom Zeiger (DBD 0) so laden?
      
      SLW                               // hängt ab vom Zeiger, ich muss x und y in je 4 bits bekommen
      SRW   
      T     DBD   10                    //hier soll dann die x-position hin, ist im DB schon angelegt
      L     DBW2
      SLW   
      SRW   
      T     DBD   14                    //und hier die y-position
      SPB   tran                        // springe dann zum transfer

Nun der letzte Schritt. Die x und y position soll in eine warteschlange eingereiht werden. Dafür wird ein extra DB verwendet (DB 4).
Hier hab ich aber eine Vorgabe: Für jeden auftrag wird ein word reserviert. Und die x und y-position soll in den bits 7 bis 0 des words stehen.
die Bits 8 bis 15 werden im MB 90 gespeichert und vervollständigen so das word
Wenn ich das richtig verstehe, muss ich da einen "offset" addieren...


Code:
tran: AUF   DB     4             // öffne meinen warteschlangen DB
      L     MB    90               //  Lade das MB, was die bits 15 bis 7 des auftrages enthällt
      T     DBB [DBD 0]         // Transferie das in den Zeiger des DB4 (gleicher aufbau wie DB 11). er sollte auf das nächste freie zeigen
      L     8                        // mein "offest" für die bits 7 bis 0 "dranzuhängen....
      L     DBD    0
      +D    
      T     DBD    0
      
      AUF   DB 11                        // öffne den platzverwaltungs-db
      L     DBB    3                      // lade NUR die x und y-position aus dem Zeiger (geht das?)
      AUF   DB     4                      // nun der warteschlangen-db 
      T     DBB [DBD 0]                 // lade das in den nächsten freien auftrag. DBD 0 ist wie im anderen DB ein zeiger auf das nächste freie Element
      L     8                               // mein "offest" um aufs nächste freie word zu kommen
      L     DBD    0
      +D    
      T     DBD    0

Das wars soweit. Nun, mein Problem ist es, dass so rein nichts funktioniert und ich jetzt nicht mehr weiß wie ich weitermachen soll.

Wäre schön wenn da mal einer drübergucken könnte, notfalls auch einen anderen Code, wenn meiner falsch ist.
Mit Pointer habe ich es auch schon probiert. Da kam ich leider auch nicht weiter.
Ich weiß es ist sehr viel Arbeit und wohl auch ein wenig verwirrend. Trotzdem schonmal einen Dank im vorraus
 
Zuletzt bearbeitet:
Das wars soweit. Nun, mein Problem ist es, dass so rein nichts funktioniert und ich jetzt nicht mehr weiß wie ich weitermachen soll.


Schon eimal das Pogramm angeschaut?
Code:
FIND: U     M     50.0                    // Mein Merker, damit das ganze starten kann, ist eine positiver Flankenmerker       L     DB11.DBD    0                 // Lade Suchzeiger       L     52                                // ist der kleiner als DBX 6.4?       <D           SPBN  ENDE                          // wenn ja mache weiter, wenn nein = voll, also ende        UN    DBX [DBD 0]                  // Hier läuft er durch, beginnend ab dbx 4.0... wie bekomme ich hier die 4.0?       SPB   ELGN        L     DB11.DBD    0       L     1       +D           L     DB11.DBD    0       SPA   FIND
Was ist denn in dem DB11.DBD0 wenn du die Schleife einmal durchlaufen hat?




Sorry, doch der Ansatz ist nicht sinnvoll, durchdacht oder gar gut.

Ich würde ein Array anlegen und dort die Werte hinterlegen.
Und dann auf dieses Array mit Pointner zugreifen.


bike
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Also, vorm ersten durchlauf soll er auf das DB11.DBX 4.0 zeigen. Wenn das eine 0 hat, ist es frei und ich kann da einlagern. Wenn es eine 1 hat hat wird die schleife eins hoch gezählt.
Ich sehe gerade, dass ich statt T ein L geschrieben habe - mein Fehler, im Programm steht da ein T. Ich änder es direkt ab.

Mit Pointer hatte ich es auch schon probiert und leider keinen Erfolg. Da tat sich rein nichts. Bin aber Grundsätzlich für jeden Vorschlag offen (sofern ich ihn nachvollziehen kann).
 
Sorry, ich versteh das Programm nicht.
Was soll die 52?
Denk einmal nach welche du Aufageb du hast und schreib dann dein Programm.

Ich denke du solltest kein Programm abschreiben, sondern deine Hausaufgaben selbst machen.


bike
 
Hallo Imker,

der Merker 50.0 hat keine Funktion, wenn du ihn mit dem Ergebnis der Vergleichsoperation verknüpfen willst, müsste es so lauten:

Code:
FIND: U     M     50.0   // Mein Merker, damit das ganze starten kann, ist eine positiver Flankenmerker
      U(
      L     DB11.DBD    0                 // Lade Suchzeiger
      L     52                                // ist der kleiner als DBX 6.4?
      <D 
      )   
      SPBN  ENDE


Die FIND-Schleife würde ich als LOOP-Schleife auslegen.


spsfreak12345
 
Das ist mein DBX 6.4... Wenn ich das richtig verstanden habe. Dbx 0.0 ist 1, dbx 0.1 ist 2, dbx 0.2 ist 3 usw. Demensprechend müsste dann DBX 6.4 = 52 sein.

Denk einmal nach welche du Aufageb du hast und schreib dann dein Programm.

Ich denke du solltest kein Programm abschreiben, sondern deine Hausaufgaben selbst machen.

Bevor hier falsche Gedanken aufkommen.... Das ist kein fremder Code, das ist von mir geschrieben. Ich kann den komplett nachvollziehen bzw. erläutern was ich mir dabei gedacht habe.
Ich sitze nur jetzt schon viele Tage dran und komme nicht mehr weiter. Von daher ist es mir am liebsten wenn ich ein paar Infos bekomme was da falsch ist...will schon was lernen dabei.
Nur übersteigt dieser Teil meine Kentnisse..

der Merker 50.0 hat keine Funktion, wenn du ihn mit dem Ergebnis der Vergleichsoperation verknüpfen willst, müsste es so lauten:

Ok, versteh ich. Änder ich im Programm ab (und im ersten Post). Leider wechselt sie SPS immer noch in SF sobald der Merker gesetzt wird :/
 
Das ist mein DBX 6.4... Wenn ich das richtig verstanden habe. Dbx 0.0 ist 1, dbx 0.1 ist 2, dbx 0.2 ist 3 usw. Demensprechend müsste dann DBX 6.4 = 52 sein.

Ich würds anders machen:

vor der Schleife ähnlich wie MichaelBart:
Code:
L P#DBX4.0
T DBD0

in der Schleife:
Code:
L DBD0
L P#DBX6.4
<D
...
L DBD0
INC 1
T DBD0
SPA ...


spsfreak12345
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Respekt...

Als Neuling so ein Einstiegsprojekt mit indirekter Adressierung und Schleifen... :confused:

Gut, jeder fängt mal an. Trotzdem halte ich Dein Vorhaben für sehr optimistisch, wenn nicht sogar für unmöglich.

Um so etwas sauber aufzuziehen braucht es einiges an Handwerkszeug, Grips und Programmiererfahrung. Ohne Dir was zu wollen... aber ich fürchte Du bringst maximal Grips für dieses Projekt mit.

Wenn Du kannst, hol Dir professionelle Hilfe.

Viel Erfolg!
 
Code:
      AUF   "PositionenRegal"

      L     P#4.0
      T     DBD    0
//Abbruchbedingung

FIND: U     M     50.0                  // Mein Merker, damit das ganze starten kann, ist eine positiver Flankenmerker
      U(    
      L     DBD    0                       // Lade Suchzeiger       
      L     P#6.4                    // ist der kleiner als DBX 6.4?
      <D    
      )      
      SPBN  ENDE                         // wenn ja mache weiter, wenn nein = voll, also ende

      UN    DBX [DBD 0]                 // Hier läuft er durch, beginnend ab dbx 4.0
      SPB   ELGN

      L     DBD    0
      INC   1
      T     DBD    0
      SPA   FIND

ELGN: S     DBX [DBD 0]                 // Setze das DBX, auf dass der Zeiger zeigt.  

      L     DBW    2                         // Weiß ich noch nicht. Kann ich den Teil vom Zeiger (DBD 0) so laden?

      SLW                                      // hängt ab vom Zeiger, ich muss x und y in je 4 bits bekommen
      SRW   
      T     DBD   10                          //hier soll dann die x-position hin, ist im DB schon angelegt
      L     DBW    2
      SLW   
      SRW   
      T     DBD   14                           //und hier die y-position
      SPB   tran

tran: AUF   DB     4                          // öffne meinen warteschlangen DB
      L     MB    90                           //  Lade das MB, was die bits 15 bis 7 des auftrages enthällt
      T     DBB [DBD 0]                     // Transferie das in den Zeiger des DB4 (gleicher aufbau wie DB 11). er sollte auf das nächste freie zeigen
      L     8                                    // mein "offest" für die bits 7 bis 0 "dranzuhängen....
      L     DBD    0
      +D    
      T     DBD    0

      AUF   "PositionenRegal"               // öffne den platzverwaltungs-db
      L     DBB    3                            // lade NUR die x und y-position aus dem Zeiger (geht das?)
      AUF   DB     4                          // nun der warteschlangen-db 
      T     DBB [DBD 0]                      // lade das in den nächsten freien auftrag. DBD 0 ist wie im anderen DB ein zeiger auf das nächste freie Element
      L     8                                    // mein "offest" um aufs nächste freie word zu kommen
      L     DBD    0
      +D    
      T     DBD    0

ENDE: NOP   0


Hier noch mal der neue Code mit den Erweiterungen. Soweit ist mir noch alles klar. Ich kann jetzt leider nicht mehr testen, erst morgen wieder
Vielen Dank schonmal bis hierhin. Ich denke da werden noch ein paar Fehler drinnen sein.

Als Neuling so ein Einstiegsprojekt mit indirekter Adressierung und Schleifen... :confused:

Gut, jeder fängt mal an. Trotzdem halte ich Dein Vorhaben für sehr optimistisch, wenn nicht sogar für unmöglich.

Um so etwas sauber aufzuziehen braucht es einiges an Handwerkszeug, Grips und Programmiererfahrung. Ohne Dir was zu wollen... aber ich fürchte Du bringst maximal Grips für dieses Projekt mit.

Wenn Du kannst, hol Dir professionelle Hilfe.
Da stimme ich voll mit überein. Wir sind zwar zu 3. und müssen ein gesamtes Projekt bearbeiten (das hier ist nur ein Teil), aber trotzdem richtig schwer. Programmiererfahrung beschrenkt sich ansich nur auf
normale Schrittketten - deswegen ist der Sprung auch recht krass.


Danke, den brauch ich! Und motivation...


Edit: Wegen der Loop-Schleife... werde ich mal suchen & nachlesen
 
Zuletzt bearbeitet:
So wie du die Bits abfragst
Code:
UN DBX [DBD 0]
musst du die Pointer ohne Speicherbreich laden:
Code:
L P#4.0
T DBD0
...
L DBD0
L P#6.4
<D

Sonst müsstest du über das Adressregister gehen (LAR1).
spsfreak12345
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Das ist mein DBX 6.4... Wenn ich das richtig verstanden habe. Dbx 0.0 ist 1, dbx 0.1 ist 2, dbx 0.2 ist 3 usw. Demensprechend müsste dann DBX 6.4 = 52 sein.

Da fängt das Problem an.
Du musst wenn überhaupt mit der zweier Potenz rechnen.
Es geht nach meine Tests hier nicht ohne AR1 und AR2, daher ist dein Ansatz nach meinem Empfinden zum Scheitern verurteilt.
Also Array mit mehren Dimensionen und du hast deine Lösung.


bike

btw: aber es ist eine Hausaufgabe und du hast wie selbst geschrieben hast, hier etwas falsches reinabgeschrieben ;-)
 
Danke, hier und im Programm geändert.

Wenn ich das mit der Loop-Schleife richtig verstehe, dann zählt die immer um 1 herunter.... ich zähle ja sozusagen 1 rauf. Dementsprechend kann ich die ja garnicht anwenden und muss es so machen wie jetzt im Code ... (denk ich mal)
 
Da fängt das Problem an.
Du musst wenn überhaupt mit der zweier Potenz rechnen.
Es geht nach meine Tests hier nicht ohne AR1 und AR2, daher ist dein Ansatz nach meinem Empfinden zum Scheitern verurteilt.
Also Array mit mehren Dimensionen und du hast deine Lösung.

Also ich kann dazu nichts sagen, weil ich nicht weiß wie das geht...
Ein Array scheint mir zuerst auch recht sinnvoll, aber wenns dann um die Zugriffe geht muss ich passen.
Mit zweier Potenz rechnen sagt mir schon eher was. Aber scheinbar scheint das doch auch so zu laufen, oder?
Bin wie gesagt für jeden Ansatz offen, sofern er zum Ziel führt.

btw: aber es ist eine Hausaufgabe und du hast wie selbst geschrieben hast, hier etwas falsches reinabgeschrieben :wink:
Das abschreiben kam daher, dass ich es von dem Rechner mit Step 7 hier auf den Rechner abgeschrieben habe - Übertragungsfehler. Inzwischen bin ich so schlau und nutze eine Text-datei....
Eine Aufgabe ist es schon, das stimmt. Aber der Code kommt in jedem Fall von mir, ein Profi hätts wohl anders gemacht ^^
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Also ich kann dazu nichts sagen, weil ich nicht weiß wie das geht...
Ein Array scheint mir zuerst auch recht sinnvoll, aber wenns dann um die Zugriffe geht muss ich passen.
Mit zweier Potenz rechnen sagt mir schon eher was. Aber scheinbar scheint das doch auch so zu laufen, oder?

Also die Bits werden so gezählt:
Bit 0 1 = 1
Bit 1 1 = 2
Bit 2 1 = 4
Bit 3 1 = 8
Bit 4 1 = 16
usw.

Also ist 52 zu vergleichen Schmarrn.

Wenn ich mich recht erinnere, dann hat hier Volker einmal sich die Mühe gemacht von und über Pointer etwas zusammen zu stellen.
Dannach würde ich suchen und mir dieses Wissen aneignen.
Dann klappt es auch mit dem suchen in einem Feld.


bike
 
Ja, den hab ich vor ein paar tagen schon gelesen. Paar Sachen verstanden, paar aber auch nicht...
Hier:
http://www.sps-forum.de/showthread.php/8887-Pointer-Zeiger-FIFO-LIFO
und hier

http://www.sps-forum.de/showthread.php/12923-Any-Zeiger-für-Datentypen

Also, wenn ich das recht verstehe müsste ich im DB nur ein Array vom typ bool erstellen. Und in meiner schleife schreib ich dann was wie...

Code:
      AUF   "PositionenRegal"
      LAR1 P#0.0

//Abbruchbedingung

FIND: U     M     50.0                  // Mein Merker, damit das ganze starten kann, ist eine positiver Flankenmerker
      U(    
      L     DWX [AR1,P#0.0]                   
      L     P#DBX 6.2                   // ist bei meinem Bool-aaray das letzte element
      <D    
      )      
      SPBN  ENDE                         // wenn ja mache weiter, wenn nein = voll, also ende

      UN    DBX [AR1,P#0.0]                 // 
      SPB   ELGN

      L    P#0.0
      +AR1 P#0.1                                // laut siemens ist das + P#0.1  
      SPA   FIND

ELGN: S     DBX [AR1,P#0.0]                 // Setze das DBX, auf dass der Zeiger zeigt.

Also so nach diesem Schema?

EDIT: Merke gerade selber, dass ist *******.... Ich versuchs nochmal...
EDIT2: so sollte es besser sein
 
Zuletzt bearbeitet:
In deinem Fall funktioniert die LOOP-Schleife nicht, geht nur bei Integer-Werten.

Ansonsten ist es vermutlich nicht so wichtig, ob den Regal von vorne oder hinten aufgefüllt wird.

spsfreak12345
 
Also die Bits werden so gezählt:
Bit 0 1 = 1
Bit 1 1 = 2
Bit 2 1 = 4
Bit 3 1 = 8
Bit 4 1 = 16
usw.

Also ist 52 zu vergleichen Schmarrn.

Wenn ich mich recht erinnere, dann hat hier Volker einmal sich die Mühe gemacht von und über Pointer etwas zusammen zu stellen.
Dannach würde ich suchen und mir dieses Wissen aneignen.
Dann klappt es auch mit dem suchen in einem Feld.


bike

Da muß ich dich mal korrigieren, was du schreibst trifft zwar zu, aber beim Thema Pointer hat Imker das schon korrekt gemacht.
Ein Pointer wird ja erstellt, indem man die gewünschte Byteadresse nimmt und damit ein SLD3 ausführt. Das bedeutet ja nicht anderes als mit 8 multiplizieren. Folglich ist der einfache Zeiger ohne Bereichsinformation im Prinzip ein "Durchnummerieren" der einzelnen Bits. DBX6.4 würde also tatsächlich 8*6+5=53 entsprechen, wenn man den Pointer dezimal eingeben will. Die Schreibweise P#6.4 gefällt mit aber auch besser.
 
Also, mal ein Zwischenstand: Bei meinem Programm ohne Array bekomme ich immer einen Fehler, die Steuerung geht auf Stop. Ich hab jetzt vieles probiert, ich blicke aber nicht mehr durch.

Mit dem Array hab ich auch noch weiter probiert, gegen ende ist es dann aber auch immer auf stop gesprungen.

Ich werde heute abend leider nicht daran weiterarbeiten können, morgen gehts aber wieder weiter. Wenn jemand noch ein sinnvolle Idee hätte, wäre ich sehr dankbar (Code ist noch vom Prinzip her wie auf der 1. Seite, unten, im Beitrag von mir). Ich brauch keinen Tiptop code, sondern vielmehr hilfe wieso die steuerung immer in stop geht...
 
Zurück
Oben