Você pode escrever um unsigned byte assim:
int valor = 230;
byte valorUnsigned = (byte)(valor & 0xFF);
Se você mandar imprimir esse valor, vai obter um número negativo. Mas não se preocupe, os bits deles são exatamente iguais ao valor dos bits num unsigned byte de valor 230, então, sua controladora deve funcionar.
No livro Java NIO, o autor propõe uma classe chamada ByteBufferWorker que faz esse tipo de conversão para inserir tipos unsigned nos ByteBuffers.
Os métodos dela são assim:
public static short getUnsignedByte(ByteBuffer bb) {
return ((short) (bb.get() & 0xff));
}
public static void putUnsignedByte(ByteBuffer bb, int value) {
bb.put((byte) (value & 0xff));
}
public static short getUnsignedByte(ByteBuffer bb, int position) {
return ((short) (bb.get(position) & (short) 0xff));
}
public static void putUnsignedByte(ByteBuffer bb, int position, int value) {
bb.put(position, (byte) (value & 0xff));
}
public static int getUnsignedShort(ByteBuffer bb) {
return (bb.getShort() & 0xffff);
}
public static void putUnsignedShort(ByteBuffer bb, int value) {
bb.putShort((short) (value & 0xffff));
}
public static int getUnsignedShort(ByteBuffer bb, int position) {
return (bb.getShort(position) & 0xffff);
}
public static void putUnsignedShort(ByteBuffer bb, int position, int value) {
bb.putShort(position, (short) (value & 0xffff));
}
public static long getUnsignedInt(ByteBuffer bb) {
return bb.getInt() & 0xffffffffL;
}
public static void putUnsignedInt(ByteBuffer bb, long value) {
bb.putInt((int) (value & 0xffffffffL));
}
public static long getUnsignedInt(ByteBuffer bb, int position) {
return bb.getInt(position) & 0xffffffffL;
}
public static void putUnsignedInt(ByteBuffer bb, int position, long value) {
bb.putInt(position, (int) (value & 0xffffffffL));
}
Eu sempre achei uma falha terrível do Java classes de Streams e a classe ByteBuffer não ter métodos como esse para lidar com dados unsigned. Afinal, se você se comunica por um stream, pode estar falando com algo que não necessariamente veio do mundo Java.