Code:
/*
Made by KinCony IoT: https://www.kincony.com
Program functionality:
This program uses ESP32-S3 to read inputs from two PCA9555 I/O expander chips (I2C addresses 0x24 and 0x25)
for channels 1-32, and control corresponding relays using two PCA9555 I/O expander chips (I2C addresses 0x21 and 0x22)
for controlling 32 relays (1-32). When input1 is triggered, relay1 is activated; when input2 is triggered,
relay2 is activated, and so on.
The I2C bus is initialized on GPIO pins 11 (SDA) and 10 (SCL) with a frequency of 100kHz.
*/
#include <PCA95x5.h>
#include <Wire.h>
// Initialize the PCA9555 objects for reading inputs (channels 1-32)
PCA9555 input_ioex1; // For channels 1-16 (I2C address 0x24)
PCA9555 input_ioex2; // For channels 17-32 (I2C address 0x25)
// Initialize the PCA9555 objects for controlling relays (channels 1-32)
PCA9555 output_ioex1; // For relays 1-16 (I2C address 0x21)
PCA9555 output_ioex2; // For relays 17-32 (I2C address 0x22)
void setup() {
// Start serial communication for debugging
Serial.begin(115200);
delay(10);
// Initialize the I2C bus with GPIO 11 as SDA and GPIO 10 as SCL, 100kHz frequency
Wire.begin(11, 10, 100000);
// Configure the input PCA9555 chips (for inputs 1-32)
input_ioex1.attach(Wire, 0x24); // I2C address 0x24 for inputs 1-16
input_ioex1.polarity(PCA95x5::Polarity::ORIGINAL_ALL); // No polarity inversion
input_ioex1.direction(PCA95x5::Direction::IN_ALL); // Set all pins as inputs
input_ioex2.attach(Wire, 0x25); // I2C address 0x25 for inputs 17-32
input_ioex2.polarity(PCA95x5::Polarity::ORIGINAL_ALL); // No polarity inversion
input_ioex2.direction(PCA95x5::Direction::IN_ALL); // Set all pins as inputs
// Configure the output PCA9555 chips (for relays 1-32)
output_ioex1.attach(Wire, 0x21); // I2C address 0x21 for relays 1-16
output_ioex1.polarity(PCA95x5::Polarity::ORIGINAL_ALL); // No polarity inversion
output_ioex1.direction(PCA95x5::Direction::OUT_ALL); // Set all pins as outputs
output_ioex1.write(PCA95x5::Level::H_ALL); // Initialize all relays to OFF (HIGH)
output_ioex2.attach(Wire, 0x22); // I2C address 0x22 for relays 17-32
output_ioex2.polarity(PCA95x5::Polarity::ORIGINAL_ALL); // No polarity inversion
output_ioex2.direction(PCA95x5::Direction::OUT_ALL); // Set all pins as outputs
output_ioex2.write(PCA95x5::Level::H_ALL); // Initialize all relays to OFF (HIGH)
delay(50); // Wait for initialization to complete
}
void loop() {
// Read the input states from the first PCA9555 chip (inputs 1-16)
uint16_t inputs_1_16 = input_ioex1.read();
// Iterate through each input (1-16) and control corresponding relay output
for (int i = 0; i < 16; ++i) {
bool input_state = bitRead(inputs_1_16, i); // Read the state of each input (0 = triggered, 1 = not triggered)
if (input_state == 0) { // If the input is triggered (pressed, i.e., LOW)
output_ioex1.write((PCA95x5::Port::Port)i, PCA95x5::Level::L); // Activate corresponding relay (LOW)
} else {
output_ioex1.write((PCA95x5::Port::Port)i, PCA95x5::Level::H); // Deactivate relay (HIGH)
}
}
// Read the input states from the second PCA9555 chip (inputs 17-32)
uint16_t inputs_17_32 = input_ioex2.read();
// Iterate through each input (17-32) and control corresponding relay output
for (int i = 0; i < 16; ++i) {
bool input_state = bitRead(inputs_17_32, i); // Read the state of each input (0 = triggered, 1 = not triggered)
if (input_state == 0) { // If the input is triggered (pressed, i.e., LOW)
output_ioex2.write((PCA95x5::Port::Port)i, PCA95x5::Level::L); // Activate corresponding relay (LOW)
} else {
output_ioex2.write((PCA95x5::Port::Port)i, PCA95x5::Level::H); // Deactivate relay (HIGH)
}
}
delay(100); // Small delay for stability
}
arduino ino file download: