I have wrote 2 simple programs receiver and transmitter in ESP32S3 connected to Lora EByte220 in a board using esp-idf, I can't see any packets receiver from receiver side and not sure how to fix/approach it
Lora transmitter program lora_transmitter.c:
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "lora_transmitter.h"
#include <string.h>
#define TAG "LoRa Tranmitter"
#define UART_NUM UART_NUM_1
#define PIN_TX 21
#define PIN_RX 14
#define BAUD_RATE 9600
#define BUF_SIZE (1024)
void init_lora_module() {
// Configure UART parameters
const uart_config_t uart_config = {
.baud_rate = BAUD_RATE,
.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_APB,
};
// Install UART driver and set up UART
ESP_ERROR_CHECK(uart_driver_install(UART_NUM, BUF_SIZE * 2, BUF_SIZE * 2, 0, NULL, 0));
ESP_ERROR_CHECK(uart_param_config(UART_NUM, &uart_config));
ESP_ERROR_CHECK(uart_set_pin(UART_NUM, PIN_TX, PIN_RX, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
ESP_LOGI(TAG, "LoRa module initialized");
}
void lora_transmit_task(void *pvParameters) {
const char *data_to_send = "Hello, LoRa!";
while (1) {
// Send data over UART
int len = uart_write_bytes(UART_NUM, data_to_send, strlen(data_to_send));
if (len > 0) {
ESP_LOGI(TAG, "Sent: %s", data_to_send);
} else {
ESP_LOGE(TAG, "Failed to send data");
}
vTaskDelay(pdMS_TO_TICKS(2000)); // Send data every 2 seconds
}
}
where lora_transmitter.h is:
#ifndef LORA_SVC_H
#define LORA_SVC_H
#ifdef __cplusplus
// for C++ calls (main.cpp) in this case
extern "C" {
#endif
void lora_transmit_task(void *pvParameters);
void init_lora_module();
#ifdef __cplusplus
}
#endif
#endif // LORA_SVC_H
main.cpp:
extern "C" void app_main(void) {
// Initialize the LoRa module
init_lora_module();
// Create a task to transmit data
xTaskCreate(lora_transmit_task, "lora_transmit_task", 4096, NULL, 5, NULL);
}
in the other hand - the receiver is similar but transmit task and pins:
#define PIN_TX 4
#define PIN_RX 5
void lora_receive_task(void *pvParameters) {
uint8_t rx_buffer[BUF_SIZE];
while (1) {
// Read data from UART
int len = uart_read_bytes(UART_NUM, rx_buffer, BUF_SIZE - 1, pdMS_TO_TICKS(100));
ESP_LOGI(TAG, "len is %d", len);
if (len > 0) {
rx_buffer[len] = '\0'; // Null-terminate the received data
ESP_LOGI(TAG, "Received: %s", (char *)rx_buffer);
}
vTaskDelay(pdMS_TO_TICKS(2000));
ESP_LOGI(TAG, "Waiting....");
}
}
choosing the pins according to board schematic.
transmit program always prints: I (3026319) LoRa Tranmitter: Sent: Hello, LoRa!
where receiver program always prints: I (1008539) LoRa Receiver: Waiting....
what did I miss in my code ? what is wrong with this UART program data packets transmitting and receiving?
I though at first it could be the pins, but reviewed the schematic of it many times even tried many pins combinations
receiver part:
transmitter part:
The issue was that I have assumed that M0, M1 defaults will be fine. apparently, I have to set them explicitly.
in transmit part, M0, M1 were easy to set via GPIO config.
in receiver part it was a bit harder since I had IO expander which I controlled via I2C.
Setting M0, M1 to normal mode (0) solved the issue.
here is how I did it in transmitter in init module function:
// Configure M0 and M1 pins for mode selection
gpio_config_t io_conf = {
.pin_bit_mask = (1ULL << PIN_M0) | (1ULL << PIN_M1),
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = GPIO_PULLUP_ENABLE,
};
gpio_config(&io_conf);
// Set module to normal mode (M0 = 0, M1 = 0)
gpio_set_level(PIN_M0, 0);
gpio_set_level(PIN_M1, 0);
and here is how I did it in receiver part:
// I2C configuration
#define I2C_MASTER_SCL_IO 2 // SCL pin
#define I2C_MASTER_SDA_IO 1 // SDA pin
#define I2C_MASTER_NUM I2C_NUM_1 // I2C port number
#define I2C_FREQ_HZ 100000 // I2C frequency
#define TCA9535_ADDR 0x24 // I2C address (A0=0, A1=0, A2=1)
#define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */
#define READ_BIT I2C_MASTER_READ /*!< I2C master read */
//I2C function
esp_err_t i2c_master_init(void) {
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C_MASTER_SDA_IO,
.scl_io_num = I2C_MASTER_SCL_IO,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = I2C_FREQ_HZ,
};
ESP_ERROR_CHECK(i2c_param_config(I2C_MASTER_NUM, &conf));
ESP_ERROR_CHECK(i2c_driver_install(I2C_MASTER_NUM, I2C_MODE_MASTER, 0, 0, 0));
return ESP_OK;
}
// Function to write data to a specific register
esp_err_t tca9535_write_register(uint8_t reg, uint8_t value) {
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (TCA9535_ADDR << 1) | WRITE_BIT, true);
i2c_master_write_byte(cmd, reg, true); // Write to the register
i2c_master_write_byte(cmd, value, true); // Write the value to the register
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
return ret;
}
// Function to configure P00 and P01 as outputs
esp_err_t configure_p00_p01_as_output(void) {
uint8_t iodir_value = 0xFC; // 1111 1100, P00 and P01 set as outputs (0)
return tca9535_write_register(0x06, iodir_value); // 0x06 is IODIR register
}
// Function to configure P01 as an output
esp_err_t configure_p01_as_output(void) {
uint8_t iodir_value = 0xFD; // 1111 1101, P01 set as output (0)
return tca9535_write_register(0x06, iodir_value); // 0x06 is IODIR register
}
// Function to set P00 and P01 to high or low
esp_err_t set_p00_p01(uint8_t p00_state, uint8_t p01_state) {
uint8_t gpio_value = (p00_state ? 0x01 : 0x00) | (p01_state ? 0x02 : 0x00);
return tca9535_write_register(0x02, gpio_value); // 0x02 is GPIO output register
}
// I2C functions end
// I2C end
and in init module:
// I2C
ESP_ERROR_CHECK(i2c_master_init());
// Configure P00 as an output
esp_err_t err = configure_p00_p01_as_output();
ESP_LOGI(TAG, "err is %s", esp_err_to_name(err));
// Set P00 and P01 to low
err = set_p00_p01(0, 0);
ESP_LOGI(TAG, "err is %s", esp_err_to_name(err));
vTaskDelay(1000 / portTICK_PERIOD_MS); // Wait for 1 second
Thanks