完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我的项目是测量水箱的水位。因为我使用了 3 个以上的 UART,所以我想使用 2 个 ESP32。
Slave ESP32:从水位传感器获取数据,通过I2C发送给Master ESP32。 Master ESP32:收集数据并将其传递给 NodeRED 进行处理和可视化。 我的问题:我无法在 ESP32 之间进行 I2C 通信。 我的基本代码在这里: 从代码: 代码:全选 #include #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/i2c.h" #include "driver/gpio.h" static const char *TAG = "i2c-slave"; #define _I2C_NUMBER(num) I2C_NUM_##num #define I2C_NUMBER(num) _I2C_NUMBER(num) #define DATA_LENGTH 512 /*!< Data buffer length of test buffer */ #define RW_TEST_LENGTH 128 /*!< Data length for r/w test, [0,DATA_LENGTH] */ #define DELAY_TIME_BETWEEN_ITEMS_MS 1000 /*!< delay time between different test items */ #define I2C_SLAVE_SCL_IO 14 /*!< gpio number for i2c slave clock */ #define I2C_SLAVE_SDA_IO 12 /*!< gpio number for i2c slave data */ #define I2C_SLAVE_NUM I2C_NUMBER(0) /*!< I2C port number for slave dev */ #define I2C_SLAVE_TX_BUF_LEN (2 * DATA_LENGTH) /*!< I2C slave tx buffer size */ #define I2C_SLAVE_RX_BUF_LEN (2 * DATA_LENGTH) /*!< I2C slave rx buffer size */ #define I2C_SLAVE_ADDR 0x45 /*!< I2C slave address */ typedef struct tankData { int tankID; int waterLevel; } tankData; tankData tankOne; /** * @brief i2c slave initialization */ static esp_err_t i2c_slave_init(void) { int i2c_slave_port = I2C_SLAVE_NUM; i2c_config_t conf_slave = { .sda_io_num = I2C_SLAVE_SDA_IO, .sda_pullup_en = GPIO_PULLUP_ENABLE, .scl_io_num = I2C_SLAVE_SCL_IO, .scl_pullup_en = GPIO_PULLUP_ENABLE, .mode = I2C_MODE_SLAVE, .slave.addr_10bit_en = 0, .slave.slave_addr = I2C_SLAVE_ADDR, .slave.maximum_speed = 100000, }; esp_err_t err = i2c_param_config(i2c_slave_port, &conf_slave); if (err != ESP_OK) { return err; } return i2c_driver_install(i2c_slave_port, conf_slave.mode, I2C_SLAVE_RX_BUF_LEN, I2C_SLAVE_TX_BUF_LEN, 0); } void app_main(void) { int counter = 0; int i2c_data = 0; ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_slave_init()); while (true) { tankOne.tankID = counter++; tankOne.waterLevel = (counter % 100); ESP_LOGI(TAG, "Tank ID: %d | Water Level: %d", tankOne.tankID, tankOne.waterLevel); i2c_data = i2c_slave_write_buffer(I2C_SLAVE_NUM, (uint8_t *)&tankOne, sizeof(tankOne), (1000 / portTICK_RATE_MS)); if (i2c_data != ESP_FAIL) { ESP_LOGI(TAG, "I2C Data Length: %d Bytes", i2c_data); } else { ESP_LOGE(TAG, "Failed to generate data"); } vTaskDelay(10000 / portTICK_RATE_MS); } } 主码: 代码:全选 #include #include #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/i2c.h" static const char *TAG = "i2c-master"; #define _I2C_NUMBER(num) I2C_NUM_##num #define I2C_NUMBER(num) _I2C_NUMBER(num) #define DATA_LENGTH 512 /*!< Data buffer length of test buffer */ #define RW_TEST_LENGTH 128 /*!< Data length for r/w test, [0,DATA_LENGTH] */ #define DELAY_TIME_BETWEEN_ITEMS_MS 1000 /*!< delay time between different test items */ #define I2C_MASTER_SCL_IO 25 /*!< gpio number for I2C master clock */ #define I2C_MASTER_SDA_IO 27 /*!< gpio number for I2C master data */ #define I2C_MASTER_NUM I2C_NUMBER(0) /*!< I2C port number for master dev */ #define I2C_MASTER_FREQ_HZ 100000 /*!< I2C master clock frequency */ #define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ #define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ #define ESP_SLAVE_ADDR 0x45 /*!< I2C slave address */ #define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */ #define READ_BIT I2C_MASTER_READ /*!< I2C master read */ #define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/ #define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */ #define ACK_VAL 0x0 /*!< I2C ack value */ #define NACK_VAL 0x1 /*!< I2C nack value */ typedef struct tankData { int tankID; int waterLevel; } tankData; tankData tankOne; /** * @brief i2c master initialization */ static esp_err_t i2c_master_init(void) { int i2c_master_port = I2C_MASTER_NUM; 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, }; esp_err_t err = i2c_param_config(i2c_master_port, &conf); if (err != ESP_OK) { return err; } return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0); } static esp_err_t __attribute__((unused)) i2c_master_read_slave(i2c_port_t i2c_num, uint8_t *data_rd, size_t size) { if (size == 0) { return ESP_OK; } i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (ESP_SLAVE_ADDR << 1) | READ_BIT, ACK_CHECK_EN); if (size > 1) { i2c_master_read(cmd, data_rd, size - 1, ACK_VAL); } i2c_master_read_byte(cmd, data_rd + size - 1, NACK_VAL); i2c_master_stop(cmd); esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS); i2c_cmd_link_delete(cmd); return ret; } void app_main(void) { uint8_t *data = (uint8_t *)malloc(DATA_LENGTH); esp_err_t i2c_read_err; ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_init()); while (true) { // i2c_read_err = i2c_master_read_from_device(I2C_MASTER_NUM, ESP_SLAVE_ADDR, data, sizeof(data), (1000 / portTICK_RATE_MS)); i2c_read_err = i2c_master_read_slave(I2C_NUM_0, data, DATA_LENGTH); if (i2c_read_err == ESP_OK) { memcpy(&tankOne, data, sizeof(tankOne)); ESP_LOGI(TAG, "tankID: %d", tankOne.tankID); ESP_LOGI(TAG, "waterLevel: %d", tankOne.waterLevel); } else { ESP_LOGE(TAG, "[%d] I2C Error: %s", i2c_read_err, esp_err_to_name(i2c_read_err)); } vTaskDelay(10000 / portTICK_RATE_MS); } } |
|
相关推荐
|
|
只有小组成员才能发言,加入小组>>
1140 浏览 1 评论
577浏览 6评论
478浏览 5评论
有没有办法在不使用混杂模式的情况下实现Wifi驱动程序接收缓冲区访问中断呢?
462浏览 5评论
463浏览 4评论
438浏览 4评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 21:51 , Processed in 0.820844 second(s), Total 76, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号