libnodave Bit setzen

foreach

Member
Beiträge
12
Punkte Reaktionen
1
Zuviel Werbung?
->Hier kostenlos registrieren
Hallo zusammen !
Ich benutze die libnodave-Funktion daveWriteBits um ein Bit aus einer .NET Anwendung in einer älteren S7 zu setzen (319er).
Da ich mißtrauisch war ob das überhaupt geht habe ich folgendes gemacht.
Die SPS zählt 2 Bytes in einem DB ständig von 0..127 und wieder von vorne so schnell sie kann.
Mit meiner PC Anwendung schreibe ich bei einem der beiden Bytes ständig (hochfrequent) das 8.Bit auf 1.
Die SPS Anwendung soll stehenbleiben sobald die Bytes (nur die untersten 7 Bit betrachtet) unterschiedlich sind.
Das dürfte ja eigentlich nicht vorkommen, wenn alles funktionieren würde. Es kommt aber vor !
Ich vermute also, daß zumindest bei der SPS die ich hier zur Verfügung habe die libnodave-Funktion daveWriteBits nicht funktioniert.
SPS Bit setzen und PC-Bit setzen beeinflussen sich.
Hat jemand eine Erklärung dafür ?
Geht es besser mit neueren SPS-en ?
Danke für eine Antwort,

Christof
 

Rainer Hönle

Well-known member
Beiträge
5.709
Punkte Reaktionen
1.005
Wie werden denn die Bytes hochgezählt? Bzw. was wird genau in dem Program mit den beiden Bytes gemacht? Wie erfolgt der Abgleich?
Als Test würde ich einfach ein nicht verwendetes Byte nehmen, und hier einzelnen Bits setzen bzw. zurücksetzen und dann das Byte zurücklesen und prüfen.
Wenn die sowohl die SPS als auch libnodave auf ein Byte schreibend zugreifen, dann kann dies schief gehen (SPS überschreibt libnodave Änderung).
 
OP
F

foreach

Member
Beiträge
12
Punkte Reaktionen
1
Zuviel Werbung?
->Hier kostenlos registrieren
Deswegen beschreibt die SPS ja auch nur 7 Bits und der PC das Achte. Damit die eben nicht gleichzeitig auf das gleiche Bit schreiben müssen.
Mir ist klar, daß wenn auf das gleiche Bit geschrieben wird, der letzte Schreiber "gewinnt".
Bei einer 400er Steuerung ist das jetzt die ganze Nacht durchgelaufen, ohne stehen zu bleiben.
 
OP
F

foreach

Member
Beiträge
12
Punkte Reaktionen
1
Ja, daveWriteBits !

Das Setzen funktioniert auch, es gibt also keine Probleme daß ich das falsche Bit treffe oder sowas.
Der Code in der SPS sieht so aus:

Im OB1



Als eigenes Netzwerk:

U DB1000.DBX 11.7

= #HW_Bit0

L DB1000.DBB 11

L W#16#7F

UW

L DB1000.DBB 13

<>I

SPB ungl

L 120

>I

SPB beg1



L DB1000.DBB 13

+ 1

SPA Z1



beg1: NOP 0

L DB1000.DBD 6

L L#1

+D

T DB1000.DBD 6

L 0

Z1: NOP 0

T DB1000.DBB 11

T DB1000.DBB 13

U #HW_Bit0

= DB1000.DBX 11.7



ungl: NOP 0

L DB1000.DBD 6
 

Rainer Hönle

Well-known member
Beiträge
5.709
Punkte Reaktionen
1.005
Deswegen beschreibt die SPS ja auch nur 7 Bits und der PC das Achte. Damit die eben nicht gleichzeitig auf das gleiche Bit schreiben müssen.
Mir ist klar, daß wenn auf das gleiche Bit geschrieben wird, der letzte Schreiber "gewinnt".
Bei einer 400er Steuerung ist das jetzt die ganze Nacht durchgelaufen, ohne stehen zu bleiben.
Tja, beim Transferieren in ein Byte werden trotz ausmaskiertem Bit 7 alle acht Bits geschrieben. Und in der Zeit zwischen merken und setzen des Bitzustandes kann bereits ein neuer Wert mit libnodave geschrieben worden sein, der durch diese Vorgehensweise überbügelt wird.
 

Jochen Kühner

Well-known member
Beiträge
4.201
Punkte Reaktionen
484
Ja durch libnodave wird also nur das 8te Bit geschrieben, aber in der SPS schreibst du durch deinen Byte Zugriff natürlich auf alle 8 Bits. Wenn du nur die ersten 7 beinflußen willst, darfst du natürlich auch nur Bitfunktionen zum setzen und rücksetzen verwenden (=, R, S)
 

Rainer Hönle

Well-known member
Beiträge
5.709
Punkte Reaktionen
1.005
Zuviel Werbung?
->Hier kostenlos registrieren
Ja durch libnodave wird also nur das 8te Bit geschrieben, aber in der SPS schreibst du durch deinen Byte Zugriff natürlich auf alle 8 Bits. Wenn du nur die ersten 7 beinflußen willst, darfst du natürlich auch nur Bitfunktionen zum setzen und rücksetzen verwenden (=, R, S)
Er setzt dann das Bit 7 wieder auf den Wert, den er sich am Anfang gemerkt hat. Allerdings kann der Schreibzugriff von außen zu jeder Zeit stattfinden, also auch während merken und reinverknüpfen.
 
OP
F

foreach

Member
Beiträge
12
Punkte Reaktionen
1
So, jetzt habe ich die 7 unteren Bits mal mit 7 Bitfunktionen gesetzt, ich schreibe also nicht mehr auf das komplette Byte.
Ich hole mir also aus dem einen Byte Bit für Bit raus und schreibe sie in das andere. Meint ihr das mit "Bitfunktionen" ?
Und trotzdem bleibt er stehen !
Kann es daran liegen das die 319-3PN/DP SPS eine integrierte CP hat und das es deswegen das Problem gibt.

U DB1000.DBX13.0
= DB1000.DBX11.0

U DB1000.DBX13.1
= DB1000.DBX11.1

usw....

U DB1000.DBX13.6
= DB1000.DBX11.6


Schönen FA
 
Zuletzt bearbeitet:

Jochen Kühner

Well-known member
Beiträge
4.201
Punkte Reaktionen
484
So, jetzt habe ich die 7 unteren Bits mal mit 7 Bitfunktionen gesetzt, ich schreibe also nicht mehr auf das komplette Byte.
Ich hole mir also aus dem einen Byte Bit für Bit raus und schreibe sie in das andere. Meint ihr das mit "Bitfunktionen" ?
Und trotzdem bleibt er stehen !
Kann es daran liegen das die 319-3PN/DP SPS eine integrierte CP hat und das es deswegen das Problem gibt.

U DB1000.DBX13.0
= DB1000.DBX11.0

U DB1000.DBX13.1
= DB1000.DBX11.1

usw....

U DB1000.DBX13.6
= DB1000.DBX11.6


Schönen FA

Dann poste doch mal deinen ganzen Code wie du's jetzt machst.
 
OP
F

foreach

Member
Beiträge
12
Punkte Reaktionen
1
Zuviel Werbung?
->Hier kostenlos registrieren
//Hier mal der ganze Code...

L DB1000.DBB 11
L W#16#7F
UW
L DB1000.DBB 13
<>I
SPB M001
L 120
>I
SPB M002
L DB1000.DBB 13
+ 1
SPA M003
M002: NOP 0
L DB1000.DBW 6
+ 1
T DB1000.DBW 6
L 0
M003: NOP 0
//T DB1000.DBB 11
T DB1000.DBB 13
U DB1000.DBX 13.0
= DB1000.DBX 11.0
U DB1000.DBX 13.1
= DB1000.DBX 11.1
U DB1000.DBX 13.2
= DB1000.DBX 11.2
U DB1000.DBX 13.3
= DB1000.DBX 11.3
U DB1000.DBX 13.4
= DB1000.DBX 11.4
U DB1000.DBX 13.5
= DB1000.DBX 11.5
U DB1000.DBX 13.6
= DB1000.DBX 11.6
// U #TEMP6
// = DB1000.DBX 11.7
M001: NOP 0
 
OP
F

foreach

Member
Beiträge
12
Punkte Reaktionen
1
Ich rufe allle paar ms folgende Funktion auf.....


public int SetBit(int db, int offset, int bitPos, object value)
{
//db=1000
//offset=11
//bitPos=7
//value=true

int result = 0;

if(Convert.ToBoolean(value) == true)
{
result = dc.setBit(libnodave.daveDB, db, offset, bitPos);
}
else
{
result = dc.clearBit(libnodave.daveDB, db, offset, bitPos);
}

return result;
}

wobei ich setBit und ClearBit noch aus libnodave heraus exportiert habe (Ich übersetzte das libnodave Projekt jedesmal mit), dmit ich sie aus C# heraus aufrufen konnte.


[DllImport("libnodave.dll"/*, PreserveSig=false */ )]
protected static extern int daveSetBit(IntPtr dc, int area, int DBnumber, int byteAdr, int bitAdr);
public int setBit(int area, int DBnumber, int byteAdr, int bitAdr)
{
return daveSetBit(pointer, area, DBnumber, byteAdr, bitAdr);
}

[DllImport("libnodave.dll"/*, PreserveSig=false */ )]
protected static extern int daveClrBit(IntPtr dc, int area, int DBnumber, int byteAdr, int bitAdr);
public int clearBit(int area, int DBnumber, int byteAdr, int bitAdr)
{
return daveClrBit(pointer, area, DBnumber, byteAdr, bitAdr);
}
 
OP
F

foreach

Member
Beiträge
12
Punkte Reaktionen
1
Ich glaube auch nicht, daß libnodave einen Fehler macht. Ich vermute, daß die SPS das nicht kann, weil sie noch einen internen Kommunikationsbaustein hat, der das verhindert.
Wie gesagt eine noch ältere 400er SPS ist 20 Stunden ohne stehenbleiben durchgelaufen.
Was mich nur wundert ist, daß libnodave aus der 300er SPS die Fehlermeldung 6 bei writeBits rausbekommen hat, als ich versucht habe 3 Bits gleichzeitig zu schreiben (testweise).
6 bedeutet, daß diese SPS nicht in der Lage ist mehrere Bits gleichzeitig zu schreiben.
Ich hätte jetzt erwartet, daß sie/oder libnodave eine Fehlermeldung bringt, daß auch ein einziges Bit schreiben schon nicht geht.

Für unsere Anwendungsfälle ist das zwar alles nicht ganz so tragisch, aber die letzte Sicherheit, daß nichts schief geht haben wir eben nicht.
Und ich würde es gerne verstehen.

Danke für eure Hilfe
 

Thomas_v2.1

Well-known member
Beiträge
8.796
Punkte Reaktionen
2.697
Also so ganz verstehe ich nicht was du da vorhast.
Deine Bedingung
Code:
L DB1000.DBB 11
L W#16#7F
UW
L DB1000.DBB 13
<>I
ist wahr wenn deine PC Anwendung im Zyklus auf das Byte schreibt. Bei alten 300er CPUs wird immer am Zykluskontrollpunkt geschrieben. Bei den 400ern immer und bei den neuen 300ern optional kann auch im Zyklus auf die Daten geschrieben werden.
Wenn dein Codeschnippsel das einzige ist was die CPU zu tun hat, ist die Wahrscheinlichkeit größer dass eben auch im Zyklus auf die Daten geschrieben wird, als wenn der Programmteil nur 1 Promille vom Gesamtcode ausmacht. Wenn man sein Programm so geschrieben hat dass es wichtig ist auf konsistente Daten zuzugreifen muss man programmtechnisch dafür Sorge tragen dass dies der Fall ist (z.B. durch atomare Befehle zwischenspeichern).

Wenn es der Fall ist dass "das Programm stoppt" wie du schreibst zeigt es doch eben dass alles wie erwartet funktioniert.
 
Oben