initial T-Beam Supreme listener

This commit is contained in:
2026-05-20 09:33:38 +02:00
parent 9ec763dc07
commit d18662d926
2 changed files with 100 additions and 34 deletions
+10 -4
View File
@@ -8,14 +8,20 @@
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:lilygo-t3-s3]
[env:t-beam-supreme]
platform = espressif32
board = lilygo-t3-s3
board = esp32-s3-devkitc-1
framework = arduino
monitor_speed = 115200
upload_speed = 921600
build_flags =
-D ARDUINO_USB_CDC_ON_BOOT=1
-D ARDUINO_USB_MODE=1
lib_deps =
jgromes/RadioLib
adafruit/Adafruit SSD1306
adafruit/Adafruit GFX Library
adafruit/Adafruit GFX Library
adafruit/Adafruit SH110X
lewisxhe/XPowersLib
+90 -30
View File
@@ -3,26 +3,40 @@
#include <Wire.h>
#include <RadioLib.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_SH110X.h>
#define XPOWERS_CHIP_AXP2101
#include <XPowersLib.h>
// LoRa pins - LilyGO T3S3 SX1262
static const int PIN_LORA_SCK = 5;
static const int PIN_LORA_MISO = 3;
static const int PIN_LORA_MOSI = 6;
static const int PIN_LORA_CS = 7;
static const int PIN_LORA_RST = 8;
static const int PIN_LORA_DIO1 = 33;
static const int PIN_LORA_BUSY = 34;
// LilyGO T-Beam Supreme V3.0 / ESP32-S3 / SX1262 / u-blox MAX-M10S
// Pin values follow LilyGO's T_BEAM_S3_SUPREME_SX1262 definitions.
// LoRa pins - T-Beam Supreme SX1262
static const int PIN_LORA_SCK = 12;
static const int PIN_LORA_MISO = 13;
static const int PIN_LORA_MOSI = 11;
static const int PIN_LORA_CS = 10;
static const int PIN_LORA_RST = 5;
static const int PIN_LORA_DIO1 = 1;
static const int PIN_LORA_BUSY = 4;
// OLED pins - LilyGO T3S3 OLED
static const int OLED_SDA = 18;
static const int OLED_SCL = 17;
// OLED pins - T-Beam Supreme SH1106, I2C bus 0
static const int OLED_SDA = 17;
static const int OLED_SCL = 18;
static const int OLED_ADDR = 0x3C;
static const int SCREEN_WIDTH = 128;
static const int SCREEN_HEIGHT = 64;
// PMU pins - AXP2101, I2C bus 1
static const int PMU_SDA = 42;
static const int PMU_SCL = 41;
// GPS pins - u-blox MAX-M10S
static const int GPS_RX_PIN = 9; // ESP32 RX, connect to GPS TX
static const int GPS_TX_PIN = 8; // ESP32 TX, connect to GPS RX
static const int GPS_EN_PIN = 7;
static const uint32_t GPS_BAUD = 9600;
// ACTIVE PROFILE (Shelly / custom LoRa)
static const float LORA_FREQ_MHZ = 865.000;
static const float LORA_BW_KHZ = 125.0;
@@ -36,7 +50,6 @@ static const bool LORA_USE_LDO = false;
static const bool LORA_USE_CRC = false;
static const bool LORA_EXPLICIT_HDR = true;
// MESHCORE SWITZERLAND PROFILE (COMMENTED)
/*
static const float LORA_FREQ_MHZ = 869.618;
@@ -52,9 +65,11 @@ static const bool LORA_USE_CRC = true;
static const bool LORA_EXPLICIT_HDR = true;
*/
// Objects
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
TwoWire PMUWire = TwoWire(1);
XPowersPMU PMU;
Adafruit_SH1106G display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
HardwareSerial GPSSerial(1);
SX1262 radio = new Module(PIN_LORA_CS, PIN_LORA_DIO1, PIN_LORA_RST, PIN_LORA_BUSY);
// Runtime state
@@ -64,6 +79,7 @@ float lastSnr = 0.0;
unsigned long rxCount = 0;
unsigned long lastIdleRefresh = 0;
unsigned long showPacketUntil = 0;
bool pmuOk = false;
// Helpers
String formatCR(uint8_t cr) {
@@ -76,15 +92,13 @@ String formatHexByte(uint8_t value) {
return String(buf);
}
// Draw one line safely
void drawLine(int x, int y, const String& text) {
display.setCursor(x, y);
display.print(text);
}
// Simple text wrapper for packet display
void drawWrappedText(const String& text, int startY, int maxLines) {
const int charsPerLine = 21; // approx for 128 px at text size 1
const int charsPerLine = 21;
int len = text.length();
int index = 0;
int line = 0;
@@ -100,10 +114,10 @@ void drawWrappedText(const String& text, int startY, int maxLines) {
void drawListeningScreen() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setTextColor(SH110X_WHITE);
drawLine(0, 0, "Listening");
drawLine(70, 0, String(rxCount) + " pk");
drawLine(0, 0, "T-Beam Supreme RX");
drawLine(92, 0, String(rxCount));
drawLine(0, 10, "F:" + String(LORA_FREQ_MHZ, 3));
drawLine(0, 20, "BW:" + String(LORA_BW_KHZ, 1) + " SF:" + String(LORA_SF));
@@ -118,7 +132,7 @@ void drawListeningScreen() {
void drawPacketScreen() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setTextColor(SH110X_WHITE);
drawLine(0, 0, "PACKET RECEIVED");
drawLine(0, 10, "RSSI:" + String(lastRssi, 1) + " SNR:" + String(lastSnr, 1));
@@ -133,7 +147,7 @@ void drawPacketScreen() {
void drawErrorScreen(const String& title, int code) {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setTextColor(SH110X_WHITE);
drawLine(0, 0, title);
drawLine(0, 12, "code: " + String(code));
@@ -141,27 +155,69 @@ void drawErrorScreen(const String& title, int code) {
display.display();
}
void initPower() {
PMUWire.begin(PMU_SDA, PMU_SCL);
pmuOk = PMU.begin(PMUWire, AXP2101_SLAVE_ADDRESS, PMU_SDA, PMU_SCL);
if (!pmuOk) {
Serial.println("PMU init failed - continuing, but OLED/LoRa/GPS power may be off");
return;
}
// T-Beam Supreme PMU channels:
// ALDO1 = BME280 + display + magnetometer
// ALDO3 = radio
// ALDO4 = GPS
PMU.setALDO1Voltage(3300);
PMU.enableALDO1();
PMU.setALDO3Voltage(3300);
PMU.enableALDO3();
PMU.setALDO4Voltage(3300);
PMU.enableALDO4();
PMU.disableTSPinMeasure();
PMU.enableBattVoltageMeasure();
PMU.enableVbusVoltageMeasure();
Serial.print("PMU AXP2101 OK, chip ID: 0x");
Serial.println(PMU.getChipID(), HEX);
}
void initGpsPowerOnly() {
pinMode(GPS_EN_PIN, OUTPUT);
digitalWrite(GPS_EN_PIN, HIGH);
GPSSerial.begin(GPS_BAUD, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN);
Serial.println("GPS UART started, GPS data not parsed in this listener sketch");
}
void setup() {
Serial.begin(115200);
delay(1500);
initPower();
delay(200);
Wire.begin(OLED_SDA, OLED_SCL);
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
Serial.println("OLED init failed");
if (!display.begin(OLED_ADDR, true)) {
Serial.println("SH1106 OLED init failed");
while (true) delay(1000);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setTextColor(SH110X_WHITE);
drawLine(0, 0, "Booting...");
display.display();
initGpsPowerOnly();
SPI.begin(PIN_LORA_SCK, PIN_LORA_MISO, PIN_LORA_MOSI, PIN_LORA_CS);
Serial.println();
Serial.println("Starting LoRa receiver...");
Serial.println("Starting LoRa receiver on T-Beam Supreme...");
int state = radio.begin(
LORA_FREQ_MHZ,
@@ -226,18 +282,22 @@ void loop() {
Serial.println();
drawPacketScreen();
showPacketUntil = millis() + 2500; // show packet screen for 2.5 s
showPacketUntil = millis() + 2500;
}
else if (state != RADIOLIB_ERR_RX_TIMEOUT) {
Serial.print("Receive failed, code ");
Serial.println(state);
}
// after packet screen timeout, return to listening screen
// Drain GPS UART to avoid buffer filling. This sketch does not parse GPS.
while (GPSSerial.available()) {
Serial.write(GPSSerial.read());
}
if (millis() > showPacketUntil) {
if (millis() - lastIdleRefresh > 500) {
drawListeningScreen();
lastIdleRefresh = millis();
}
}
}
}