Datentypen Byte geht nicht höher als 126 auch nicht mit casten?

xJan45x

Aktives Mitglied
Guten Abend,
Ich programmiere zurzeit mein kleines Homecockpit. Und sende mir über mein Mirkocontroller die Geschwindigkeit die ich über ein Drehknopf wähle. Ich muss aber um die Daten an mein Flug Simulator zu übertragen ein Byte haben. Also der Byte ist nachher der Wert der im FS(flug simulator) angezeigt wird.
Code:
                String[] value = line.split(":");
                String finalStr = value[1];
                byte[] b = new byte[1];
                b[0] = (byte)Integer.parseInt(finalStr);
line ist der Scanner der das Ausliegt gibt: "Speed:0 bis 409" zurück. Dann Spiltten damit ich nur denn zweiten wert habe. Ich caste hier denn Byte damit ich höher als 128 gehen kann. Aber bei ca. 126 geht der im minus bereich weiter. zb:
Code:
0
1
50
100
126
-118
-101
-81
-74
0
4
5
....
Wo ran liegt das?

Mfg Jan.
 
ein byte ist nunmal nur ein byte groß.
Mit deinen zehn fingern kannst du auch nicht bis 1 million zählen.
Wenn du erwartest größere Werte zu haben, musst du eben einen anderen Datentyp nutzen, z.B. short oder int
 
ein byte ist nunmal nur ein byte groß.
Mit deinen zehn fingern kannst du auch nicht bis 1 million zählen.
Wenn du erwartest größere Werte zu haben, musst du eben einen anderen Datentyp nutzen, z.B. short oder int
Das ist mir auch klar. Aber die Methode writeDataToFS(int offSet, int mode, byte[] value); braucht ein byte[] und wenn ich kann kein int[] zum byte[] oder int zum byte[] casten. Wie soll ich es dann machen?
 
Das ist mir auch klar. Aber die Methode writeDataToFS(int offSet, int mode, byte[] value); braucht ein byte[] und wenn ich kann kein int[] zum byte[] oder int zum byte[] casten. Wie soll ich es dann machen?
dann sag das doch gleich^^

Du sollst ein byte array senden, vermutlich soll das array eben aus mehr als nur einem byte bestehen.
Da ein int aus 4 byte besteht, kannst du ihn eben in einem byte array der größe 4 unterbringen:
Java:
public static final byte[] intToByteArray(int value){
    return new byte[]{(byte)(value >>>24), (byte)(value >>>16), (byte)(value >>>8), (byte)value};
}
 
dann sag das doch gleich^^
Java:
public static final byte[] intToByteArray(int value){
    return new byte[]{(byte)(value >>>24), (byte)(value >>>16), (byte)(value >>>8), (byte)value};
}
Ja sorry, ich denke endweder habe ich was falsch geschrieben oder du hast was falsch verstanden. Denn die Methode braucht ein Byte[] das ist richtig aber ich muss dieses Byte ja "füttern" mit b[0] = Wert; und dort muss es ja ein Byte sein und kein Byte[]. Oder wo muss die die methode anwenden?

So sieht das nun aus:
Code:
                String[] value = line.split(":");
                byte[] b = new byte[1];
                b[0] = intToByteArray(Integer.parseInt(value[1])); //Geht nicht ist kein Byte sondern ein Byte[]
              
                fsuipc_wrapper.WriteData(0x07E2, 1, b);
 
Du must halt deinen Wert in zwei oder vier Bytes umrechnen. Wieviel genau erwartet werden können wir nicht wissen, das sollte in den Docs zu der Funktion stehen. Ebenfalls wichtig wäre noch ob die Bytes in Little oder Bigendian geschrieben werden müssen....
 
Ja sorry, ich denke endweder habe ich was falsch geschrieben oder du hast was falsch verstanden. Denn die Methode braucht ein Byte[] das ist richtig aber ich muss dieses Byte ja "füttern" mit b[0] = Wert; und dort muss es ja ein Byte sein und kein Byte[]. Oder wo muss die die methode anwenden?

So sieht das nun aus:
Code:
                String[] value = line.split(":");
                byte[] b = new byte[1];
                b[0] = intToByteArray(Integer.parseInt(value[1])); //Geht nicht ist kein Byte sondern ein Byte[]
             
                fsuipc_wrapper.WriteData(0x07E2, 1, b);
anstatt
Java:
byte[] b = new byte[1];
 b[0] = (byte)Integer.parseInt(finalStr);
eben einfach
Java:
byte[] b = intToByteArray(Integer.parseInt(value[1]));
 
eben einfach
Java:
byte[] b = intToByteArray(Integer.parseInt(value[1]));
Das Problem ist nicht das erstellen ich brauche nur 1 Wert im Byte diesen erstelle ich mit byte b = new byte[1] und b[0] das ist der Wert der die Geschwindigkeit im Flug SImulator ändert. Und diesen muss ich irgendwie mit einer Zahl über 128 füllen. Im Internet steht casten aber das funktioniert nur konstanten Zahlen aber die Zahl ändert sich ja so bald ich am Drehknopf drehe.
 
Also Du kannst doch an den mathematischen Grundlagen nichts ändern! Byte ist nun einmal nur 8 Bit. Man könnte sich noch überlegen, dass man statt einem signed byte (-128 - 127 als Wertebereich) ein unsigned byte nimmt. Dafür gibt es mehrere Möglichkeiten, wie man das in Java abbilden könnte da Java halt ein unsigned byte in dem Sinne nicht kennt. Aber damit ist man dann bei einem Wertebereich von 0 - 256. Auf die 409 kannst du einfach nicht kommen!

Das ist als ob Du ein kleines Kinderfahrrad hast und nun verzweifelt versuchst, damit 1t Kies zu transportieren. Wir erzählen dann noch was von Anhänger und so, aber du willst 1t Kies in deiner Hosentasche transportieren. Die passen da nicht rein! Also wenn dann mehrfach fahren (=Array, viele kleine Ladungen) aber über die kleinen Hosentaschen müssen wir nicht diskutieren 🙂
 
Also Du kannst doch an den mathematischen Grundlagen nichts ändern! Byte ist nun einmal nur 8 Bit. Man könnte sich noch überlegen, dass man statt einem signed byte (-128 - 127 als Wertebereich) ein unsigned byte nimmt. Dafür gibt es mehrere Möglichkeiten, wie man das in Java abbilden könnte da Java halt ein unsigned byte in dem Sinne nicht kennt. Aber damit ist man dann bei einem Wertebereich von 0 - 256. Auf die 409 kannst du einfach nicht kommen!

Das ist als ob Du ein kleines Kinderfahrrad hast und nun verzweifelt versuchst, damit 1t Kies zu transportieren. Wir erzählen dann noch was von Anhänger und so, aber du willst 1t Kies in deiner Hosentasche transportieren. Die passen da nicht rein! Also wenn dann mehrfach fahren (=Array, viele kleine Ladungen) aber über die kleinen Hosentaschen müssen wir nicht diskutieren 🙂

Okay. Danke
Dann bleibt mir ja keine andere Wahl als denn Typen anzuschreiben der diese Library entworfen hat. Irgendwie muss es ja eine Lösung dafür geben. Trotzdem danke euch 🙂
 
Nein das geht natuerlich aber Java ist eine denkbar ungünstige Sprache dafür und man sollte natuerlich wissen wie ein Hexadezimales Zahlensystem funktioniert.

Da Du das wahrscheinlich nicht weist schreibe ich ausnahmsweise mal den Code hierhin auch wenn Du dadurch überhaupt nichts lernst. Der Code ist aber ungetestet und sollte nicht einfach nur abgeschrieben werden.

Code:
String valueString = XXXX // Deine Value aus dem String also 0 - 409
int value = Integer.parseInt(valueString) // gibt Dir die Zahl als Integer

// Nun zerlegen wir die Zahl in zwei Bytes die man maximal braucht um eine Zahl bis 409 in Hex darzustellen. Da Java keine unsinged byte kann, benutzen wir zunächst int damit wir bis 256 rechnen können
// Als Beispiel 257 würde zerlegt in zwei unsigned Bytes mit den Werten high 0xFF und low 0x02.
int highByte = value/256;
int lowByte = value-highByte*256;
// nun packen wir diese beiden int in ein byte Array
byte[0] = (byte) lowByte;
byte[1] = (byte) highByte;
// Hier ist es jetzt wichtig zu wissen ob der Empfänger mit Little- oder Bigendian arbeitet. Das bestimmt in welcher Reihenfolge Du die Bytes beschreiben musst. Also wenn das so nicht klappt, dann must du es vertauschen in
byte[1] = (byte) lowByte;
byte[0] = (byte) highByte;
// unter Umständen verlangt der Empfänger sogar noch mehr bytes. Du sprachst von 4 bytes. Dann must du halt byte[2] und byte[3] auch noch füllen. Aber auch hier gilt es kann dann sein, dass die leeren Bytes am Anfang oder am Ende des Array stehen können. Das must du entweder ausprobieren oder versuchen in der Doku herauszufinden

Gruß

Claus
 
Die Frage ist, wieso der TE meint, dass der Wert in genau einem Byte gesendet werden muss. Wenn er davon so überzeugt ist, dann muss das doch einen Grund haben. Ich habe in der Vergangenheit auch schon einmal ein "Binary Protokoll" erstellt und da war dann ganz klar definiert, was wie zu senden war. Spricht ein oder zwei byte war dann sozusagen ein Befehl und dann war klar, was wie übertragen werden muss. Und dann war halt angegeben, was da an Daten folgen musste.
Sowas würde ich da auch erwarten.

Ich habe hier absolut keinen Überblick. Es ist angesprochen, dass es um "Geschwindigkeit" geht. Aber wenn es um die Steuerung eines Flugzeuges geht, dann stelle ich doch den Schub ein, oder?
Und was bedeutet denn da dann eine 409? Evtl. ist es tatsächlich nur ein byte. Wenn es wirklich um Geschwindigkeit geht, dann wäre denkbar, dass diese nur auf die 10er genau ist. Dann wäre ein byte von 1 evt. 10 km/h / m/s / was auch immer. Oder wenn es um Schub geht, dann ist es evtl. ein Prozentwert. Dann ist 1 gleichbedeutend mit 1% Schub. 100 wäre volle Leistung. Oder es wäre ein Prozentsatz x/128 oder x/256.

Die Details müssen irgendwo beschrieben sein. Wenn ich Daten von a nach b übermittel, dann wird es da ein Protokoll geben, das klar macht, was da übermittelt wird.
 
Also im Offset Blatt steht das so:
Offset | Size | Use
0x07E2 2 Autopilot airspeed value, in knots

Size ist wahrscheinlich die Angabe wie groß das Byte Array sein muss. Denn es gibt auch manche Offset wo 4 steht
 
Das ist dann doch die fehlende Beschreibung. Bezüglich der Reihenfolge findet man zwar jetzt keine Angabe, aber das findet sich evtl. noch an anderer Stelle.

Und damit hast Du die Lösung doch im Post von Thallius.
 
Nein das geht natuerlich aber Java ist eine denkbar ungünstige Sprache dafür und man sollte natuerlich wissen wie ein Hexadezimales Zahlensystem funktioniert.

Da Du das wahrscheinlich nicht weist schreibe ich ausnahmsweise mal den Code hierhin auch wenn Du dadurch überhaupt nichts lernst. Der Code ist aber ungetestet und sollte nicht einfach nur abgeschrieben werden.

Code:
String valueString = XXXX // Deine Value aus dem String also 0 - 409
int value = Integer.parseInt(valueString) // gibt Dir die Zahl als Integer

// Nun zerlegen wir die Zahl in zwei Bytes die man maximal braucht um eine Zahl bis 409 in Hex darzustellen. Da Java keine unsinged byte kann, benutzen wir zunächst int damit wir bis 256 rechnen können
// Als Beispiel 257 würde zerlegt in zwei unsigned Bytes mit den Werten high 0xFF und low 0x02.
int highByte = value/256;
int lowByte = value-highByte*256;
// nun packen wir diese beiden int in ein byte Array
byte[0] = (byte) lowByte;
byte[1] = (byte) highByte;
// Hier ist es jetzt wichtig zu wissen ob der Empfänger mit Little- oder Bigendian arbeitet. Das bestimmt in welcher Reihenfolge Du die Bytes beschreiben musst. Also wenn das so nicht klappt, dann must du es vertauschen in
byte[1] = (byte) lowByte;
byte[0] = (byte) highByte;
// unter Umständen verlangt der Empfänger sogar noch mehr bytes. Du sprachst von 4 bytes. Dann must du halt byte[2] und byte[3] auch noch füllen. Aber auch hier gilt es kann dann sein, dass die leeren Bytes am Anfang oder am Ende des Array stehen können. Das must du entweder ausprobieren oder versuchen in der Doku herauszufinden

Gruß

Claus

Bohr wirklich tausend dank. Klaus! Funktioniert problemlos. Eine Frage hätte ich da noch wenn ich ein 4 byte Array übergeben muss. Muss ich dann wieder durch zwei teilen also so?:
Code:
byte bytes = new bytes[4];
bytes[0] = (byte)lowByte;
bytes[1] = (byte)highByte;
bytes[2] = (byte)lowByte /2;
bytes[3] = (byte) highByte/2;
Bin zwar noch nicht so weit im meinen Homecockpit. Aber das wird später auch kommen
 
Also normalerweise löst man int -> byte[] -> int mit einem ByteBuffer. Da braucht man sich auch keine Sorgen über die Konvertierung/Rechnerei/etc. zu machen.
Java:
int i = 409;
ByteBuffer buffer = ByteBuffer.allocate(4 /* int hat 4 bytes -> 32 bits */).putInt(i);
byte[] bytes = buffer.array();
System.out.println(Arrays.toString(bytes));
int j = ByteBuffer.wrap(bytes).getInt();
System.out.println(j);
 
Also normalerweise löst man int -> byte[] -> int mit einem ByteBuffer. Da braucht man sich auch keine Sorgen über die Konvertierung/Rechnerei/etc. zu machen.
Java:
int i = 409;
ByteBuffer buffer = ByteBuffer.allocate(4 /* int hat 4 bytes -> 32 bits */).putInt(i);
byte[] bytes = buffer.array();
System.out.println(Arrays.toString(bytes));
int j = ByteBuffer.wrap(bytes).getInt();
System.out.println(j);

und woher weiß der ByteBuffer ob Little oder Bigendian?

Gruß

Claus
 

Zurück
Oben