ESP32의 I2C slave측 샘플 코드(송신만)를 만들어 보았다
소개
ESP32를 I2C 통신의 슬레이브로 작동시키는 좋은 샘플 코드를 찾을 수 없었기 때문에 만들었습니다.
espressif github 코드 을 기반으로 간단한 코드로 변경한 것입니다.
※espressif의 github의 코드는 ESP-IDF(≠Arduino)이므로, 그 환경의 이야기가 됩니다(Arduino에서는 사용할 수 없는 샘플 코드입니다)
사용한 것
ESP-WROOM-32 피치 변환된 모듈《풀판》
샘플 코드 개요 사양
ESP-WROOM-32 피치 변환된 모듈《풀판》
샘플 코드 개요 사양
※ I2C 송신하는 데이터의 선두에 0x55 (SYNC_BYTE)의 1 바이트를 붙이고 있습니다 (슬레이브가 데이터 갱신 한 것을 판정하기 위해)
ESP32의 결선
아래와 같이 결선합니다.
SDA
SCL
I2C Master
GPIO18
GPIO19
I2C 슬레이브
GPIO25
GPIO26
결선도 :
코드
변경 개요
espressif 샘플 프로젝트 의 i2c_example_main.c 에 대해 다음과 같이 변경합니다.
변경 개요
espressif 샘플 프로젝트 의 i2c_example_main.c 에 대해 다음과 같이 변경합니다.
변경 후 코드(상기의 「변경 개요」의 부분만 기재)
#define DELAY_TIME_MASTER_MS 1000
#define DELAY_TIME_SLAVE_MS 2000
#define SYNC_BYTE 0x55
static void i2c_master_task(void *arg)
{
int ret;
uint32_t task_idx = (uint32_t)arg;
uint8_t *data_rd = (uint8_t *)malloc(DATA_LENGTH);
int cnt = 0;
while (1) {
ESP_LOGI(TAG, "TASK[%d](master) test cnt: %d", task_idx, cnt++);
//---------------------------------------------------
xSemaphoreTake(print_mux, portMAX_DELAY);
ret = ESP_OK;
while(ret == ESP_OK) {
ret = i2c_master_read_slave(I2C_MASTER_NUM, data_rd, RW_TEST_LENGTH);
if (ret == ESP_ERR_TIMEOUT) {
ESP_LOGE(TAG, "I2C Timeout");
} else if (ret == ESP_OK) {
if (data_rd[0] == SYNC_BYTE) {
printf("*******************\n");
printf("TASK[%d] MASTER READ FROM SLAVE\n", task_idx);
printf("*******************\n");
printf("====TASK[%d] Master read ====\n", task_idx);
disp_buf(data_rd, RW_TEST_LENGTH);
}
else {
printf("*******************\n");
printf("TASK[%d] MASTER READ FROM SLAVE\n", task_idx);
printf("*******************\n");
printf("NO DATA\n\n");
ret = ESP_FAIL;
}
} else {
ESP_LOGW(TAG, "TASK[%d] %s: Master read slave error, IO not connected...\n",
task_idx, esp_err_to_name(ret));
}
}
xSemaphoreGive(print_mux);
vTaskDelay((DELAY_TIME_MASTER_MS * (task_idx + 1)) / portTICK_RATE_MS);
}
vSemaphoreDelete(print_mux);
vTaskDelete(NULL);
}
static void i2c_slave_task(void *arg)
{
int i = 0;
uint32_t task_idx = (uint32_t)arg;
uint8_t *data = (uint8_t *)malloc(DATA_LENGTH);
int cnt = 0;
while (1) {
ESP_LOGI(TAG, "TASK[%d](slave) test cnt: %d", task_idx, cnt++);
//---------------------------------------------------
data[0] = SYNC_BYTE;
for (i = 1; i < DATA_LENGTH; i++) {
data[i] = i;
}
xSemaphoreTake(print_mux, portMAX_DELAY);
size_t d_size = i2c_slave_write_buffer(I2C_SLAVE_NUM, data, RW_TEST_LENGTH, 1000 / portTICK_RATE_MS);
if (d_size == 0) {
ESP_LOGW(TAG, "i2c slave tx buffer full");
}
else {
printf("slave send size: %d\n", d_size);
}
printf("*******************\n");
printf("TASK[%d] SLAVE SEND TO MASTER\n", task_idx);
printf("*******************\n");
disp_buf(data, d_size);
xSemaphoreGive(print_mux);
vTaskDelay((DELAY_TIME_SLAVE_MS * (task_idx + 1)) / portTICK_RATE_MS);
}
vSemaphoreDelete(print_mux);
vTaskDelete(NULL);
}
void app_main()
{
print_mux = xSemaphoreCreateMutex();
ESP_ERROR_CHECK(i2c_slave_init());
ESP_ERROR_CHECK(i2c_master_init());
xTaskCreate(i2c_slave_task, "i2c_test_task_0", 1024 * 2, (void *)0, 10, NULL);
xTaskCreate(i2c_master_task, "i2c_test_task_1", 1024 * 2, (void *)1, 10, NULL);
}
끝에
위의 샘플 코드에서는 I2C 슬레이브는 전송만 했지만 i2c_slave_read_buffer() 같은 함수를 사용하여 I2C 슬레이브에서 수신할 수도 있습니다.
또, I2C 슬레이브의 송신이라고 하는 것은 과거 기사 의 농척 측과 같습니다. 할 수 있을 것 같습니다(ΦωΦ) 후후후…
보고 주셔서 감사합니다.
tnejk чoμ_〆(・ω・。)
덤
I2C 슬레이브 송신을 인터럽트 방식으로 할 수 있으면 좋겠다.
이번에 만든 샘플 코드는 기본 코드 과 같이 폴링 방식으로 I2C의 송신을 실시하고 있습니다만, 그 부분은 사용하기 어렵게 느낍니다.
거기서, Arduino의 Wire.h의 인터럽트 핸들러 등록과 같이 사용할 수 없을까 생각해 조금 조사하면, 「함수 i2c_isr_register를 사용하면 좋겠다」라고 하는 기사를 곳곳에서 찾아냈습니다.
그러나 i2c_driver_install이라는 초기 설정을 하는 함수 내에서 i2c_isr_handler_default라는 디폴트 핸들러가 이미 등록되어 있거나 하고 「미다리에 등록해도 괜찮지 않아」라고 조금 조사할 필요를 느끼면서도 그 수고를 현재 포기중 입니다・・・.
업데이트 내역
I2C 슬레이브 송신을 인터럽트 방식으로 할 수 있으면 좋겠다.
이번에 만든 샘플 코드는 기본 코드 과 같이 폴링 방식으로 I2C의 송신을 실시하고 있습니다만, 그 부분은 사용하기 어렵게 느낍니다.
거기서, Arduino의 Wire.h의 인터럽트 핸들러 등록과 같이 사용할 수 없을까 생각해 조금 조사하면, 「함수 i2c_isr_register를 사용하면 좋겠다」라고 하는 기사를 곳곳에서 찾아냈습니다.
그러나 i2c_driver_install이라는 초기 설정을 하는 함수 내에서 i2c_isr_handler_default라는 디폴트 핸들러가 이미 등록되어 있거나 하고 「미다리에 등록해도 괜찮지 않아」라고 조금 조사할 필요를 느끼면서도 그 수고를 현재 포기중 입니다・・・.
업데이트 내역
Reference
이 문제에 관하여(ESP32의 I2C slave측 샘플 코드(송신만)를 만들어 보았다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/TwDaiki/items/0e1c7705485b54911999텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)