SIGNAL - Deklaration - Bereich durch INT-Variablen statt feste Zahlen

  • Hallo Leute!


    Es gab schonmal einen thread zu einem anderen Thema, der dann unbeantwortet mit dem Problem endete, dass ich jetzt habe.


    http://www.roboterforum.de/rob…ndeklaration-t2553.0.html


    Ich habe in einem globalen .dat-file meines Hauptprogramms Integer-Variablen deklariert und möchte diese in Unterprogrammen dazu benutzen SIGNAL-Bereiche du definieren. Zum besseren Verständnis, in etwa so:


    dat-file:
    DEFDAT Haupt PUBLIC
    ...
    GLOBAL INT Xout1 = 1000
    GLOBAL INT Xout2 = 1031
    ...
    ENDDAT


    Unterprogramm:
    DEF UP1()


    SIGNAL PosX $OUT[Xout1] TO $OUT[Xout2]


    INI
    ...
    PosX = $POS_ACT.X
    ...
    END



    Das ganze funktioniert einwandfrei, wenn ich statt Xout1/2 im Unterprogramm feste Zahlen eintrage. Das möchte ich aber nicht.
    Problem: wenn ich es so mache, wie oben beschrieben, kommt folgender Fehler: "Positive ganze Zahl erwartet"
    ...nun war ich ja der Meinung, dass Xout1 = 1000 diese Bedingung erfüllt...


    wo liegt hier der Fehler? oder liegt es daran, dass eine Integer auch negativ sein KANN ?
    gibt es nen Variablentyp, der hier funktionieren würde?


    mfg Speed

    200% Override ... irgendwas klingt hier komisch ... und irgendwie riecht es auch ...<br /><br />Abkühlzeit Bremsen Achse 2: 57 Sekunden :D

    Einmal editiert, zuletzt von SpeedFreak ()

  • Schritt für Schritt zum Roboterprofi!

  • ...
    Das ganze funktioniert einwandfrei, wenn ich statt Xout1/2 im Unterprogramm feste Zahlen eintrage. Das möchte ich aber nicht.
    ...


    Musst Du aber leider, 'möchten' hin oder her.
    Liegt wohl am Compiler, der erwartet da eine Konstante.
    Wenn man eine Variable eintragen könnte, dann könnte
    man den Bereich zur Laufzeit ändern. Das gibt der Compiler
    halt nicht her.

  • hallo,


    Verstehe! ...das Problem mit den Variablen/Konstanten hatte ich schon öfter...nur kam da bisher die Meldung "Konstante erwartet"
    Naja lässt sich nicht ändern.


    DECL GLOBAL CONST INT Xout1 = 1000
    ...dieser Umweg hilft leider auch nicht weiter


    mfg Speed

    200% Override ... irgendwas klingt hier komisch ... und irgendwie riecht es auch ...<br /><br />Abkühlzeit Bremsen Achse 2: 57 Sekunden :D

  • Hallo,
    ich vermute eher, es liegt an dieser SIGNAL-Deklaration zur Unzeit, denn $OUT[integer-variable]=... geht ja durchaus. Da wird der Compiler nicht so genau wissen, was zuerst kommt, Henne oder Ei.
    Ich würde mir eine Subroutine schreiben, die den Job selbst übernimmt. Geht auch recht schnell, wenn man ein bisschen brachial programmiert, z. B. den Wert erst in einen Int übernehmen, dann in zwei Byte aufteilen (/256), und dann der Reihe nach mit
    $OUT[ausgangsstartnummer + 0]=(('B00000001' B_AND Verbleichsbyte)=='B00000001')
    $OUT[ausgangsstartnummer + 1]=(('B00000010' B_AND Verbleichsbyte)=='B00000010')
    ...usw, nicht schön, aber sollte gehen.
    -
    Beim Schreiben der Antwort fiel mir aber gerade auf, dass Du ja einen REAL-Wert direkt in ein Signal schreiben willst. Geht das überhaupt? Hm....


    Grüße,
    Michael

  • hi.


    jo das geht. ich übertrage so meine ist-position an einen anderen profibus-teilnehmer


    SIGNAL PosX $OUT[1185] TO $OUT[1216] ;Ausgaenge X
    SIGNAL PosY $OUT[1217] TO $OUT[1248] ;Ausgaenge Y
    SIGNAL PosZ $OUT[1249] TO $OUT[1280] ;Ausgaenge Z


    PosX = ($POS_ACT.X*10)
    PosY = ($POS_ACT.Y*10)
    PosZ = ($POS_ACT.Z*10)


    das läuft astrein... ich wollte nur gerne die i/o-bereiche global in einem dat-file festmachen und in den unterprogrammen dann immer die variablennamen benutzen, falls ich mal nen i/o-bereich verschieben muss, der in mehreren unterprogrammen benutzt wird...also dass ich den dann nur an einer stelle ändern muss...


    entschuldige, aber ich verstehe die funktion von



    Ich würde mir eine Subroutine schreiben, die den Job selbst übernimmt. Geht auch recht schnell, wenn man ein bisschen brachial programmiert, z. B. den Wert erst in einen Int übernehmen, dann in zwei Byte aufteilen (/256), und dann der Reihe nach mit
    $OUT[ausgangsstartnummer + 0]=(('B00000001' B_AND Verbleichsbyte)=='B00000001')
    $OUT[ausgangsstartnummer + 1]=(('B00000010' B_AND Verbleichsbyte)=='B00000010')
    ...usw, nicht schön, aber sollte gehen.


    überhaupt nicht. was soll das ganze bewirken? kannst du mir das bitte etwas genauer erklären? ich überblicks nich...


    mfg Speed

    200% Override ... irgendwas klingt hier komisch ... und irgendwie riecht es auch ...<br /><br />Abkühlzeit Bremsen Achse 2: 57 Sekunden :D

  • Hi,
    ja, geht ja im Prinzip darum, aus einem beliebigen Integer eine Reihe von Bits zu machen.
    Das 1. Bit ist ganz rechts, ist in einer Signaldefinition der niedrigste Ausgang und im Integer 1
    Das 2. Bit ist das zweite von rechts, der zweitniedrigste Ausgang und im Integer 2.
    Das 3. Bit ist das dritte von rechts, der drittniedrigste Ausgang und im Integer 4.
    Und so weiter.
    Man kann sich jetzt eine Routine schreiben, die Folgendes macht:
    1. Wandle den Realwert in eine Integerzahl um
    2. Stelle dir die Integerzahl in Binärdarstellung vor
    3. Gehe von hinten her durch und setze jeden Ausgang entsprechend der Binärdarstellung der Zahl.


    Dazu kann man sich verschiedene Wege ausdenken.
    Zum Beispiel (im Beispiel erwarte ich eine Integerzahl zw. 0 und 65535):


    1. Zähle von 15 bis 0 mit Zähler z
    2. Ziehe vom Integer 2^z ab, und setze den Ausgang $OUT[z+offset] auf TRUE, wenn das Ergebnis größer oder gleich 0 ist, ansonsten auf FALSE.
    3. Mach das, bis die Zählschleife durchgelaufen ist


    Fertig.
    Nachteil: Der Kuka kennt keine POW() ... muss man sich erst schreiben, glaube ich. Dann kurbelt er enervierend lange durch diese Routinen, wenn man mal im Schrittbetrieb was testen will. Geht aber einwandfrei.


    Im (anderen) Beispiel im Beitrag oben verzichte ich auf die (2 hoch Zähler) und mache 8 Einzelvergleiche unter Zuhilfenahme der KRL-Vergleichsoperation B_AND (bitweises UND) und nehme als Vergleichszahl sofort die Binärdarstellung (das frisst der Kuka so). Mit B_AND kann man so sofort rausfinden, ob das Bit gesetzt ist und braucht nichts abziehen etc.
    Übersetzt heisst die Zeile
    $OUT[ausgangsstartnummer + 1]=(('B00000010' B_AND Verbleichsbyte)=='B00000010')
    in etwa:
    "Setze den Ausgang $OUT[...] auf den Wert, den der Vergleich von Klammerinhalt mit 2 ergibt; wobei der Klammerinhalt 2 ergibt, wenn in der Binärdarstellung das Bit für "2" gesetzt ist, egal was sonst noch."
    Dumm bei dieser Variante ist, dass die binären Vergleichsoperatoren nur auf Byte angewendet werden können. Das heisst: wenn man einen INT hat, der aus 2 Byte besteht, muss man vorher teilen (DIV 256 und ins andere Byte den Rest)...


    Na ja, irgendwie so halt, hauptsache man setzt halt die Ausgänge so wie die Binärdarstellung der Zahl, mehr brauchste ja nicht. Wie mans macht, ist eigentlich wurscht.


    Grüße,
    Michael

  • hallo,


    vielen dank für deine mühe und das viele schreiben :D
    das prinzip hab ich jetz verstanden, aber das is ja ganz schön aufwändig... das sprengt ein wenig den rahmen :D


    was ich nicht verstehe, wieso du das alles in ein unterprogramm schreiben kannst... das problem ist doch, dass man signale eben nicht global definieren kann. und in jedes unterprogramm diesen algorithmus reinschreiben, da hab ich dann ja wenig gekonnt.
    oder verstehe ich da immer noch etwas falsch?


    mfg Speed

    200% Override ... irgendwas klingt hier komisch ... und irgendwie riecht es auch ...<br /><br />Abkühlzeit Bremsen Achse 2: 57 Sekunden :D

  • Einfach eine globale Routine irgendwo hinterlegen.
    Ich mach' mir immer mindestens 1 Modul (nur SRC) mit einer "Bibliothek" darinnen, die unverändert irgendwo im Programmverzeichnis liegt und dort alle Funktionen bereitstellt, die ich häufiger brauche, die mir KRL aber nicht zur Verfügung stellt.
    Und da rein geht dann sowas wie


    global def setze_signal (wert:in, signaloffset:in)
    int wert, signaloffset


    blablabla wie oben beschrieben, einzelne Ausgänge je nach Binärdarstellung von "wert" setzen


    end



    Dann kannst Du aus jedem beliebigen Programm heraus aufrufen:
    setze_signal($pos_act.x,1000)
    und er schreibt den Wert auf $OUT[1000] und Folgende, so als wenn Du ein "SIGNAL" deklariert hättest. Sollte zumindest :)




    Falls Du noch eine der älteren Steuerungen hast, die das "global def" noch nicht kennen, musst Du eben eine eigene src anlegen und die dann z. B. über die $CONFIG global einbinden - geht auch. Wenn Du es auf die Spitze treiben willst, guck Dir mal an, wie die bei KUKA den Aufruf der BAS.SRC handhaben, mit dem ENUM-Parameter, dessen Typ in der $CONFIG festgelegt wird. Das geht auch mit eigenen Bibliotheken sehr fein, solange keine Funktionen mit Rückgabewerten aufgerufen werden müssen. Dann könntest Du etwas basteln wie
    bibliothek (#setze_signal,$pos_act.x,1000)


    Grüße,
    Michael

  • die bas.src-aufrufe nutze ich manchmal zum ändern für fdat, ldat und pdat und sowas...


    das von dir beschriebene funktioniert bestimmt, aber dann hab ich ja nicht mehr viel gekonnt, wenn ich am ende doch die zahlen und so übergeben muss. da muss ich das dann ja trotzdem in jedem unterprog einzeln machen. sprich also die zahlen in jedem prog ändern...


    werd mich wohl damit abfinden müssen, dass es nicht funktioniert, die i/o-nr. global zu verwalten.


    mfg Speed

    200% Override ... irgendwas klingt hier komisch ... und irgendwie riecht es auch ...<br /><br />Abkühlzeit Bremsen Achse 2: 57 Sekunden :D

  • Versteh ich jetzt nicht. Du kannst doch den Offset als Variable nehmen, dann hast Du doch genau das, was Du wolltest, oder nicht.
    Also dann z. B.
    setze_signal($pos_act.x,xout1)
    entspräche Deiner Anforderung aus dem Eröffnungsposting.
    Innerhalb der Routine "setze_signal" werden dann die Ausgänge flexibel gesetzt mit $OUT[signaloffset+bitstelle].


    Oder habe ich Dich jetzt komplett mißverstanden? :denk:


    (Wobei man - wenn man schon die IO GLOBAL verwalten will - die Signaldefinition ganz gerne in die $CONFIG.DAT schreibt, denn dort gehört sie eigentlich hin. Ich dachte, Du wolltest da flexibler sein?!)
    Michael

  • jetz haben wir uns endgültig verstanden :genau:


    jetz kapier ich auch wie das funktioniert, hast recht damit würde es gehen... blöd nur, dass ich noch ziemlicher anfänger bin und mit der bit-routine ne weile zu kämpfen haben werde :D


    danke für deine geduld, mal sehen ob sich paar freie stunden/tage ergeben :zwink:


    mfg Speed

    200% Override ... irgendwas klingt hier komisch ... und irgendwie riecht es auch ...<br /><br />Abkühlzeit Bremsen Achse 2: 57 Sekunden :D

  • Meine?
    Och, nix Dramatisches. Ein paar Routinen, um Dialoge, Meldungen und Fehler einfacher auszugeben, so dass man nicht immer das ganze Gedöns schreiben muss; ein bissl Mathematik; Überprüfungen und Vergleiche als boolesche Funktionen mit Parameterübergabe, damit das eigentliche Programm schlanker wird; etwas für Erfassung und Ausgabe von Zeiten; irgendwelche "schalt-mich-ein-schalt-mich-aus" mit Ergebnisabfrage, was ja auch immer irgendwie dasselbe ist; solche Sachen halt, meiner Faulheit entgegenkommend.
    Hier in der Firma gibt's so "vagabundierende Routinen", man kommt an eine Anlage, die ein Kollege gemacht hat und sieht: huch, den Code kennt man doch?! Jeder nimmt sich, was er braucht, verändert den Code evolutionär, und manchmal entstehen dabei lebende Fossilien, die auch noch nach Jahren unverändert einsatzbar sind.


    Ich neige auch dazu, Logik- und Bahnprogrammierung bestmöglich voneinander zu trennen, sowohl wg. unserer Offline-Bahnprogrammierung als auch wg. der Wiederverwendbarkeit der Programmierarbeit. Wenn ich mit Famos arbeite, kann ich keine großen IF-THEN-Sonstwas-Verzweigungen in die Bewegungsbahnen reinbauen, wohl aber Routinen- und Funktionsaufrufe bis zum Exzess. Da kommt das dann von allein...


    Beim Kuka habe ich das bisher ohne größeren Aufwand verfolgt, der ist ja recht "bodennah" zu programmieren. Das wächst dann so aus "quick'n dirty"-Lösungen heraus, an die man sich erinnert, und die man dann in einen gebrauchsfähigen Rahmen quetscht. Beim ABB hingegen murkse ich mir dagegen schon mal Module hin, die ich nach einem halben Jahr selbst nicht mehr verstehe, egal, solange es funktioniert :mrgreen:


    Grüße,
    Michael

Erstelle ein Benutzerkonto oder melde dich an um zu kommentieren

Du musst ein Benutzerkonto haben um einen Kommentar hinterlassen zu können

Benutzerkonto erstellen
Neues Benutzerkonto für unsere Community erstellen. Geht einfach!
Neues Benutzerkonto erstellen
Anmelden
Du hast bereits ein Benutzerkonto? Melde dich hier an.
Jetzt anmelden