Go Down

Topic: I2C Problem, Communicating Between Two Arduinos (Read 13100 times) previous topic - next topic


I'm sorry about the variable kolik- it is the variable howMany. This mistake was caused by translating code from Czech to English.
The Arduino accessory is used to set value of the msg array. I think that two bytes are going to be send and if there are no data from accessory it's going to send -1s there.

Thanks for your reply


May I suggest using Bill Porters Easy Transfer I2C edition for this sort of problem? May make your life a lot easier.

He also has a serial edition. I used the serial version at 1MBit/s between two Atmels on one board.


Thanks for your reply. I'll definitely try it. But I'd rather use I2C because in my project there'll be more than one slave.


Thanks for your reply. I'll definitely try it. But I'd rather use I2C because in my project there'll be more than one slave.

Should work great. His library includes examples, so hopefully it won't take much to get it all implemented quickly. I2C is a great bus, but be aware of the limitations re: bus length - Phillips originally designed it to be used only on one PCB. That's not to say that it won't work, but buses longer what than the OEM planned for may not be as reliable as you would like.

It's one reason I went to RS485-based buses between my Arduinos. Very good resistance against interference and the possibility of running shielded cables if necessary. But my distances are likely larger than yours...


I've had little to no issue with the I2C bus since I got my stuff working, and I'm running it from an mBed to 4 seperate atmega chips, a gyro, and an accelerometer all on the same line. So long as you are routing signals over short distances (within a couple of feet or so) you should be fine. My rule of thumb is to always have a 10k pullup resistor on the SDA and SCL lines for each device you have, so the resistance will decrease as the capacitance added increases. I would also recommend you stick to the Wire library rather than going to an external one as there is more support here on the forum, and outside little issues like this, it is quite robust.

Anyways, I don't know if you are still having trouble with your code but here is my 2 cents on it. Your main problem is that you did not include your array length in your Wire.write command. The syntax is void write(*char data, int length). So you are only sending 1 byte, thus the reason why only the last byte is sent as that is what the index pulls up first. Double check the reference page: http://arduino.cc/en/Reference/WireWrite

Also why do you have a 10ms delay in the receiver? Essentially what is going to happen to your I2C line will be a really long pull-down of the SCL then a very rapid stream of data, I wouldn't be surprised if things got lost in that. The i2c request and receive functions are both run through interrupts, and generally you do not want to stick delays (especially of the ms variety, you could get away with micro delays) into interrupts as you want them to run as fast as possible.

There are other quirks and shenanigans in your code that you probably will have to debug out, but I think the issue related to the I2C bus is that you are sending a data array without specifying the data array length as the library wants.


Thank you for your response, it's finally working.


Thank you for your response, it's finally working.

Great. So, what was the problem? How did you correct it?
The art of getting good answers lies in asking good questions.


The problem was in using Wire.write() without buffer length in the slave code. Correct command in this case is Wire.write(msg,2);


Just wanted to confirm that this solved my problem.

I was dealing with a .onRequest event on my slave arduino and my response was 2x Wire.write(), and for some reason I was only receiving the first byte.

Adding .beginTransmission and .endTransmission around the .writes cause my arduino to hang.

Building and sending an array sans Transmission functions fixed my problem.

Many thanks :)


For those who need to call write( ) multiple times in a slave response, I was able to modify twi_transmit( ) in twi.c to the following code and this works fine:

Code: [Select]

uint8_t twi_transmit(const uint8_t* data, uint8_t length)
 uint8_t i;
   // ensure data will fit into buffer
   if(TWI_BUFFER_LENGTH < twi_txBufferLength+length){
       return 1;
   // ensure we are currently a slave transmitter
   if(TWI_STX != twi_state){
       return 2;
   // set length and copy data into tx buffer
   for(i = 0; i < length; ++i){
       twi_txBuffer[i+twi_txBufferLength] = data[i];
   twi_txBufferLength += length;
 return 0;

Go Up