Connecting 3rd-Party I2C Devices#
This guide is for those who wish to interface 3rd-party I2C devices. As EVOX1 is made to be open source, you are not limited to the sensors and motors that are provided by the EVOX1.
The Arduino library for these devices will work with the EVOX1, but you will need to make some modifications to the library code to make it compatible with the EVOX1.
Note
This guide is for advanced users who are familiar with Arduino programming and electronics. If you are a beginner, we recommend that you start with the official sensors and motors provided by the EVOX1.
Understanding I2C Communication#
I2C lets multiple devices share just two wires: SDA (Serial Data) and SCL (Serial Clock). Each device has an address, like a name. The host (like EVOX1) talks to one device at a time by calling its address. Only the matching device responds, the rest stay silent.
However, some devices can’t change their address. If you connect two devices with the same address, they clash and the system fails.
Instead of connecting all devices directly, we use an I2C multiplexer. It works like a switch, letting only one device at a time appear on the I2C bus. This avoids address conflicts without needing extra pins or soldering.
Now, before talking to a device, we first tell the multiplexer which channel to activate. It adds one extra I2C step, but makes everything work smoothly even with devices that share the same address.
Making Changes to the code#
Folder Structure#
/src
├── sensors/
│ ├── EvoSensorName.h
│ └── EvoSensorName.cpp
└── main.ino
Step 1: Header File#
1#ifndef EVO_SENSORNAME_H
2#define EVO_SENSORNAME_H
3
4#include "../helper/EvoI2CDevice.h"
5#include <ThirdPartySensorLibrary.h> // Replace with the actual sensor header
6
7class EvoSensorName {
8private:
9 ThirdPartySensor sensor; // Instance of third-party sensor class
10 I2CChannel _channel; // I2C multiplexer channel
11 I2CDevice &i2CDevice = I2CDevice::getInstance(); // Singleton multiplexer manager
12
13public:
14 EvoSensorName(I2CChannel channel) : sensor() {
15 _channel = channel;
16 }
17
18 void begin();
19 float readValue(); // Replace with actual sensor methods
20};
21
22#endif
Step 2: Source File#
1#include "EvoSensorName.h"
2
3void EvoSensorName::begin() {
4 i2CDevice.selectChannel(_channel);
5 if (!sensor.begin()) {
6 Serial.println(F("Sensor failed to start"));
7 }
8}
9
10// Add this line to All the functions in the library
11float EvoSensorName::readValue() {
12 i2CDevice.selectChannel(_channel);
13 return sensor.read(); // Replace with actual read function
14}
Step 3: Add to your Main code#
1#include "EvoSensorName.h"
2
3EvoSensorName sensor0(i2c_port);
4EvoSensorName sensor1(i2c_port);
5
6void setup() {
7 Serial.begin(115200);
8 sensor0.begin();
9 sensor1.begin();
10}
11
12void loop() {
13 float val0 = sensor0.readValue();
14 float val1 = sensor1.readValue();
15
16 Serial.print("Sensor 0: "); Serial.println(val0);
17 Serial.print("Sensor 1: "); Serial.println(val1);
18 delay(500);
19}