#define U8X8_USE_PINS #include #include #include #include #include #include #include "sx127x_driver.h" #include "u8g2_esp32_hal.h" const char *TAG = "uas-ugv"; // U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, 16, 15, 4); u8g2_t u8g2; // SPIClass lora_spi(VSPI); #define LORA_SCK 5 #define LORA_MISO 19 #define LORA_MOSI 27 #define LORA_CS 18 #define LORA_RST 14 #define LORA_IRQ 26 #define LORA_FREQ (433E6) #define LORA_BUF_LEN 64 #define OLED_H 64 #define OLED_W 128 struct Packet { int rssi; double snr; size_t buffer_len; char buffer[LORA_BUF_LEN]; }; uint16_t packet_num; void loraTask(void *params); void loraOnReceive(int packetSize); TaskHandle_t lora_task_hndl; // packets recieved (type Packet) QueueHandle_t lora_packet_recv_queue; // packet lengths from the recieve isr (type int) QueueHandle_t lora_packet_isr_queue; struct Packet packet; void setup_serial(void) { const uart_port_t uart_num = UART_NUM_2; 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_CTS_RTS, .rx_flow_ctrl_thresh = 122, }; // Configure UART parameters ESP_ERROR_CHECK(uart_param_config(uart_num, &uart_config)); } void setup_oled(void) { u8g2_esp32_hal_t u8g2_hal_config = { .scl = 15, .sda = 4, .reset = 16, }; u8g2_esp32_hal_init(u8g2_hal_config); u8g2_Setup_ssd1306_i2c_128x64_noname_f(&u8g2, U8G2_R0, u8g2_esp32_i2c_byte_cb, u8g2_esp32_gpio_and_delay_cb); u8g2_InitDisplay(&u8g2); u8g2_ClearDisplay(&u8g2); u8g2_SetPowerSave(&u8g2, false); } void setup(void) { setup_serial(); ESP_LOGI(TAG, "setup"); setup_oled(); lora_packet_recv_queue = xQueueCreate(4, sizeof(struct Packet)); lora_packet_isr_queue = xQueueCreate(4, sizeof(int)); configASSERT(lora_packet_recv_queue != 0); configASSERT(lora_packet_isr_queue != 0); sx127x_config_t lora_config = SX127X_CONFIG_DEFAULT; lora_config.tx_power = 17; lora_config.spreading_factor = 11; lora_config.signal_bandwidth = 125E3; lora_config.sync_word = 0x34; lora_config.crc = SX127X_CRC_ENABLED; sx127x_t* lora; esp_err_t ret = sx127x_init(&lora_config, &lora); if (ret != ESP_OK) { const char *err_name = esp_err_to_name(ret); ESP_LOGE(TAG, "LoRa init failed: %s", err_name); } else { ESP_LOGI(TAG, "LoRa initialized"); ret = sx127x_start(lora); if (ret != ESP_OK) { ESP_LOGI(TAG, "LoRa start failed: %d", ret); } } // LoRa.onReceive(loraOnReceive); // LoRa.receive(0); packet_num = 0; xTaskCreate(loraTask, "loraTask", 1024 * 10, NULL, 2, &lora_task_hndl); memset(&packet, 0, sizeof(struct Packet)); } #define XO 10 void loraOnReceive(int packetSize) { if (packetSize == 0) return; ESP_LOGV(TAG, "loraOnReceive"); xQueueSendFromISR(lora_packet_isr_queue, &packetSize, NULL); } void loraTask(void *params) { char outBuf[20]; const size_t outBufLen = (sizeof(outBuf) / sizeof(uint8_t)); int packet_len; TickType_t send_period = pdMS_TO_TICKS(2000); TickType_t current_time = xTaskGetTickCount(); TickType_t next_send = current_time + send_period; struct Packet recvd_packet; while (true) { TickType_t delay_ticks = next_send - current_time; BaseType_t didReceive = xQueueReceive(lora_packet_isr_queue, &packet_len, delay_ticks); if (didReceive) { int packetSize = (packet_len > LORA_BUF_LEN - 1) ? (LORA_BUF_LEN - 1) : (packet_len); // LoRa.setTimeout(50); // LoRa.readBytes(recvd_packet.buffer, packetSize); recvd_packet.buffer_len = packetSize; recvd_packet.buffer[packetSize - 1] = '\0'; // recvd_packet.rssi = LoRa.packetRssi(); // recvd_packet.snr = LoRa.packetSnr(); xQueueSend(lora_packet_recv_queue, &recvd_packet, 10); } current_time = xTaskGetTickCount(); if (current_time >= next_send) { sprintf(outBuf, "hello world %d", packet_num); packet_num++; // LoRa.beginPacket(); // size_t written = LoRa.write((uint8_t *)outBuf, outBufLen - 1); // LoRa.endPacket(); // ESP_LOGI(TAG, "lora wrote %d bytes\n", written); // LoRa.receive(0); // go back to receive mode current_time = xTaskGetTickCount(); next_send = current_time + send_period; } } } void loop(void) { ESP_LOGI(TAG, "loop"); u8g2_FirstPage(&u8g2); bool recieved_packet = xQueueReceive(lora_packet_recv_queue, &packet, 10); do { u8g2_DrawRFrame(&u8g2, 0, 0, OLED_W, OLED_H, 4); uint32_t free_heap = xPortGetFreeHeapSize(); u8g2_SetFont(&u8g2, u8g2_font_4x6_mf); u8g2_DrawStr(&u8g2, 4, 8, "Hello World!"); char buf[40]; snprintf(buf, 40, "free heap: %d", free_heap); u8g2_DrawStr(&u8g2, 4, 8 + 8, buf); if (packet.buffer_len) { ESP_LOGI(TAG, "lora received packet (len %d, rssi: %d, snr: %f): %s\n", packet.buffer_len, packet.rssi, packet.snr, packet.buffer); u8g2_SetFont(&u8g2, u8g2_font_4x6_mf); snprintf(buf, 40, "lora pkt(rssi: %d, snr: %f)", packet.rssi, packet.snr); u8g2_DrawStr(&u8g2, 4, 8 + 8 + 8, buf); snprintf(buf, 40, "%s", packet.buffer); u8g2_DrawStr(&u8g2, 4, 8 + 8 + 8 + 8, buf); } } while (u8g2_NextPage(&u8g2)); vTaskDelay(pdMS_TO_TICKS(1000)); } void loopTask(void *pvUser) { setup(); while (1) { loop(); } } void app_main() { xTaskCreatePinnedToCore(loopTask, "loopTask", 8192, NULL, 1, NULL, 1); }