Introduction
This tutorial will guide you through setting up I2C communication between a master and a slave device using a CONTROLLINO PLC. The master device reads analog and digital inputs and sends this data to the slave, while the slave responds with data that controls the outputs on the master.
Prerequisites
- Installed Arduino IDE.
- CONTROLLINO PLC board (e.g., MINI, MAXI, or MEGA).
- Basic understanding of I2C communication and pin setup.
I2C Connection example
This example of connection is based on the Controllino Mega but I2C connections for Maxi and Mini uses the same pins of the same X1 connector.
Example Code
Please grab the following example .ino file from Github:
Step-by-Step Guide
Step 1: Setup the Arduino Environment
- Connect your CONTROLLINO board to your computer.
- Open the Arduino IDE.
- Ensure that the appropriate CONTROLLINO board and port are selected in the Tools menu.
- Include the Wire and Controllino libraries in your project.
Step 2: Initialize I2C Communication and Serial Debugging
- In the
setup()
function, initialize the I2C communication by callingWire.begin()
. This sets up the CONTROLLINO device as a master. - Initialize serial communication for debugging purposes using
Serial.begin(9600)
.
Step 3: Configure Digital and Analog Pins
- Set up the digital pins:
- The first 5 digital pins (
CONTROLLINO_D0
toCONTROLLINO_D4
) are configured as inputs. - The corresponding relay pins (
CONTROLLINO_R0
toCONTROLLINO_R4
) are set as outputs.
- The first 5 digital pins (
- Set up the analog pins:
- The next 2 analog input pins (
CONTROLLINO_A0
andCONTROLLINO_A1
) are configured as inputs. - The same pins will also serve as PWM outputs, configured as outputs.
- The next 2 analog input pins (
Step 4: Sending Analog and Digital Inputs to the Slave
- In the
loop()
function, start communication with the slave by callingWire.beginTransmission(slaveAddress)
. - Read the values from the analog input pins and split each 10-bit value into two bytes. Send these bytes to the slave using
Wire.write()
. - Read the states of the digital input pins, and store them in a single byte using bitwise operations. Send this byte to the slave.
Step 5: Receiving Data from the Slave
- After ending the transmission with
Wire.endTransmission()
, request data from the slave by callingWire.requestFrom(slaveAddress, 5)
. - Once data is available, read the byte that contains the digital output states and update the output pins accordingly.
- For analog data, combine the two bytes received into a single integer, and use this value to set the PWM outputs on the master.
Step 6: Control Digital Outputs Based on Slave Data
- Use the byte received from the slave to set the states of the digital output pins (
CONTROLLINO_R0
toCONTROLLINO_R4
). - Each bit in the byte represents the state of one output pin, and the
digitalWrite()
function is used to control these pins.
Certainly! Here’s an expanded explanation with more details on how the slave code works and its interaction with the master:
Step 7: Set Up the Slave Address and Digital/Analog Pins
In the slave code, the device is initialized with a specific I2C address using Wire.begin(8)
. This address must match the address used in the master code for communication to work.
The digital and analog pins on the slave are then configured:
- The first 5 digital pins are set as inputs and outputs, similar to the master.
- The next 2 pins are designated as PWM outputs (for receiving analog data from the master) and as analog inputs (for sending data back to the master).
This ensures that both the master and slave are working with the same configuration, which is essential for seamless data exchange.
Step 8: Handling Data Received from the Master
The receiveEvent()
function in the slave code is triggered whenever the master sends data to the slave. This function:
- Reads the analog values sent by the master, reconstructing each value from two bytes.
- Writes the reconstructed analog values to the designated PWM output pins on the slave, enabling the master to control the analog output on the slave remotely.
- Reads the byte representing the digital output states, where each bit corresponds to the state of one digital output pin.
The slave then uses digitalWrite()
to set its digital output pins based on the master’s instructions, allowing the master to control these outputs directly.
Step 9: Responding to the Master’s Data Request
When the master requests data from the slave, the requestEvent()
function on the slave is executed:
- The analog inputs are read, its value is splited into two bytes for transmission.
- The combined digital input states are read and stored in a single byte, with each bit representing one digital input.
The slave then sends these values back to the master via Wire.write()
, allowing the master to read the current state of the slave’s inputs and use this data in its control logic.
Step 10: Synchronizing Data Between Master and Slave
The master and slave continuously communicate over I2C to maintain synchronization:
- The master sends analog values to control the PWM outputs on the slave.
- The master also sends digital states to control specific digital outputs on the slave.
- The slave responds with its own digital and analog input states, enabling the master to monitor and react to the slave’s environment.
This bidirectional data flow ensures the master can dynamically control and respond to the conditions on the slave, creating a cohesive system where both devices operate in harmony.
Troubleshooting
- Ensure the I2C address of the slave matches the value set in
slaveAddress
. - Check the wiring between the master and slave, ensuring the I2C SDA and SCL lines are connected properly.
- Verify the CONTROLLINO board and port are correctly selected in the Arduino IDE.
Conclusion
You have now successfully established I2C communication between a CONTROLLINO master and slave. By reading analog and digital inputs on the master and controlling its outputs based on data received from the slave, this setup enables synchronized control between two devices. Experiment with different pin configurations and data handling to expand your project!