# Bosch BME680 Sensor [](https://github.com/K0I05) [](/LICENSE) [](https://en.wikipedia.org/wiki/C_(programming_language)) [](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/index.html) [](https://code.visualstudio.com/) [](https://platformio.org/) [](https://registry.platformio.org/libraries/k0i05/esp_mux4052a) [](https://components.espressif.com/components/k0i05/esp_mux4052a) This ESP32 espressif IoT development framework (esp-idf) i2c peripheral driver was developed for the MUX4052A uart port multiplexer. The 4052A denotes the multiplexer type (SN74LV4052A) and number of channels supported when utilized for serial applications. Information on features and functionality are documented and can be found in the `mux4052a.h` header file and in the `documentation` folder. ## Repository The component is hosted on github and is located here: <https://github.com/K0I05/ESP32-S3_ESP-IDF_COMPONENTS/tree/main/components/peripherals/i2c/esp_mux4052a> ## General Usage To get started, simply copy the component to your project's `components` folder and reference the `mux4052a.h` header file as an include. The component includes documentation for the peripheral such as the datasheet, application notes, and/or user manual where applicable. ```text components └── esp_mux4052a ├── CMakeLists.txt ├── README.md ├── LICENSE ├── idf_component.yml ├── library.json ├── documentation │ └── datasheets, etc. ├── include │ └── mux4052a_version.h │ └── mux4052a.h └── mux4052a.c ``` ## Basic Example Once a driver instance is instantiated the multiplexer is ready for usage as shown in the below example. This basic implementation of the driver utilizes default configuration settings, configures the MUX4052A's channel, transmits a message from UART_NUM_2 at user defined interval, and prints the message received from UART_NUM_0. The MUX4052A is interfaced to the MCU on UART_NUM_2 and MUX4052A channels 0 and 2 are interfaced to the MCU on UART_NUM_0. The uart transmit lines for channels 0 and 2 on the MUX4052A are connected to the MCU's receive lines on UART_NUM_0. There is a 5 second delay between channel configuration and message transmission. ```c #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <unistd.h> #include <limits.h> #include <string.h> #include <time.h> #include <sys/time.h> #include <math.h> #include <esp_system.h> #include <esp_timer.h> #include <esp_event.h> #include <esp_log.h> #include <nvs.h> #include <nvs_flash.h> #include <freertos/FreeRTOS.h> #include <freertos/task.h> #include <freertos/semphr.h> #include <freertos/queue.h> #include <freertos/event_groups.h> #include <mux4052a.h> #include <driver/uart.h> #include <driver/gpio.h> #define UART_0_TASK_NAME "uart_0_rx_tsk" #define UART_0_TASK_STACK_SIZE (configMINIMAL_STACK_SIZE * 4) #define UART_0_TASK_PRIORITY (tskIDLE_PRIORITY + 2) #define UART_2_TASK_NAME "uart_2_tx_tsk" #define UART_2_TASK_STACK_SIZE (configMINIMAL_STACK_SIZE * 4) #define UART_2_TASK_PRIORITY (tskIDLE_PRIORITY + 2) #define UART_0_PORT_NUM (UART_NUM_0) #define UART_0_TXD_IO_NUM (GPIO_NUM_1) #define UART_0_RXD_IO_NUM (GPIO_NUM_3) #define UART_RX_BUF_SIZE (1024) #define APP_TAG "MUX4052A [APP]" static inline void vTaskDelaySecUntil(TickType_t *previousWakeTime, const uint sec) { const TickType_t xFrequency = ((sec * 1000) / portTICK_PERIOD_MS); vTaskDelayUntil( previousWakeTime, xFrequency ); } /** * @brief Initializes UART 0. */ static inline void init_uart( void ) { // configuration for UART 1 and 2 const uart_config_t uart_config = { .baud_rate = 115200, .data_bits = UART_DATA_8_BITS, .parity = UART_PARITY_DISABLE, .stop_bits = UART_STOP_BITS_1, .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, .source_clk = UART_SCLK_DEFAULT, }; // UART0 - tx uart_driver_install(UART_0_PORT_NUM, UART_RX_BUF_SIZE * 2, 0, 0, NULL, 0); uart_param_config(UART_0_PORT_NUM, &uart_config); uart_set_pin(UART_0_PORT_NUM, UART_0_TXD_IO_NUM, UART_0_RXD_IO_NUM, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); } /** * @brief Transmits data from UART 2. * * @param log_name Log name for ESP logging. * @param data Data to transmit from UART 2. * @return int Numbers of bytes transmitted from UART 2. */ static inline int uart_2_tx_data(const char* log_name, const char* data) { const int len = strlen(data); const int tx_bytes = uart_write_bytes(MUX4052A_PORT_NUM, data, len); ESP_LOGI(log_name, "Wrote %d bytes", tx_bytes); return tx_bytes; } static void uart_2_tx_task( void *pvParameters ) { static const char *TX_TASK_TAG = "UART_1_TX_TASK"; TickType_t xLastWakeTime = xTaskGetTickCount (); mux4052a_config_t mux_cfg = MUX4052A_CONFIG_DEFAULT; mux4052a_handle_t mux_hdl = NULL; esp_log_level_set(TX_TASK_TAG, ESP_LOG_INFO); /* attempt to instantiate mux handle */ mux4052a_init(&mux_cfg, &mux_hdl); if(mux_hdl == NULL) { ESP_LOGE(APP_TAG, "mux4052a_init failed"); esp_restart(); } // task loop entry point for ( ;; ) { mux4052a_set_channel(mux_hdl, MUX4052A_CHANNEL_0); ESP_LOGI(TX_TASK_TAG, "Set MUX4052A to channel 0"); uart_2_tx_data(TX_TASK_TAG, "Hello World via MUX4052A channel 0!"); vTaskDelay(5000 / portTICK_PERIOD_MS); mux4052a_set_channel(mux_hdl, MUX4052A_CHANNEL_2); ESP_LOGI(TX_TASK_TAG, "Set MUX4052A to channel 2"); uart_2_tx_data(TX_TASK_TAG, "Hello World via MUX4052A channel 2!"); // pause the task per defined wait period vTaskDelaySecUntil( &xLastWakeTime, 10 ); } // free up task resources and remove task from stack mux4052a_delete( mux_hdl ); vTaskDelete( NULL ); } static void uart_0_rx_task(void *pv_parameters) { static const char *RX_TASK_TAG = "UART_0_RX_TASK"; esp_log_level_set(RX_TASK_TAG, ESP_LOG_INFO); uint8_t* data = (uint8_t*)malloc(UART_RX_BUF_SIZE + 1); while (1) { const int rx_bytes = uart_read_bytes(UART_0_PORT_NUM, data, UART_RX_BUF_SIZE, 1000 / portTICK_PERIOD_MS); if (rx_bytes > 0) { data[rx_bytes] = 0; ESP_LOGI(RX_TASK_TAG, "Read %d bytes: '%s'", rx_bytes, data); ESP_LOG_BUFFER_HEXDUMP(RX_TASK_TAG, data, rx_bytes, ESP_LOG_INFO); uart_flush(UART_0_PORT_NUM); } } free(data); vTaskDelete(NULL); } void app_main( void ) { ESP_LOGI(APP_TAG, "Startup.."); ESP_LOGI(APP_TAG, "Free memory: %lu bytes", esp_get_free_heap_size()); ESP_LOGI(APP_TAG, "IDF version: %s", esp_get_idf_version()); esp_log_level_set("*", ESP_LOG_INFO); esp_log_level_set(APP_TAG, ESP_LOG_VERBOSE); esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK( nvs_flash_erase() ); ret = nvs_flash_init(); } ESP_ERROR_CHECK( ret ); init_uart(); xTaskCreatePinnedToCore( uart_2_tx_task, UART_2_TASK_NAME, UART_2_TASK_STACK_SIZE, NULL, UART_2_TASK_PRIORITY, NULL, APP_CPU_NUM ); xTaskCreatePinnedToCore( uart_0_rx_task, UART_0_TASK_NAME, UART_0_TASK_STACK_SIZE, NULL, UART_0_TASK_PRIORITY, NULL, APP_CPU_NUM ); } ``` ```text I (21100) UART_1_TX_TASK: Set MUX4052A to channel 0 I (21100) UART_1_TX_TASK: Wrote 35 bytes I (22100) UART_0_RX_TASK: Read 35 bytes: 'Hello World via MUX4052A channel 0!' I (22100) UART_0_RX_TASK: 0x3fca70a4 48 65 6c 6c 6f 20 57 6f 72 6c 64 20 76 69 61 20 |Hello World via | I (22110) UART_0_RX_TASK: 0x3fca70b4 4d 55 58 34 30 35 32 41 20 63 68 61 6e 6e 65 6c |MUX4052A channel| I (22110) UART_0_RX_TASK: 0x3fca70c4 20 30 21 | 0!| I (26100) UART_1_TX_TASK: Set MUX4052A to channel 2 I (26100) UART_1_TX_TASK: Wrote 35 bytes I (27100) UART_0_RX_TASK: Read 35 bytes: 'Hello World via MUX4052A channel 2!' I (27100) UART_0_RX_TASK: 0x3fca70a4 48 65 6c 6c 6f 20 57 6f 72 6c 64 20 76 69 61 20 |Hello World via | I (27110) UART_0_RX_TASK: 0x3fca70b4 4d 55 58 34 30 35 32 41 20 63 68 61 6e 6e 65 6c |MUX4052A channel| I (27110) UART_0_RX_TASK: 0x3fca70c4 20 32 21 | 2!| ``` Copyright (c) 2024 Eric Gionet (<gionet.c.eric@gmail.com>)
idf.py add-dependency "k0i05/esp_mux4052a^1.2.6"