Asked — Edited
Resolved Resolved by Rich!


Good day,

I2CRead is no recognise in the scrip, it's on the list at the left but the only command for I2C functionning is I2CWrite.


Upgrade to ARC Pro

Experience the transformation – subscribe to Synthiam ARC Pro and watch your robot evolve into a marvel of innovation and intelligence.

United Kingdom

Have you looked at the examples?

I'm literally just about to look in to I2CRead.

Can you post the code you have been trying?

United Kingdom

Have a look at the I2C examples, the I2CRead command is used (and works) in the I2C example.

# Shift the bits over
# Set the LSB (first bit) to a 1
# When first bit is a 1 on i2c, that means
# it is a Read Address
$i2cAddress = 0x09

Print("BlinkM Address: $i2cAddress ")

# Tell BlinkM we want the RGB Values
i2cWrite(0, $i2cAddress, 0x67)

# Receive the RGB Values
$raw = i2cRead(0, AUTO, $i2cAddress , 3)

# Print the number of bytes
Print("Received: Length($Raw) Bytes")

# Print the hex value of each byte

# Split the array of bytes and assign to each variable
$Red = GetByte($Raw[0])
$Green = GetByte($Raw[1])
$Blue = GetByte($Raw[2])


Thank you @Rich ! I2C is a very important part of the EZ-Board ..if not the most important, as it can piggy back many many sensors etc. .....and curiosity asks , why do you need to read the RGB values of the BlinkM ...I will take a bold leap here and think the reason is to have a base line from which to change the values and hence the color sequence.?

United Kingdom

The short and quick answer is you don't.

It's the example for I2CRead which was good since the BlinkM is one of two I2C devices I have to play with so I could test it. There could be a use for reading it but to be honest, you will have written the RGB value to it in the first place so you should know what it is.

Basically the above code (taken from the example) demonstrates how to read from an I2C device and use that information within ARC.

As you say, I2C is important. I2C opens up so much. I'm still getting to grips with it myself but I plan to use a fair amount of I2C devices in the future in order to expand my EZ-Bs and give more functions to my robots:)


Thank you Rich ! Now I anderstand my trouble, I was trying to make a read without a variable... I am too new in programming, I must think much more. Again, you are very helpfull Rich !


Thanks for the speedy reply and clear answer! .. I too will be using a I2C BlinkM for my project as well .....I am thinking that I2C reads and write scripts can also be uploaded to the cloud . There must be others that are using or will be using I2C cryptic commands:)

United Kingdom

I2C is simple... if you have a datasheet that's clear like the BlinkM one (ThingM are awesome for that, i've seen some I2C stuff that's got no info and near impossible to work out, ThingM have covered everything nicely and clearly in their datasheet).

I've put some BlinkM stuff on the cloud and there is a topic somewhere too I put up or added to when I got my BlinkM the other week. I only went through some basics like fading to colours and changing to colours, there is more that can be done such as programming sequences into the BlinkM itself which I haven't looked into (I plan to).

I will say I am very impressed with the BlinkM and unlike some other I2C devices the wire length isn't a major issue and it doesn't need any pull up resistors. Just plug it in and away it goes.

The only other I2C device I have at the moment is the LCD in Melvin which was easy to use thanks to the clear datasheet. I plan to get more I2C stuff as and when I can. When I do you can expect to see info and tutorials on them too (like I even need to say that, it should be a given by now).


Hello Rich, I made a copy of your example and I am playing with it but I do not anderstand correctly the answer I have for the last line.

Set the adress to read an angle

$i2cAddress = 0x31

show the adress in decimal

Print("BlinkM Address:"$i2cAddress)

read the angle

$raw = i2cRead(0, AUTO, $i2cAddress , 8)

Print the number of bytes

Print("Received: Length($Raw) Bytes")

Print the hex value of each byte


just keeping for reference

$Red = GetByte($Raw[0]) $Green = GetByte($Raw[1]) $Blue = GetByte($Raw[2]) $dir = i2cRead(0, Auto, $i2cAddress, 8)

Result manually copie: Start BlinkM Address: 49 Received: 8 Bytes 0x3F 0x3F 0x3F 0x3F 0x3F 0x3F 0x3F 0x3F -- look like it's not fine, I am not sure if the device communicate Done (00:00:00.1092012) -- never the same ?

United Kingdom

What is it you are trying to do? What device is it for? Do you have the datasheet?


Hell Rich, it's a compass, GY-26, the data sheet are easy to find, no trouble with the wire lenght too. I now anderstand a lot more about it because of you. I still have a big amount of work to do to anderstand the data I receive and principally to format the received data but I am progressing bit by bit. The I2C is easier than expected, probably because of the EZ two instructions. I know now I had to make a write and just after a read, now i have to look in the EZ instruction set to determine how to format the data. In the cloud I had posted a very little example of my progress. Thank you again Rich, you have opened my eyes.

United Kingdom

I see.

In that case, let's have a look at the code that's needed (Note: I do not have a GY-26 to test any of this with but basing it on the datasheets available, please post if anything is confusing or doesn't work and I'll do my best to help).

First I assume it would be good practice to calibrate the compass module, you may skip this if you don't think it needs calibrating. It is assumed the robot is mobile and you use a Movement Panel to control it. It is also assumed it takes 1000ms for one single rotation of the robot - adjust the variable $rotationtime to suit your robot design. It is also assumed you have not changed the default I2C address.

Add a new EZ-Script control or new script to the script manager and call it Calibrate Compass. Copy and paste the code below into the script and run to calibrate (or add as part of an init script with a ControlCommand)

# Calibrate GY-26 I2C Compass
# Default address 0xE0

# Variables
$rotationtime = 1000
$rotations = 2

# Do not alter calibraterotatetime variable
$calibraterotatetime = $rotationtime * $rotations

# Set the compass to calibrate
I2CWrite(0, 0xE0, 0xC0)

# Rotate the robot twice
Right(255, $calibraterotatetime)

# Set the compass to end calibration
I2CWrite(0, 0xE0, 0xC1)

# Compass now calibrated

Now it's calibrated you want to know the robot's direction so again, the same assumptions as above and add a new EZ-Script control or script to the script manager called Compass Read. Copy and paste the code below.

# Read From GY-26 I2C Compass
# Default address 0xE0

# Read the current angle
$Raw = I2CRead(0, auto, 0xE0, 0x31)

# Split the array of bytes and assign to each variable
$anglehundreths = GetByte($Raw[2])
$angletens = GetByte($Raw[3])
$anglebits = GetByte($Raw[4])
$angledecimalpoint = GetByte($Raw[5])
$angledecimal = GetByte($Raw[6])

# Combine results to make up angle
$currentangle = $anglehundreths$angletens$anglebits$angledecimalpoint$angledecimal

# Done

The current angle should be stored in the variable $currentangle for use anywhere else in the project.

You can have this on a loop with a slight delay to avoid saturation of the comms, if that's what you need just add in a label at the top


and a sleep and goto at the end


Hopefully that will work but without the device I can't test it and it is based upon my interpretation of the datasheet. However there should be enough there for you to get cracking with and again, if not just ask and I'll delve in deeper.

United Kingdom

And to add, the format of the received data, according to the datasheet is this;

Byte0 is ASCII enter Byte1 is ASCII new line Byte2 is ASCII angle hundreths Byte3 is ASCII angle tens Byte4 is ASCII angle bits Byte5 is ASCII decimal Byte6 is ASCII angle decimals Byte7 is ASCII Calibration Sum

I kinda missed the explanation above however did show the script stripping the bytes individually and then putting them back together (which is something I've never done before so please say if it works or not).

It also can read the temperature from the looks of it, have a look at the datasheet and (if the above works for the angle) have a look to see if you can figure out how to read that:) If you can't and you need help feel free to ask.


You are incredible Rich, it's not working but it's because you do not have a unit. To be able to read I need to put the adress of the unit on the bus before:

Read From GY-26 I2C Compass

Default address 0xE0

Read the current angle

I2CWrite(0, 0xE0, 0x00, 0x31) $Raw = I2CRead(0, auto, 0xE0, 8)

Split the array of bytes and assign to each variable

$anglehundreths = GetByte($Raw[2]) $angletens = GetByte($Raw[3]) $anglebits = GetByte($Raw[4]) $angledecimalpoint = GetByte($Raw[5]) $angledecimal = GetByte($Raw[6])

Combine results to make up angle

$currentangle = $anglehundreths$angletens$anglebits$angledecimalpoint$angledecimal



With this I have a result but it look like I need to make a better installation, too much interference to have a constant reading.

Thank you very much Rich, i now anderstand much more the formating of the data for this unit and in script.

DJ Sure has make a very good scriting tool and you anderstand it very well. I keep looking at all your post because you give hints and very usefull advice,