Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[ESP-IDF code examples for A32 Pro]-01 Turn ON/OFF relay
#1
Code:
/*
* Made by KinCony IoT: https://www.kincony.com
*
* This program controls two PCA9555 I/O expander chips via I2C to control a total of 32 relays.
* The first PCA9555 (at I2C address 0x21) controls relays 1-16, while the second PCA9555 (at I2C address 0x22)
* controls relays 17-32. The relays are turned ON (LOW) and OFF (HIGH) in sequence.
*
* Each PCA9555 chip has two ports: port 0 controls relays 1-8 (or 17-24), and port 1 controls relays 9-16 (or 25-32).
*
* The program will initialize both chips and turn all relays OFF initially, then turn each relay ON one by one.
* After a delay, all relays are turned OFF again.
*/

#include <stdio.h>
#include <string.h>
#include "driver/i2c.h"
#include "esp_log.h"

// I2C communication settings
#define I2C_MASTER_SCL_IO           10    // GPIO number for I2C clock line (SCL)
#define I2C_MASTER_SDA_IO           11    // GPIO number for I2C data line (SDA)
#define I2C_MASTER_FREQ_HZ          100000 // Frequency for I2C clock (100kHz)
#define I2C_MASTER_PORT             I2C_NUM_0 // I2C port number used in this program

// I2C write/read settings
#define WRITE_BIT                   I2C_MASTER_WRITE // I2C write mode
#define READ_BIT                    I2C_MASTER_READ  // I2C read mode
#define ACK_CHECK_EN                0x1     // Enable I2C ACK checking
#define ACK_CHECK_DIS               0x0     // Disable I2C ACK checking
#define ACK_VAL                     0x0     // I2C ACK value
#define NACK_VAL                    0x1     // I2C NACK value

// PCA9555 I2C addresses (chip 1: controls relays 1-16, chip 2: controls relays 17-32)
#define PCA9555_ADDR_1              0x21    // I2C address for the first PCA9555 (1-16 relays)
#define PCA9555_ADDR_2              0x22    // I2C address for the second PCA9555 (17-32 relays)

// PCA9555 Register addresses
#define PCA9555_REG_OUTPUT_0        0x02    // Output register for port 0 (controls relays 1-8 or 17-24)
#define PCA9555_REG_OUTPUT_1        0x03    // Output register for port 1 (controls relays 9-16 or 25-32)

// Function declarations (prototypes)
esp_err_t i2c_master_init(); // Initializes the I2C master
esp_err_t pca9555_write_byte(uint8_t device_addr, uint8_t reg_addr, uint8_t data); // Writes a byte to a PCA9555 register
void control_relays(); // Main function to control the relays

// Main application entry point
void app_main() {
    // Initialize I2C master interface
    ESP_ERROR_CHECK(i2c_master_init());

    // Set both PCA9555 chips' all pins as output and turn all relays OFF initially (0xFF = all HIGH = OFF)
    ESP_ERROR_CHECK(pca9555_write_byte(PCA9555_ADDR_1, PCA9555_REG_OUTPUT_0, 0xFF)); // Turn off relays 1-8
    ESP_ERROR_CHECK(pca9555_write_byte(PCA9555_ADDR_1, PCA9555_REG_OUTPUT_1, 0xFF)); // Turn off relays 9-16
    ESP_ERROR_CHECK(pca9555_write_byte(PCA9555_ADDR_2, PCA9555_REG_OUTPUT_0, 0xFF)); // Turn off relays 17-24
    ESP_ERROR_CHECK(pca9555_write_byte(PCA9555_ADDR_2, PCA9555_REG_OUTPUT_1, 0xFF)); // Turn off relays 25-32

    // Start controlling relays (turn on one by one, then off)
    control_relays();
}

// Function to initialize the I2C master
esp_err_t i2c_master_init() {
    // I2C configuration structure
    i2c_config_t conf = {
        .mode = I2C_MODE_MASTER,       // Set the I2C mode to master
        .sda_io_num = I2C_MASTER_SDA_IO, // Set the SDA GPIO pin
        .scl_io_num = I2C_MASTER_SCL_IO, // Set the SCL GPIO pin
        .sda_pullup_en = GPIO_PULLUP_ENABLE, // Enable internal pull-up for SDA line
        .scl_pullup_en = GPIO_PULLUP_ENABLE, // Enable internal pull-up for SCL line
        .master.clk_speed = I2C_MASTER_FREQ_HZ, // Set I2C clock frequency to 100kHz
    };
    // Apply I2C configuration to I2C master port
    i2c_param_config(I2C_MASTER_PORT, &conf);
    // Install the I2C driver for the master port
    return i2c_driver_install(I2C_MASTER_PORT, conf.mode, 0, 0, 0);
}

// Function to write a byte of data to a specified register of the PCA9555
// device_addr: I2C address of the PCA9555 chip (0x21 or 0x22)
// reg_addr: Register address to write to (e.g., output register 0 or 1)
// data: The byte of data to write (e.g., relay states: HIGH = OFF, LOW = ON)
esp_err_t pca9555_write_byte(uint8_t device_addr, uint8_t reg_addr, uint8_t data) {
    // Create a new I2C command link
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    // Start the I2C communication
    i2c_master_start(cmd);
    // Send the PCA9555's I2C address with the write bit
    i2c_master_write_byte(cmd, (device_addr << 1) | WRITE_BIT, ACK_CHECK_EN);
    // Send the register address where the data should be written
    i2c_master_write_byte(cmd, reg_addr, ACK_CHECK_EN);
    // Send the actual data to be written to the register
    i2c_master_write_byte(cmd, data, ACK_CHECK_EN);
    // Stop the I2C communication
    i2c_master_stop(cmd);
    // Execute the I2C command and return the result
    esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_PORT, cmd, 1000 / portTICK_PERIOD_MS);
    // Delete the I2C command link after use
    i2c_cmd_link_delete(cmd);
    return ret;
}

// Function to control the relays on both PCA9555 chips
void control_relays() {
    uint8_t relay_state_0 = 0xFE; // Relay 1 ON (LOW), others OFF (HIGH) for port 0
    uint8_t relay_state_1 = 0xFF; // All OFF (HIGH) for port 1 initially

    // Control the first PCA9555 chip (relays 1-16)
    // Port 0 controls relays 1-8
    for (int i = 0; i < 8; ++i) {
        ESP_LOGI("Relay Control", "Setting relay %d ON (chip 1, port 0)", i + 1);
        // Write relay states to port 0 of the first PCA9555 (1-8 relays)
        pca9555_write_byte(PCA9555_ADDR_1, PCA9555_REG_OUTPUT_0, relay_state_0);
        relay_state_0 = (relay_state_0 << 1) | 0x01; // Shift to the next relay
        vTaskDelay(100 / portTICK_PERIOD_MS); // Delay between relay actions
    }

    relay_state_0 = 0xFE; // Reset state for port 0, relay 9 ON

    // Port 1 controls relays 9-16
    for (int i = 0; i < 8; ++i) {
        ESP_LOGI("Relay Control", "Setting relay %d ON (chip 1, port 1)", i + 9);
        // Write relay states to port 1 of the first PCA9555 (9-16 relays)
        pca9555_write_byte(PCA9555_ADDR_1, PCA9555_REG_OUTPUT_1, relay_state_0);
        relay_state_0 = (relay_state_0 << 1) | 0x01; // Shift to the next relay
        vTaskDelay(100 / portTICK_PERIOD_MS); // Delay between relay actions
    }

    relay_state_0 = 0xFE; // Relay 17 ON (LOW), others OFF (HIGH) for port 0

    // Control the second PCA9555 chip (relays 17-32)
    // Port 0 controls relays 17-24
    for (int i = 0; i < 8; ++i) {
        ESP_LOGI("Relay Control", "Setting relay %d ON (chip 2, port 0)", i + 17);
        // Write relay states to port 0 of the second PCA9555 (17-24 relays)
        pca9555_write_byte(PCA9555_ADDR_2, PCA9555_REG_OUTPUT_0, relay_state_0);
        relay_state_0 = (relay_state_0 << 1) | 0x01; // Shift to the next relay
        vTaskDelay(100 / portTICK_PERIOD_MS); // Delay between relay actions
    }

    relay_state_0 = 0xFE; // Reset state for port 1, relay 25 ON

    // Port 1 controls relays 25-32
    for (int i = 0; i < 8; ++i) {
        ESP_LOGI("Relay Control", "Setting relay %d ON (chip 2, port 1)", i + 25);
        // Write relay states to port 1 of the second PCA9555 (25-32 relays)
        pca9555_write_byte(PCA9555_ADDR_2, PCA9555_REG_OUTPUT_1, relay_state_0);
        relay_state_0 = (relay_state_0 << 1) | 0x01; // Shift to the next relay
        vTaskDelay(100 / portTICK_PERIOD_MS); // Delay between relay actions
    }

    // After a short delay, turn all relays OFF
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    // Set all relays on both chips to OFF (HIGH)
    pca9555_write_byte(PCA9555_ADDR_1, PCA9555_REG_OUTPUT_0, 0xFF); // Turn off relays 1-8
    pca9555_write_byte(PCA9555_ADDR_1, PCA9555_REG_OUTPUT_1, 0xFF); // Turn off relays 9-16
    pca9555_write_byte(PCA9555_ADDR_2, PCA9555_REG_OUTPUT_0, 0xFF); // Turn off relays 17-24
    pca9555_write_byte(PCA9555_ADDR_2, PCA9555_REG_OUTPUT_1, 0xFF); // Turn off relays 25-32
}
   
Reply


Forum Jump:


Users browsing this thread:
1 Guest(s)