I’m experiencing a screen blackout issue when the LoRa module and the display share the same SPI bus on the XIAO ESP32C3. Despite setting separate Chip Select (CS) pins for each device, conflicts still arise when the LoRa module transmits data over SPI, causing the display to momentarily lose connection and black out. Any suggestions?
Code below:
#include <lvgl.h>
#include <SPI.h>
#include <LoRa.h>
// Define the graphics library (make sure this matches your setup)
#define USE_TFT_ESPI_LIBRARY // Uncomment if using TFT_eSPI
// #define USE_ARDUINO_GFX_LIBRARY // Uncomment if using Arduino GFX
#include "lv_xiao_round_screen.h"
// Display and LoRa SS Pins
#define DISPLAY_SS 3 // Updated SS pin for the display
#define LORA_SS 21 // SS pin for LoRa
#define LORA_DIO0 2 // DIO0 pin for LoRa
static lv_obj_t *label;
unsigned long lastButtonPressTime = 0; // Variable to store the last button press time
const unsigned long debounceDelay = 250; // Debounce time in milliseconds
void setup() {
Serial.begin(115200);
lv_init();
lv_xiao_disp_init(); // Initializes the display (using DISPLAY_SS = GPIO3)
lv_xiao_touch_init(); // Initializes touch input
// Set the background color to #64696C
lv_obj_set_style_bg_color(lv_scr_act(), lv_color_hex(0x000000), 0);
create_ui();
// Set SS pins as outputs
pinMode(DISPLAY_SS, OUTPUT);
pinMode(LORA_SS, OUTPUT);
// Make sure LoRa is initially disabled
digitalWrite(LORA_SS, HIGH);
// Initialize LoRa with the new pins (no reset pin)
Serial.println("Initializing LoRa...");
LoRa.setPins(LORA_SS, -1, LORA_DIO0); // Use -1 for reset pin as it's not used
if (!LoRa.begin(915E6)) { // Set frequency to 915 MHz (adjust if needed)
Serial.println("Starting LoRa failed!");
while (1) delay(100); // Stop here if initialization fails
}
// Set LoRa SPI frequency to a lower rate to reduce conflicts
LoRa.setSPIFrequency(1E6); // Set frequency to 1 MHz
Serial.println("LoRa initialized successfully.");
}
void loop() {
lv_timer_handler();
delay(5);
}
// UI creation with LVGL
void create_ui() {
// Set the main label for feedback
label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "Press a button");
lv_obj_align(label, LV_ALIGN_TOP_MID, 0, 20);
// Create buttons with specific positions and sizes
create_button("Play", 80, 60, 70, 70, btn_event_handler); // Larger, centered "Play" button
create_button("Next", 170, 130, 60, 60, btn_event_handler); // Standard size "Next" button
create_button("Back", 10, 130, 60, 60, btn_event_handler); // Smaller "Back" button
}
void create_button(const char* text, int x, int y, int width, int height, lv_event_cb_t event_cb) {
lv_obj_t *btn = lv_btn_create(lv_scr_act());
lv_obj_set_size(btn, width, height); // Set custom size
lv_obj_set_pos(btn, x, y); // Set position with (x, y) coordinates
// Make the button round
lv_obj_set_style_radius(btn, LV_RADIUS_CIRCLE, 0);
// Add event callback for button
lv_obj_add_event_cb(btn, event_cb, LV_EVENT_CLICKED, (void*)text);
// Create a label for the button and set the text color to white
lv_obj_t *label_btn = lv_label_create(btn);
lv_label_set_text(label_btn, text);
lv_obj_center(label_btn);
lv_obj_set_style_text_color(label_btn, lv_color_hex(0xFFFFFF), 0); // Set text color to white
}
// Event handler for button clicks
void btn_event_handler(lv_event_t *e) {
lv_event_code_t code = lv_event_get_code(e);
unsigned long currentTime = millis();
// Check if enough time has passed since the last button press
if (code == LV_EVENT_CLICKED && (currentTime - lastButtonPressTime >= debounceDelay)) {
lastButtonPressTime = currentTime; // Update the last button press time
const char *btn_label = (const char*)lv_event_get_user_data(e);
lv_label_set_text_fmt(label, "%s button pressed", btn_label);
Serial.println(String(btn_label) + " button pressed");
// Send command over LoRa
LoRa.beginPacket();
LoRa.print(btn_label);
LoRa.endPacket();
Serial.println("LoRa packet sent!");
// Wait for acknowledgment with RSSI
long start = millis();
bool ackReceived = false;
while (millis() - start < 1000) { // Wait up to 1 second for ACK
int packetSize = LoRa.parsePacket();
if (packetSize) {
String incoming = "";
while (LoRa.available()) {
incoming += (char)LoRa.read();
}
if (incoming.startsWith("ACK")) {
int rssi = incoming.substring(4).toInt(); // Extract RSSI from ACK message
Serial.print("RSSI from receiver: ");
Serial.println(rssi);
// Display RSSI on screen
lv_label_set_text_fmt(label, "%s sent, RSSI: %d", btn_label, rssi);
ackReceived = true;
break;
}
}
}
if (!ackReceived) {
Serial.println("No ACK received.");
lv_label_set_text(label, "No ACK received.");
}
}
}