How do I use I2C?

I wanted the title to be short :wink:

I want to use the i2c pins on the Arduino connectors on the Cerbuino and I can’t have any success yet :frowning:

I am currently rewriting some code of my modules so that they can be used on the Cerbuino but not via the Gadgeteer sockets.

If I use this code :

UART = new SerialPort(ComPort, 9600, Parity.None, 8, StopBits.Two);
UART.Open();

then it doesn’t work.

If I use this code :

UART = new GTI.Serial(NumSocket, 9600, GTI.Serial.SerialParity.None, GTI.Serial.SerialStopBits.Two, 8, GTI.Serial.HardwareFlowControl.NotRequired, null);
UART.Open();

then it works.

What is the way of using the “classical” Arduino pins for i2c or Serial (or else) without relying on Gadgeteer ? Kind of “raw” access to the pins, I would say.

Edit; the code is about Serial com but the problem is the same with i2c, of course :wink:

You can simply use it the same way you did it before gadgeteer and not use gadgeteer wrappers as this maybe easier, since you are not using a gadgeteer socket.

Gus, “the same way you did it before gadgeteer” doesn’t seem to be enough :frowning:

For example, if I tkae the code that is working on a FEZ Panda 1 (which does not make us any younger…) then nothing is working : neither Serial or I2C.
As you can see in the example, the SerialPort code does not work on the Cerbuino. That’s why I think I’m missing something, maybe obvious, but I can’t find it.

What do you mean by “it doesn’t work”? It is really the same as panda. Should be 100% the same but 4.2 may have change something, which I doubt.

Hum…

After looking at the schematics, here’s what I’ve come to, so far :
[ul]Serial pins are working but they are connected to “COM3” instead of COM1, which is used by socket 2. If I use COM3 in my code (for the LCD, for example) then it works.
It’s more problematic with I2C, though, as it is shared with serial pins :frowning: I2C_1 pins are shared with UART_1 pins on socket 2 . And I2C_2 pins are shared with UART3 pins in the Arduino headers.
Worth : I2C_2 has no resistors :frowning: So hardware I2C seems gone on Arduino pins :([/ul]

The hardware I2C pins are only available on the middle socket and they have pull up resistors.

Note how we now have built-in software I2C that is written natively so it works pretty fast and very well. Give it a try bot note the existing bug, see “after release known issues” here http://www.tinyclr.com/forum/topic?id=7982

Ok, I will try that. Though I have to admit I’m reluctant doing this…

Since SoftwareI2C requires a socket as a parameter, what would be the socket number for I2C2 ?

May I ask why you didn’t put pullup resistors on I2C2 ?

Also, I’m confused with the Cerbuino’s schematics : I2C1 is on two different sets of pins. See attached picture. And we find the same pins on the socket #3, which is not I2C.

Edit: forgot the image :frowning:

Do not worry about those labels. I2C can in theory be in 2 places but ti is actually only supported in one please.

I know you are reluctant to use software I2C since you complained about having X socket on IO60P16 but if I didn’t tell you we are using software I2C you wouldn’t know :slight_smile: It just works as well, even better because you can use any pins. Give it a try, what do you get to lose. But maybe wait for the next fix since there is a bug in restart condition, start and stop are fine.

:slight_smile:

Btw, I think I’l complaining too much those days (or asking too much questions, I don’t know)… yet I’m in vacation.

Anyway, I wanted to try and prepared all the code but I still miss a socket number for software I2C. The constructor does indeed permit the use of different pins, but it still need a socket number. And that’s where I’m lost : what is the socket number that is connected to the “Arduino headers” ?

Also, while waiting for an answer, I’ve checked that it was good with hardware i2c, using Extender on socket #2.

Well… it’s almost good for a first try. The same code does not behave the same on the Cerbuino and on the Panda. See attached picture, on which you can see two LCDs, one connected to the Panda on the right and the other on the Cerbuino on the left.
The text that should be displayed is obviously wrong on the Cerbuino :slight_smile: It should of course read “Cerbuino LCD I2C #1”.

Now, what is weird here is that other functions of the LCD are working good, which means that there are no lost bytes. For example, to turn the backlight on, I send an array with 2 bytes in it : 0 and 19. And the backlight indeed turns on (and off with [0,20]).
The same erroneous string is also displayed if I set the cursor some columns away : the position of the cursor is good, but the string is still missing its 2 first chars !

After some research, it looks like the Cerbuino doesn’t like more that one transaction at a time.
The following code does not work :

I2CDevice.I2CTransaction[] xActions = new I2CDevice.I2CTransaction[2];
xActions[0] = I2CDevice.CreateWriteTransaction(new byte[4] { 0, 3, y, x });
xActions[1] = I2CDevice.CreateWriteTransaction(System.Text.Encoding.UTF8.GetBytes((byte)0 + Text));
I2C.Execute(xActions, 1000);

but this one does work :

I2CDevice.I2CTransaction[] xActions = new I2CDevice.I2CTransaction[1];
xActions[0] = I2CDevice.CreateWriteTransaction(new byte[4] { 0, 3, y, x });
I2C.Execute(xActions, 1000);
Thread.Sleep(5);
xActions[0] = I2CDevice.CreateWriteTransaction(System.Text.Encoding.UTF8.GetBytes((byte)0 + Text));
I2C.Execute(xActions, 1000);

Now I have the correct display “Cerbuino LCD I2C #1”.

I don’t know if it is important or if it matters or not, but it’s a (major) difference between USBizi and Cerbuino (I didn’t check on Hydra).

We will test it with I2C analyzer.

Ok. Then I will wait for your results to see if I have to modify the code to take care of the Cerbuino.

But… sorry to insist but I still miss the (mandatory) socket number for the I2C2 pins (Arduino headers) to use software I2C.

Looking at the schematics and the codeplex source code for Cerbuino, I think I’ve found it. It seems to be socket #1, pins 4 & 5. You can forget my question about this, then.

Just to let you know : I’ve successfully run my code with software I2C on the first two Arduino pins of the Cerbuino.

Some things I’ve noticed :
[ul]the Devantech LCD03 does not include pullup resistors
so I had to add real pullup resistors to have it working
the “SoftwareI2C.ForceManagedPullUps” wasn’t of any help. Maybe because there’s no internal pullups on the chip’s pins, I don’t know yet.
do not forget to “>> 1” the device’s address :frowning: (beginner’s mistake here)[/ul]

Reluctant, but determined ! And not necessarilly sectarian, despite appearances :wink:

pet peeve: >>1 of the address means you’re not using the I2C address properly. An I2C device address is a 7-bit value; from there, an 8-bit address is determined depending on whether you are reading from or writing to the device.

@ Brett - No necessarily !

My LCDs addresses are 0xC6 and 0xC8, for example. Those are shown at startup : “LCD03 REVISION8, I2CMODE @ 0xC6”. So here, I have to shift this address.

But, for the Seeed I2C motor driver, its address is indeed a 7bit one : 0x28. In which case I don’t shift it in the driver, of course :wink:
Same applies for the IO60P16 module which address is 0x20. Once again, no need to shift.

On the other hand, if you take the 24LC256 eeprom, it will have 0xA0, for example. Which then needs to be shifted.

Actually, the 24LC256 address is 1010xxx where xxx is the 3 address bits; see figure 5.1 in the datasheet, so assuming all address pins grounded it corresponds to 0x50, and it shows a 7-bit address. The R/W bit is not included in the slave address.

In the original definition there was a 7-bit address or a 10-bit address, personally I’ve never seen a 10-bit address device but I’m sure they exist.

In your case, the LCD is just mis-representing the address and perpetuating the incorrect assumption.

This level of confusion is exactly why it’s important to understand this; making it confusing for beginners.