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

1 Like

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

1 Like

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:

1 Like

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

1 Like

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

1 Like

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.

Hello, I am quite late to the discussion of the problem, however, I think I’ve solved it and it’s much simpler than it seems, but it involved modifying the Dexter I2C block.

The inputs of the I2C block are of type UInt32. If I send a single byte of this type over I2C or UART, it sends correctly, the problem occurs when the ReplaceArraySubset functions puts together the array of bytes to be sent, this is where the capping of the value at 127 happens, I am not sure why. I tried replacing this function with InitializeArray and BuildArray, but to no avail as the EV3 threw an error and it didn’t want to run code with these functions.

The solution was to change the type of the input value of the byte from UInt32 to Byte in the code of the block, after this change, the values can be sent without any issues. I compiled this modified block and it’s available on this Github repository:

https://github.com/Dannero/LEGO-Mindstorms-EV3-Motor-Driver/tree/main/EV3-G_Blocks

It is the Dexter_Mod.ev3b block and it implements these changes for the writei2c and writei2c_8b functions.

1 Like

@Dannero,

You can submit a pull request at the Dexter Industries GitHub repo and I am sure Nicole will be glad to merge it after everyone has had a chance to bang on it for awhile.

Can you create a “diff” file for the patch?

GREAT find!!
 

@cyclicalobsessive

Maybe this is something worth investigating regarding the various i2c issues we’ve been having?  This is just the kind of insidious bug that could explain a lot.

1 Like

I don’t understand enough about I2C to investigate, and I’m through investigating the platform. I am building upon it with all its warts and idiosyncracies.

2 Likes