We are trying to read a value from an external sensor that is connected to a USB CP2102 USB to UART bridge.
We used this library in order to make serial communication, we could send bytes such as
0x69 0x14 0x00
.. and any other kind of positive bytes (0 to 127)
in order to open the sensor we need to send sensor's number, which in our case was 0x82 (the equivalent of 130 in unsigned bytes and -126 in signed 2's)
In Kotlin we could not assign 0x82 to a byte variable so we had to use it's decimal form -126, but sending that byte causes the device to stop sending or receiving data.
We tried with all positive bytes and nothing caused that problem, only negative ones do.
From my point of view, the device uses unsigned bytes for receiving and sending data, sending a signed byte is somehow out of its range
there are unsigned bytes in experimental Kotlin, as UBytes but unfortunately, both the Android USB Host Api and the serial communication library uses the traditional ByteArray
as a buffer.
Is there anyway we can send 0x82 to the device without causing it to stop working?
Using this Serial Terminal App, we could normally send 82 as hex. The data from the sensor returned successfully and as expected in the documentations of the device.
How is that possible?
note: we also tried some utilities that convert hexStringToBytes, for example 69 to 105 but the result is still the same as assigning the 0x82 byte directly to -126.
EDIT:
The library has a writeAsync
method that accepts a ByteArray
as a parameter.
In our view we have an edit text that asks the user to write Bytes
such as 105, 20... so we are passing a byteArrayOf(editText.text.toString.ToByte())
which throws if the value exceeds 127.
The user must enter a byte from -128 to 127.
In order to receive configuration file from the sensor, the user must send
0x69 - which is 105 in bytes then 0x82 - which is 130 in Ubytes or -126 in bytes. 0x00 - which is 0 and last the CRC (one byte of the remainder of division by 256) which is here 0x14. which equals 20.
after that the user should receive the following data (in hex it would look like):
96 82 00 3C 54 79 70 65 3D 70 48 20 EC E5 F2 F0 0A 50 61 72
61 6D 3D 70 48 0A 55 6E 69 74 3D 0A 6B 3D 3D 5B 8B AC 0A 62 3D 3E
C1 FF 2E 0A 6D 69 6E 00 3D 00 00 00 0A 6D 61 78 3D 41 60 00 0A 00 51
the user writes 105, send, successfully sent, then -127, send, failure, device stops responding.
We can't receive this data because 0x82 is required.
Sending 105, then 0, then 21 or any other positive byte doesn't return any error. Sending any negative byte stops the device from reading/writing
In application log we convert the ByteArray
to hex string for easy reading.
Sending 105 writes request: byte= 105 hex= 69
in the log cat, the device receives that data back and write answer: byte= 105 hex= 69
.
Writing 130 (for 0x82) throws a casting exception, which forces you to use the other value which is -126, which immediately stops the device from reading or sending data, the log only shows request: byte= -126 hex= 82
with no answer, and accepts no requests after then.
Hard coding values also does the same thing.