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

Seite 1 von 4 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 34

Thema: PC WorX und erster Versuch eines FB in ST

  1. #1
    Registriert seit
    07.09.2011
    Beiträge
    145
    Danke
    0
    Erhielt 3 Danke für 3 Beiträge

    Frage


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo,

    ich möchte einen RS232_Receive in einem FB programmieren. Als FBD (Graphisch) habe ich es schon geschafft.
    Nun möchte ich es aber in ST umsetzen.

    Also habe ich mir einen neuen FB angelegt und das mal reingeschrieben:

    Variabeln:
    Code:
    CMD_INPUT BYTE VAR   0 0 0 0 0 0 0 
    Data_Count BYTE VAR   4 0 0 0 0 0 0 
    BIT0 BOOL VAR_OUTPUT   FALSE 0 0 0 0 0 0 
    BIT1 BOOL VAR_OUTPUT   FALSE 0 0 0 0 0 0 
    BIT2 BOOL VAR_OUTPUT   FALSE 0 0 0 0 0 0 
    BIT3 BOOL VAR_OUTPUT   FALSE 0 0 0 0 0 0 
    BIT4 BOOL VAR_OUTPUT   FALSE 0 0 0 0 0 0 
    BIT5 BOOL VAR_OUTPUT   FALSE 0 0 0 0 0 0 
    BIT6 BOOL VAR_OUTPUT   FALSE 0 0 0 0 0 0 
    BIT7 BOOL VAR_OUTPUT   FALSE 0 0 0 0 0 0 
    BIT8 BOOL VAR_OUTPUT   FALSE 0 0 0 0 0 0 
    BIT9 BOOL VAR_OUTPUT   FALSE 0 0 0 0 0 0 
    BIT10 BOOL VAR_OUTPUT   FALSE 0 0 0 0 0 0 
    BIT11 BOOL VAR_OUTPUT   FALSE 0 0 0 0 0 0 
    BIT12 BOOL VAR_OUTPUT   FALSE 0 0 0 0 0 0 
    BIT13 BOOL VAR_OUTPUT   FALSE 0 0 0 0 0 0 
    BIT14 BOOL VAR_OUTPUT   FALSE 0 0 0 0 0 0 
    BIT15 BOOL VAR_OUTPUT   FALSE 0 0 0 0 0 0 
    Receive_Data RS232_Data VAR    0 0 0 0 0 0 
    RS232_RECEIVE_DATA RS232_RECEIVE VAR    0 0 0 0 0 0 
    BYTE_TO_BITS BYTE_TO_BITS VAR    0 0 0 0 0 0
    ST Code:
    Code:
    RS232_RECEIVE_DATA(REQUEST:=FALSE,DATA:=Receive_Data);
    Receive_Data := RS232_RECEIVE_DATA.DATA;
    
    IF RS232_RECEIVE_DATA.RECEIVE_BUFFER_COUNT = BYTE_TO_INT(Data_Count) THEN
     RS232_RECEIVE_DATA.REQUEST := TRUE;
    END_IF;
    
    IF RS232_RECEIVE_DATA.DONE THEN
     IF (Receive_Data[0] = Data_Count) AND (Receive_Data[1] = CMD_INPUT) THEN
      BYTE_TO_BITS(IN:=Receive_Data[2]);
      BIT0 := BYTE_TO_BITS.B0;
      BIT1 := BYTE_TO_BITS.B1;
      BIT2 := BYTE_TO_BITS.B2;
      BIT3 := BYTE_TO_BITS.B3;
      BIT4 := BYTE_TO_BITS.B4;
      BIT5 := BYTE_TO_BITS.B5;
      BIT6 := BYTE_TO_BITS.B6;
      BIT7 := BYTE_TO_BITS.B7;
      BYTE_TO_BITS(IN:=Receive_Data[3]);
      BIT8 := BYTE_TO_BITS.B0;
      BIT9 := BYTE_TO_BITS.B1;
      BIT10 := BYTE_TO_BITS.B2;
      BIT11 := BYTE_TO_BITS.B3;
      BIT12 := BYTE_TO_BITS.B4;
      BIT13 := BYTE_TO_BITS.B5;
      BIT14 := BYTE_TO_BITS.B6;
      BIT15 := BYTE_TO_BITS.B7;
     END_IF;
    END_IF;
    Der Ablauf geht so:
    Erst wird gewartet, bis 4 Bytes im RECEIVE_BUFFER_COUNT drinnen sind. Dann soll der REQUEST auf TRUE gesetzt werden um die Daten in meine Receive_Data : Array[0..7] of Byte zu kopieren.

    Per DONE wird dann angezeigt, wann das Kopieren fertig ist.
    Danach sollen einfach die BIT0-BIT15 gesetzt werden.

    Per RS232 kommen diese Daten rein:
    Byte 0: Complete len (4)
    Byte 1: Command, CMD_INPUT = 0
    Byte 2: Data BITs 0..7
    Byte 3: Data BITs 8..15

    Wenn ich nun Funktionsblock ausführe reagiert er nur einmal und dann gar nicht mehr.
    Ich glaube das RS232_RECEIVE_DATA.REQUEST := TRUE; löst das kopieren der Daten nicht aus und somit steigt der Buffer_count immer höher.

    Kann hier jemand einen Anfänger etwas helfen!?
    Zitieren Zitieren PC WorX und erster Versuch eines FB in ST  

  2. #2
    Portisch ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    07.09.2011
    Beiträge
    145
    Danke
    0
    Erhielt 3 Danke für 3 Beiträge

    Ausrufezeichen

    Ich habe es nun zum Laufen gebracht:

    Code:
    IF NOT RS232_INIT_DONE THEN
     RETURN;
    END_IF;
    RS232_RECEIVE_1(REQUEST:=RS232_RECEIVE_1.BUFFER_NOT_EMPTY ,DATA:=Receive_Buffer);
    Receive_Buffer:=RS232_RECEIVE_1.DATA;
    IF RS232_RECEIVE_1.ERROR THEN
     Error := TRUE;
     Status := RS232_RECEIVE_1.STATUS;
    END_IF;
     
    IF RS232_RECEIVE_1.DONE THEN
     BYTE_TO_BITS_1(IN:=Receive_Buffer[2]);
     BIT0:=BYTE_TO_BITS_1.B0;
     BIT1:=BYTE_TO_BITS_1.B1;
     BIT2:=BYTE_TO_BITS_1.B2;
     BIT3:=BYTE_TO_BITS_1.B3;
     BIT4:=BYTE_TO_BITS_1.B4;
     BIT5:=BYTE_TO_BITS_1.B5;
     BIT6:=BYTE_TO_BITS_1.B6;
     BIT7:=BYTE_TO_BITS_1.B7;
    END_IF;
    Jedoch scheint der FB von RS232_RECEIVE ein Problem zu haben.
    Es geht eine Zeit lang gut, aber danach bleibt RS232_RECEIVE_1.BUFFER_NOT_EMPTY auf TRUE obwohl der Buffer leer ist.
    hier hilft dann nur ein Kaltstart damit es wider geht...

  3. #3
    Registriert seit
    25.06.2008
    Ort
    Blomberg/Lippe
    Beiträge
    1.293
    Danke
    51
    Erhielt 130 Danke für 124 Beiträge

    Standard

    Morgen,

    warum weist du überhaupt DATA doppelt zu?
    Code:
    RS232_RECEIVE_1(REQUEST:=RS232_RECEIVE_1.BUFFER_NOT_EMPTY ,DATA:=Receive_Buffer); 
    Receive_Buffer:=RS232_RECEIVE_1.DATA;
    Und nutzt du die RS232-Schnittstelle von dem ILC oder hast du eine RS232-Klemme?
    Weil dann musst du nämlich andere Bausteine nehmen.
    Gruß
    Mobi


    „Das Einfache kompliziert zu machen ist alltäglich. Das Komplizierte einfach zu machen –
    das ist Kreativität“ (Charles Mingus).

  4. #4
    Portisch ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    07.09.2011
    Beiträge
    145
    Danke
    0
    Erhielt 3 Danke für 3 Beiträge

    Standard

    Zitat Zitat von Mobi Beitrag anzeigen
    Morgen,

    warum weist du überhaupt DATA doppelt zu?
    Code:
    RS232_RECEIVE_1(REQUEST:=RS232_RECEIVE_1.BUFFER_NOT_EMPTY ,DATA:=Receive_Buffer); 
    Receive_Buffer:=RS232_RECEIVE_1.DATA;
    Und nutzt du die RS232-Schnittstelle von dem ILC oder hast du eine RS232-Klemme?
    Weil dann musst du nämlich andere Bausteine nehmen.
    Doppelt, da es PC WorX so verlangt. DATA ist ein VAR_IN_OUT.
    Wenn ich die untere Zeile weglasse gibt es einen Fehler.

    Ich benutze die eingebaute RS232 der ILC - keine extra Klemme.

  5. #5
    Registriert seit
    25.06.2008
    Ort
    Blomberg/Lippe
    Beiträge
    1.293
    Danke
    51
    Erhielt 130 Danke für 124 Beiträge

    Standard

    Ich hab nun auch mal was probiert, kann es aber nicht testen.

    Code:
    EN    BOOL    VAR_INPUT                0    0    0    0    0    0    
    BIT0    BOOL    VAR_OUTPUT                0    0    0    0    0    0    
    BIT1    BOOL    VAR_OUTPUT                0    0    0    0    0    0    
    BIT2    BOOL    VAR_OUTPUT                0    0    0    0    0    0    
    BIT3    BOOL    VAR_OUTPUT                0    0    0    0    0    0    
    BIT4    BOOL    VAR_OUTPUT                0    0    0    0    0    0    
    BIT5    BOOL    VAR_OUTPUT                0    0    0    0    0    0    
    BIT6    BOOL    VAR_OUTPUT                0    0    0    0    0    0    
    BIT7    BOOL    VAR_OUTPUT                0    0    0    0    0    0    
    BIT8    BOOL    VAR_OUTPUT                0    0    0    0    0    0    
    BIT9    BOOL    VAR_OUTPUT                0    0    0    0    0    0    
    BIT10    BOOL    VAR_OUTPUT                0    0    0    0    0    0    
    BIT11    BOOL    VAR_OUTPUT                0    0    0    0    0    0    
    BIT12    BOOL    VAR_OUTPUT                0    0    0    0    0    0    
    BIT13    BOOL    VAR_OUTPUT                0    0    0    0    0    0    
    BIT14    BOOL    VAR_OUTPUT                0    0    0    0    0    0    
    BIT15    BOOL    VAR_OUTPUT                0    0    0    0    0    0    
    RS232_RECEIVE_1    RS232_RECEIVE    VAR                0    0    0    0    0    0    
    RS232_INIT_1    RS232_INIT    VAR                0    0    0    0    0    0    
    xRequest    BOOL    VAR                0    0    0    0    0    0    
    arrReceiveData    ARRAY_OF_BYTE_0_7    VAR                0    0    0    0    0    0
    Code:
    RS232_INIT_1(ENABLE:=EN,PARAMETER:=(* ANY *));
    
    RS232_RECEIVE_1(REQUEST:=xRequest,DATA:=arrReceiveData);
    arrReceiveData := RS232_RECEIVE_1.DATA;
    
    IF RS232_RECEIVE_1.RECEIVE_BUFFER_COUNT = INT#4 AND RS232_INIT_1.VALID AND NOT xRequest THEN
        xRequest := TRUE;
    END_IF;
    
    IF RS232_RECEIVE_1.DONE THEN
        BIT0 := arrReceiveData[2].X0;
        BIT1 := arrReceiveData[2].X1;
        BIT2 := arrReceiveData[2].X2;
        BIT3 := arrReceiveData[2].X3;
        BIT4 := arrReceiveData[2].X4;
        BIT5 := arrReceiveData[2].X5;
        BIT6 := arrReceiveData[2].X6;
        BIT7 := arrReceiveData[2].X7;
        BIT8 := arrReceiveData[3].X0;
        BIT9 := arrReceiveData[3].X1;
        BIT10 := arrReceiveData[3].X2;
        BIT11 := arrReceiveData[3].X3;
        BIT12 := arrReceiveData[3].X4;
        BIT13 := arrReceiveData[3].X5;
        BIT14 := arrReceiveData[3].X6;
        BIT15 := arrReceiveData[3].X7;
        xRequest := FALSE;
    END_IF;
    Was noch fehlt ist natürlich das Error-Handling und die Parameter.
    Aber ich wollte nur erstmal den Ablauf bekommen.
    Gruß
    Mobi


    „Das Einfache kompliziert zu machen ist alltäglich. Das Komplizierte einfach zu machen –
    das ist Kreativität“ (Charles Mingus).

  6. #6
    Portisch ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    07.09.2011
    Beiträge
    145
    Danke
    0
    Erhielt 3 Danke für 3 Beiträge

    Frage

    Das habe ich schon so ähnlich gehabt.

    Das RS232_INIT habe ich nicht hier untergebracht, da es nur einmal verwendet werden kann im Projekt. Es gibt ja auch noch ein RS232_SEND...
    Ich habe (oben nicht drinnen) beim RS232_INIT das über eine globale VAR gelöst.

    Code:
    RS232_RECEIVE_1.RECEIVE_BUFFER_COUNT = INT#4
    Das gab bei mir einige Hänger, denn wenn nun 5 Bytes im Buffer sind wird dieser nie ausgelesen.
    Wenn man also >=INT#4 macht gehen aber Bytes verloren falls 5 oder mehr im Buffer sind.

    Am liebsten möchte ich Byte für Byte aus dem Buffer lesen.
    Das erste Byte sagt mir die Anzahl von Bytes die reinkommen. Danach lese ich nachfolgenden Bytes ein.
    So würde ich es in Delphi/C machen.

    Wenn man nähmlich z.B. mehrere Bytes an die SPS schickt, ist nicht gesagt das schon alle Bytes im Buffer sind bis ich den Buffer auslese.
    Und wenn nun mehrere Bytes schnell hintereinander reinkommen kann es sein wenn ich auf z.B. >=INT#512 warte und dann beim nächten Durchlauf erst auslese das schon z.B. 600 Bytes im Buffer sind. Die über 512 gehen dann verloren.

  7. #7
    Registriert seit
    25.06.2008
    Ort
    Blomberg/Lippe
    Beiträge
    1.293
    Danke
    51
    Erhielt 130 Danke für 124 Beiträge

    Standard

    Wenn du weißt wie du es in C# machen willst, dann schreib es doch einfach um. Wie stellst du dir denn den Code in C+ vor, vielleicht kann ich das dann so in ST abwandeln.

    Wenn du weißt wieviele Bytes kommen, warum wartest du dann nicht einfach bist du alle hast? Sind es immer unterschiedliche Anzahlen von Bytes?
    Gruß
    Mobi


    „Das Einfache kompliziert zu machen ist alltäglich. Das Komplizierte einfach zu machen –
    das ist Kreativität“ (Charles Mingus).

  8. #8
    Portisch ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    07.09.2011
    Beiträge
    145
    Danke
    0
    Erhielt 3 Danke für 3 Beiträge

    Standard

    Eigentlich wollte ich gestern schon Antworten. Scheint aber verloren geganngen zu sein, egal.

    Es ist nicht sicher, dass immer die gleiche Anzahl von Bytes reinkommen.
    Ich arbeite gerade daran:
    http://www.mikrocontroller.net/topic/244302#2503381

    Es wird sozusagen per RS232 z.B. 1-Wire Temperatursensoren und aber auch andere Daten zur Verfügung gestellt.
    z.B. ein zusätzlicher µC der im Wohnzimmer sitzt und IR-Signale empfangen kann. Somit kann man dann per Fernbedienung Lichter schalten.

    Derzeit kommen z.B. die Daten der RS232 so an die SPS:
    Code:
    Beispiel der RS232 mit 2 Temp Sensoren:
    000 085 011 048 040 033 057 187 003 000 000 009 236 000 000 085 011 048
    040 168 056 187 003 000 000 184 236 000
    
    000 sync byte 1
    085 sync byte 2
    011 data len
    048 command byte
    040 id
    033 id
    057 id
    187 id
    003 id
    000 id
    000 id
    009 id
    236 temp int16
    000 temp int16 = 23,6°C
    
    000 sync byte 1
    085 sync byte 2
    011 data len
    048 command byte
    040 id
    168 id
    056 id
    187 id
    003 id
    000 id
    000 id
    184 id
    236 temp int16
    000 temp int16 = 23,6°C
    Und oder auch die IR Commands:
    Code:
    Wenn nun dieser Code empfangen wird bekommt man das IRMP Command byte:
    0x00 0x55 0x02 0x10 0x11
    
    0x00 sync byte 1
    0x55 sync byte 2
    0x02 data len
    0x10 command
    0x11 IRMP Command
    Von der SPS -> µC über die RS232 mache ich das dann z.B. so wie in der AVR_Bus.c.

    Was ich eben leider nicht in der SPS abbilden kann. Im µC wird immer Byte für Byte eingelesen. Die ersten 2 Bytes sind SyncBytes und dann das data len Byte um zu wissen wieviele Bytes noch folgen.
    Wenn die SPS nun jetzt bei jedem Durchlauf ein Byte einließt und dann im Buffer hat kann ich es mir vorstellen da es ähnlich dem C-Code abläuft.
    Wenn nun aber z.B. schon 3 Bytes im Buffer sind und dann beim nächsten Durchlauf die restlichen wird's kompliziert.

    Auch wenn ich auf Buffer_Count >= INT#3 warte sind beim nächsten Durchlauf ja schon wieder neue Bytes (vielleicht auch noch nicht alle Bytes der Nachricht) im Buffer.

  9. #9
    Registriert seit
    25.06.2008
    Ort
    Blomberg/Lippe
    Beiträge
    1.293
    Danke
    51
    Erhielt 130 Danke für 124 Beiträge

    Standard

    Cool. Das wollte ich auch schon machen. Nur hatte ich für den AVR keine Zeit, das ganze zu entwickeln. Ich wollte es machen wegen der IR-Fernbedienung. Das einfachste wäre gewesen, das ganze in PC Worx umzusetzen. Aber nun kann ich ja deins nehmen.

    Also wenn du die Syncbytes bekommst, solltest du erstmal alle Bytes zwischenspeichern. Und dann wenn du alle hast, das ganze auswerten. Ich müsste mir den AVR-Kram mal aufbauen, dann kann ich dir zeigen was ich meine.
    Gruß
    Mobi


    „Das Einfache kompliziert zu machen ist alltäglich. Das Komplizierte einfach zu machen –
    das ist Kreativität“ (Charles Mingus).

  10. #10
    Portisch ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    07.09.2011
    Beiträge
    145
    Danke
    0
    Erhielt 3 Danke für 3 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Zitat Zitat von Mobi Beitrag anzeigen
    Also wenn du die Syncbytes bekommst, solltest du erstmal alle Bytes zwischenspeichern. Und dann wenn du alle hast, das ganze auswerten.
    Ok, aber hier scheidet sich mein Verständniss.
    Ich sage ich warte bis der Buffer mindestens 2 Bytes enthält. Dann überprüfe ich die 2 Bytes auf das Sync.
    Was aber wenn nun 3 Bytes im Buffer sind und das Sync erst beim zweiten anfängt usw.

    Wenn bei jedem durchlauf immer 1 Byte gelesen wird sollte es ohne Probleme funktionieren.

    EDIT:
    Ich glaub jetzt hat im Kopf geklickelt:
    Speicher in den die Daten des Empfangsspeicher der seriellen Schnittstelle
    kopiert werden. Es werden nur so viele Zeichen eingelesen, wie der an DATA
    angelegte Speicher groß ist.
    Wenn man also an DATA ein Array mit der Länge 1 anlegt sollte immer nur ein Byte aus dem Buffer gelesen werden. Was aber mit den übrigen geschieht kann ich noch nicht sagen. Ob diese dann sozusagen aufrücken oder verlorengehen (was ich nicht glaube) könnte es funktionieren.

Ähnliche Themen

  1. 2ter versuch, cpu 314 ifm, diverse karten und netzteil
    Von AlterEgo im Forum Suche - Biete
    Antworten: 1
    Letzter Beitrag: 07.01.2011, 11:26
  2. Mein erster FB
    Von WL7001 im Forum Simatic
    Antworten: 16
    Letzter Beitrag: 15.03.2008, 15:44
  3. AB erster Zyklus, oder erster Aufruf des Task nach RUN
    Von MSB im Forum Sonstige Steuerungen
    Antworten: 2
    Letzter Beitrag: 22.02.2008, 10:09
  4. Erster!
    Von mariob im Forum Stammtisch
    Antworten: 29
    Letzter Beitrag: 10.01.2008, 10:04

Lesezeichen

Berechtigungen

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