• Anonymous 6 months ago

    given I have an esp32c3 board, can you write a program that scans i2c connections and prints it out when i use the following code on the linux terminal: idf.py build flash monitor

  • Chat GPT

    Sure! Here's an example of a program that scans for I2C devices and prints their addresses. You can use this code with the ESP-IDF framework on an ESP32-C3 board.

    First, create a new project directory and navigate to it. Then, create a file named "CMakeLists.txt" in the project directory with the following content:

    cmake
    cmake_minimum_required(VERSION 3.16)

    set(PROJECT_NAME "i2c_scanner")
    set(IDF_SDKCONFIG_DEFAULTS sdkconfig.defaults)

    include($ENV{IDF_PATH}/tools/cmake/project.cmake)

    project(${PROJECT_NAME})

    Create another file named "sdkconfig.defaults" in the same directory with the following content:

    makefile
    CONFIG_ESP32C3_DEFAULT_CPU_FREQ_160=y

    Now create a "main" directory and navigate to it. Inside the "main" directory, create a file named "CMakeLists.txt" with the following content:

    cmake
    set(SOURCES "i2c_scanner_main.c")

    idf_component_register(SRCS ${SOURCES}
    INCLUDE_DIRS "")

    Finally, create a file named "i2c_scanner_main.c" in the "main" directory with the following content:

    c
    #include <stdio.h>
    #include "freertos/FreeRTOS.h"
    #include "freertos/task.h"
    #include "driver/i2c.h"
    #include "esp_log.h"

    #define I2C_MASTER_SCL_IO 22
    #define I2C_MASTER_SDA_IO 21
    #define I2C_MASTER_FREQ_HZ 100000
    #define I2C_MASTER_NUM I2C_NUM_0

    static const char *TAG = "i2c_scanner";

    void i2c_master_init() {
    i2c_config_t conf = {
    .mode = I2C_MODE_MASTER,
    .sda_io_num = I2C_MASTER_SDA_IO,
    .sda_pullup_en = GPIO_PULLUP_ENABLE,
    .scl_io_num = I2C_MASTER_SCL_IO,
    .scl_pullup_en = GPIO_PULLUP_ENABLE,
    .master.clk_speed = I2C_MASTER_FREQ_HZ
    };
    i2c_param_config(I2C_MASTER_NUM, &conf);
    i2c_driver_install(I2C_MASTER_NUM, conf.mode, 0, 0, 0);
    }

    void i2c_scanner_task(void *arg) {
    i2c_master_init();

    while (1) {
    ESP_LOGI(TAG, "Scanning I2C bus...");

    uint8_t device_found = 0;
    for (uint8_t addr = 0x08; addr < 0x78; addr++) {
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (addr << 1) | I2C_MASTER_WRITE, true);
    i2c_master_stop(cmd);

    esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 10 / portTICK_RATE_MS);
    i2c_cmd_link_delete(cmd);

    if (ret == ESP_OK) {
    ESP_LOGI(TAG, "I2C device found at address 0x%02X", addr);
    device_found++;
    }
    }

    if (!device_found) {
    ESP_LOGI(TAG, "No I2C devices found");
    }

    vTaskDelay(pdMS_TO_TICKS(5000));
    }
    }

    void app_main(void) {
    xTaskCreate(i2c_scanner_task, "i2c_scanner_task", 204

  • Anonymous

    continue

  • Chat GPT

    Apologies for the cut-off, here is the complete app_main function:

    c
    void app_main(void) {
    xTaskCreate(i2c_scanner_task, "i2c_scanner_task", 2048, NULL, 5, NULL);
    }

    This code creates a FreeRTOS task that continuously scans the I2C bus for devices. It attempts to write to each address on the bus and checks for an acknowledgment. If it receives an acknowledgment, it logs the address of the device.

    Now, you can use the idf.py command to build, flash and monitor this program:

    idf.py build flash monitor

    This command will build the program, flash it to your ESP32-C3 board, and then start a serial monitor so you can view the output from the program. You should see it log the addresses of any I2C devices that it finds on the bus.

  • Anonymous

    Given this DFRobot_LCD.cpp, can you rewrite the following code without using Arduino.h and Wire.h and instead use esp32c3 functions?

    #include
    #include
    #include
    #include
    #include

    #include "DFRobot_LCD.h"

    const uint8_t color_define[4][3] =
    {
    {255, 255, 255}, // white
    {255, 0, 0}, // red
    {0, 255, 0}, // green
    {0, 0, 255}, // blue
    };

    /*******************************public*******************************/
    DFRobot_LCD::DFRobot_LCD(uint8_t lcd_cols,uint8_t lcd_rows,uint8_t lcd_Addr,uint8_t RGB_Addr)
    {
    _lcdAddr = lcd_Addr;
    _RGBAddr = RGB_Addr;
    _cols = lcd_cols;
    _rows = lcd_rows;
    }

    void DFRobot_LCD::init()
    {
    Wire.begin();
    _showfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
    begin(_cols, _rows);
    }

    void DFRobot_LCD::clear()
    {
    command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero
    delayMicroseconds(2000); // this command takes a long time!
    }

    void DFRobot_LCD::home()
    {
    command(LCD_RETURNHOME); // set cursor position to zero
    delayMicroseconds(2000); // this command takes a long time!
    }

    void DFRobot_LCD::noDisplay()
    {
    _showcontrol &= ~LCD_DISPLAYON;
    command(LCD_DISPLAYCONTROL | _showcontrol);
    }

    void DFRobot_LCD::display() {
    _showcontrol |= LCD_DISPLAYON;
    command(LCD_DISPLAYCONTROL | _showcontrol);
    }

    void DFRobot_LCD::stopBlink()
    {
    _showcontrol &= ~LCD_BLINKON;
    command(LCD_DISPLAYCONTROL | _showcontrol);
    }
    void DFRobot_LCD::blink()
    {
    _showcontrol |= LCD_BLINKON;
    command(LCD_DISPLAYCONTROL | _showcontrol);
    }

    void DFRobot_LCD::noCursor()
    {
    _showcontrol &= ~LCD_CURSORON;
    command(LCD_DISPLAYCONTROL | _showcontrol);
    }

    void DFRobot_LCD::cursor() {
    _showcontrol |= LCD_CURSORON;
    command(LCD_DISPLAYCONTROL | _showcontrol);
    }


    void DFRobot_LCD::setRGB(uint8_t r, uint8_t g, uint8_t b)
    {
    setReg(REG_RED, r);
    setReg(REG_GREEN, g);
    setReg(REG_BLUE, b);
    }


    void DFRobot_LCD::setColor(uint8_t color)
    {
    if(color > 3)return ;
    setRGB(color_define[color][0], color_define[color][1], color_define[color][2]);
    }

    void DFRobot_LCD::blinkLED(void)
    {
    ///< blink period in seconds = ( + 1) / 24
    ///< on/off ratio = / 256
    setReg(0x07, 0x17); // blink every second
    setReg(0x06, 0x7f); // half on, half off
    }

    void DFRobot_LCD::noBlinkLED(void)
    {
    setReg(0x07, 0x00);
    setReg(0x06, 0xff);
    }

    inline size_t DFRobot_LCD::write(uint8_t value)
    {

    uint8_t data[3] = {0x40, value};
    send(data, 2);
    return 1; // assume sucess
    }

    inline void DFRobot_LCD::command(uint8_t value)
    {
    uint8_t data[3] = {0x80, value};
    send(data, 2);
    }
    void DFRobot_LCD::setBacklight(uint8_t new_val){
    if(new_val){
    blinkLED(); // turn backlight on
    }else{
    noBlinkLED(); // turn backlight off
    }
    }

    void DFRobot_LCD::load_custom_character(uint8_t char_num, uint8_t *rows){
    customSymbol(char_num, rows);
    }

    void DFRobot_LCD::printstr(const char c[]){
    ///< This function is not identical to the function used for "real" I2C displays
    ///< it's here so the user sketch doesn't have to be changed
    print(c);
    }

    /*******************************private*******************************/
    void DFRobot_LCD::begin(uint8_t cols, uint8_t lines, uint8_t dotsize)
    {
    if (lines > 1) {
    _showfunction |= LCD_2LINE;
    }
    _numlines = lines;
    _currline = 0;

    ///< for some 1 line displays you can select a 10 pixel high font
    if ((dotsize != 0) && (lines == 1)) {
    _showfunction |= LCD_5x10DOTS;
    }

    ///< SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
    ///< according to datasheet, we need at least 40ms after power rises above 2.7V
    ///< before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
    delay(50);


    ///< this is according to the hitachi HD44780 datasheet
    ///< page 45 figure 23

    ///< Send function set command sequence
    command(LCD_FUNCTIONSET | _showfunction);
    delay(5); // wait more than 4.1ms

    ///< second try
    command(LCD_FUNCTIONSET | _showfunction);
    delay(5);

    ///< third go
    command(LCD_FUNCTIONSET | _showfunction);




    ///< turn the display on with no cursor or blinking default
    _showcontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
    display();

    ///< clear it off
    clear();

    ///< Initialize to default text direction (for romance languages)
    _showmode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
    ///< set the entry mode
    command(LCD_ENTRYMODESET | _showmode);


    ///< backlight init
    setReg(REG_MODE1, 0);
    ///< set LEDs controllable by both PWM and GRPPWM registers
    setReg(REG_OUTPUT, 0xFF);
    ///< set MODE2 values
    ///< 0010 0000 -> 0x20 (DMBLNK to 1, ie blinky mode)
    setReg(REG_MODE2, 0x20);

    setColorWhite();

    }

    void DFRobot_LCD::send(uint8_t *data, uint8_t len)
    {
    Wire.beginTransmission(_lcdAddr); // transmit to device #4
    for(int i=0; i Wire.write(data[i]);
    delay(5);
    }
    Wire.endTransmission(); // stop transmitting
    }

    void DFRobot_LCD::setReg(uint8_t addr, uint8_t data)
    {
    Wire.beginTransmission(_RGBAddr); // transmit to device #4
    Wire.write(addr);
    Wire.write(data);
    Wire.endTransmission(); // stop transmitting
    }

    /************************unsupported API functions***************************/
    void DFRobot_LCD::off(){}
    void DFRobot_LCD::on(){}
    void DFRobot_LCD::setDelay (int cmdDelay,int charDelay) {}
    uint8_t DFRobot_LCD::status(){return 0;}
    uint8_t DFRobot_LCD::keypad (){return 0;}
    uint8_t DFRobot_LCD::init_bargraph(uint8_t graphtype){return 0;}
    void DFRobot_LCD::draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end){}
    void DFRobot_LCD::draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_row_end){}
    void DFRobot_LCD::setContrast(uint8_t new_val){}

  • Chat GPT

    This is a substantial rewrite and without having the specific LCD and RGB module it's a bit complex to assure correctness. However, I can get you started on how you might approach this task.

    To remove dependency on Arduino.h, you would replace the Arduino specific functions with their ESP-IDF counterparts.

    To remove the dependency on Wire.h (which is an I2C library), you would replace I2C operations with ESP-IDF I2C functions.

    As a starting point, here's how you might rewrite the init(), send() and setReg() functions:

    c
    #include "driver/i2c.h"
    #include "freertos/task.h"

    #define I2C_MASTER_SCL_IO 22
    #define I2C_MASTER_SDA_IO 21
    #define I2C_MASTER_FREQ_HZ 100000
    #define I2C_MASTER_NUM I2C_NUM_0

    // Other code ...

    void DFRobot_LCD::init()
    {
    i2c_config_t conf = {
    .mode = I2C_MODE_MASTER,
    .sda_io_num = I2C_MASTER_SDA_IO,
    .sda_pullup_en = GPIO_PULLUP_ENABLE,
    .scl_io_num = I2C_MASTER_SCL_IO,
    .scl_pullup_en = GPIO_PULLUP_ENABLE,
    .master.clk_speed = I2C_MASTER_FREQ_HZ
    };
    i2c_param_config(I2C_MASTER_NUM, &conf);
    i2c_driver_install(I2C_MASTER_NUM, conf.mode, 0, 0, 0);

    // Other initialization code...
    }

    void DFRobot_LCD::send(uint8_t *data, uint8_t len)
    {
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (_lcdAddr << 1) | I2C_MASTER_WRITE, true);
    for(int i=0; i<len; i++) {
    i2c_master_write_byte(cmd, data[i], true);
    vTaskDelay(pdMS_TO_TICKS(5));
    }
    i2c_master_stop(cmd);
    i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 10 / portTICK_RATE_MS);
    i2c_cmd_link_delete(cmd);
    }

    void DFRobot_LCD::setReg(uint8_t addr, uint8_t data)
    {
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (_RGBAddr << 1) | I2C_MASTER_WRITE, true);
    i2c_master_write_byte(cmd, addr, true);
    i2c_master_write_byte(cmd, data, true);
    i2c_master_stop(cmd);
    i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 10 / portTICK_RATE_MS);
    i2c_cmd_link_delete(cmd);
    }

    In this example, I2C is initialized in the init() function. The send() function sends data to the LCD via I2C, and the setReg() function writes a value to a register on the RGB device.

    You would need to replace other Arduino specific functions throughout the code in a similar manner.

    Please note that this is just a simple example and might not work as expected, depending on your specific hardware and its requirements. Testing and debugging on your specific hardware would be required to ensure correct operation.

  • Anonymous

    i'm having issues with my main.cpp, i'm trying to incorporate the DFRobot_LCD.cpp and DFRobot_LCD.h to create a simple program that displays the lcd screen

  • Chat GPT

    I can certainly help with that, but I would need a bit more information about the issues you are encountering. Are you receiving any specific error messages? If so, could you provide these error messages?

    However, here's a very basic example of how you might incorporate the DFRobot_LCD class into a main.cpp file:

    cpp
    #include "DFRobot_LCD.h"

    #define LCD_ADDRESS 0x27 // Your LCD I2C address
    #define RGB_ADDRESS 0x62 // Your RGB I2C address
    #define LCD_COLS 16 // Number of LCD columns
    #define LCD_ROWS 2 // Number of LCD rows

    extern "C" {
    void app_main(void);
    }

    void app_main(void) {
    // Create an instance of the LCD
    DFRobot_LCD lcd(LCD_COLS, LCD_ROWS, LCD_ADDRESS, RGB_ADDRESS);

    // Initialize the LCD
    lcd.init();

    // Print a message on the LCD
    lcd.print("Hello, World!");
    }

    In this example, app_main() is the entry point of the program. A DFRobot_LCD object is created, initialized, and used to print a message on the LCD.

    This is a very basic example and your specific usage might require more complex code. Also, please note that the I2C addresses and the number of LCD columns and rows might be different for your specific hardware, so you would need to adjust these values accordingly.

    If you're experiencing specific issues or error messages, please provide them so I can assist you more accurately.

  • Anonymous

    i want void app_main(void) function to incorpoate a xTaskCreate() from freertos/task.h

  • Chat GPT

    Sure, here's an example of how you could structure your app_main function to create a FreeRTOS task that displays a message on the LCD screen:

    cpp
    #include "DFRobot_LCD.h"
    #include "freertos/FreeRTOS.h"
    #include "freertos/task.h"

    #define LCD_ADDRESS 0x27 // Your LCD I2C address
    #define RGB_ADDRESS 0x62 // Your RGB address
    #define LCD_COLS 16 // Number of LCD columns
    #define LCD_ROWS 2 // Number of LCD rows

    DFRobot_LCD lcd(LCD_COLS, LCD_ROWS, LCD_ADDRESS, RGB_ADDRESS);

    void lcd_task(void *pvParameter) {
    lcd.init();
    lcd.print("Hello, World!");
    while(1) {
    // This task should never end.
    vTaskDelay(1000 / portTICK_RATE_MS);
    }
    }

    extern "C" {
    void app_main(void);
    }

    void app_main(void) {
    xTaskCreate(lcd_task, "LCD Task", 2048, NULL, 5, NULL);
    }

    In this example, lcd_task is a FreeRTOS task that initializes the LCD and prints a message. The app_main function creates this task with xTaskCreate.

    Note that the task function should never return, so it includes an infinite loop that delays the task. If you want the message on the LCD to change over time, you could modify the contents of this loop.

    As always, you would need to adjust the I2C addresses and the number of LCD columns and rows to match your specific hardware.

  • Anonymous

    please include DFRobot_LCD.cpp into the program,

  • Chat GPT

    Sure, but we won't be including the .cpp file directly into main.cpp. In C++, the common practice is to include the header file (.h), not the source file (.cpp). The linker will take care of linking the object files together.

    Here's an example of how you might structure your project:

    Project structure:

    lua
    /project
    |-- main
    | |-- main.cpp
    | |-- DFRobot_LCD.h
    | |-- DFRobot_LCD.cpp
    |-- CMakeLists.txt
    |-- sdkconfig
    |-- ...

    And your main.cpp file would look like this:

    cpp
    #include "freertos/FreeRTOS.h"
    #include "freertos/task.h"
    #include "DFRobot_LCD.h"

    #define LCD_ADDRESS 0x27 // Your LCD I2C address
    #define RGB_ADDRESS 0x62 // Your RGB I2C address
    #define LCD_COLS 16 // Number of LCD columns
    #define LCD_ROWS 2 // Number of LCD rows

    DFRobot_LCD lcd(LCD_COLS, LCD_ROWS, LCD_ADDRESS, RGB_ADDRESS);

    void lcd_task(void *pvParameter) {
    lcd.init();
    lcd.print("Hello, World!");
    while(1) {
    // This task should never end.
    vTaskDelay(1000 / portTICK_RATE_MS);
    }
    }

    extern "C" {
    void app_main(void);
    }

    void app_main(void) {
    xTaskCreate(lcd_task, "LCD Task", 2048, NULL, 5, NULL);
    }

    If you want to include the .cpp file directly in your main.cpp (which is not common practice and not recommended), you can use #include "DFRobot_LCD.cpp". But be aware that this can lead to multiple definition errors if the .cpp file is compiled separately as well.

    Please ensure to update the DFRobot_LCD.cpp to use ESP-IDF functions as per your earlier queries.

  • Anonymous

    can you incorporate this cpp file with the following code:
    #include "driver/i2c.h"
    #include "freertos/task.h"

    #define I2C_MASTER_SCL_IO 22
    #define I2C_MASTER_SDA_IO 21
    #define I2C_MASTER_FREQ_HZ 100000
    #define I2C_MASTER_NUM I2C_NUM_0

    // Other code ...

    void DFRobot_LCD::init()
    {
    i2c_config_t conf = {
    .mode = I2C_MODE_MASTER,
    .sda_io_num = I2C_MASTER_SDA_IO,
    .sda_pullup_en = GPIO_PULLUP_ENABLE,
    .scl_io_num = I2C_MASTER_SCL_IO,
    .scl_pullup_en = GPIO_PULLUP_ENABLE,
    .master.clk_speed = I2C_MASTER_FREQ_HZ
    };
    i2c_param_config(I2C_MASTER_NUM, &conf);
    i2c_driver_install(I2C_MASTER_NUM, conf.mode, 0, 0, 0);

    // Other initialization code...
    }

    void DFRobot_LCD::send(uint8_t *data, uint8_t len)
    {
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (_lcdAddr << 1) | I2C_MASTER_WRITE, true);
    for(int i=0; i i2c_master_write_byte(cmd, data[i], true);
    vTaskDelay(pdMS_TO_TICKS(5));
    }
    i2c_master_stop(cmd);
    i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 10 / portTICK_RATE_MS);
    i2c_cmd_link_delete(cmd);
    }

    void DFRobot_LCD::setReg(uint8_t addr, uint8_t data)
    {
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (_RGBAddr << 1) | I2C_MASTER_WRITE, true);
    i2c_master_write_byte(cmd, addr, true);
    i2c_master_write_byte(cmd, data, true);
    i2c_master_stop(cmd);
    i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 10 / portTICK_RATE_MS);
    i2c_cmd_link_delete(cmd);
    }
    from a separate .cpp file onto my main.cpp?

  • Chat GPT

    It seems you want to incorporate some I2C related code written in a separate .cpp file into your main.cpp. You can certainly do this, but the best practice is to keep the I2C related functions in the DFRobot_LCD.cpp and include the DFRobot_LCD.h in your main.cpp.

    Here is how you can incorporate the given code in your main.cpp:

    cpp
    #include "driver/i2c.h"
    #include "freertos/task.h"
    #include "DFRobot_LCD.h"

    #define I2C_MASTER_SCL_IO 22
    #define I2C_MASTER_SDA_IO 21
    #define I2C_MASTER_FREQ_HZ 100000
    #define I2C_MASTER_NUM I2C_NUM_0
    #define LCD_ADDRESS 0x27 // Your LCD I2C address
    #define RGB_ADDRESS 0x62 // Your RGB I2C address
    #define LCD_COLS 16 // Number of LCD columns
    #define LCD_ROWS 2 // Number of LCD rows

    DFRobot_LCD lcd(LCD_COLS, LCD_ROWS, LCD_ADDRESS, RGB_ADDRESS);

    void lcd_task(void *pvParameter) {
    lcd.init();
    lcd.print("Hello, World!");
    while(1) {
    // This task should never end.
    vTaskDelay(1000 / portTICK_RATE_MS);
    }

  • Anonymous

    please use the given DFRobot.cpp file using c++ function calls so my main.cpp can work with it

  • Chat GPT

    Assuming you have the modified DFRobot_LCD.cpp and DFRobot_LCD.h files in the same directory as your main.cpp, you should be able to use them directly in main.cpp. Here's how you can set up your main.cpp:

    cpp
    #include "freertos/FreeRTOS.h"
    #include "freertos/task.h"
    #include "DFRobot_LCD.h"

    #define LCD_ADDRESS 0x27 // Your LCD I2C address
    #define RGB_ADDRESS 0x62 // Your RGB I2C address
    #define LCD_COLS 16 // Number of LCD columns
    #define LCD_ROWS 2 // Number of LCD rows

    DFRobot_LCD lcd(LCD_COLS, LCD_ROWS, LCD_ADDRESS, RGB_ADDRESS);

    void lcd_task(void *pvParameter) {
    lcd.init();
    lcd.print("Hello, World!");
    while(1) {
    // This task should never end.
    vTaskDelay(1000 / portTICK_RATE_MS);
    }
    }

    extern "C" {
    void app_main(void);
    }

    void app_main(void) {
    xTaskCreate(lcd_task, "LCD Task", 2048, NULL, 5, NULL);
    }

    Make sure to update the DFRobot_LCD.cpp and DFRobot_LCD.h files with the modifications you've mentioned in previous messages, such as replacing Arduino Wire.h functions with ESP-IDF I2C functions.

    This should work with the provided task and your ESP32C3 board. The ESP-IDF environment will handle compiling and linking all the .cpp and .h files together.

  • Anonymous

    when i run idf.py build, i get the following errors from the DFRobot_LCD.h: error: expected class-name before '{' token, here is the line that gives my file an error

    class DFRobot_LCD :
    {

    public:

    //rest of the code
    }

  • Chat GPT

    The error you're seeing typically occurs when the base class in a class inheritance is not defined. But in your case, you're not using inheritance. The issue could be that the compiler doesn't recognize DFRobot_LCD as a class.

    Ensure that your DFRobot_LCD.h file is structured properly. It should have a similar structure as below:

    cpp
    #ifndef DFRobot_LCD_H
    #define DFRobot_LCD_H

    #include "driver/i2c.h"

    class DFRobot_LCD {
    public:
    DFRobot_LCD(uint8_t lcd_cols, uint8_t lcd_rows, uint8_t lcd_Addr, uint8_t RGB_Addr);
    void init();
    // Other function declarations...

    private:
    // Private function declarations...
    // Member variables...
    };

    #endif /* DFRobot_LCD_H */

    Make sure that you've defined DFRobot_LCD class in your DFRobot_LCD.h file and included this header file wherever you use DFRobot_LCD. Also, ensure that there are no syntax errors in the DFRobot_LCD.h and DFRobot_LCD.cpp files.

    If you're still having trouble, there might be an issue elsewhere in your code. Please provide the context around the error so I can help you better.

  • Anonymous

    E (279) i2c: i2c_param_config(751): i2c clock choice is invalid, please check flag and frequency
    ESP_ERROR_CHECK failed: esp_err_t 0x102 (ESP_ERR_INVALID_ARG) at 0x42007192
    0x42007192: DFRobot_LCD::init() at /home/ubuntu/esp/esp-idf/Lab_4/Lab4_2/main/DFRobot_LCD.cpp:57 (discriminator 1)

    file: "/IDF/Lab_4/Lab4_2/main/DFRobot_LCD.cpp" line 57
    func: void DFRobot_LCD::init()
    expression: i2c_param_config(I2C_PORT, &conf)

  • Chat GPT

    This error occurs when the I2C configuration parameters are not valid for the given I2C port. The I2C clock choice is considered invalid, so you need to double-check the flag and frequency settings.

    To fix this issue, please make sure the I2C frequency and other parameters are set correctly in the init() function in the DFRobot_LCD.cpp file.

    Currently, you have:

    cpp
    i2c_config_t conf = {
    .mode = I2C_MODE_MASTER,
    .sda_io_num = I2C_MASTER_SDA_IO,
    .sda_pullup_en = GPIO_PULLUP_ENABLE,
    .scl_io_num = I2C_MASTER_SCL_IO,
    .scl_pullup_en = GPIO_PULLUP_ENABLE,
    .master.clk_speed = I2C_MASTER_FREQ_HZ
    };
    i2c_param_config(I2C_MASTER_NUM, &conf);
    i2c_driver_install(I2C_MASTER_NUM, conf.mode, 0, 0, 0);

    Make sure that the I2C frequency (I2C_MASTER_FREQ_HZ)

  • Anonymous

    void DFRobot_LCD::init()
    {
    i2c_config_t conf;
    conf.mode = I2C_MODE_MASTER;
    conf.sda_io_num = I2C_MASTER_SDA_GPIO;
    conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
    conf.scl_io_num = I2C_MASTER_SCL_GPIO;
    conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
    conf.master.clk_speed = I2C_MASTER_FREQ_HZ;

    ESP_ERROR_CHECK(i2c_param_config(I2C_PORT, &conf));
    ESP_ERROR_CHECK(i2c_driver_install(I2C_PORT, conf.mode, 0, 0, 0));
    }
    I keep on getting this error:
    E (280) i2c: i2c_param_config(751): i2c clock choice is invalid, please check flag and frequency
    ESP_ERROR_CHECK failed: esp_err_t 0x102 (ESP_ERR_INVALID_ARG) at 0x4200718a
    0x4200718a: DFRobot_LCD::init() at /home/ubuntu/esp/esp-idf/Lab_4/Lab4_2/main/DFRobot_LCD.cpp:58 (discriminator 1)

    file: "/IDF/Lab_4/Lab4_2/main/DFRobot_LCD.cpp" line 58
    func: void DFRobot_LCD::init()
    expression: i2c_param_config(I2C_PORT, &conf)

  • Chat GPT

    The error message E (280) i2c: i2c_param_config(751): i2c clock choice is invalid, please check flag and frequency suggests that the frequency for I2C is not set to an acceptable value or the GPIO pins you're using are not valid.

    Your I2C master frequency is set by I2C_MASTER_FREQ_HZ. Please make sure this value is set to a valid frequency for your ESP32C3 module. The standard frequencies are usually 100kHz, 400kHz or sometimes up to 1MHz for fast mode devices.

    Also, make sure the GPIO pins (SDA and SCL) you've chosen are valid for I2C use. From your code, these are defined as I2C_MASTER_SDA_GPIO and I2C_MASTER_SCL_GPIO.

    Please check these values in your code.

    If the issue persists, please share the part of your code where these values are defined.

  • Anonymous

    E (284) i2c: i2c_param_config(751): i2c clock choice is invalid, please check flag and frequency
    ESP_ERROR_CHECK failed: esp_err_t 0x102 (ESP_ERR_INVALID_ARG) at 0x4200797e
    i still get the error when i move my SDA and SCL GPIO while also changing my clk.speed

  • Chat GPT

    The error message i2c_param_config(751): i2c clock choice is invalid means the function i2c_param_config() has returned ESP_ERR_INVALID_ARG error. This can happen due to invalid parameters passed to this function, especially clk_speed which is the frequency of the I2C clock.

    In your case, the clk_speed is set by I2C_MASTER_FREQ_HZ. Make sure that it is set to a valid value. For standard mode, it can be up to 100kHz, for fast mode it can be up to 400kHz, and for fast mode plus it can be up to 1MHz.

    Also, ensure that the GPIO pins (SDA and SCL) used are valid for I2C use on your specific ESP32 chip. Some GPIO pins are input-only, and others may have special functions that prevent them from being used as general purpose I/O.

    If you have checked these and are still facing issues, you might want to recheck the power supply to your I2C device or even consider using a different I2C device for testing purposes to rule out any hardware defects.

    If the issue persists, please share the updated part of your code where these values are defined.

  • Anonymous

    E (284) i2c: i2c_param_config(751): i2c clock choice is invalid, please check flag and frequency
    ESP_ERROR_CHECK failed: esp_err_t 0x102 (ESP_ERR_INVALID_ARG) at 0x42007986
    0x42007986: DFRobot_LCD::init() at /home/ubuntu/esp/esp-idf/Lab_4/Lab4_2/main/DFRobot_LCD.cpp:58 (discriminator 2)

    file: "/IDF/Lab_4/Lab4_2/main/DFRobot_LCD.cpp" line 58
    func: void DFRobot_LCD::init()
    expression: i2c_param_config(I2C_PORT, &conf)

    abort() was called at PC 0x40384dcf on core 0
    0x40384dcf: _esp_error_check_failed at /home/ubuntu/esp/esp-idf/components/esp_system/esp_err.c:50

    Stack dump detected
    Core 0 register dump:
    MEPC : 0x403806ea RA : 0x40384dda SP : 0x3fc91070 GP : 0x3fc8c800
    0x403806ea: panic_abort at /home/ubuntu/esp/esp-idf/components/esp_system/panic.c:451

    0x40384dda: __ubsan_include at /home/ubuntu/esp/esp-idf/components/esp_system/ubsan.c:313

    TP : 0x3fc87730 T0 : 0x37363534 T1 : 0x7271706f T2 : 0x33323130
    S0/FP : 0x00000004 S1 : 0x3fc910d4 A0 : 0x3fc9109c A1 : 0x3fc910d2
    A2 : 0x00000000 A3 : 0x3fc910c9 A4 : 0x00000001 A5 : 0x3fc8e000
    A6 : 0x7a797877 A7 : 0x76757473 S2 : 0x00000000 S3 : 0x00000000
    S4 : 0x00000000 S5 : 0x00000000 S6 : 0x00000000 S7 : 0x00000000
    S8 : 0x00000000 S9 : 0x00000000 S10 : 0x00000000 S11 : 0x00000000
    T3 : 0x6e6d6c6b T4 : 0x6a696867 T5 : 0x66656463 T6 : 0x62613938
    MSTATUS : 0x00001881 MTVEC : 0x40380001 MCAUSE : 0x00000007 MTVAL : 0x00000000
    0x40380001: _vector_table at ??:?

    MHARTID : 0x00000000

  • Chat GPT

    The error message you're getting suggests an issue with the I2C configuration. Here are a few things to check:

    1. Make sure that the I2C port you are using (which you've defined as I2C_PORT) is valid. The ESP32 supports two I2C interfaces, I2C_NUM_0 and I2C_NUM_1.

    2. Confirm that the GPIO pins you're using for SDA and SCL are valid and are not being used by another part of your code or by the ESP32 for something else.

    3. Double-check the clock speed you've set (I2C_MASTER_FREQ_HZ). It should be a valid frequency for the I2C mode you're using. For standard mode, it can be up to 100kHz, for fast mode it can be up to 400kHz, and for fast mode plus it can be up to 1MHz.

    4. Make sure that the I2C device is correctly connected and powered.

    If you've checked all of these and you're still seeing the error, it would be helpful to see the full DFRobot_LCD::init() method and the definitions of the constants you're using (like I2C_PORT and I2C_MASTER_FREQ_HZ).

  • Anonymous

    here is the function:
    void DFRobot_LCD::init()
    {
    i2c_config_t conf;
    conf.mode = I2C_MODE_MASTER;
    conf.sda_io_num = I2C_MASTER_SDA_GPIO;
    conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
    conf.scl_io_num = I2C_MASTER_SCL_GPIO;
    conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
    conf.master.clk_speed = I2C_MASTER_FREQ_HZ;

    ESP_ERROR_CHECK(i2c_param_config(I2C_PORT, &conf));
    ESP_ERROR_CHECK(i2c_driver_install(I2C_PORT, conf.mode, 0, 0, 0));
    }
    it is written in cpp

  • Chat GPT

    Thank you for providing the function. Please also provide the definitions of the constants you're using, such as I2C_PORT, I2C_MASTER_FREQ_HZ, I2C_MASTER_SDA_GPIO, and I2C_MASTER_SCL_GPIO. This information is necessary for me to help diagnose the issue.

    The constant definitions should look something like:

    cpp
    #define I2C_PORT I2C_NUM_0
    #define I2C_MASTER_FREQ_HZ 100000
    #define I2C_MASTER_SDA_GPIO 21
    #define I2C_MASTER_SCL_GPIO 22

    Please provide the values you are using for these constants, as they might be causing the error you're experiencing.

  • Anonymous

    #define I2C_PORT I2C_NUM_0 //I2C port
    #define I2C_MASTER_SDA_GPIO 10
    #define I2C_MASTER_SCL_GPIO 8
    #define I2C_MASTER_FREQ_HZ 100000

  • Chat GPT

    Thank you for providing the definitions. The I2C pins you are using (SDA_GPIO 10 and SCL_GPIO 8) might not be suitable for I2C communication on your specific board. This might be the reason why i2c_param_config() is failing.

    If you're using an ESP32 board, you should check the board's documentation to verify the recommended I2C pins.

    Alternatively, you could try using the default I2C pins, which are typically GPIO 21 for SDA and GPIO 22 for SCL.

    Please try changing the definitions like so:

    cpp
    #define I2C_MASTER_SDA_GPIO 21
    #define I2C_MASTER_SCL_GPIO 22

    And see if it solves your issue. If it doesn't, please refer to your ESP32 board's documentation to determine the correct I2C pins for your specific model.

  • Anonymous

    i am using an esp32c3 board

  • Chat GPT

    For ESP32-C3, the available GPIO pins can be different from other ESP32 models. It's essential to check your specific board's pinout and available functionalities for each pin.

    The ESP32-C3 has less GPIO pins available compared to ESP32, and not all of them can be used for I2C communication. Also, some pins might have internal pull-up or pull-down resistors or could be used by onboard devices like flash memory or UART, so they might not be suitable for I2C communication.

    If GPIO 10 and 8 are not suitable for I2C on your board, you should try using other pins. For example, you might try using GPIO 6 and 7 if they are available and not used by other onboard devices:

    cpp
    #define I2C_MASTER_SDA_GPIO 6
    #define I2C_MASTER_SCL_GPIO 7

    Please refer to your ESP32-C3 board's documentation to determine the correct and available I2C pins for your specific model. After determining the suitable pins, don't forget to connect your I2C device to these pins correctly.

    If you still encounter issues, there might be other problems like incorrect clock speed or hardware connection issues. You might need to check your I2C device's documentation to see the correct clock speed for the device, and also check your hardware connections to make sure they are correct.

  • Anonymous

    ESP-ROM:esp32c3-api1-20210207
    Build:Feb 7 2021
    rst:0x3 (RTC_SW_SYS_RST),boot:0xc (SPI_FAST_FLASH_BOOT)
    Saved PC:0x40048b82
    SPIWP:0xee
    mode:DIO, clock div:1
    load:0x3fcd5820,len:0x171c
    load:0x403cc710,len:0x974
    load:0x403ce710,len:0x2f68
    entry 0x403cc710
    I (24) boot: ESP-IDF v5.1-dev-4557-gf404fe96b1-dirty 2nd stage bootloader
    I (24) boot: compile time May 10 2023 11:32:54
    I (25) boot: chip revision: v0.4
    I (29) boot.esp32c3: SPI Speed : 80MHz
    I (34) boot.esp32c3: SPI Mode : DIO
    I (38) boot.esp32c3: SPI Flash Size : 2MB
    I (43) boot: Enabling RNG early entropy source...
    I (49) boot: Partition Table:
    I (52) boot: ## Label Usage Type ST Offset Length
    I (59) boot: 0 nvs WiFi data 01 02 00009000 00006000
    I (67) boot: 1 phy_init RF data 01 01 0000f000 00001000
    I (74) boot: 2 factory factory app 00 00 00010000 00100000
    I (82) boot: End of partition table
    I (86) esp_image: segment 0: paddr=00010020 vaddr=3c020020 size=0b158h ( 45400) map
    I (102) esp_image: segment 1: paddr=0001b180 vaddr=3fc8c000 size=01178h ( 4472) load
    I (104) esp_image: segment 2: paddr=0001c300 vaddr=40380000 size=03d18h ( 15640) load
    I (114) esp_image: segment 3: paddr=00020020 vaddr=42000020 size=1b724h (112420) map
    I (138) esp_image: segment 4: paddr=0003b74c vaddr=40383d18 size=0819ch ( 33180) load
    I (148) boot: Loaded app from partition at offset 0x10000
    I (148) boot: Disabling RNG early entropy source...
    I (159) cpu_start: Unicore app
    I (160) cpu_start: Pro cpu up.
    I (168) cpu_start: Pro cpu start user code
    I (168) cpu_start: cpu freq: 160000000 Hz
    I (168) cpu_start: Application information:
    I (171) cpu_start: Project name: Lab4_2
    I (176) cpu_start: App version: v5.1-dev-4557-gf404fe96b1-dirty
    I (183) cpu_start: Compile time: May 10 2023 11:32:51
    I (189) cpu_start: ELF file SHA256: 3daf99c5459f8b20...
    I (195) cpu_start: ESP-IDF: v5.1-dev-4557-gf404fe96b1-dirty
    I (202) cpu_start: Min chip rev: v0.3
    I (207) cpu_start: Max chip rev: v0.99
    I (212) cpu_start: Chip rev: v0.4
    I (217) heap_init: Initializing. RAM available for dynamic allocation:
    I (224) heap_init: At 3FC8E0A0 len 0004E670 (313 KiB): DRAM
    I (230) heap_init: At 3FCDC710 len 00002950 (10 KiB): STACK/DRAM
    I (237) heap_init: At 50000020 len 00001FE0 (7 KiB): RTCRAM
    I (244) spi_flash: detected chip: generic
    I (248) spi_flash: flash io: dio
    W (252) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
    I (265) sleep: Configure to isolate all GPIO pins in sleep state
    I (271) sleep: Enable automatic switching of GPIO sleep configuration
    I (279) app_start: Starting scheduler on CPU0
    I (284) main_task: Started on CPU0
    I (284) main_task: Calling app_main()
    E (284) i2c: i2c_param_config(751): i2c clock choice is invalid, please check flag and frequency
    ESP_ERROR_CHECK failed: esp_err_t 0x102 (ESP_ERR_INVALID_ARG) at 0x42007942
    0x42007942: DFRobot_LCD::init() at /home/ubuntu/esp/esp-idf/Lab_4/Lab4_2/main/DFRobot_LCD.cpp:58 (discriminator 2)

    file: "/IDF/Lab_4/Lab4_2/main/DFRobot_LCD.cpp" line 58
    func: void DFRobot_LCD::init()
    expression: i2c_param_config(I2C_PORT, &conf)

    abort() was called at PC 0x40384dcf on core 0
    0x40384dcf: _esp_error_check_failed at /home/ubuntu/esp/esp-idf/components/esp_system/esp_err.c:50

    Stack dump detected
    Core 0 register dump:
    MEPC : 0x403806ea RA : 0x40384dda SP : 0x3fc91070 GP : 0x3fc8c800
    0x403806ea: panic_abort at /home/ubuntu/esp/esp-idf/components/esp_system/panic.c:451

    0x40384dda: __ubsan_include at /home/ubuntu/esp/esp-idf/components/esp_system/ubsan.c:313

    TP : 0x3fc87738 T0 : 0x37363534 T1 : 0x7271706f T2 : 0x33323130
    S0/FP : 0x00000004 S1 : 0x3fc910d4 A0 : 0x3fc9109c A1 : 0x3fc910d2
    A2 : 0x00000000 A3 : 0x3fc910c9 A4 : 0x00000001 A5 : 0x3fc8e000
    A6 : 0x7a797877 A7 : 0x76757473 S2 : 0x00000000 S3 : 0x00000000
    S4 : 0x00000000 S5 : 0x00000000 S6 : 0x00000000 S7 : 0x00000000
    S8 : 0x00000000 S9 : 0x00000000 S10 : 0x00000000 S11 : 0x00000000
    T3 : 0x6e6d6c6b T4 : 0x6a696867 T5 : 0x66656463 T6 : 0x62613938
    MSTATUS : 0x00001881 MTVEC : 0x40380001 MCAUSE : 0x00000007 MTVAL : 0x00000000
    0x40380001: _vector_table at ??:?

    MHARTID : 0x00000000


    Backtrace:


    panic_abort (details=details@entry=0x3fc9109c "abort() was called at PC 0x40384dcf on core 0") at /home/ubuntu/esp/esp-idf/components/esp_system/panic.c:451
    451 *((volatile int *) 0) = 0; // NOLINT(clang-analyzer-core.NullDereference) should be an invalid operation on targets
    #0 panic_abort (details=details@entry=0x3fc9109c "abort() was called at PC 0x40384dcf on core 0") at /home/ubuntu/esp/esp-idf/components/esp_system/panic.c:451
    #1 0x40384dda in esp_system_abort (details=details@entry=0x3fc9109c "abort() was called at PC 0x40384dcf on core 0") at /home/ubuntu/esp/esp-idf/components/esp_system/port/esp_system_chip.c:84
    #2 0x4038a8da in abort () at /home/ubuntu/esp/esp-idf/components/newlib/abort.c:38
    #3 0x40384dd2 in _esp_error_check_failed (rc=, file=, line=, function=, expression=) at /home/ubuntu/esp/esp-idf/components/esp_system/esp_err.c:50
    #4 0x42007946 in DFRobot_LCD::init (this=this@entry=0x3fc8dd00 ) at /home/ubuntu/esp/esp-idf/Lab_4/Lab4_2/main/DFRobot_LCD.cpp:58
    #5 0x4200789c in app_main () at /home/ubuntu/esp/esp-idf/Lab_4/Lab4_2/main/Lab4_2.cpp:19
    #6 0x4201acdc in main_task (args=) at /home/ubuntu/esp/esp-idf/components/freertos/app_startup.c:208
    #7 0x40387290 in vPortTaskWrapper (pxCode=, pvParameters=) at /home/ubuntu/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c:202
    ELF file SHA256: 3daf99c5459f8b20

  • Chat GPT

    The error is related to the I2C clock speed configuration. The specific error is E (284) i2c: i2c_param_config(751): i2c clock choice is invalid, please check flag and frequency.

    The i2c_param_config function is complaining about an invalid clock choice. This usually means that the frequency you're trying to set for the I2C communication isn't supported.

    The clock speed you've defined is #define I2C_MASTER_FREQ_HZ 100000, which is 100 kHz. This is a standard I2C clock speed and should be fine, but there might be other factors at play.

    • The clock speed of the ESP32-C3's CPU may not be capable of supporting the 100kHz I2C clock speed due to a prescaler value or clock source issue. Try reducing the I2C clock speed to a lower value, like 50 kHz or even lower, to see if the error persists.

    • Make sure the I2C pins you are using support the clock speed. Some GPIO pins may have limitations on the clock speed they support.

    • Check if there are other hardware or software factors that could be affecting the clock speed. Are there other devices on the I2C bus? Is there a long wire length or other physical factors that could be affecting the signal?

    • Ensure that the I2C bus is not being used by another task or device at the time of initialization.

    • Lastly, make sure that the ESP-IDF version you're using is compatible with the ESP32-C3 and doesn't have any known bugs related to I2C.

    If you've checked all these and the issue persists, it might be worth reaching out to the manufacturer or checking forums for other potential solutions.

  • Anonymous

    here is my DFRobot_LCD.cpp:
    /*!
    * @file DFRobot_LCD.cpp
    * @brief DFRobot's LCD
    * @n High Accuracy Ambient Light Sensor
    *
    * @copyright [DFRobot](http://www.dfrobot.com), 2016
    * @copyright GNU Lesser General Public License
    *
    * @author [yangyang]([email protected])
    * @version V1.0
    * @date 2017-2-10
    */

    //#include
    #include
    #include
    #include
    //#include
    #include
    #include
    #include
    #include "DFRobot_LCD.h"

    #define I2C_PORT I2C_NUM_0 //I2C port
    #define I2C_MASTER_SDA_GPIO 10
    #define I2C_MASTER_SCL_GPIO 8
    #define I2C_MASTER_FREQ_HZ 50000



    const uint8_t color_define[4][3] =
    {
    {255, 255, 255}, // white
    {255, 0, 0}, // red
    {0, 255, 0}, // green
    {0, 0, 255}, // blue
    };


    /*******************************public*******************************/
    DFRobot_LCD::DFRobot_LCD(uint8_t lcd_cols,uint8_t lcd_rows,uint8_t lcd_Addr,uint8_t RGB_Addr)
    {
    _lcdAddr = lcd_Addr;
    _RGBAddr = RGB_Addr;
    _cols = lcd_cols;
    _rows = lcd_rows;
    }
    void DFRobot_LCD::init()
    {
    i2c_config_t conf;
    conf.mode = I2C_MODE_MASTER;
    conf.sda_io_num = I2C_MASTER_SDA_GPIO;
    conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
    conf.scl_io_num = I2C_MASTER_SCL_GPIO;
    conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
    conf.master.clk_speed = I2C_MASTER_FREQ_HZ;

    ESP_ERROR_CHECK(i2c_param_config(I2C_PORT, &conf));
    ESP_ERROR_CHECK(i2c_driver_install(I2C_PORT, conf.mode, 0, 0, 0));
    }

    void DFRobot_LCD::clear()
    {
    command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero
    vTaskDelay(pdMS_TO_TICKS(2)); // this command takes a long time!
    }

    void DFRobot_LCD::home()
    {
    command(LCD_RETURNHOME); // set cursor position to zero
    vTaskDelay(pdMS_TO_TICKS(2)); // this command takes a long time!
    }

    void DFRobot_LCD::noDisplay()
    {
    _showcontrol &= ~LCD_DISPLAYON;
    command(LCD_DISPLAYCONTROL | _showcontrol);
    }

    void DFRobot_LCD::display() {
    _showcontrol |= LCD_DISPLAYON;
    command(LCD_DISPLAYCONTROL | _showcontrol);
    }

    void DFRobot_LCD::stopBlink()
    {
    _showcontrol &= ~LCD_BLINKON;
    command(LCD_DISPLAYCONTROL | _showcontrol);
    }
    void DFRobot_LCD::blink()
    {
    _showcontrol |= LCD_BLINKON;
    command(LCD_DISPLAYCONTROL | _showcontrol);
    }

    void DFRobot_LCD::noCursor()
    {
    _showcontrol &= ~LCD_CURSORON;
    command(LCD_DISPLAYCONTROL | _showcontrol);
    }

    void DFRobot_LCD::cursor() {
    _showcontrol |= LCD_CURSORON;
    command(LCD_DISPLAYCONTROL | _showcontrol);
    }

    void DFRobot_LCD::scrollDisplayLeft(void)
    {
    command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
    }

    void DFRobot_LCD::scrollDisplayRight(void)
    {
    command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
    }

    void DFRobot_LCD::leftToRight(void)
    {
    _showmode |= LCD_ENTRYLEFT;
    command(LCD_ENTRYMODESET | _showmode);
    }

    void DFRobot_LCD::rightToLeft(void)
    {
    _showmode &= ~LCD_ENTRYLEFT;
    command(LCD_ENTRYMODESET | _showmode);
    }

    void DFRobot_LCD::noAutoscroll(void)
    {
    _showmode &= ~LCD_ENTRYSHIFTINCREMENT;
    command(LCD_ENTRYMODESET | _showmode);
    }

    void DFRobot_LCD::autoscroll(void)
    {
    _showmode |= LCD_ENTRYSHIFTINCREMENT;
    command(LCD_ENTRYMODESET | _showmode);
    }

    void DFRobot_LCD::customSymbol(uint8_t location, uint8_t charmap[])
    {

    location &= 0x7; // we only have 8 locations 0-7
    command(LCD_SETCGRAMADDR | (location << 3));


    uint8_t data[9];
    data[0] = 0x40;
    for(int i=0; i<8; i++)
    {
    data[i+1] = charmap[i];
    }
    send(data, 9);
    }

    void DFRobot_LCD::setCursor(uint8_t col, uint8_t row)
    {

    col = (row == 0 ? col|0x80 : col|0xc0);
    uint8_t data[3] = {0x80, col};

    send(data, 2);

    }

    void DFRobot_LCD::setRGB(uint8_t r, uint8_t g, uint8_t b)
    {
    setReg(REG_RED, r);
    setReg(REG_GREEN, g);
    setReg(REG_BLUE, b);
    }


    void DFRobot_LCD::setColor(uint8_t color)
    {
    if(color > 3)return ;
    setRGB(color_define[color][0], color_define[color][1], color_define[color][2]);
    }

    void DFRobot_LCD::blinkLED(void)
    {
    ///< blink period in seconds = ( + 1) / 24
    ///< on/off ratio = / 256
    setReg(0x07, 0x17); // blink every second
    setReg(0x06, 0x7f); // half on, half off
    }

    void DFRobot_LCD::noBlinkLED(void)
    {
    setReg(0x07, 0x00);
    setReg(0x06, 0xff);
    }

    inline size_t DFRobot_LCD::write(uint8_t value)
    {

    uint8_t data[3] = {0x40, value};
    send(data, 2);
    return 1; // assume sucess
    }

    inline void DFRobot_LCD::command(uint8_t value)
    {
    uint8_t data[3] = {0x80, value};
    send(data, 2);
    }

    void DFRobot_LCD::blink_on(){
    blink();
    }

    void DFRobot_LCD::blink_off(){
    stopBlink();
    }

    void DFRobot_LCD::cursor_on(){
    cursor();
    }

    void DFRobot_LCD::cursor_off(){
    noCursor();
    }

    void DFRobot_LCD::setBacklight(uint8_t new_val){
    if(new_val){
    blinkLED(); // turn backlight on
    }else{
    noBlinkLED(); // turn backlight off
    }
    }

    void DFRobot_LCD::load_custom_character(uint8_t char_num, uint8_t *rows){
    customSymbol(char_num, rows);
    }

    void DFRobot_LCD::printstr(const char c[]){
    ///< This function is not identical to the function used for "real" I2C displays
    ///< it's here so the user sketch doesn't have to be changed
    printf("%s", c);
    }

    /*******************************private*******************************/
    void DFRobot_LCD::begin(uint8_t cols, uint8_t lines, uint8_t dotsize)
    {
    if (lines > 1) {
    _showfunction |= LCD_2LINE;
    }
    _numlines = lines;
    _currline = 0;

    ///< for some 1 line displays you can select a 10 pixel high font
    if ((dotsize != 0) && (lines == 1)) {
    _showfunction |= LCD_5x10DOTS;
    }

    ///< SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
    ///< according to datasheet, we need at least 40ms after power rises above 2.7V
    ///< before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
    vTaskDelay(pdMS_TO_TICKS(50));


    ///< this is according to the hitachi HD44780 datasheet
    ///< page 45 figure 23

    ///< Send function set command sequence
    command(LCD_FUNCTIONSET | _showfunction);
    vTaskDelay(pdMS_TO_TICKS(50)); // wait more than 4.1ms

    ///< second try
    command(LCD_FUNCTIONSET | _showfunction);
    vTaskDelay(pdMS_TO_TICKS(50));

    ///< third go
    command(LCD_FUNCTIONSET | _showfunction);




    ///< turn the display on with no cursor or blinking default
    _showcontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
    display();

    ///< clear it off
    clear();

    ///< Initialize to default text direction (for romance languages)
    _showmode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
    ///< set the entry mode
    command(LCD_ENTRYMODESET | _showmode);


    ///< backlight init
    setReg(REG_MODE1, 0);
    ///< set LEDs controllable by both PWM and GRPPWM registers
    setReg(REG_OUTPUT, 0xFF);
    ///< set MODE2 values
    ///< 0010 0000 -> 0x20 (DMBLNK to 1, ie blinky mode)
    setReg(REG_MODE2, 0x20);

    setColorWhite();

    }

    void DFRobot_LCD::send(uint8_t *data, uint8_t len)
    {
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (_lcdAddr << 1) | I2C_MASTER_WRITE, true);
    for (int i = 0; i < len; i++) {
    i2c_master_write_byte(cmd, data[i], true);
    vTaskDelay(5 / portTICK_PERIOD_MS);
    }
    i2c_master_stop(cmd);
    i2c_master_cmd_begin(I2C_PORT, cmd, 10);
    i2c_cmd_link_delete(cmd);
    }

    void DFRobot_LCD::setReg(uint8_t addr, uint8_t data)
    {
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (_RGBAddr << 1) | I2C_MASTER_WRITE, true);
    i2c_master_write_byte(cmd, addr, true);
    i2c_master_write_byte(cmd, data, true);
    i2c_master_stop(cmd);
    i2c_master_cmd_begin(I2C_PORT, cmd, 10);
    i2c_cmd_link_delete(cmd);
    }


    /************************unsupported API functions***************************/
    void DFRobot_LCD::off(){}
    void DFRobot_LCD::on(){}
    void DFRobot_LCD::setDelay (int cmdDelay,int charDelay) {}
    uint8_t DFRobot_LCD::status(){return 0;}
    uint8_t DFRobot_LCD::keypad (){return 0;}
    uint8_t DFRobot_LCD::init_bargraph(uint8_t graphtype){return 0;}
    void DFRobot_LCD::draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end){}
    void DFRobot_LCD::draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_row_end){}
    void DFRobot_LCD::setContrast(uint8_t new_val){}

    i can't get i2c_param_config past ESP_ERROR_CHECK

  • Chat GPT

    It seems like your I2C initialization is failing at i2c_param_config. This could be because of a few possible issues:

    1. Incorrect GPIO pins: Ensure that the SDA and SCL pins you have chosen (GPIO 10 and 8 in your case) are correct and available for use on your specific ESP32 board. Some pins on the ESP32 are used for specific functions or have specific characteristics, so not all pins are suitable for use as I2C pins.

    2. Incorrect I2C Mode: Your I2C mode is set to I2C_MODE_MASTER. Ensure that the device you're trying to communicate with is indeed set up to be a slave device.

    3. Interrupted I2C Bus: Make sure that nothing else is trying to use the I2C bus at the same time.

    4. Hardware issues: Check your wiring, pull-up resistors, and whether the devices you're communicating with are powered correctly.

    5. I2C Frequency: You might be running the I2C bus too quickly. Try a lower frequency.

    To debug this issue, it would be helpful to print the return value of i2c_param_config to see the specific error code. This will give you a better idea of what the problem might be. You can do this by changing your ESP_ERROR_CHECK line to something like this:

    cpp
    esp_err_t ret = i2c_param_config(I2C_PORT, &conf);
    if (ret != ESP_OK) {
    printf("i2c_param_config returned %d
    "
    , ret);
    return;
    }

    This will print the error code if i2c_param_config fails, which you can then lookup in the ESP-IDF documentation or source code to see what it means.

  • Anonymous

    I (265) sleep: Configure to isolate all GPIO pins in sleep state
    I (272) sleep: Enable automatic switching of GPIO sleep configuration
    I (279) app_start: Starting scheduler on CPU0
    I (284) main_task: Started on CPU0
    I (284) main_task: Calling app_main()
    E (284) i2c: i2c_param_config(751): i2c clock choice is invalid, please check flag and frequency
    i2c_param_config returned 258
    E (304) i2c: i2c_master_cmd_begin(1480): i2c driver not installed
    E (304) i2c: i2c_master_cmd_begin(1480): i2c driver not installed
    E (314) i2c: i2c_master_cmd_begin(1480): i2c driver not installed
    I (324) main_task: Returned from app_main()

  • Chat GPT

    The error message you're seeing - i2c clock choice is invalid, please check flag and frequency - indicates that there's a problem with the I2C clock configuration you're using.

    In your case, the frequency of the I2C bus is set to I2C_MASTER_FREQ_HZ 50000, which should be within the valid range for an I2C bus (typically between 10 kHz and 400 kHz).

    However, it's possible that the ESP32's I2C driver cannot generate a 50 kHz clock precisely due to the divider value it uses. You might try changing the frequency to 100 kHz (a common default value for I2C) and see if that resolves the issue:

    cpp
    #define I2C_MASTER_FREQ_HZ 100000

    Also, please ensure that the SDA and SCL pins you have chosen (GPIO 10 and 8 in your case) are correct and available for use on your specific ESP32 board. Some pins on the ESP

  • Anonymous

    how do i use the provided DFRobot_LCD.cpp and DFRobot_LCD.h to display "Hello World, [My Name]" on the lcd using cpp for Lab4_2.cpp (meaning main.cpp)

  • Chat GPT

    To use the provided DFRobot_LCD library to display a "Hello World, [Your Name]" on your LCD, you first need to include the DFRobot_LCD library in your main program. After that, you can create an instance of the DFRobot_LCD class and use its methods to interact with your LCD.

    Here is a simple example of how to use it in your main.cpp:

    cpp
    #include "DFRobot_LCD.h"

    // Define LCD characteristics, replace these with the actual parameters of your LCD
    #define LCD_COLS 16
    #define LCD_ROWS 2
    #define LCD_ADDRESS 0x27
    #define RGB_ADDRESS 0x62

    // Initialize LCD
    DFRobot_LCD lcd(LCD_COLS, LCD_ROWS, LCD_ADDRESS, RGB_ADDRESS);

    extern "C" void app_main()
    {
    // Initialize the LCD
    lcd.init();

    // Print "Hello World, [Your Name]" on the LCD
    lcd.setCursor(0, 0); // Set the cursor to the top-left corner
    lcd.printstr("Hello World, ");
    lcd.printstr("[Your Name]"); // Replace [Your Name] with your actual name

    // Loop indefinitely, doing nothing
    while (1) {
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
    }

    In this example, DFRobot_LCD lcd(LCD_COLS, LCD_ROWS, LCD_ADDRESS, RGB_ADDRESS); creates an instance of the DFRobot_LCD class, initializing it with the number of columns and rows of your LCD, and the I2C addresses of the LCD and the RGB backlight.

    The lcd.init(); line initializes the LCD, the lcd.setCursor(0, 0); line sets the cursor to the top-left corner of the LCD, and the lcd.printstr("Hello World, [Your Name]"); line sends the "Hello World, [Your Name]" string to the LCD.

    Please replace [Your Name] with your actual name and the LCD_COLS, LCD_ROWS, LCD_ADDRESS, RGB_ADDRESS with the actual parameters of your LCD.

    This is a simple example and the real code might need to handle errors and more complex situations. Also, please ensure that the I2C pins and frequency defined in your DFRobot_LCD.cpp are correct for your setup.

  • Anonymous

    how should lcd.printstr() be made?

  • Chat GPT

    The printstr() function is a method of the DFRobot_LCD class, so it needs to be defined within that class in the DFRobot_LCD.cpp file. This function will typically use the I2C interface to send the string to the LCD.

    Here's a simple example of how the printstr() function might be implemented, assuming the LCD uses the standard HD44780 instruction set and write() is a method of DFRobot_LCD that writes a single character to the LCD:

    cpp
    void DFRobot_LCD::printstr(const char *str) {
    // Loop over each character in the string
    while (*str) {
    // Write the character to the LCD
    write(*str);
    // Increment the string pointer to the next character
    str++;
    }
    }

    In this example, printstr() is a method that takes a pointer to a null-terminated string as its argument. It then loops over each character in the string (stopping when it encounters a null character, which signifies the end of the string) and writes that character to the LCD using the write() method.

    The write() method would then need to implement the actual I2C communication to write a character to the LCD. This method would depend on the specific LCD module and I2C interface you're using.

    This is a basic implementation and may not cover all use cases. You may need to adjust it to suit your needs, such as adding error checking, handling special characters, wrapping text that exceeds the LCD's width, etc.

    Please also note that the printstr() function as written above does not handle the case where the string is longer than the number of characters that can be displayed on one line of the LCD. You may need to add additional code to handle this situation, such as wrapping the text to the next line or scrolling the text.

  • Anonymous

    can you rewrite the void DFRobot_LCD::printstr(const char *str) in to void DFRobot_LCD::printstr(const char c[])

  • Chat GPT

    Sure, the printstr() method can be rewritten to take a character array as input. However, it's worth noting that in C++ a character array and a pointer to a character (i.e., a C-style string) are often interchangeable, especially as function parameters. Here's how you could rewrite the method:

    cpp
    void DFRobot_LCD::printstr(const char c[]) {
    // Loop over each character in the string
    for (int i = 0; c[i] != '\0'; i++) {
    // Write the character to the LCD
    write(c[i]);
    }
    }

    In this version, we use a for-loop to iterate through each character in the array until we reach the null character, which signifies the end of the string. The write() method is then called to write each character to the LCD.

    The write() function is assumed to be a method that sends a single character to the LCD, you will need to implement this function as per your LCD's specifications.

    This function assumes that the array c is a null-terminated string (i.e., the last element of the array is the null character '\0'). This is a common convention in C and C++ for representing strings as character arrays.

  • Anonymous

    can you rewrite these functions in DFRobot_LCD.cpp so it uses esp32c3 i2c/driver.h:
    void DFRobot_LCD::begin(uint8_t cols, uint8_t lines, uint8_t dotsize)
    {
    if (lines > 1) {
    _showfunction |= LCD_2LINE;
    }
    _numlines = lines;
    _currline = 0;

    ///< for some 1 line displays you can select a 10 pixel high font
    if ((dotsize != 0) && (lines == 1)) {
    _showfunction |= LCD_5x10DOTS;
    }

    ///< SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
    ///< according to datasheet, we need at least 40ms after power rises above 2.7V
    ///< before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
    delay(50);


    ///< this is according to the hitachi HD44780 datasheet
    ///< page 45 figure 23

    ///< Send function set command sequence
    command(LCD_FUNCTIONSET | _showfunction);
    delay(5); // wait more than 4.1ms

    ///< second try
    command(LCD_FUNCTIONSET | _showfunction);
    delay(5);

    ///< third go
    command(LCD_FUNCTIONSET | _showfunction);




    ///< turn the display on with no cursor or blinking default
    _showcontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
    display();

    ///< clear it off
    clear();

    ///< Initialize to default text direction (for romance languages)
    _showmode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
    ///< set the entry mode
    command(LCD_ENTRYMODESET | _showmode);


    ///< backlight init
    setReg(REG_MODE1, 0);
    ///< set LEDs controllable by both PWM and GRPPWM registers
    setReg(REG_OUTPUT, 0xFF);
    ///< set MODE2 values
    ///< 0010 0000 -> 0x20 (DMBLNK to 1, ie blinky mode)
    setReg(REG_MODE2, 0x20);

    setColorWhite();

    }

    void DFRobot_LCD::send(uint8_t *data, uint8_t len)
    {
    Wire.beginTransmission(_lcdAddr); // transmit to device #4
    for(int i=0; i Wire.write(data[i]);
    delay(5);
    }
    Wire.endTransmission(); // stop transmitting
    }

    void DFRobot_LCD::setReg(uint8_t addr, uint8_t data)
    {
    Wire.beginTransmission(_RGBAddr); // transmit to device #4
    Wire.write(addr);
    Wire.write(data);
    Wire.endTransmission(); // stop transmitting
    }

  • Chat GPT

    The ESP32-C3 uses the ESP-IDF (Espressif IoT Development Framework) for programming. The ESP-IDF I2C driver is different from the Arduino Wire library. Below is an example of how you might rewrite the functions to use the ESP-IDF I2C driver.

    Please note that you have to configure and install the I2C driver before you can use it. You may need to adjust this code to fit your specific hardware setup.

    cpp
    #include "driver/i2c.h"

    #define ESP_I2C_NUM I2C_NUM_0 // or I2C_NUM_1, depending on which I2C port you are using

    // replace Wire.beginTransmission, Wire.write, and Wire.endTransmission with this function
    esp_err_t DFRobot_LCD::i2c_write(uint8_t addr, uint8_t *data, uint8_t len)
    {
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (addr << 1) | I2C_MASTER_WRITE, true);
    i2c_master_write(cmd, data, len, true);
    i2c_master_stop(cmd);
    esp_err_t ret = i2c_master_cmd_begin(ESP_I2C_NUM, cmd, 1000 / portTICK_RATE_MS);
    i2c_cmd_link_delete(cmd);
    return ret;
    }

    void DFRobot_LCD::send(uint8_t *data, uint8_t len)
    {
    esp_err_t ret = i2c_write(_lcdAddr, data, len);
    if (ret != ESP_OK) {
    ESP_LOGE(TAG, "Error sending data to LCD: %s", esp_err_to_name(ret));
    }
    vTaskDelay(5 / portTICK_PERIOD_MS);
    }

    void DFRobot_LCD::setReg(uint8_t addr, uint8_t data)
    {
    uint8_t buffer[2] = {addr, data};
    esp_err_t ret = i2c_write(_RGBAddr, buffer, 2);
    if (ret != ESP_OK) {
    ESP_LOGE(TAG, "Error setting register: %s", esp_err_to_name(ret));
    }
    }

    void DFRobot_LCD::begin(uint8_t cols, uint8_t lines, uint8_t dotsize)
    {
    // the rest of the function...
    }

    In this code, I've created a helper function i2c_write() to replace the Wire.beginTransmission(), Wire.write(), and Wire.endTransmission() functions from the Arduino Wire library. The i2c_write() function uses the ESP-IDF I2C driver to send data over I2C.

    Please note that this is just a basic example and may not work perfectly in your specific situation. You should adjust this code as necessary to fit your specific hardware and software setup. Also, error handling should be added to make sure that the I2C operations succeed.