Sure! Here's a detailed README for the `bang_bang_temperature_control_relay` example, which highlights the specifics of using the `AutoPID` library for controlling a relay. --- # Bang-Bang Temperature Control Relay Example This example demonstrates how to use the `AutoPID` library to implement a bang-bang control algorithm for a heating element, controlled via a relay. The example showcases the features of the `AutoPIDRelay` class, which is specifically designed for relay control applications. ## Features - **Bang-Bang Control**: Implements a simple on/off control strategy for maintaining temperature within a specified range. - **Simulated Temperature Input**: Uses a random temperature value near the setpoint for testing purposes. - **Relay Control**: Uses a relay to control a heating element based on the temperature. ## Prerequisites - **ESP-IDF**: Ensure you have the ESP-IDF environment set up. Follow the official [ESP-IDF Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/index.html) if needed. - **Hardware**: ESP32 development board, a relay module, and an LED for indication. ## Hardware Setup - **Relay Pin**: Connect the relay control pin to GPIO 5 of the ESP32. - **LED Pin**: Connect an LED to GPIO 6 of the ESP32 to indicate when the system is at the setpoint. ## Code Overview ### Main Components 1. **GPIO Initialization**: - Initializes GPIO pins for the relay and LED. 2. **Temperature Simulation**: - Simulates temperature readings with random values near the setpoint. 3. **Bang-Bang Control with `AutoPIDRelay`**: - Uses the `AutoPIDRelay` class to control the relay output. - Configures bang-bang control thresholds and time steps. ### Key Points - **Using `AutoPIDRelay`**: For relay control applications, you should use the `AutoPIDRelay` class instead of the `AutoPID` class. This class is specifically designed to handle relay states efficiently. - **Setting Parameters**: The `AutoPIDRelay` constructor requires parameters for input, setpoint, relay state, pulse width, and PID gains. ## Code ### main.cpp ```cpp #include <stdio.h> #include <stdlib.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" #include "esp_timer.h" #include "esp_log.h" #include "AutoPID-for-ESP-IDF.h" // Logging tag #define TAG "AutoPID_Example" // Pins #define RELAY_PIN GPIO_NUM_5 // GPIO pin for the relay #define LED_PIN GPIO_NUM_6 // GPIO pin for the LED #define TEMP_READ_DELAY 800 // can only update temperature every ~800ms // PID settings #define OUTPUT_MIN 0 #define OUTPUT_MAX 1 // Setpoint temperature (user can set this value) #define SETPOINT_TEMPERATURE 30.0 // Simulate an initial temperature reading double temperature = 25.0; // Starting temperature double setPoint = SETPOINT_TEMPERATURE; uint64_t lastTempUpdate; // Tracks clock time of last temperature update // Function to initialize GPIO for relay and LED void init_gpio() { esp_rom_gpio_pad_select_gpio(RELAY_PIN); gpio_set_direction(RELAY_PIN, GPIO_MODE_OUTPUT); esp_rom_gpio_pad_select_gpio(LED_PIN); gpio_set_direction(LED_PIN, GPIO_MODE_OUTPUT); } // Function to update the temperature reading with a simulated random value near the setpoint bool updateTemperature() { uint64_t now = esp_timer_get_time() / 1000; // Convert to milliseconds if ((now - lastTempUpdate) > TEMP_READ_DELAY) { // Simulate temperature reading: random value within +-5 degrees of the setpoint temperature = setPoint + (rand() % 1000) / 100.0 - 5.0; lastTempUpdate = now; return true; } return false; } extern "C" void app_main() { // Seed the random number generator srand((unsigned int)esp_timer_get_time()); init_gpio(); bool relayState; float KP = 0.12; // Proportional gain float KI = 0.0003; // Integral gain float KD = 0; // Derivative gain AutoPIDRelay myPID(&temperature, &setPoint, &relayState, 4000, KP, KI, KD); // Create an AutoPIDRelay object myPID.setBangBang(4); // Set bang-bang control thresholds while (true) { updateTemperature(); // Update the temperature with a simulated value myPID.run(); // Call every loop, updates automatically at the set time interval gpio_set_level(RELAY_PIN, relayState); // Control the relay based on PID output gpio_set_level(LED_PIN, myPID.atSetPoint(1)); // Light up LED when at setpoint +-1 degree ESP_LOGI(TAG, "Temperature: %.2f, SetPoint: %.2f, Relay State: %d", temperature, setPoint, relayState); // Log the values vTaskDelay(pdMS_TO_TICKS(100)); // Delay for a short period } } ``` 1. **Initialization**: - The `init_gpio()` function sets up the GPIO pins for the relay and the LED. 2. **Temperature Simulation**: - The `updateTemperature()` function generates random temperature values near the setpoint to simulate real sensor data. 3. **Bang-Bang Control**: - The `AutoPIDRelay` object is initialized with pointers to the temperature, setpoint, relay state, pulse width, and PID gains. - The `setBangBang()` method sets the thresholds for the bang-bang control. - The `run()` method updates the relay state based on the temperature. 4. **Logging**: - Logs the temperature, setpoint, and relay state for monitoring and debugging. ### Conclusion This example demonstrates how to use the `AutoPIDRelay` class for relay control in a bang-bang temperature control system. It highlights the simplicity and effectiveness of the `AutoPID` library for various control applications. By using `AutoPIDRelay`, you can efficiently manage relay states and implement robust control systems with minimal code.
To create a project from this example, run:
idf.py create-project-from-example "hayschan/autopid_for_esp_idf^1.0.2:temperature_control_relay"