Problem if I send a value greater than 127 using the I2C block

Hi,

I am doing some I2C tests using an Arduino board with a EV3 brick and I don’t know why if I send 128, the EV3 block doesn’t read that value. I think that a byte store values from 0-256, but I send the integer, I have can’t read. Any idea?

Arduino connection:
https://github.com/jabrena/livingrobots/blob/master/chapter10/arduino/i2c/EV3_to_Arduino.png

Arduino Sketch:

EV3 test:
https://github.com/jabrena/livingrobots/blob/master/chapter10/ev3/ev3g/i2c/readI2C.png
https://github.com/jabrena/livingrobots/blob/master/chapter10/ev3/ev3g/i2c/i2cTest1.ev3

Juan Antonio

This problem is related with this thread:
http://www.dexterindustries.com/forum/?topic=i2c-readwrite-block-for-ev3

Hey Jabrena,

I’ll try to get our friends at Tufts to take a look. I suspect when we first put this code together, we missed a msb/lsb issue that shifts everything over. I know that i2c communications with LEGO do end up shifting one bit over on the address, but I’m not sure about the data payload.

Let me check and come back to it. EV3 is incredibly hard to work with; any way we could convince you to switch to RobotC or some other halfway well implemented language? :slight_smile:

Hi JohnC,
is there any update on this topic?
I also checked the related post I2C Read/Write block for EV3 , but nothing new.

Hey @palto unfortunately no updates on this. We haven’t had much time to look at this code for Arduino and EV3.

Hi, I think I have identified the root cause and found a workaround for it :slight_smile:

The problem is that the values are interpreted as signed int8 and not unsigned Byte. I saw this as I tested the receive function and found that the value 128 (1000 0000) was displayed as “—” (no number) and 129 was displayed as -127 on the EV3. This means that the EV3 interprets the values as 2’s complement and not as unsigned Byte.

So if you want to send a value >127, then you need to send a negative number. Unfortunately the I2C block doesn’t allow the input of negative values, but it is possible to put the negative number into a contact or variable block and connect this to the I2C input.

One issue remains: the 2’s complement of 1000 0000 is “-0” which you can’t enter in EV3. But I found that you can receive this value via I2C, store it into a variable block and then send it back via I2C.

To test for a recieved “-0” value it works to use the range test “-127 to 127” where it is not included (out of range). Whith this you can convert between the unsigned Byte and signed int8 values.

Not sure if this helps to fix the issues with the I2C block (to interpret the Byte correctly), but I hope it helps other users to workaround this limitation and use the full range of values (except maybe the “-0” case).

To convert an unsigned Byte into a singed int, you need to test if the value is above 128 and if yes substract 256. Example: Byte 130 = int8 130-256 = int8 -126. The issue remains with the value 128 which can’t be converted to a “-0” in EV3 (at least I have no idea how).
In the other direction you just add +256 if the received value is <0.