Interfacing Raspberry Pi and M-Duino via I2C communication

February 12, 2024 by
Interfacing Raspberry Pi and M-Duino via I2C communication
Boot & Work Corp. S.L., Queralt del Águila Munté

Introduction

In this blog post, we will see an example of how two of the PLC models can communicate with each other via I2C by exchanging messages. One will be a model of the M-Duino Family, and the other can be any of our models based on Raspberry: Raspberry PLC Family, TouchBerry Family or UPSafePi

First of all, we will be able to ensure if the I2C communication is functioning and if other devices are detected in order to be able to communicate. Additionally, afterward, we will be able to execute the code; one for the Raspberry Pi, which will act as the master, and the other for the M-Duino, which will be the slave.

Setup

Hardware schematics

  • Link the GND of the Raspberry Pi to the GND of the Arduino.
  • Connect the SDA (I2C data) of the Pi to the M-Duino SDA.
  • Connect the SCL (I2C clock) of the Pi to the M-Duino SCL.

Make sure to check the switch on the M-duino to enable I2C. In zone A, the upper switches 3 and 4 must be in the Off position.

Software setup

If you haven't used I2C on your Raspberry Pi before, chances are the I2C communication isn't activated. To enable it, locate the "/boot/config.txt" file.

Open this file using sudo, locate the line #dtparam=i2c_arm=on and delete the leading '#' to uncomment it.

Then, reboot your Pi, and I2C will be enabled unless you re-comment the I2C line in the config file.

Installing WiringPi library

If you have to install the WiringPi library run the following commands:

  • sudo apt-get purge wiringpi
  • git clone --branch final_official_2.50 https://github.com/WiringPi/WiringPi.git ~/wiringpi
  • cd ~/wiringPi
  • ./build

If you’re using Raspberry Pi 4B, the following gpio readall command might not work for you. You have to upgrade the library from version 2.50 to 2.52.

To do that, just run the following commands:

  • cd /tmp
  • wget https://project-downloads.drogon.net/wiringpi-latest.deb
  • sudo dpkg -i wiringpi-latest.deb

Now, in order to use WiringPi in your Cpp code you need to know 2 things:

  • In your Cpp programs, add the <wiringPi.h> header.
  • When compiling, add -lwiringPi to the g++ parameters so it will find and link your program to the WiringPi library.

Detection of I2C bus

To check that Raspberry Pi PLC can detect M-Duino PLC on the I2C bus, you can do it with i2cdetect command.

To install it you might run the following commands:

  • sudo apt update
  • sudo apt install i2c-tools

After the installation is finished, you can use the i2cdetect command to detect I2C devices connected to your Raspberry Pi. For example, to scan the default I2C bus (bus number 1), you can run:

  • sudo i2cdetect -y 1

You have to check if it detects a device on the 0x08 address.

$ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- 08 -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --

If you want to detect the I2C devices with Arduino IDE, you can take a look on this blog post.

Master and slave programs

After executing both programs you have to receive on the raspberry the same data you send, so in the screen you will see:

I2C communication successfully setup.
Sent data: 17
Data received: 17
Success!

M-duino I2C slave program

You have to upload the code on the Arduino IDE platform.

#include <Wire.h>

#define SLAVE_ADDRESS 0x08

byte data_to_echo = 0;

void setup() {
  Wire.begin(SLAVE_ADDRESS);
  Wire.onReceive(receiveData);
  Wire.onRequest(sendData);
}

void loop() { }

void receiveData(int bytecount) {
  for (int i = 0; i < bytecount; i++) {
    data_to_echo = Wire.read();
  }
}

void sendData() {
  Wire.write(data_to_echo);
}

The Arduino is now configured as an I2C slave and its device ID is 8.

Raspberry I2C master program

You have to download the following code in a file called rpi_i2c_test.cpp.

#include <iostream>
#include <wiringPiI2C.h>

#define DEVICE_ID 0x08

int main (int argc, char **argv)
{
    // Setup I2C communication
    int fd = wiringPiI2CSetup(DEVICE_ID);
    if (fd == -1) {
        std::cout << "Failed to init I2C communication.\n";
        return -1;
    }
    std::cout << "I2C communication successfully setup.\n";

    // Send data to arduino
    uint8_t data_to_send = 17;
    wiringPiI2CWrite(fd, data_to_send);
    std::cout << "Sent data: " << (int)data_to_send << "\n";

    // Read data from arduino
    int received_data = wiringPiI2CRead(fd);
    std::cout << "Data received: " << received_data << "\n";

    if (received_data == data_to_send) {
        std::cout << "Success!\n";
    }
    return 0;
}

You have to execute the code using those commands: 

  • g++ -o rpi_i2c rpi_i2c_test.cpp -lwiringPi 
  • ./rpi_i2c

​Search in our Blog

Interfacing Raspberry Pi and M-Duino via I2C communication
Boot & Work Corp. S.L., Queralt del Águila Munté February 12, 2024
Share this post

Looking for your ideal Programmable Logic Controller?

Take a look at this product comparison with other industrial controllers Arduino-based. 

We are comparing inputs, outputs, communications and other features with the ones of the relevant brands.


Industrial PLC comparison >>>