Pessoal,
Estou desenvolvendo um software que se comunica atraves de comunicação serial com uma placa Controladora.
A placa já tem todo o protocolo de comunicação programado e funcionando.
O problema é que em java só existe o tipo byte sinalizado.
Eu preciso enviar valores maiores que 127 para a porta serial, e no metodo (write) usado para escrever na porta eu enviaria um array de byte para a placa. mas não dá!
e pelo que me paresse só da pra enviar um int por vez? é isso mesmo?
Alguem já passou por isso?
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.
Cara, Muito obrigado pela ajuda!
Tomara que funcione!
vou fazer os teste!
abraço
Pra confirmar a minha crença, utilizo este metodo para valores maiores que 127?
é isso mesmo né?
Abraço
Sim, é isso mesmo.
Note que sempre há promoção ou redução do tipo. Se vc vai armazenas valores > 127, faça-o no mínimo num short e deixe que o método putUnsignedByte (que faz o 0xFF) transforme num byte para você.
Da mesma forma, na hora de ler o dado, o método getUnsignedByte consegue ler da rede num byte, e "promove" a informação para um int, de modo que você possa ler o valor corretamente.
Na rede, sempre trafega um único byte unsigned.