Communicating with another Arduino over i2c

Having a problem? Post it here and someone will be along shortly to help
User avatar
mlapaglia
Printmaster!
Posts: 121
Joined: Sat May 24, 2014 10:41 am
Location: Indianapolis, IN

Communicating with another Arduino over i2c

Post by mlapaglia »

I'm looking for a way to connect the RAMBO to another arduino via the i2c connection. I'm going through the source code but can't find any good examples of opening up a simple connection and writing strings out. Does anyone know where I can find some sample code on creating some methods like this?
User avatar
Captain Starfish
Printmaster!
Posts: 962
Joined: Tue Dec 10, 2013 5:24 am

Re: Communicating with another Arduino over i2c

Post by Captain Starfish »

Also known as TWI (two wire interface), supported as such under the Arduino libraries. It's a master/slave protocol so watch out for that, it's not uniformly bidirectional. Master can write whenever but the slave has to wait for an invitation before it can send data back. And I2C is very susceptible to noise - no good at all for anything longer than a few inches of separation. And don't forget pullups on the data lines - caught me out recently.

I would suggest dropping the cash on another baby Arduino and getting it talking to your new other board first. Then migrate the code into the Repetier firmware you're using to hook the two up. If you try to dev your I2C protocol within the Repetier's framework you're fighting too many battles at once, you're gonna have a bad time.
User avatar
mlapaglia
Printmaster!
Posts: 121
Joined: Sat May 24, 2014 10:41 am
Location: Indianapolis, IN

Re: Communicating with another Arduino over i2c

Post by mlapaglia »

Thanks, I've already gotten two arduinos talking and have the setup complete, I'm just not sure where in the Repetier firmware to put the communication code? I see it already has a class involving i2c, but I can't find how to use it successfully. Do I just import my own library and use that instead of what's already in the firmware?
User avatar
Jimustanguitar
ULTIMATE 3D JEDI
Posts: 2631
Joined: Sun Mar 31, 2013 1:35 am
Location: Notre Dame area
Contact:

Re: Communicating with another Arduino over i2c

Post by Jimustanguitar »

This may not be exactly what you're looking for, but give this a look https://github.com/wolfmanjm/universal-panel-adapter" onclick="window.open(this.href);return false;
User avatar
Captain Starfish
Printmaster!
Posts: 962
Joined: Tue Dec 10, 2013 5:24 am

Re: Communicating with another Arduino over i2c

Post by Captain Starfish »

mlapaglia wrote:Thanks, I've already gotten two arduinos talking and have the setup complete, I'm just not sure where in the Repetier firmware to put the communication code? I see it already has a class involving i2c, but I can't find how to use it successfully. Do I just import my own library and use that instead of what's already in the firmware?
Probably not.

Safest way would be to identify from the Atmel 2560 datasheet where the scl/sda pins are on the micro. Then find where they are already used - either as Atmel pin numbers/mnemonics, via the TWI registers (again, details in the datasheets), or as they're mapped in to Arduino DIO numbers in pins.h or whatever it is they use to map particular parts.

If you find it in use (and I remember Repetier having stuff in there for this) then try piggyback on top, otherwise you know you're safe to park your own i2c or twimaster drivers in there to play.
Mac The Knife
ULTIMATE 3D JEDI
Posts: 1409
Joined: Sun May 11, 2014 6:18 pm

Re: Communicating with another Arduino over i2c

Post by Mac The Knife »

I am curious what the purpose of doing this is. Remote operation? Or monitoring?
R-Max V2
Eris
Folger Tech FT-5 R2
User avatar
teoman
ULTIMATE 3D JEDI
Posts: 1783
Joined: Sat May 24, 2014 5:43 pm

Re: Communicating with another Arduino over i2c

Post by teoman »

Adding extra doodads.

Nozzle wiper
Leds
Heated chamber
Dehumidifier

All controlled by gCodes (MCodes).
When on mobile I am brief and may be perceived as an arsl.
User avatar
mlapaglia
Printmaster!
Posts: 121
Joined: Sat May 24, 2014 10:41 am
Location: Indianapolis, IN

Re: Communicating with another Arduino over i2c

Post by mlapaglia »

Captain Starfish wrote:
mlapaglia wrote:Thanks, I've already gotten two arduinos talking and have the setup complete, I'm just not sure where in the Repetier firmware to put the communication code? I see it already has a class involving i2c, but I can't find how to use it successfully. Do I just import my own library and use that instead of what's already in the firmware?
Probably not.

Safest way would be to identify from the Atmel 2560 datasheet where the scl/sda pins are on the micro. Then find where they are already used - either as Atmel pin numbers/mnemonics, via the TWI registers (again, details in the datasheets), or as they're mapped in to Arduino DIO numbers in pins.h or whatever it is they use to map particular parts.

If you find it in use (and I remember Repetier having stuff in there for this) then try piggyback on top, otherwise you know you're safe to park your own i2c or twimaster drivers in there to play.
Thanks I'll take a look tonight and see. I know there is already code for talking over i2c for the optional displays so piggy backing on it might work. I tried initializing the communication without success. I will keep trying though :)
Mac The Knife wrote:I am curious what the purpose of doing this is. Remote operation? Or monitoring?
I have some neopixels on hand and want to tie them in with gcode processing, different lights when certain actions happen etc. The processing for changing colors is CPU intensive and I don't want to overburden the RAMBO. I want to setup a simple communication where the RAMBO will say "hey the heat turned on" or "layer change occuring", then the second arduino can act accordingly.
User avatar
teoman
ULTIMATE 3D JEDI
Posts: 1783
Joined: Sat May 24, 2014 5:43 pm

Re: Communicating with another Arduino over i2c

Post by teoman »

http://reprap.org/wiki/Rambo_v1.2" onclick="window.open(this.href);return false;

Says it has spi pins.
When on mobile I am brief and may be perceived as an arsl.
User avatar
mlapaglia
Printmaster!
Posts: 121
Joined: Sat May 24, 2014 10:41 am
Location: Indianapolis, IN

Re: Communicating with another Arduino over i2c

Post by mlapaglia »

teoman wrote:http://reprap.org/wiki/Rambo_v1.2

Says it has spi pins.
The SPI is used by the LCD though.

I'm messing around with the code trying to get something to output. In the printer.cpp file at the bottom of the setup method I have:

Code: Select all

HAL::i2cStartWait(4+I2C_WRITE);
HAL::i2cWrite('a');
HAL::i2cStop();
When I upload it to the board it looks like it goes into a boot loop. I've found that taking out the i2cWrite command causes it to boot up find, but obviously nothing gets written.
User avatar
teoman
ULTIMATE 3D JEDI
Posts: 1783
Joined: Sat May 24, 2014 5:43 pm

Re: Communicating with another Arduino over i2c

Post by teoman »

Ai i remember spi uses a bus for data transmission. But then an extra pin to say hey i am talking to you.
When on mobile I am brief and may be perceived as an arsl.
User avatar
Captain Starfish
Printmaster!
Posts: 962
Joined: Tue Dec 10, 2013 5:24 am

Re: Communicating with another Arduino over i2c

Post by Captain Starfish »

SPI ≠ I2C/TWI

The LCD is direct drive by pin bashing, the SPI port is used to talk to the SD card. You can piggyback atop the SPI bus by adding another general purpose IO pin as a "device enable" pin for your add-ons, though, and making sure your DE is never enabled at the same time as the SD DE (aka chip select CS).

The arduinos support both and I'm pretty darned sure I had both coming off the extension connectors when I was stuffing around with thermocouple adapters earlier this year. Alas, no notes to refer to or I'd copy them straight up here.
Eric
Printmaster!
Posts: 726
Joined: Sat Aug 18, 2012 4:09 am
Location: Chula Vista, CA

Re: Communicating with another Arduino over i2c

Post by Eric »

teoman wrote:http://reprap.org/wiki/Rambo_v1.2

Says it has spi pins.
Looking at the RAMBO schematic at the same link tells me that that there are dedicated SDA/SCL pins for the Rambo's I2C port which are not shared with the SPI or EXT headers. I also see 10K pullups on both lines.

Now whether the I2C code in the firmware is actually using those pins is a subject for further research.
User avatar
mlapaglia
Printmaster!
Posts: 121
Joined: Sat May 24, 2014 10:41 am
Location: Indianapolis, IN

Re: Communicating with another Arduino over i2c

Post by mlapaglia »

Eric wrote:
teoman wrote:http://reprap.org/wiki/Rambo_v1.2

Says it has spi pins.
Looking at the RAMBO schematic at the same link tells me that that there are dedicated SDA/SCL pins for the Rambo's I2C port which are not shared with the SPI or EXT headers. I also see 10K pullups on both lines.

Now whether the I2C code in the firmware is actually using those pins is a subject for further research.
When I ran a simple tutorial sketch on the rambo and another arduino device I got it to work using the dedicated i2c connector on the rambo.
http://arduino.cc/en/Tutorial/MasterWriter" onclick="window.open(this.href);return false;

I'm not sure how to tell what port the repetier firmware is using for i2c though.. I assumed it was the same one because the firmware can control LCD displays through it.
User avatar
Captain Starfish
Printmaster!
Posts: 962
Joined: Tue Dec 10, 2013 5:24 am

Re: Communicating with another Arduino over i2c

Post by Captain Starfish »

Be careful with those 10k resistors. In another project I have been chasing a problem for months (on and off) whereby an OLED display sitting 2cm away from an Atmel would work for a while then fritz out. Chased all sorts of things and in the end it turned out to be too high an impedance on the pull-ups.

10k internals on the Atmel? Nope.
10k externals? Nope.
4k7 externals? Still nope (and this is the generally recommended value).
2k externals? Getting better.
1k externals? Bingo!

I'm guessing the edge detector in the OLED controller is pretty lame and needs low impedance pull ups to really haul the lines high with a nice square edge.

I seem to recall all the I2C logic being in the repetier firmware somewhere, but can't remember where it ended up either.
User avatar
mlapaglia
Printmaster!
Posts: 121
Joined: Sat May 24, 2014 10:41 am
Location: Indianapolis, IN

Re: Communicating with another Arduino over i2c

Post by mlapaglia »

This is the kind of functionality I'm getting at. Right now the actions are soley controlled by the external arduino though..

https://www.youtube.com/watch?v=u4f7OIhouQg" onclick="window.open(this.href);return false;
Eric
Printmaster!
Posts: 726
Joined: Sat Aug 18, 2012 4:09 am
Location: Chula Vista, CA

Re: Communicating with another Arduino over i2c

Post by Eric »

Captain Starfish wrote:Be careful with those 10k resistors. In another project I have been chasing a problem for months (on and off) whereby an OLED display sitting 2cm away from an Atmel would work for a while then fritz out. Chased all sorts of things and in the end it turned out to be too high an impedance on the pull-ups.

10k internals on the Atmel? Nope.
10k externals? Nope.
4k7 externals? Still nope (and this is the generally recommended value).
2k externals? Getting better.
1k externals? Bingo!

I'm guessing the edge detector in the OLED controller is pretty lame and needs low impedance pull ups to really haul the lines high with a nice square edge.

I seem to recall all the I2C logic being in the repetier firmware somewhere, but can't remember where it ended up either.
Internal pullups are more like 35KΩ (datasheet for 2560 says min 20K, max 50K, so assume the middle). Not strong enough for general purpose I2C, so external pullups are recommended.

For talking to another Arduino, 10K pullups should be fine.
User avatar
teoman
ULTIMATE 3D JEDI
Posts: 1783
Joined: Sat May 24, 2014 5:43 pm

Re: Communicating with another Arduino over i2c

Post by teoman »

Any progress?
When on mobile I am brief and may be perceived as an arsl.
User avatar
mlapaglia
Printmaster!
Posts: 121
Joined: Sat May 24, 2014 10:41 am
Location: Indianapolis, IN

Re: Communicating with another Arduino over i2c

Post by mlapaglia »

Indeed! I found out over at reprap forums that the address needs a left bit shift in order to work properly. Here's the code I am using now:

Code: Select all

HAL::i2cInit(100000L);
HAL::i2cStartWait(4 << 1);
HAL::i2cWrite('a');
HAL::i2cStop();
Right now I'm trying to figure out how to get a float converted to a string.

Code: Select all

message += "X: ";
message += (long)code->X;
message += " ";
When I get the serial output I only get the first digit of the X value..
User avatar
teoman
ULTIMATE 3D JEDI
Posts: 1783
Joined: Sat May 24, 2014 5:43 pm

Re: Communicating with another Arduino over i2c

Post by teoman »

Aaaa,

Why would you want to trasnfer strings?

Write your own protocol that transers bytes and integers and floats. It would be much faster and efficient in my opinion.
When on mobile I am brief and may be perceived as an arsl.
User avatar
mlapaglia
Printmaster!
Posts: 121
Joined: Sat May 24, 2014 10:41 am
Location: Indianapolis, IN

Re: Communicating with another Arduino over i2c

Post by mlapaglia »

I'm mainly a web developer with C# skills, writing my own methods for this is a bit over my head. I am trying to reuse the code already in the project. The i2cWrite method only takes in chars, so I was trying to get everything that way.

I looked at the i2cWrite method, I can't fine where the variable are being assigned or how they are actually sent over the wire:

Code: Select all

unsigned char HAL::i2cWrite( unsigned char data )
{
    uint8_t   twst;
    // send data to the previously addressed device
    TWDR = data;
    TWCR = (1<<TWINT) | (1<<TWEN);
    // wait until transmission completed
    while(!(TWCR & (1<<TWINT)));
    // check value of TWI Status Register. Mask prescaler bits

    return 0;
}
User avatar
teoman
ULTIMATE 3D JEDI
Posts: 1783
Joined: Sat May 24, 2014 5:43 pm

Re: Communicating with another Arduino over i2c

Post by teoman »

Give me a few hours to get back home.

Then i can have a look at it. I also need i2c communication.
When on mobile I am brief and may be perceived as an arsl.
Eric
Printmaster!
Posts: 726
Joined: Sat Aug 18, 2012 4:09 am
Location: Chula Vista, CA

Re: Communicating with another Arduino over i2c

Post by Eric »

mlapaglia wrote:I'm mainly a web developer with C# skills, writing my own methods for this is a bit over my head. I am trying to reuse the code already in the project. The i2cWrite method only takes in chars, so I was trying to get everything that way.

I looked at the i2cWrite method, I can't fine where the variable are being assigned or how they are actually sent over the wire:

Code: Select all

unsigned char HAL::i2cWrite( unsigned char data )
{
    uint8_t   twst;
    // send data to the previously addressed device
    TWDR = data;
    TWCR = (1<<TWINT) | (1<<TWEN);
    // wait until transmission completed
    while(!(TWCR & (1<<TWINT)));
    // check value of TWI Status Register. Mask prescaler bits

    return 0;
}
Reading from a C# viewpoint explains your confusion. The C and C++ languages and data types predate the existence of unicode. "char" was defined as the smallest addressable unit that would contain the machines character set. These days "char" almost always means 8-bit integer; the exceptions are mostly history now. Thus "unsigned char" means an unsigned 8-bit integer, or any value from 0 to 255. In C# you would call that a "byte".

i2cWrite as written does not send strings, it sends a single byte. If you need more than one byte, call it more than once. The read side has to match, of course.

As for how it works: The Atmega actually has hardware TWI (aka i2c) support (http://www.atmel.com/images/doc2549.pdf, page 247 has a good diagram). TWDR is a data register. TWCR is a control register. When the hardware sees the the enabled bit has been set, it sends the byte in the data register. When the data has been successfully sent, it resets the bits in the control register to indicate it's done and ok to send another byte.
User avatar
Captain Starfish
Printmaster!
Posts: 962
Joined: Tue Dec 10, 2013 5:24 am

Re: Communicating with another Arduino over i2c

Post by Captain Starfish »

^^ this

Where you see "unsigned char" assume "byte".

You can treat anything as a series of bytes.

For example, your float (call it fMyValue) could be sent:

Code: Select all

// in the global space, not in a function, put this:
typedef unsigned char byte;  // now we can call things byte or unsigned char interchangeably.

// in your function, at sending time, put this:
byte *tempArray = (byte *)(&fMyValue);  // creates a byte pointer that points at your variable
for (int i=0; i<sizeof(float); ++i) {
    i2cWrite(*(tempArray+i));
}
Do the same on the receiving side to spoon the incoming bytes into the variables.
User avatar
mlapaglia
Printmaster!
Posts: 121
Joined: Sat May 24, 2014 10:41 am
Location: Indianapolis, IN

Re: Communicating with another Arduino over i2c

Post by mlapaglia »

Thanks guys, learning more and more every hour. teoman and I have made great progress tonight, we now have the rambo communicating with the auxilary arduino.
Post Reply

Return to “Troubleshooting”