# Serialport Bit für Bit auslesen



## ByeBye 46085 (15. Dezember 2006)

hallo,

für eine Semesterarbeit probier ich Daten über den Parallelport an eine Hardware zu senden und auch andere Daten zu empfangen. Zum Ausprobieren arbeite ich mit einem Nullmodem.
Die Daten sind 8bit Binärdaten (als Integer 0-255). Der Port ist auf 1Start, 1Stop und 8 Datenbits eingestellt.
Ich kann alle Werte ausser 128-160 übertragen. Bei diesen kommt immer 63 (ASCII "?") an. Das liegt irgendwie am Unicode. Kann man den Port mit RxTx auch bitweise auslesen?

Den Port lese ich folgendermassen aus:

```
byte[] readBuffer = new byte[8];
byte Byte;
while (runtimetest.ins.available() > 0)
{int numBytes = runtimetest.ins.read(readBuffer);}
Byte = readBuffer[0];
```
ins ist der Inputstream.
Weiss jemand wie man das richtig macht?


Gruss Markus


----------



## Thomas Darimont (16. Dezember 2006)

Hallo!

Verwendest du das Java Communications API oder die Lib von RXTX.org?
http://rxtx.org/

Gruß Tom


----------



## nove (16. Dezember 2006)

Das hab ich vor langer Zeit mal für eine CNC Management Anwendung geschrieben


```
import java.util.*;
import javax.comm.*;
import java.io.*;
import java.nio.*;
public class transmitter implements Runnable, SerialPortEventListener {
    public maschine mymaschine;
    //needed for both read and write
    static Enumeration portList;
    static CommPortIdentifier portID;
    //needed for write
    static SerialPort serialPort;
    static OutputStream outputStream;
    //needed for read
    InputStream inputStream;
    Thread readThread;
    String readedString;
    
    
    /** Creates a new instance of transmitter */
    public transmitter(maschine masch) {
        mymaschine=masch;
    }
    
    
    
    public boolean send(String sendstring){
        //send Code
        boolean isSended = false;
            try{
                
            portID = CommPortIdentifier.getPortIdentifier(mymaschine.getComport());
            serialPort = (SerialPort)portID.open("PortOpener",10);
            //set the parity
            serialPort.setSerialPortParams(
                    //sets the Serialport Parameters
                    Integer.valueOf(mymaschine.getBaudrate()).intValue(),
                    Integer.valueOf(mymaschine.getDatabit()).intValue(),
                    Integer.valueOf(mymaschine.getStopbit()).intValue(), 
                    mymaschine.getParityAsInteger());
            outputStream=serialPort.getOutputStream();
            outputStream.write(sendstring.getBytes());
            outputStream.flush();
            serialPort.close();
            isSended = true;
        }catch(NoSuchPortException e){
            e.printStackTrace();
        }catch(IOException e){
            e.printStackTrace();
        }catch(UnsupportedCommOperationException e){
            e.printStackTrace();
        }catch(PortInUseException e){
            e.printStackTrace();
        }
        return isSended;
    }
    
    public void receive(){
        try{
            portID= CommPortIdentifier.getPortIdentifier(mymaschine.getComport());
            serialPort = (SerialPort)portID.open("PortOpener", 10);
            serialPort.setSerialPortParams(
                //sets the Serialport Parameters
                    Integer.valueOf(mymaschine.getBaudrate()).intValue(),
                    Integer.valueOf(mymaschine.getDatabit()).intValue(),
                    Integer.valueOf(mymaschine.getStopbit()).intValue(), 
                    mymaschine.getParityAsInteger()
            );
            inputStream = serialPort.getInputStream();
            serialPort.setFlowControlMode(3);
            serialPort.addEventListener(this);
            serialPort.notifyOnDataAvailable(true);
            readThread = new Thread(this);
            readThread.start();
        }catch(NoSuchPortException e){
            e.printStackTrace();
        }catch(IOException e){
            e.printStackTrace();
        }catch(UnsupportedCommOperationException e){
            e.printStackTrace();
        }catch(PortInUseException e){
            e.printStackTrace();
        }catch(TooManyListenersException e){
            e.printStackTrace();
        }
        
    }
    
    public void closeSerialPort(){
        serialPort.close();
    }
    
    public void run() {
       try{
            Thread.sleep(2000);
       }catch(InterruptedException e){
            e.printStackTrace();
        }
    }
    
    public void serialEvent(javax.comm.SerialPortEvent serialPortEvent) {
        switch (serialPortEvent.getEventType()){
            case SerialPortEvent.BI:
            case SerialPortEvent.OE:
            case SerialPortEvent.FE:
            case SerialPortEvent.PE:
            case SerialPortEvent.CD:
            case SerialPortEvent.CTS:
            case SerialPortEvent.DSR:
            case SerialPortEvent.RI:
            case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
                break;
            case SerialPortEvent.DATA_AVAILABLE:
                byte[] readBuffer=new byte[2048];
                try{
                    while (inputStream.available()>0){
                        int numBytes=inputStream.read(readBuffer);
                    }
                    readedString=new String(readBuffer);
                }catch(IOException e){
                    System.out.print(e);
                    break;
                }
        }
    }
    public String getReadedString(){
        return readedString;
    }
   
}
```

ich muss noch dazusagen das die Einstellungen bei mir aus einer class namens maschine kamen in der alle Verbindungsrelevanten Daten gespeichert ware. Ich poste das Dingens hier nur nicht weils sonst zu unübersichtlich werden würde. Stell dir einfach anstatt mymaschine.getirgendwas den dementsprechenden Wert vor.


----------



## ByeBye 46085 (16. Dezember 2006)

hallo,

bin weitergekommen, das Problem hat was mit der Definition von Bytes unter Java zu tun.  Bytes können die Integer werte  -128 bis 127 annehmen.  Ich benötige jedoch  0-255. Davon kann ich bis jetzt aber nur 0-127 nutzen. Kann man das Byte nicht so auslesen, dass man die 8 Bit als Boolean werte hat? Zum Beispiel als Booleanarray.

Gibt es eine andere möglichkeit einen Integer (0-255) in ein  Byte zu konvertieren und als ein Byte per Serialschnittstelle zu senden?

@ nove: den weg über Strings habe ich auch versucht. Leider sind die Werte 128 bis 160 nicht definiert und ergeben immer ein "?". Danke trotzdem.

Gruss Markus


----------



## nove (16. Dezember 2006)

vielleicht trifft das zu?!
http://www.tutorials.de/forum/java/228129-konvertierung-von-integer-byte-array.html


----------



## ByeBye 46085 (16. Dezember 2006)

Hallo,

die Umwandlung funktioniert soweit. Lokal kann ich umwandeln:


```
public static byte fromUnsignedInt(int value)
  {
    return (byte)value;
  }

public static int toUnsignedInt(byte value)
  {
    return (value & 0x7F) + (value < 0 ? 128 : 0);
  }
```
Damit kann ich ohne Port alles hin und her umwandeln.

Um Werte über 160 zu empfangen brauche ich noch folgende erweiterung: 0xff

```
Byte = ByteKit.fromUnsignedInt(x);
PrintWriter aus = new PrintWriter(runtimetest.out);
aus.write(Byte & 0xff);
```

Wenn ich mit einem Nullmodem das senden Teste erhalte ich für die Zahlen 0-255 folgende ausgabe (Nur die Problemstellen aufgelistet):

```
...
Int: 127 Bin: 01111111
Int: 63 Bin: 00111111
...
...
Int: 63 Bin: 00111111
Int: 160 Bin: 10100000
Int: 161 Bin: 10100001
Int: 162 Bin: 10100010
...
```

@Thomas: ich verwende RxTx unter Windows XP Pro
Da kein Serialport vorhanden ist verwenden ich einen USB-Serialport-Adapter

Gruss Markus


----------



## nove (16. Dezember 2006)

chiefwiegam hat gesagt.:


> Hallo,
> 
> 
> @Thomas: ich verwende RxTx unter Windows XP Pro
> ...



das funktioniert auch mit der commApi


----------



## ByeBye 46085 (17. Dezember 2006)

hi,

das problem ist ja nicht, dass ich den Port nicht ansprechen kann, sondern, dass nicht alle Werte richtig übertragen werden werden.

gruss Markus


----------

