I am sending byte[] array to Arduino from java over UART. But in java value above 127 is represented in 2's complement which Arduino is not able to comprehend properly. How to solve this issue?
2 Answers
Java's lack of unsigned types is a know pain.
The easiest solution for bytes is to simply use a larger datatype, like short
or int
, and cast appropriately:
byte b = (byte) 0x80;
System.out.println(b); //prints "-128"
int i = (int) b & 0xff; //casting is optional since 0xff is an int
System.out.println(i); //prints "128"
Oh, and if that helps, Google's Guava library has a nice little class for handling unsigned Bytes
If the problem is with sending the bytes, and not receiving them, that's even simpler. If you need to send 0x80
, just send 0x80
. The fact that Java treats it as -128 is not important. You'll still be sending 0x80
over the wire.

- 28,965
- 9
- 65
- 105
-
@Matt but I have to send byte[] array over uart . How can I achieve this? – Xena_psk Oct 01 '19 at 09:32
-
What's the problem you're having with that? Just create the array and send it. – Malt Oct 01 '19 at 09:33
-
I have this hex string ={c88090}; now when I am converting it to bytes which is giving 2's complement. for c8 = -56 so on. And when I am sending singed byte array to Arduino, data is misinterpreted. – Xena_psk Oct 01 '19 at 09:38
-
Okay, you can just send the array `new byte[]{(byte)0xc8,(byte)0x80,(byte)0x90}`. The fact that Java treats these values as negative doesn't change anything. The arduino will still get the values c88090 – Malt Oct 01 '19 at 09:40
-
since `0xff` is int, the `&` auto-promotes the other operand and you don't have to cast the result – Mark Jeronimus Oct 01 '19 at 09:46
-
True. I've used casting for clarity since otherwise it's harder to understand what's going on. – Malt Oct 01 '19 at 09:48
Since any Java rs232 library is blind to 'signedness', you just send the bytes as-is.
For example, the JSSC library (and iirc RXTX library too) have a method SerialPort.writeBytes(byte[])
In Arduino, for received data, you have the choice to interpret signedness as you like, by using uint8_t
or int8_t
as appropriately:
uint8_t c = Serial.read();

- 9,278
- 3
- 37
- 50
-
To be precise, `Serial.read()` will return an `int` in the range of 0 .. 0xff, or -1 for `EOF`/nothing to read – datafiddler Oct 01 '19 at 11:56
-
I recommend using `while(Serial.available())` since after EOF new data can arrive. – Mark Jeronimus Oct 01 '19 at 13:01
-
1