0

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.

Tamim Attafi
  • 2,253
  • 2
  • 17
  • 34
  • Show us the code that creates and/or sends the message. – Joachim Sauer Oct 07 '19 at 15:12
  • @JoachimSauer the code is just an implementation of the mentioned library. it is somehow similar to the code in this article: http://www.fpgalover.com/software/coding-usb-serial-using-android-studio – Tamim Attafi Oct 07 '19 at 15:19
  • I don't need to know what code it looks *somewhat similar to*. Why don't you show us a minimal example of how you send your message and/or how you construct it? Without that we can only guess... – Joachim Sauer Oct 07 '19 at 15:21
  • @JoachimSauer I hope the question is now clearer than it was. – Tamim Attafi Oct 07 '19 at 15:37
  • `In Kotlin we could not assign 0x82 to a byte variable`. Hard to believe. (I dont know Kotlin).There would be something fundamentaly wrong in kotlin then. Please show your code. `so we had to use it's decimal form -126` Bytes are not signed or unsigned. They are just 8 bits. So how would you assign something negative? – blackapps Oct 07 '19 at 15:53
  • `byteArrayOf(editText.text.toString.ToByte())` Please give an exact example of what the user types in and the sequence of bytes you get. – blackapps Oct 07 '19 at 15:56
  • @blackapps I updated my answer – Tamim Attafi Oct 07 '19 at 16:08
  • `the compiler accepts byte = -126 but not byte = 0x82. same for java.`. Nonsense. In java one can assign all values 0x00-0xFF to a byte. I think you could better open another thread where you ask how in kotlin you can assing 0x82 to a byte. – blackapps Oct 07 '19 at 16:09
  • @blackapps please check this Kotlin doc about basic types: https://kotlinlang.org/docs/reference/basic-types.html – Tamim Attafi Oct 07 '19 at 16:09
  • @blackapps a quick test on java writing Byte mByte = 0x82; the compiler points an error with this message: Incompatible Types Required: java.lang.Byte Found: int – Tamim Attafi Oct 07 '19 at 16:14
  • Yes. I see `Byte 8 -128 127` but a byte is (should be) nor signed nor unsigned. There are 8 bits. Its up to you how you interpret them. But.. i see now why you tried to assign negative values. I have to reread your whole story now... tomorrow. – blackapps Oct 07 '19 at 16:14
  • In java: byte mybyte = (byte)0x82; or Byte hisbyte = (byte)0x82; – blackapps Oct 07 '19 at 16:15
  • @blackapps a quick test of (byte)0x82 prints -126 – Tamim Attafi Oct 07 '19 at 16:19
  • That can be but blame your print function who interprets it as signed. Does not matter further. It is you that should interpret the 8 bits. Print them hexadecimal or bitwise and you will get 0x82 again. – blackapps Oct 07 '19 at 16:21
  • @blackapps it's not the print function it's the casting function (byte) or toByte() has two constants: public const val MIN_VALUE: Byte = -128 public const val MAX_VALUE: Byte = 127 – Tamim Attafi Oct 07 '19 at 16:25
  • The casting does not matter i think. Just print the byte's value in hexadecimal notation. Try: byte mybyte = 0; mybyte |= (byte)0xFF; What is the hexvalue then? – blackapps Oct 07 '19 at 16:26
  • @blackapps the hex is correct, but we need to send bytes to the device not hex, hex value doesn't matter as much as byte value. – Tamim Attafi Oct 07 '19 at 16:28
  • 2
    You send bytes to the device. You send 8 bits to the device. You do not send signed or unsigned or decimal or hexadecimal to the device. You send just 8 bits. How you interpret them is up to you. The device sees just a byte or 8 bits. – blackapps Oct 07 '19 at 16:29
  • @blackapps in this situation, what do you suggest? – Tamim Attafi Oct 07 '19 at 16:34
  • I have to reread you whole problem again... tomorrow. But you will try to assign hex values to a byte in kotlin and print the value hexadecimal to check. If the hexadecimal notation is ok then it should work. – blackapps Oct 07 '19 at 16:36
  • @blackapps quick Kotlin test, `mByte = 0x82.toByte()` prints: `byte = -126` `hex = 82` – Tamim Attafi Oct 07 '19 at 16:46

0 Answers0