Hallo,
ich empfange Daten-Frames (unsigned Bytes von C) von einem Microcontroller, der über die serielle Schnittstelle mit dem PC verbunden ist.
Dazu verwende ich das RXTX-Paket und letztendlich die read(byte[]) Methode des InputStream.
Die read-Methode kann als Puffer-Array leider nur byte[].
Bisher war das kein Problem, ich habe mit dem Byte-Feld gearbeitet und den Fehler, der sich aus dem Konflikt zwischen unsigned Byte (C) und signed Byte (JAVA) ergibt beim Zugriff manuell korrigiert.
Ich habe nun aber eine Test-Methode, mit der ich einen manuell angegebenen Frame testen kann und da in diesem Frame Werte über 128 vorkommen, muss ich den Test-Frame als Integer-Feld deklarieren. Bisher hatte ich eine extra Testklasse, was mit aber zu umständlich geworden ist.
Und genau da ist mein Problem:
Ich muss wegen der read-Methode mit byte[] arbeiten aber den Testframe muss ich als int[] deklarieren.
Receiver:
Durch den Receiver bitte nicht erschrecken lassen, wichtig sind nur der in.read Befehl und der Aufruf des FrameAnalyzer.
Die Klasse FrameAnalyzer kann also auf 2 unterschiedliche Arten aufgerufen werden.
Entweder über die Test-Methode, wo ich ihr ein Integer-Feld übergeben muss.
Oder über meine Receiver-Klasse, die ihr ein Byte-Feld übergibt.
3 Möglichkeiten zur Lösung sehe ich:
- den Receiver auf Int[] "umbauen"
- den Test-Frame zu byte[] machen
- Dem FrameAnalyzer ist es egal, ob er Byte[] oder Int[] übergeben bekommt, vielleicht kann man ihn dazu bringen beides zu akzeptieren.
Das read nicht mit integer kann habe ich gemerkt, als ich alle byte[] zu int[] machte.
Als nächstes habe ich versucht das byte-Feld über arraycopy in ein int-Feld zu kopieren, dank der Suchfunktion hier im Forum weiss ich nun auch wieso nicht.
Vielen Dank für eure Hilfe.
ich empfange Daten-Frames (unsigned Bytes von C) von einem Microcontroller, der über die serielle Schnittstelle mit dem PC verbunden ist.
Dazu verwende ich das RXTX-Paket und letztendlich die read(byte[]) Methode des InputStream.
Die read-Methode kann als Puffer-Array leider nur byte[].
Bisher war das kein Problem, ich habe mit dem Byte-Feld gearbeitet und den Fehler, der sich aus dem Konflikt zwischen unsigned Byte (C) und signed Byte (JAVA) ergibt beim Zugriff manuell korrigiert.
Ich habe nun aber eine Test-Methode, mit der ich einen manuell angegebenen Frame testen kann und da in diesem Frame Werte über 128 vorkommen, muss ich den Test-Frame als Integer-Feld deklarieren. Bisher hatte ich eine extra Testklasse, was mit aber zu umständlich geworden ist.
Und genau da ist mein Problem:
Ich muss wegen der read-Methode mit byte[] arbeiten aber den Testframe muss ich als int[] deklarieren.
Code:
public void Test(){
int[] Frame = new int[]{0x02,0x20,0x35,0x61,0x88,0xa7,0x4c,0x1b,0x6f,0x79,0x00...};
FrameAnalyzer fana = new FrameAnalyzer(Frame);
}
Receiver:
Code:
public void serialEvent(SerialPortEvent event) {
byte[] frameBuffer = new byte[0];
byte[] buffer = new byte[512];
int cnt = 0;
try {
while((cnt = in.read(buffer)) > 0) {
// Alte Buffer-Länge + Neu gelesene bytes = Neue Buffer-Länge
byte[] newFrameBuffer = new byte[frameBuffer.length + cnt];
// Alten Inhalt kopieren
System.arraycopy(frameBuffer, 0, newFrameBuffer, 0, frameBuffer.length);
// Neuen Inhalt kopieren
System.arraycopy(buffer, 0, newFrameBuffer, frameBuffer.length, cnt);
frameBuffer = newFrameBuffer;
// -1 Damit das length byte immer dabei ist
for (int i = 0 ; i < frameBuffer.length - 1; i++) {
// 0x02 markiert den Start des Frames
if(frameBuffer[i] == 0x02) {
byte frameLength = frameBuffer[i + 1];
// Kompletter Frame im Buffer?
if(frameBuffer.length <= i + 3 + frameLength) {
break;
}
byte[] slicedFrame = new byte[frameLength + 4];
System.arraycopy(frameBuffer, i, slicedFrame, 0, slicedFrame.length);
Anzeige(slicedFrame);
if (slicedFrame[2]==0x35){
@SuppressWarnings("unused")
FrameAnalyzer fa = new FrameAnalyzer(slicedFrame);
}
// Alte Buffer-Länge - Anzahl Bytes des Frames = Neue Buffer-Länge
byte[] cutFrameBuffer = new byte[frameBuffer.length - (frameLength+4)];
// Inhalt vor dem herausgeschnittenen Frame kopieren
System.arraycopy(frameBuffer, 0, cutFrameBuffer, 0, i);
// Inhalt nach dem herausgeschnittenen Frame kopieren
System.arraycopy(frameBuffer, i+4+frameLength, cutFrameBuffer, i, frameBuffer.length-i-4-frameLength);
frameBuffer = cutFrameBuffer;
}
}
}
}
catch (IOException e) {e.printStackTrace();}
}
Code:
public class FrameAnalyzer {
public FrameAnalyzer(byte Frame[]){
MacExtractor(Frame);
}
...
Durch den Receiver bitte nicht erschrecken lassen, wichtig sind nur der in.read Befehl und der Aufruf des FrameAnalyzer.
Die Klasse FrameAnalyzer kann also auf 2 unterschiedliche Arten aufgerufen werden.
Entweder über die Test-Methode, wo ich ihr ein Integer-Feld übergeben muss.
Oder über meine Receiver-Klasse, die ihr ein Byte-Feld übergibt.
3 Möglichkeiten zur Lösung sehe ich:
- den Receiver auf Int[] "umbauen"
- den Test-Frame zu byte[] machen
- Dem FrameAnalyzer ist es egal, ob er Byte[] oder Int[] übergeben bekommt, vielleicht kann man ihn dazu bringen beides zu akzeptieren.
Das read nicht mit integer kann habe ich gemerkt, als ich alle byte[] zu int[] machte.
Als nächstes habe ich versucht das byte-Feld über arraycopy in ein int-Feld zu kopieren, dank der Suchfunktion hier im Forum weiss ich nun auch wieso nicht.
Vielen Dank für eure Hilfe.