I2C Communication between Arducopter 3.1.5 and Arduino Uno

1,322 views
Skip to first unread message

Fahrettin Ay

unread,
Jul 30, 2014, 10:45:26 AM7/30/14
to drones-...@googlegroups.com
Hello,

Im working on a project and i need to communicate an APM and Arduino Uno via I2C protocol. As you know, APM uses a specific library for I2C (I2CDriver.cpp) and Arduino uses default Wire library. The APM roles as master and Arduino UNO is slave. I can write a data to I2C bus and can read by UNO. However, i can not read a data from UNO by APM. There is no function in I2CDriver.cpp corresponsing requestFrom on Wire libary. Thus, i can not achieve the communication. Is there a way to do this? Or do i have to try to write a requestFrom function for  I2CDriver library?

yours sincerely...
Fahrettin Ay

Robert Lefebvre

unread,
Jul 30, 2014, 12:08:02 PM7/30/14
to drones-discuss
It should definitely be possible, but might be more complicated than the Arduino way.

Our compass is I2C, and we get data from it.  So have a look at this file for example:



Fahrettin Ay

--
You received this message because you are subscribed to the Google Groups "drones-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to drones-discus...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jason Short

unread,
Jul 30, 2014, 12:09:03 PM7/30/14
to drones-...@googlegroups.com
sure. 

I use an I2C slave for my wheel encoders:


// I2C Receive buffer
static union {
    int32_t long_value;
    int16_t int_value;
    uint8_t bytes[];
} bytes_union;


static bool update_wheel_encoders()
{
uint8_t buff[12];

    if (!_i2c_sem->take(5)) {
        // the bus is busy - try again later
        return false;
    }
if (hal.i2c->read(ENCODER_ADDRESS, sizeof(buff), buff) != 0) {
I2Cfail++;
  _i2c_sem->give();
return false;
}
_i2c_sem->give();


memcpy(bytes_union.bytes, &buff[1], 2);
wheel.left_distance = bytes_union.int_value * WHEEL_ENCODER_DIR_LEFT;

...

}





Fahrettin Ay

unread,
Jul 30, 2014, 1:34:54 PM7/30/14
to drones-...@googlegroups.com
Thak you for your replies Jason and Robert,

At the code below, i tried to read the data from Arduino UNO. However, The UNO use Wire library and i think it does not works as i thought. The whole data i get from the i2c bus is meaningless. 

void ReadData() 
{
cliSerial->printf_P(PSTR("Reading.."));
cliSerial->println();
hal.scheduler->delay(500);
        AP_HAL::Semaphore* i2c_sem = hal.i2c->get_semaphore();
        
        if(!i2c_sem->take(200))
          return;
   
        hal.i2c->read(SLAVE_ADDRESS, 1, &readData);
        i2c_sem->give();

cliSerial->printf_P(PSTR("Read: %d"), (int)readData);
//cliSerial->printf_P(readData);
cliSerial->println();
}

 The all thing i understand from the example of Master_Reader and Slave_Sender of the Wire library is that master interrupts the slave for requesting data by (requestFrom function)  and slave sends the data to the i2c bus after it recognizes the interrupt.  


Master Side: 

Wire.requestFrom(2, 6);    // request 6 bytes from slave device #2

  while(Wire.available())    // slave may send less than requested
  { 
    char c = Wire.read(); // receive a byte as character
  }


Slave side:

void setup()
{
  Wire.begin(2);                // join i2c bus with address #2
  Wire.onRequest(requestEvent); // register event
}

void requestEvent()
{
  Wire.write("hello "); // respond with message of 6 bytes
                       // as expected by master
}



And im not sure i can achieve reading data from the UNO by using the I2CDriver. Or there is another approach? 

Yours sincerely..
Fahrettin

Jason Short

unread,
Jul 30, 2014, 4:34:04 PM7/30/14
to drones-...@googlegroups.com
Here is my Slave code. It uses Wire lib since I2C lib does not do slave mode. 
i2c_dual_motor_encoder.pde

jolyboy

unread,
Jul 30, 2014, 4:45:30 PM7/30/14
to drones-...@googlegroups.com
Very useful for our rpm sensor, thanks ;)

Swetapadma Sahoo

unread,
Jun 24, 2016, 6:32:22 PM6/24/16
to drones-discuss
Hi,

I know this is a very old thread, but I hope I can get some answers here. I am also trying to establish an I2C connection between ArduPilot and Arduino uno. I am trying to send the airspeed value through I2C. How do I write data to the I2C bus?

Any help is really appreciated!

Thanks,
Sweta.

Nitay Megides

unread,
Jun 29, 2016, 7:42:47 AM6/29/16
to drones-discuss
Hello!

Unfortunately it's not as simple as one may think...
In order to talk with the I2C bus you need to:
1. implement a PX4Firmware driver to handle the I2C for you - That's on the PX4Firmware project
2. Implement a library in the ArudPilot code to communicate with this driver through ORB messages (or similar)

There is pretty close driver you could copy-paste from - IRLock driver uses I2C to communicate with a Pixy-based device called IR-LOCK.
I'd start with reading the code in the "irlock" driver (PX4Firmware project), then reading the code in the AP_IRLock library (ArduPilot project).
(Another example, maybe a more simple one, is the SMBus Battery driver)

There were also some tutorials regarding to the uORB messaging system, and to PX4 development in general. But I can't find them now :(
They were all here:

Here are some threads about the subject:

There are more if you search for "I2C driver" on this group.

Good luck!!
Nitay

vittorio radalli

unread,
Oct 25, 2016, 12:09:50 PM10/25/16
to drones-discuss
hi all,
 i have same problem. i would like Pixfalcon send out some messages (bytes) and arduino to read them to do...something.
I started by modifying pca9684.cpp and, wiring pixfalcon and arduino (with slave I2C loaded, the simplest example i found in internet) i see some messages.
Now the point is: ho can i send out my message, instead of pre-defined ones?

Do you have some code (px4) i can start from to modify and implement?

all helps are appreciated
thank you
Vi3da
Reply all
Reply to author
Forward
0 new messages