# Libnodave JAVA readBit



## schirgitom (7 August 2012)

Hallo liebe Community!

Ich habe gerade meine ersten Gehversuche mit LIBNODAVE in Java unternommen. Funktioniert bislang einwandfrei.
Ich würde allerdings eine getBit oder readBit wo wirklich nur 1 Bit ausgelesen wird benötigen.
Hat jemand von Euch schon sowas gemacht bzw. wäre bereit mir diese Funktion zur Verfügung zu stellen?

Vielen Dank,

LG

Thomas


----------



## schirgitom (7 August 2012)

Hi!

Das Problem hat sich schon erübrigt, habe es zusammenbekommen.
Jetzt hänge ich aber beim schreiben von einem einzigen Bit.
Kann mir da jemand bitte helfen?

Vielen Dank,

LG

Thomas


----------



## nullok (21 März 2013)

*Brauchst du die Hilfe noch ?*

Falls du noch Hilfe brauchst dann melde dich
MFG


----------



## bike (21 März 2013)

Wenn der Kollge nach fast 9 Monaten  keine Lösung gefunden hätte da  ist eine späte Geburt.


bike


----------



## Bastueh89 (14 Juni 2013)

Hallo. Brauche dringend Hilfe!

Hat nun jemand ne Lösung gefunden? ich möchte auch unbedingt einzelne Bits anzeigen lassen und steuern!

gerne auch private email.

ist wirklich dringend. sitze an meiner Bachelorarbeit.


----------



## nullok (15 Juni 2013)

- 8 bit einlesen. 
- mittels Teilen und Modulo das gesuchte Bit herausfiltern oder per Bitshiften
- vergleichen ob das Bit verändert werden muss oder nicht.
- wenn es verändert werden muss, dann die 8 Bits mit dem veränderten Wert wieder zusammenbasteln.
- 8 bits schreiben.
siehe Grundlagen Binärrechnen.
Lg


----------



## Bastueh89 (15 Juni 2013)

danke erst einmal für die schnelle Antwort ich hatte schon angst, dass hier keiner mehr reinguckt.

ich muss das ganze mal ein bissl zurückschrauben. Habe jetzt erst seit 2 Monaten Java- bzw. Android-Programmierung-Erfahrungen. Ich versuch mich immer noch in libnodave reinzuarbeiten, sehe da aber noch nicht wirklich durch. Wie meinst du das denn mit den Bit einlesen? Ich finde wie gesagt nur readBytes() bzw. getByte(). soll ich das das byte, welches das Bit enthält mit getbyte() einlesen und dann immer durch 2 teilen und über den Rest (Modulo) die Bits iwie auslesen???


----------



## Bastueh89 (16 Juni 2013)

Ich habe jetzt mal ein kleines java-Programm (nicht android-Programm) geschrieben, was einzelne Bits ausliest und auch einlesen kann. Die wichtigen Stellen habe ich schwarz markiert: 


```
[COLOR=#931A68][FONT=Monaco]import[/FONT][/COLOR][FONT=Monaco] java.io.IOException;[/FONT][FONT=Monaco][COLOR=#931a68]import[/COLOR] java.util.Scanner;[/FONT]
[FONT=Monaco]
[/FONT]
[FONT=Monaco][COLOR=#931a68]public[/COLOR] [COLOR=#931a68]class[/COLOR] readAndWriteBit {[/FONT]
[FONT=Monaco]
[/FONT]
[FONT=Monaco]    [COLOR=#931a68]public[/COLOR] [COLOR=#931a68]static[/COLOR] [COLOR=#931a68]void[/COLOR] main(String[] args) [COLOR=#931a68]throws[/COLOR] IOException[/FONT]
[FONT=Monaco]    {[/FONT]
[COLOR=#4E9072][FONT=Monaco]// [COLOR=#91afcb]TODO[/COLOR] Auto-generated method stub[/FONT][/COLOR]
[FONT=Monaco]        [COLOR=#931a68]byte[/COLOR] b = ([COLOR=#931a68]byte[/COLOR]) 10010001;[/FONT]
[FONT=Monaco]        outputBits(b);[/FONT]
[FONT=Monaco]    }[/FONT]
[FONT=Monaco]
[/FONT]
[B][FONT=Monaco]    [COLOR=#931a68]public[/COLOR] [COLOR=#931a68]static[/COLOR] [COLOR=#931a68]void[/COLOR] outputBits([COLOR=#931a68]byte[/COLOR] b) [COLOR=#931a68]throws[/COLOR] IOException[/FONT]
[FONT=Monaco]    {[/FONT]
[FONT=Monaco]        System.[COLOR=#0326cc]out[/COLOR].print([COLOR=#3933ff]"Output: "[/COLOR]);[/FONT]
[FONT=Monaco]        [COLOR=#931a68]for[/COLOR] ([COLOR=#931a68]int[/COLOR] bit = 7; bit>=0; bit--)[/FONT]
[FONT=Monaco]        {[/FONT]
[FONT=Monaco]            [COLOR=#931a68]int[/COLOR] i = 0;[/FONT]
[FONT=Monaco]            [COLOR=#931a68]boolean[/COLOR] is = ((b >> bit) & 1 ) == 1;[/FONT]
[FONT=Monaco]            [COLOR=#931a68]if[/COLOR] (is == [COLOR=#931a68]true[/COLOR])[/FONT]
[FONT=Monaco]            {[/FONT]
[FONT=Monaco]                i = 1;[/FONT]
[FONT=Monaco]                System.[COLOR=#0326cc]out[/COLOR].print(i);[/FONT]
[FONT=Monaco]            }[/FONT]
[COLOR=#931A68][FONT=Monaco]else[/FONT][/COLOR]
[FONT=Monaco]            {[/FONT]
[FONT=Monaco]                i = 0;[/FONT]
[FONT=Monaco]                System.[COLOR=#0326cc]out[/COLOR].print(i);[/FONT]
[FONT=Monaco]            }[/FONT]
[FONT=Monaco]
[/FONT]
[FONT=Monaco]        }[/FONT][/B]
[FONT=Monaco]        System.[COLOR=#0326cc]out[/COLOR].println([COLOR=#3933ff]""[/COLOR]);[/FONT]
[COLOR=#3933FF][FONT=Monaco][COLOR=#000000]        System.[/COLOR][COLOR=#0326cc]out[/COLOR][COLOR=#000000].print([/COLOR]"Do you want to change certain Bits? y/n: "[COLOR=#000000]);[/COLOR][/FONT][/COLOR]
[FONT=Monaco]        queryContinue(b);[/FONT]
[FONT=Monaco]    }[/FONT]
[FONT=Monaco]
[/FONT]
[FONT=Monaco]    [COLOR=#931a68]public[/COLOR] [COLOR=#931a68]static[/COLOR] [COLOR=#931a68]void[/COLOR] queryContinue([COLOR=#931a68]byte[/COLOR] b) [COLOR=#931a68]throws[/COLOR] IOException[/FONT]
[FONT=Monaco]    {[/FONT]
[FONT=Monaco]        Scanner inputQueryContinue = [COLOR=#931a68]new[/COLOR] Scanner(System.[COLOR=#0326cc]in[/COLOR]);[/FONT]
[FONT=Monaco]        String queryAnswerContinue = inputQueryContinue.nextLine();[/FONT]
[FONT=Monaco]
[/FONT]
[FONT=Monaco]        [COLOR=#931a68]if[/COLOR](queryAnswerContinue.equals([COLOR=#3933ff]"y"[/COLOR]))[/FONT]
[FONT=Monaco]        {[/FONT]
[COLOR=#3933FF][FONT=Monaco][COLOR=#000000]            System.[/COLOR][COLOR=#0326cc]out[/COLOR][COLOR=#000000].print([/COLOR]"Which bit do you want to change? (0-7): "[COLOR=#000000]);[/COLOR][/FONT][/COLOR]
[FONT=Monaco]            queryBit(b);[/FONT]
[FONT=Monaco]        }[/FONT]
[FONT=Monaco]        [COLOR=#931a68]else[/COLOR] [COLOR=#931a68]if[/COLOR](queryAnswerContinue.equals([COLOR=#3933ff]"n"[/COLOR]))[/FONT]
[FONT=Monaco]        {[/FONT]
[COLOR=#3933FF][FONT=Monaco][COLOR=#000000]            System.[/COLOR][COLOR=#0326cc]out[/COLOR][COLOR=#000000].println([/COLOR]"Completed program !!!"[COLOR=#000000]);[/COLOR][/FONT][/COLOR]
[FONT=Monaco]            System.exit(0);[/FONT]
[FONT=Monaco]        }[/FONT]
[COLOR=#931A68][FONT=Monaco]else[/FONT][/COLOR]
[FONT=Monaco]        {[/FONT]
[COLOR=#3933FF][FONT=Monaco][COLOR=#000000]            System.[/COLOR][COLOR=#0326cc]out[/COLOR][COLOR=#000000].print([/COLOR]"___Please, just enter 'y' or 'n' !!!___: "[COLOR=#000000]);[/COLOR][/FONT][/COLOR]
[FONT=Monaco]            queryContinue(b);[/FONT]
[FONT=Monaco]        }[/FONT]
[FONT=Monaco]    }[/FONT]
[FONT=Monaco]
[/FONT]
[COLOR=#931A68][FONT=Monaco]public static void[COLOR=#000000] queryBit([/COLOR]byte[COLOR=#000000] b)[/COLOR][/FONT][/COLOR]
[FONT=Monaco]    {[/FONT]
[FONT=Monaco]        [COLOR=#931a68]int[/COLOR] bitAnswer = 0;[/FONT]
[FONT=Monaco]        Scanner inputBit = [COLOR=#931a68]new[/COLOR] Scanner(System.[COLOR=#0326cc]in[/COLOR]);[/FONT]
[FONT=Monaco]
[/FONT]
[COLOR=#931A68][FONT=Monaco]try[/FONT][/COLOR]
[FONT=Monaco]        {[/FONT]
[FONT=Monaco]            bitAnswer = inputBit.nextInt();[/FONT]
[FONT=Monaco]            [COLOR=#931a68]int[/COLOR] bit = 7 - bitAnswer;[/FONT]
[COLOR=#3933FF][FONT=Monaco][COLOR=#000000]            System.[/COLOR][COLOR=#0326cc]out[/COLOR][COLOR=#000000].print([/COLOR]"True or false? (0/1): "[COLOR=#000000]);[/COLOR][/FONT][/COLOR]
[FONT=Monaco]            queryCondition(b, bit);[/FONT]
[FONT=Monaco]        }[/FONT]
[FONT=Monaco]        [COLOR=#931a68]catch[/COLOR] (Exception e)[/FONT]
[FONT=Monaco]        {[/FONT]
[COLOR=#3933FF][FONT=Monaco][COLOR=#000000]            System.[/COLOR][COLOR=#0326cc]out[/COLOR][COLOR=#000000].print([/COLOR]"ERROR:___Please, just enter the bit position of the 8-digit-byte !!! (0-7)___: "[COLOR=#000000]);[/COLOR][/FONT][/COLOR]
[FONT=Monaco]            queryBit(b);[/FONT]
[FONT=Monaco]        }[/FONT]
[FONT=Monaco]    }[/FONT]
[FONT=Monaco]
[/FONT]
[FONT=Monaco]    [COLOR=#931a68]public[/COLOR] [COLOR=#931a68]static[/COLOR] [COLOR=#931a68]void[/COLOR] queryCondition([COLOR=#931a68]byte[/COLOR] b, [COLOR=#931a68]int[/COLOR] bit)[/FONT]
[FONT=Monaco]    {[/FONT]
[FONT=Monaco]        [COLOR=#931a68]int[/COLOR] conditionAnswer;[/FONT]
[FONT=Monaco]
[/FONT]
[FONT=Monaco]        Scanner inputCondition = [COLOR=#931a68]new[/COLOR] Scanner(System.[COLOR=#0326cc]in[/COLOR]);[/FONT]
[COLOR=#931A68][FONT=Monaco]try[/FONT][/COLOR]
[FONT=Monaco]        {[/FONT]
[FONT=Monaco]            conditionAnswer = inputCondition.nextInt();[/FONT]
[FONT=Monaco]            setBit(b, bit, conditionAnswer);[/FONT]
[FONT=Monaco]
[/FONT]
[FONT=Monaco]        }[/FONT]
[FONT=Monaco]        [COLOR=#931a68]catch[/COLOR](Exception e)[/FONT]
[FONT=Monaco]        {[/FONT]
[COLOR=#3933FF][FONT=Monaco][COLOR=#000000]            System.[/COLOR][COLOR=#0326cc]out[/COLOR][COLOR=#000000].print([/COLOR]"ERROR:___Please, enter 0 for FALSE or 1 for TRUE !!! (0/1)___: "[COLOR=#000000]);[/COLOR][/FONT][/COLOR]
[FONT=Monaco]            queryCondition(b, bit);[/FONT]
[FONT=Monaco]        }[/FONT]
[FONT=Monaco]    }[/FONT]
[FONT=Monaco]
[/FONT]
[B][FONT=Monaco]    [COLOR=#931a68]public[/COLOR] [COLOR=#931a68]static[/COLOR] [COLOR=#931a68]void[/COLOR] setBit([COLOR=#931a68]byte[/COLOR] b, [COLOR=#931a68]int[/COLOR] bit, [COLOR=#931a68]int[/COLOR] conditionAnswer) [COLOR=#931a68]throws[/COLOR] IOException[/FONT]
[FONT=Monaco]    {[/FONT]
[FONT=Monaco]        [COLOR=#931a68]if[/COLOR]( conditionAnswer == 1)[/FONT]
[FONT=Monaco]        {[/FONT]
[FONT=Monaco]            b = ([COLOR=#931a68]byte[/COLOR])(b | (1 << bit));[/FONT]
[FONT=Monaco]            outputBits(b);[/FONT]
[FONT=Monaco]        }[/FONT]
[FONT=Monaco]        [COLOR=#931a68]else[/COLOR] [COLOR=#931a68]if[/COLOR](conditionAnswer == 0)[/FONT]
[FONT=Monaco]        {[/FONT]
[FONT=Monaco]            b = ([COLOR=#931a68]byte[/COLOR])(b & ~(1 << bit));[/FONT]
[FONT=Monaco]            outputBits(b);[/FONT]
[FONT=Monaco]        }[/FONT]
[FONT=Monaco]    }[/FONT][/B]
[FONT=Monaco]}
[/FONT]
```

Meine Frage ist jetzt nur wie kann ich das auf mein libnodave-Quellcode übertragen (TestISOTCP-Klasse?!) ? Wie oder wo wird das Byte denn übergeben? Wird das nicht irgendwo als Array übergeben? Wenn ich in meine Merker-Klasse schaue, sehe ich, dass das Byte MD0 als float deklariert wird !? Oder kann ich das dort einfach als byte deklarieren und dann mein Programm (s.o.) anwenden? oder muss ich schon eher das Byte abgreifen?


----------



## nullok (16 Juni 2013)

Lieber Bastueh,
zuerst macht es wirklich keinen Sinn, einzelne Bits hin- und herzuschieben.
Wenn du mit einer Methode getBit() ein Bit anschauen willst, startest du eine TCP/IP Kommunikation von zweimal 1540 Bits also  3080 Bits wovon du mal eines brauchst und 2999 Bits Müll enthält.
Je mehr Trash du durch die gegen schiebst, desto höher die Verzögerung deines System.
Aus diesem Grund holt man sich so viel Daten auf einmal wie möglich und bastelt die Daten die man braucht in Java ins System ein.

Nun, was muss ich tun, wenn ich ein einzelnes Bit auslösen möchte.

Zuerst ließt du ein Byte ein. 
Ein Byte besteht aus 8 Bit also 256 Möglichkeiten.

Von binäre 0 0 0 0 0 0 0 0 = dezimal 0
von binäre 1 1 1 1 1 1 1 1 = dezimal 255.

Ich nehmen jetzt die binäre Zahl 01010101 also dezimal = 85 als Beispiel.
Die Bits haben die Zahlenwertigkeit von 128/64 /32/16 /8/4/2/1
                                                                    0   1    0    1   0 1 0 1
						 64 +     16 + 4  + 1 = 85.

Ich möchte jetzt prüfen ob das 5te bit eine 1 oder null ist.
Zuerst setze ich alle Bits vor der 5ten Stelle auf Null.
Das geht mit %32 also Modulo32 (Wertigkeit des gesuchten Bits). 
Damit wird aus der 85 eine 25.
Nun dividierst du das Ergebnis durch die Wertigkeit der 5ten Stelle also 32.
Dadurch das 32 eine Integer Zahl ist, wird das Ergebnis eine Integer also eine Ganzzahl sein,
25/32 ergibt dann 0. 

Du kannst das auch mit deinem Bitshiften oder deinem logischen und Operator machen.
Das 5te Bit ist somit eine „Null“.

Also musst du nun lediglich eine Methode schreiben die ein Byte einließt und als zusätzlichen Übergabeparameter welches Bit ausgelesen werden muss. Als Rückgabeparameter kann du dann ein Boolean machen.

Willst du nur ein Bit schreiben.
Dann lese die 8 Bytes ein. 
Speichere den Zwischenstand der Bits in lokalen Variablen . 
Kontrolliere ob sich das Bit was du setzen willst sich geändert hat. 
Wenn ja dann bastle die 8 Bits wieder zusammen und rufe die Methode writeByte() auf.

Die ganze Methode sollte dann am Ende ein achtzeiler werden. 
Welchen Bachelor machst du eigentlich ?
Have Fun ;-)


----------



## Bastueh89 (16 Juni 2013)

Danke erst einmal für die schnelle und ausführliche Antwort.

Mit dem binären Zahlensystem und Rechnen und so kenn ich mich schon aus. Hatte 2 Semester Informatik und mache BAoE Elektro- und Informationstechnik. Dort habe ich aber halt nur die Grundlagen beigebracht bekommen. Java-Programmierung lerne ich jetzt für mich erst seit 2 Monaten da ich die Aufgabe für ne android-app bekommen habe. Ich würde gerne zum Überprüfen die 8 Bits eines Bytes auslesen und ein Bit setzen. Warum ich das machen will ist erst einmal egal.

Das mit dem Modulo kenn ich nur vom Papier her…ich teile eine Zahl solange durch 2, bis ich über den Rest den Binärcode rausbekomme...kann mir aber das quellcode-mäßig nicht vorstellen ?! Kann ich das denn mit einer float- oder long-Variable machen? wie gesagt ich habe die libnodave-Quellcode-Sammlung in meine App integriert und würde sie auch gerne verstehen, aber selbst mit dem Debugger sehe ich nicht so richtig durch, was passiert. Auch ne Anleitung finde ich nicht wirklich. Für die C-libnodave-Sammlung scheint es dies zu geben ?! Und als Beispiel ist ein Merker MD1 als long und ein MD12 als float deklariert.

Und wie sieht mein Programm aus? Ich lese doch ein deklariertes Byte ein, lasse mir nacheinander die Bits angeben (wahrscheinlich über dieses "Bitshiften") und setze in der letzten Methode ein vom Benutzer gewähltes Bit auf True oder False (wie der Nutzer es eben will). Ist das denn nicht in Ordnung?

Also das Programm funktioniert auch…nur weiß ich nicht wie ich das in libnodave integrieren kann verstehst du was ich meine?
Mal nen kurzen Auszug aus libnodave….


Merker.class:

```
public class Merker
{
    [B]public static byte MB0;[/B]
    public static long MD1;
    public static float MD12;
}
```
aus der TestISOTCP.class:

```
...
System.out.println("Trying to read 16 bytes from FW0.\n");
                [B]dc.readBytes(Nodave.FLAGS, 0, 0, 16, null);// Read Flag

                Merker.MB0 = (byte) dc.getBYTE();

                for (int bit = 7; bit>=0; bit--)
                {
                    int i = 0;
                    boolean is = ((Merker.MB0 >> bit) & 1 ) == 1;
                    if (is == true)
                    {
                        i = 1;
                        System.out.print(i);
                    }
                    else
                    {
                        i = 0;
                        System.out.print(i);
                    }
                }[/B]

                Merker.MD1 = dc.getU32();
                Merker.MD12 = dc.getFloat();    

                [B]System.out.println("1 Byte" + Merker.MB0);[/B]
                System.out.println("4 DWORDS " + Merker.MD1);
                System.out.println("1 Float: " + Merker.MD12);

                [B]if (doWrite)// Here we write from PLC
                {
                    System.out.println("Now we write back these data");

                    by = Nodave.bswap_8(Merker.MB0);
                    dc.writeBytes(Nodave.FLAGS,0, 0, 4, by);[/B]
            
                    by = Nodave.bswap_32(Merker.MD1 + 1);
                    dc.writeBytes(Nodave.FLAGS, 0, 1, 4, by);

                    by = Nodave.toPLCfloat(Merker.MD12 + 0.1);
                    dc.writeBytes(Nodave.FLAGS, 0, 12, 4, by);

                    dc.readBytes(Nodave.FLAGS, 0, 0, 16, null);

                    [B]Merker.MB0 = (byte) dc.getBYTE();[/B]
                    Merker.MD1 = dc.getU32();
                    Merker.MD12 = dc.getFloat();

                    [B]System.out.println("FD0: " + Merker.MB0);[/B]
                    System.out.println("FD1: " + Merker.MD1);
                    System.out.println("FD12: " + Merker.MD12);
…
```

ich hab lediglich MB0 und alles um MB0 zu Testzwecken hinzugefügt. Kann es aber leider jetzt nicht testen, da ich nur auf Arbeit meine Steuerung dazu habe.


----------



## Bastueh89 (17 Juni 2013)

ok ich habs hinbekommen 
wer wissen will wie…:


Merker.class:

```
byte MB2;
```

TestISOTCP.class:

```
…
runSomething()
{
….
                                [B]System.out.println("initialisize");
                by = Nodave.bswap_8(Merker.MB2-Merker.MB2);
                dc.writeBytes(Nodave.FLAGS,0, 2, 1, by);[/B]

                System.out.println("Trying to read data");
                dc.readBytes(Nodave.FLAGS, 0, 2, 1, null);
                Merker.MB2 = (byte) dc.getBYTE();
                [B]outputBits();[/B]

                if (doWrite)// Here we write from PLC
                {
                    System.out.println("Now we write back these data");

                    [B]by = Nodave.bswap_8(Merker.MB2+2);[/B]
                    dc.writeBytes(Nodave.FLAGS,0, 2, 1, by);
                    dc.readBytes(Nodave.FLAGS, 0, 2, 1, null);

                    Merker.MB2 = (byte) dc.getBYTE();
                    outputBits();
                                } 
                                disconnectPLC();
                                disconnectAdapter();
…
}
[B]public static void outputBits()[/B]
    {System.out.println("__________BYTE MB2: ");
    for (int bit = 7; bit>=0; bit--)
    {
        int i = 0;
        boolean is = ((Merker.MB2 >> bit) & 1 ) == 1;
        if (is == true)
        {
            i = 1;
            System.out.print(i);
        }
        else
        {
            i = 0;
            System.out.print(i);
        }
    }
}
```

zum Ablauf:
bevor ich überhaupt was lese überschreibe ich das Merkerbyte mit 00000000 mit dem Befehl: _by = Nodave.bswap_8(Merker.MB2-Merker.MB2);_

danach lese ich die einzelnen Bits mit meinem Programm-Teil aus und lass es mir in der Console anzeigen. 

jetzt addiere ich eine dezimale 2, was nach gelernter Binärrechnung ein Byte mit 0000010 erzeugt. _by = Nodave.bswap_8(Merker.MB2+2);_

zum Schluss überschreibe ich wieder das Byte mit meinem neu erzeugten Byte, lese es auch wieder aus und lasse es mir ausgeben.

siehe da: in M2.1 steht ne 1 drin.




leider würde ich gerne nach dem Verbindungsabbau das byte wieder zurücksetzen…weiß aber nicht, ob da jemand ne Ahnung hat ?!
und/oder weiß jemand wie man die Verbindung aufrechterhalten kann? Wer mir da weiterhelfen will….
http://www.sps-forum.de/software/64035-libnodave-java-verbindung-aufrechterhalten.html#post448375


----------



## Thomas_v2.1 (17 Juni 2013)

Als Hinweis für das Schreiben von einzelnen Bits:
Wenn ihr zum Schreiben eines einzelnen Bits erst ein Byte aus der SPS liest, dann das zu setzende Bit einmaskiert und dann das Byte wieder
in die SPS zurückschreibt, kann es sein dass Änderungen die vom SPS-Programm aus in dieser Zeit an diesem Byte gemacht wurden dadurch wieder
rückgängig gemacht werden.
Denn in dem Zeitraum in dem gelesen und wieder geschrieben wird, hat die SPS etliche Zyklen durchlaufen.
Wenn ihr das unbedingt so machen wollt, muss man im SPS-Programm sicherstellen dass auf keine anderen Bits dieses Bytes schreibend zugegriffen wird.

Die bessere Variante ist hingegen, zum Setzen von einzelnen Bits die wirklichen Bit-Schreibbefehle zu benutzen. Die C-Implementierung von libnodave bietet diese Funktionen auch an.
Und auch in der Java Umsetzung ist diese zumindest intern vorhanden.

In der Klasse PDU ist dazu eine Methode addBitVarToWriteRequest() schon ausprogrammiert. Die Klasse S7Connection müsste man nur noch um eine Methode ergänzen
die diese Funktion integriert.

Jede vernünftige Visualisierung die mit einer S7 kommuniziert macht das bei Schreibzugriff auf Bit-Variablen so. Lesen kann man hingegen mit dem Lesen
des gesamten Bytes und Ausmaskieren so umsetzen, da macht es nichtmal von der Performance einen Unterschied ob ein Byte oder nur ein Bit gelesen wird.

Ich würde auch mal prüfen, inwieweit Korrekturen die zwischenzeitlich in libnodave eingeflossen sind überhaupt in die Java Version übernommen wurden.
Mir scheint das wird von Zottel nicht weiter gepflegt. Ich habe da vor einiger Zeit mal einen Blick reingeworfen, weil das ja durch Android mit Java wieder aktuell ist.


----------



## Bastueh89 (17 Juni 2013)

Das gewählte Byte ist abgesichert. Also wird für nix anderes verwendet. Die Hauptaufgabe meiner BA ist auch nicht ein Bit auslesen bzw. einlesen (*g*), sondern eine App zu schreiben, die nach Einscannen eines Labels (Strichcode/Barcode usw.) einen bestimmten Eingang ansteuert. Also mir reicht meine Lösung soweit. Es funktioniert sehr gut. Trotzdem vielen dank Thomas 

hier ein kurzer Ausschnitt ausm derzeitigen Programm:


```
public static String barcode1 = "1234567890";
public static String barcode2 = "2645";
public static String[] barcodeArray= {barcode1, barcode2};
```
…

```
System.out.println("initialisize");

                dc.readBytes(Nodave.FLAGS, 0, 2, 1, null);
                Merker.MB2 = (byte) dc.getBYTE();

                by = Nodave.bswap_8(Merker.MB2-Merker.MB2);
                dc.writeBytes(Nodave.FLAGS,0, 2, 1, by);

                dc.readBytes(Nodave.FLAGS, 0, 2, 1, null);
                Merker.MB2 = (byte) dc.getBYTE();

                if(doWrite)
                {
                    if (ScanForVisuActivity.barcode.equals("leer"))
                    {
System.out.println("Barcode leer");
                    }
                    else
                        if (ScanForVisuActivity.barcode.equals(barcodeArray[0]))
                        {
System.out.println("Barcode 1 identified");
                            by = Nodave.bswap_8(Merker.MB2+2);
                        }
                        else if (ScanForVisuActivity.barcode.equals(barcodeArray[1]))
                        {
System.out.println("Barcode 2 identified");
                            by = Nodave.bswap_8(Merker.MB2+64);
                        }

                    dc.writeBytes(Nodave.FLAGS,0, 2, 1, by);
                    dc.readBytes(Nodave.FLAGS, 0, 2, 1, null);
                    Merker.MB2 = (byte) dc.getBYTE();

                    System.out.println("Now disconnecting\n");
                    dc.disconnectPLC();    // disconnecting PLC
                    di.disconnectAdapter();    // disconnecting adapter
                    System.out.println("Disconnected\n");
```
Wie gesagt es funktioniert sehr gut  Wer Fragen DAZU hat, gerne an mich.

Vielleicht kann ja doch noch jemand erklären, wie das mit addBitVarToWriteRequest aussieht? Weiß nicht, was die Methode genau macht !?


----------



## Thomas_v2.1 (17 Juni 2013)

Bastueh89 schrieb:


> Vielleicht kann ja doch noch jemand erklären, wie das mit addBitVarToWriteRequest aussieht? Weiß nicht, was die Methode genau macht !?



Theoretisch ist es möglich verschiedene Speicherbereiche mit einem einzigen Request in der SPS anzusprechen. Als Beispiel könntest du in einem Rutsch das MB10, MD100 und 20 Bytes ab DB10.DBX0.0 auslesen oder auch schreiben. In dem C-libnodave ist das vorhanden, in der Java-Version aber nicht, zumindest nicht vollständig nach außen geführt.
addBitVarToWriteRequest() würde z.B. ein oder mehrere Bits einem Write-Request hinzufügen, d.h. du könntest mit einem Schreibbefehl an die SPS  M2.2, M50.3 und DB10.DBX6.7 auf einen bestimmten Wert (1 oder 0) setzen, ohne dass die anderen Bits in dem Byte angetastet werden.

Die Methode readBytes() die du momentan verwendest ruft intern eine ähnliche Funktion namens addVarToReadRequest() auf. Das wird nur einmal gemacht, darum kannst du auch mit einer Anfrage an die SPS nur einen Bereich in einem Rutsch auslesen.


----------



## Bastueh89 (22 Juli 2013)

neuste Version:

extra Klasse für Barcodes:


```
[FONT=Monaco][COLOR=#931A68]public [/COLOR][COLOR=#931A68]class[/COLOR][COLOR=#000000] Barcodes[/COLOR][/FONT]
[FONT=Monaco]{[/FONT]
[FONT=Monaco]    [COLOR=#931a68]public[/COLOR] [COLOR=#931a68]static[/COLOR] String [COLOR=#0326cc]barcode1[/COLOR] = [COLOR=#3933ff]"1234567890"[/COLOR];[/FONT]
[FONT=Monaco]    [COLOR=#931a68]public[/COLOR] [COLOR=#931a68]static[/COLOR] String [COLOR=#0326cc]barcode2[/COLOR] = [COLOR=#3933ff]"2645"[/COLOR];[/FONT]
[FONT=Monaco]    [COLOR=#931a68]public[/COLOR] [COLOR=#931a68]static[/COLOR] String [COLOR=#0326cc]barcode3[/COLOR] = [COLOR=#3933ff]"90311017"[/COLOR];[/FONT]
[FONT=Monaco]    [COLOR=#931a68]public[/COLOR] [COLOR=#931a68]static[/COLOR] String [COLOR=#0326cc]barcode4[/COLOR] = [COLOR=#3933ff]"01560689"[/COLOR];[/FONT]
[FONT=Monaco]    [COLOR=#931a68]public[/COLOR] [COLOR=#931a68]static[/COLOR] String [COLOR=#0326cc]barcode5[/COLOR] = [COLOR=#3933ff]"725272730706"[/COLOR];[/FONT]
[FONT=Monaco]    [COLOR=#931a68]public[/COLOR] [COLOR=#931a68]static[/COLOR] String [COLOR=#0326cc]barcode6[/COLOR] = [COLOR=#3933ff]"7789"[/COLOR];[/FONT]
[COLOR=#3933FF][FONT=Monaco][COLOR=#931a68]   public [/COLOR][COLOR=#931a68]static[/COLOR][COLOR=#000000] String [/COLOR][COLOR=#0326cc]barcode7[/COLOR][COLOR=#000000] = [/COLOR]"8984564919781495"[COLOR=#000000];[/COLOR][/FONT][/COLOR]
[FONT=Monaco]   [COLOR=#931a68]public[/COLOR] [COLOR=#931a68]static[/COLOR] String [COLOR=#0326cc]barcode8[/COLOR] = [COLOR=#3933ff]"14851341005"[/COLOR];[/FONT]

[COLOR=#0326CC][FONT=Monaco][COLOR=#931a68]   public [/COLOR][COLOR=#931a68]static[/COLOR][COLOR=#000000] String[] [/COLOR]barcodeArray[COLOR=#000000]= {[/COLOR]barcode1[COLOR=#000000], [/COLOR]barcode2[COLOR=#000000], [/COLOR]barcode3[COLOR=#000000], [/COLOR]barcode4[COLOR=#000000], [/COLOR]barcode5[COLOR=#000000], [/COLOR]barcode6[COLOR=#000000], [/COLOR]barcode7[COLOR=#000000], [/COLOR]barcode8[COLOR=#000000]};[/COLOR][/FONT][/COLOR]
[FONT=Monaco]}[/FONT]
```

TestISOTCP-Klasse:

reset Byte


```
[FONT=Monaco][COLOR=#931a68]void[/COLOR] resetBytes()[/FONT]
[FONT=Monaco]	{[/FONT]
[COLOR=#3933FF][FONT=Monaco][COLOR=#000000]		System.[/COLOR][COLOR=#0326cc]out[/COLOR][COLOR=#000000].println([/COLOR]"TestISOTCP.resetByte()"[COLOR=#000000]);[/COLOR][/FONT][/COLOR]
[FONT=Monaco]
[/FONT]
[FONT=Monaco]		[COLOR=#0326cc]tcpc[/COLOR].readBytes(Nodave.[COLOR=#0326cc]Flags[/COLOR], 0, 2, 1, [COLOR=#931a68]null[/COLOR]);[/FONT]
[COLOR=#3933FF][FONT=Monaco][COLOR=#000000]		System.[/COLOR][COLOR=#0326cc]out[/COLOR][COLOR=#000000].println([/COLOR]"===== read Byte from PLC init"[COLOR=#000000]);[/COLOR][/FONT][/COLOR]
[FONT=Monaco]		[/FONT]
[FONT=Monaco]		[COLOR=#0326cc]MB2[/COLOR] = ([COLOR=#931a68]byte[/COLOR]) [COLOR=#0326cc]tcpc[/COLOR].getBYTE();[/FONT]
[COLOR=#3933FF][FONT=Monaco][COLOR=#000000]		System.[/COLOR][COLOR=#0326cc]out[/COLOR][COLOR=#000000].println([/COLOR]"===== assigned read Byte to MB2-Variable"[COLOR=#000000]);[/COLOR][/FONT][/COLOR]
[FONT=Monaco]		[/FONT]
[FONT=Monaco]		outputBits();[/FONT]
[FONT=Monaco]		[/FONT]
[FONT=Monaco]		[COLOR=#0326cc]newByte[/COLOR] = Nodave.bswap_8([COLOR=#0326cc]MB2[/COLOR]-[COLOR=#0326cc]MB2[/COLOR]);[/FONT]
[COLOR=#3933FF][FONT=Monaco][COLOR=#000000]		System.[/COLOR][COLOR=#0326cc]out[/COLOR][COLOR=#000000].println([/COLOR]"===== newByte = MB2 - MB2 = 00000000"[COLOR=#000000]);[/COLOR][/FONT][/COLOR]
[FONT=Monaco]		[/FONT]
[FONT=Monaco]		[COLOR=#0326cc]tcpc[/COLOR].writeBytes(Nodave.[COLOR=#0326cc]Flags[/COLOR],0, 2, 1, [COLOR=#0326cc]newByte[/COLOR]);[/FONT]
[COLOR=#3933FF][FONT=Monaco][COLOR=#000000]		System.[/COLOR][COLOR=#0326cc]out[/COLOR][COLOR=#000000].println([/COLOR]"===== wrote 00000000 to Byte on PLC"[COLOR=#000000]);[/COLOR][/FONT][/COLOR]
[FONT=Monaco]
[/FONT]
[FONT=Monaco]		testBarcodeContent();[/FONT]
[FONT=Monaco]	}[/FONT]
```

test Barcode content


```
[FONT=Monaco][COLOR=#931a68]void[/COLOR] testBarcodeContent()[/FONT]
[FONT=Monaco]	{[/FONT]
[COLOR=#3933FF][FONT=Monaco][COLOR=#000000]		System.[/COLOR][COLOR=#0326cc]out[/COLOR][COLOR=#000000].println([/COLOR]"TestISOTCP.testBarcodeContent()"[COLOR=#000000]);[/COLOR][/FONT][/COLOR]
[FONT=Monaco]
[/FONT]
[FONT=Monaco]		[COLOR=#931a68]if[/COLOR] (ScanForVisuActivity.[COLOR=#0326cc]barcodeOk[/COLOR]==[COLOR=#931a68]true[/COLOR])[/FONT]
[FONT=Monaco]		{[/FONT]
[FONT=Monaco]			[/FONT]
[COLOR=#3933FF][FONT=Monaco][COLOR=#000000]			System.[/COLOR][COLOR=#0326cc]out[/COLOR][COLOR=#000000].println([/COLOR]"===== Barcode = initialized"[COLOR=#000000]);[/COLOR][/FONT][/COLOR]
[FONT=Monaco]			readAndWrite();[/FONT]
[FONT=Monaco]		}[/FONT]
[COLOR=#931A68][FONT=Monaco][COLOR=#000000]		[/COLOR]else[/FONT][/COLOR]
[FONT=Monaco]		{[/FONT]
[COLOR=#3933FF][FONT=Monaco][COLOR=#000000]			System.[/COLOR][COLOR=#0326cc]out[/COLOR][COLOR=#000000].println([/COLOR]"===== Barcode = blank or no initialized"[COLOR=#000000]);[/COLOR][/FONT][/COLOR]
[FONT=Monaco]			finalize();[/FONT]
[FONT=Monaco]		}[/FONT]
[FONT=Monaco]	}[/FONT]
```

read and write


```
[FONT=Monaco][COLOR=#931a68]void[/COLOR] readAndWrite()[/FONT]
[FONT=Monaco]	{[/FONT]
[COLOR=#3933FF][FONT=Monaco][COLOR=#000000]		System.[/COLOR][COLOR=#0326cc]out[/COLOR][COLOR=#000000].println([/COLOR]"TestISOTCP.readAndWrite()"[COLOR=#000000]);[/COLOR][/FONT][/COLOR]
[FONT=Monaco]
[/FONT]
[COLOR=#0326CC][FONT=Monaco][COLOR=#000000]		[/COLOR][COLOR=#931a68]if[/COLOR][COLOR=#000000]([/COLOR]noError[COLOR=#000000])[/COLOR][/FONT][/COLOR]
[FONT=Monaco]		{[/FONT]
[FONT=Monaco]			[COLOR=#0326cc]tcpc[/COLOR].readBytes(Nodave.[COLOR=#0326cc]Flags[/COLOR], 0, 2, 1, [COLOR=#931a68]null[/COLOR]);[/FONT]
[COLOR=#3933FF][FONT=Monaco][COLOR=#000000]			System.[/COLOR][COLOR=#0326cc]out[/COLOR][COLOR=#000000].println([/COLOR]"===== read Byte from PLC 00000000"[COLOR=#000000]);[/COLOR][/FONT][/COLOR]
[FONT=Monaco]
[/FONT]
[FONT=Monaco]			[COLOR=#0326cc]MB2[/COLOR] = ([COLOR=#931a68]byte[/COLOR]) [COLOR=#0326cc]tcpc[/COLOR].getBYTE();[/FONT]
[COLOR=#3933FF][FONT=Monaco][COLOR=#000000]			System.[/COLOR][COLOR=#0326cc]out[/COLOR][COLOR=#000000].println([/COLOR]"===== assigned read Byte 00000000 to MB2-Variable"[COLOR=#000000]);[/COLOR][/FONT][/COLOR]
[FONT=Monaco]
[/FONT]
[FONT=Monaco]			setBit();[/FONT]
[COLOR=#3933FF][FONT=Monaco][COLOR=#000000]			System.[/COLOR][COLOR=#0326cc]out[/COLOR][COLOR=#000000].println([/COLOR]"===== Byte changed from 00000000 to Barcode-Byte"[COLOR=#000000]);[/COLOR][/FONT][/COLOR]
[FONT=Monaco]
[/FONT]
[FONT=Monaco]			[COLOR=#0326cc]tcpc[/COLOR].writeBytes(Nodave.[COLOR=#0326cc]Flags[/COLOR],0, 2, 1, [COLOR=#0326cc]newByte[/COLOR]);[/FONT]
[COLOR=#3933FF][FONT=Monaco][COLOR=#000000]			System.[/COLOR][COLOR=#0326cc]out[/COLOR][COLOR=#000000].println([/COLOR]"===== wrote newByte to Byte on PLC finally"[COLOR=#000000]);[/COLOR][/FONT][/COLOR]
[FONT=Monaco]
[/FONT]
[FONT=Monaco]			finalize();[/FONT]
[FONT=Monaco]		}[/FONT]
[COLOR=#931A68][FONT=Monaco][COLOR=#000000]		[/COLOR]else[/FONT][/COLOR]
[FONT=Monaco]		{[/FONT]
[FONT=Monaco]			[COLOR=#0326cc]ErrPLC[/COLOR] = [COLOR=#931a68]true[/COLOR];[/FONT]
[COLOR=#3933FF][FONT=Monaco][COLOR=#000000]			System.[/COLOR][COLOR=#0326cc]out[/COLOR][COLOR=#000000].println([/COLOR]"Couldn't connect to PLC."[COLOR=#000000]);[/COLOR][/FONT][/COLOR]
[FONT=Monaco]		}[/FONT]
[FONT=Monaco]	}[/FONT]
```


----------



## Bastueh89 (26 Juli 2013)

weiter…

set Bit


```
void setBit()
	{
		System.out.println("TestISOTCP.setBit()");
		
		int a = 0;
		for(int i=128;i>=1;i=i/2)
		{
			if (ScanForVisuActivity.barcode.equals(Barcodes.barcodeArray[a]))
			{
				System.out.println("===== Barcode "+a+" identified");
				newByte = Nodave.bswap_8(MB2+i);
			}
			a++;
		}
	}
```

output Bits


```
public static void outputBits()
	{
		System.out.println("TestISOTCP.outputBits()"+"\n");
		for (int bit = 7; bit>=0; bit--)
		{
			boolean is = ((MB2 >> bit) & 1 ) == 1;
			if (is == true)
			{
				binArray[7-bit]="1";
			}
			else
			{
				binArray[7-bit]="0";
			}
		}
		System.out.println("");
		for(int i = 0; i<=7; i++)
		{
			System.out.println("M2." + i + " = " + binArray[7-i] + "\n");
		}
		System.out.println("_________________________");
	}
```

finalize


```
protected void finalize()
	{
		System.out.println("TestISOTCP.finalize()");

		tcpc.readBytes(Nodave.Flags, 0, 2, 1, null);
		System.out.println("===== read Byte from PLC finally (only for outputBits();)");

		MB2 = (byte) tcpc.getBYTE();
		System.out.println("===== assigned read Byte finally to MB2-Variable (only for outputBits();)");

		outputBits();

		System.out.println("===== Now disconnecting\n");
		tcpc.disconnectPLC();
		System.out.println("===== Disconnected\n");
	}
}
```


----------

