Create 4 bytes from 16 bits
I have 16 bits. In every bit, I can set some property and send COM port (fiscal printer). For example: if 0 bit is checked, then show the logo when checking.
These 16 bits I need to convert to 4 bytes and send to the COM port. For example: if 0 bit is checked, 4 bytes will be 0x30, 0x31, 0x30, 0x30. Bytes Result I am getting the COM Port Monitoring API.
What do I need to do to get 4 bytes out of 16 bits?
Other examples:
- 1 bit checked - 0x30, 0x32, 0x30, 0x30
- 2 bits - 0x30, 0x34, 0x30, 0x30
- 0 and 2 bits checked - 0x30, 0x35, 0x30, 0x30
- 0 and 9 bits checked - 0x30, 0x31, 0x30, 0x32
- 0,1,2,3,4,5,9 bits - 0x33, 0x46, 0x30, 0x32
source to share
Note that 0x30 = '0' in ASCII. It seems to me that you are transmitting sixteen bits as two bytes of hex code, first with bits 0-7 and 8-15 seconds, i.e. Do you want to transfer
- hexadecimal digit for bits 4-7
- hexadecimal digit for bit 0-3
- hexadecimal digit for bits 12-15
- hexadecimal digit for bit 8-11
We'll need some additional data, but this matches your examples above:
bit 0 set encodes to string "0100" = 0x30 0x31 0x30 0x30
bit 1 set "0200" = 0x30 0x32 0x30 0x30
bit 2 set "0400" = 0x30 0x34 0x30 0x30
0+2 "0500" = 0x30 0x30 0x30 0x30
0+9 "0102" = 0x30 0x31 0x30 0x32
0,1,2,3,4,5,9 "3F02" = 0x33 0x46 0x30 0x32
i.e. in Java if you have your bits in one whole n
, you probably want
String output = Integer.toHexString((n >> 4) & 0xf)
+ Integer.toHexString(n & 0xf)
+ Integer.toHexString((n >> 12) & 0xf)
+ Integer.toHexString((n >> 8) & 0xf);
byte[] data = output.toUpperCase().getBytes("ASCII");
through a line or
byte[] data = new byte[4];
data[0] = (byte)((n >> 4) & 0xf);
data[1] = (byte)(n & 0xf);
data[2] = (byte)((n >> 12) & 0xf);
data[3] = (byte)((n >> 8) & 0xf);
for(int i = 0; i < 4; ++i) {
data[i] += (data[i] < 10) ? '0' : ('A' - 10);
}
avoiding the line.
To parse four bytes back into one int, you can use
int bits = (((data[0] & 0xf) + ((data[0] >= 'A') ? 9 : 0)) << 4)
| ((data[1] & 0xf) + ((data[1] >= 'A') ? 9 : 0))
| (((data[2] & 0xf) + ((data[2] >= 'A') ? 9 : 0)) << 12)
| (((data[3] & 0xf) + ((data[3] >= 'A') ? 9 : 0)) << 8);
Obviously, there is no input validation here - I am assuming we will get the input in the expected format. The main bit in parentheses should just parse one sixth digit from the string - you could refactor or implement something more robust if you like.
source to share
Well, 16 bits is 2 bytes. So if you split those 2 bytes in half, you get 4 bytes.
Mainly
byte b = ...;
byte firstHalf = (byte)((b & 0x0F) >> 4);
byte secondHalf = (byte)(b & 0xF0);
Please note, however, that this is mostly just a splitting and will not give the result you describe in your question. As noted, it is not clear what to check for the "0" bit and how you get these 0x30 0x31 0x30 0x30 values (which you couldn't get by simply breaking the 16 bits into 4 packets and putting them in bytes each).
source to share
Not sure what you mean:
You have 16 bits, which is only 2 bytes, so you can just leave the first 2 bytes at 0 and use 16 bits in the last two bytes ...
Byte1: 0000 0000
Byte2: 0000 0000
Byte3: first 8 bits of your 16 bits
Byte4: second 8 bits of your 16 bits
EDIT: I don't understand how you get 0x30, 0x30, 0x31, 0x30
0x means hexadecimal
0x30 hexadecimal = 0011 0000 binairy So I don't understand why you would use 0x30 instead of 0x00 ...
source to share
This question is a little open to interpretation, I assume you mean the following:
I have to check every bit of 16 bit datatype if set. If it is set, then I have to send data to the COM port. What data I need to send depends on the bit that has been set. For now, the data I need to send is always 4 bytes long.
Suppose the bit to be checked is part of Java int
, that is, a 32-bit integer where the top 16 bits are always 0. I would suggest using a BitSet to check the bits and an array to determine what to send if a bit set:
closed static end byte [] [] BYTES_TO_SEND = new byte [] [] {{0x30, 0x31, 0x30, 0x30}, // data to send, if bit # 0 is marked {0x42}, // data to send, if bit # 1 marked // ... data to send if bit # 2, # 3, ... is checked};
private OutputStream com;
private static final byte[][] BYTES_TO_SEND = new byte[][] {
{ 0x30, 0x31, 0x30, 0x30 }, // data to send if bit #0 is checked
{ 0x42 }, // data to send if bit #1 is checked
// ... data to send if bit #2, #3, ... is checked
};
private OutputStream com;
public void initializeCOMFromBits(int bits) throws IOException {
for (byte[] toSendIfSet : BYTES_TO_SEND) {
if ((bits & 0x1) == 0x1) { // check if the lowest bit is set
com.write(toSendIfSet);
}
bits >>>= 1; // shift all bits by one to the left
// now the lowest bit if the bit that was second-to-lowest previously
}
assert bits == 0 : "There should be at most " + BYTES_TO_SEND.length + " bits set in the incoming bit set";
}
If your bits are in a BitSet then change the loop to a loop with an index and check the i-th bit with .get(i)
- if it was set, then send BYTES_TO_SEND[i]
to the COM port.
source to share