# simple C-Aktion in WinCC



## Spanier (5 Oktober 2006)

Hallo,

ich bin neu hier und habe dementsprechend wenig Erfahrung mit WinCC 6 und fuer diesen Fall auch mit C. 
Ich mache eine Visualisierung fuer eine Sortierstation einer Schulungsanlage. Dabei werden ueber 2 Sensoren, die ich auswerten muss, erkannt ob das Stueck schwarz, silber oder rot ist. So wie ich bis jetzt in den Foren gelesen habe geht das wohl am besten mit einer C-Aktion. Ich moechte ein Textfeld anzeigen lassen wenn ein schwarzes Stueck erkannt wurde. Habe mal hierueber probiert, dass hat aber nicht funktioniert, da ich nicht weiss, was als return zurueckgegeben werden muss:

#include "apdefap.h"
 BOOL _main(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName)
{
if (GetTagBit("metallic_workpiece")==0 && (GetTagBit("workpiece-not-black")==1))
return ????;

Ich hoffe es kann mir jemand weiterhelfen. Vielen Dank schon mal.


----------



## hm988 (8 Oktober 2006)

hallo Spanier, 

ich weiß nicht ganz wo du die Funktion mit dem Rückgabewert BOOL her hast,  aber hier mal meine Lösung zu dem Thema.


Ich habe ein EA_Feld verwendet, die C-Action rufst du über  Ausgabe/Eingabe Ausgabewert C-Action auf.

Wobei das Datenformat auf String stehen sollte.
Dann bekommt erwartet deine Funktion einen Char Rückgabewert (Textzeichen)  Der Rückgabewert ist dann die Ausgabe in deinem EA_Feld.

Die vorgegebene Struktur solltest du nicht löschen (später nötig für die CrossReference) 

Natürlich gibt es noch mehr arten dein Problem zu lösen, aber ich denke das sollte ein Ansatz sein.

#include "apdefap.h"
 char* _main(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName)
{
// WINCC:TAGNAME_SECTION_START
// syntax: #define TagNameInAction "DMTagName"
// next TagID : 1
// WINCC:TAGNAME_SECTION_END
// WINCCICNAME_SECTION_START
// syntax: #define PicNameInAction "PictureName"
// next PicID : 1
// WINCCICNAME_SECTION_END

// definition für silber  
if ((GetTagBit("metallic_workpiece")==0) && (GetTagBit("workpiece_not_black")==1))

 return "silber";


// definition für rot
if ((GetTagBit("metallic_workpiece")==1) && (GetTagBit("workpiece_not_black")==1))

 return "rot";


// definition für schwarz
if ((GetTagBit("metallic_workpiece")==0) && (GetTagBit("workpiece_not_black")==0))

 return "schwarz";
}


viele grüße Steven


----------



## Spanier (11 Oktober 2006)

hallo steven
vielen dank fuer deine antwort, dass hat mir schon mal sehr geholfen.
habe leider jetzt ein neues problem:
ich moechte eine digitalanzeige aus wincc hochzaehlen lassen wenn ein impuls von einem eingang der sps kommt. meine idee dazu war eine c-aktion bei einem ea-feld unter Eigenschaften/Ausgabe/Ausgabewert. das war mein versuch:

#include "apdefap.h"
 double _main(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName)
{
// WINCC:TAGNAME_SECTION_START
#define TAG1 "Slide-full"
#define TAG2 "Leuchtmelder-Rutsche-voll"
#define TAG3 "Station_Bereit"
// WINCC:TAGNAME_SECTION_END
// WINCCICNAME_SECTION_START
// syntax: #define PicNameInAction "PictureName"
// next PicID : 1
// WINCCICNAME_SECTION_END
int i;
while (GetTagBit(TAG2)==0)
  {
  if (GetTagBit(TAG1)==1)
    {
      i++;
      return i;
    }
  }
}

gedacht war es so, dass er in die whileschleife geht und dort so lange bleibt bis der leuchtmelder kommt (nach 5 werkstuecken) und nach jedem impuls die ausgabe erhoeht. bei mir wird nur der erste impuls erkannt, danach keine weiteren. 
kann man im laufenden betrieb ueberpruefen, was die c-aktion gerade macht?
Ich hoffe es kann mir nochmal jemand helfen. Vielen Dank.
gruss michael


----------



## Praktikant (11 Oktober 2006)

hi,

überprüfen kannst du wincc mit apdiag. das liegt im verzeichniss utools im wincc programmverzeichniss.

das hochzählen würde ich anders machen, und zwar würde ich eine neue akion im globalscript erstellen und  den trigger auf  die variable Leuchtmelder-Rutsche-voll auf ändeung setzen.

da das script aber bei jedem flankenwechsel aufgerufen wird, also auch von 1 auf 0, muss du nur TAG2 auf 1 überprüfen.

if (GetTagBit(TAG2)==1)
    {
      i++;
    }


jetzt noch i in eine interne variable schreiben und dein ausgabefeld damit verbinden


----------



## Spanier (12 Oktober 2006)

hallo,

danke fuer deine schnelle hilfe. ich habe leider noch ein paar probleme damit, da ich sowas noch nicht erstellt habe.
mein ablauf:
1. neue aktion erstellt unter Global Script/Aktionen/globale Aktionen
2. Trigger auf Variable TAG2 eingestellt, bei Aenderung
3. folgendes Programm eingegeben:

#include "apdefap.h"
int gscAction( void )
{
// WINCC:TAGNAME_SECTION_START
#define TAG1 "Slide-full"
#define TAG2 "Leuchtmelder-Rutsche-voll"
// WINCC:TAGNAME_SECTION_END
// WINCCICNAME_SECTION_START
// syntax: #define PicNameInAction "PictureName"
// next PicID : 1
// WINCCICNAME_SECTION_END
int i;
if (GetTagBit(TAG2)==1)
  {
    i++;
    return i;
  }
}

4. interne variable angelegt da muesste doch ein vorzeichenloser 8-Bit-Wert reichen wenn ich nix vergessen habe.

Problem: Wie schreibe ich i in eine interne variable? global script muss ich wahrscheinlich noch in die runtime mitaufnehmen. muss sonst noch etwas beachtet werden?
Vielen Dank fuer die Hilfe.


----------

