Heltec display trouble

Hi N,
To clarify: As a none programmer, AI is a big help, and allows me to have code written.
Working with AI needs it own skills, so I still have to concentrate, and proof read. When I say proof read, I am able to skim down the code and see mostly what’s going on.

I think the problems started when i bought a couple of V3.2s, which needed different libraries, then my system fell to bits.

At the moment, my project is, I have a base, repeater, and remote with each end sending its gps location. The base reads a serial output, so I can range check. Today I (AI) added a menu to remote, so I can change Bandwidth, spread factor, and power, by pressing a button and watching the led. This will eventually change all of the other modules settings. So I’m having fun. All of this works fine as long as I use V3.1s.

I spent a long time trying to find why I was getting errors with the screen etc, and it’s possible that one of the modules uses I2C, and maybe these use SPI. I see SPI flash by as it’s uploading the module?

Regarding posting questions, I’m sure I did ask previously, but there wasn’t a clear answer.
C

Tried 4 times to get code to review, but now the Troll Alarm has been triggered.

Outa here.

Hi,
I’ve just noticed other posts, ‘thanks’ that I haven’t seen before sorry for missing them!
Also I tried to keep as few includes as possible, so with the one I posted only 1x, which I’ll look into later.

I had some Heltecs in the post, and asked the vendors if they are 3.2s or 3.1s like the photo. They replied 3.2s, we use old photos!
Anyway, I received them and tried them with my 3.1 code. The screens were dim, so like many times before I asked AI to modify it to work on both modules, and it did, here:
//REPEATER_TOGGLE_140626_V3.1 AND V3.2

#include <heltec_unofficial.h>

// ------------------ IDENTIFIERS ------------------

#define BASE_ID “BASE”

#define REMOTE_ID “REMOTE”

// ------------------ FREQUENCIES ------------------

#define FROM_BASE_FREQ 863.8

#define TO_REMOTE_FREQ 864.4

#define FROM_REMOTE_FREQ 865.0

#define TO_BASE_FREQ 865.8

// ------------------ RADIO SETTINGS ------------------

int currentBW = 125;

int currentSF = 9;

int currentTxPower = 0;

// ------------------ TIMING ------------------

#define LISTEN_WINDOW_MS 10000UL // 10s on each side

// ------------------ STATE ------------------

volatile bool rxFlag = false;

String rxData;

enum RxSource { RX_FROM_BASE, RX_FROM_REMOTE };

RxSource currentRxSource = RX_FROM_BASE;

uint32_t windowStartedAt = 0;

String lastBaseMsg = “”;

String lastRemoteMsg = “”;

// ------------------ ISR ------------------

void rxISR() { rxFlag = true; }

// ------------------ RADIO MODES ------------------

void setRadioRx(float freq, RxSource src) {

currentRxSource = src;

windowStartedAt = millis();

radio.standby();

RADIOLIB_OR_HALT(radio.setFrequency(freq));

delay(10);

RADIOLIB_OR_HALT(radio.startReceive(RADIOLIB_SX126X_RX_TIMEOUT_INF));

}

void setRadioTx(float freq) {

radio.standby();

RADIOLIB_OR_HALT(radio.setFrequency(freq));

}

// ------------------ APPLY REMOTE SETTINGS ------------------

void applyRemoteSettings(int bw, int sf, int pwr) {

if (bw != currentBW) {

RADIOLIB_OR_HALT(radio.setBandwidth(bw));

currentBW = bw;

}

if (sf != currentSF) {

RADIOLIB_OR_HALT(radio.setSpreadingFactor(sf));

currentSF = sf;

}

if (pwr != currentTxPower) {

RADIOLIB_OR_HALT(radio.setOutputPower((int8_t)pwr));

currentTxPower = pwr;

}

}

// ------------------ PARSERS ------------------

// Base packet: “BASE,lat,lon,time”

// Remote packet: “REMOTE,lat,lon,time,bw,sf,pwr”

bool parseBase(const String& msg, float& lat, float& lon, String& t) {

int c1 = msg.indexOf(’,’);

int c2 = msg.indexOf(’,’, c1+1);

int c3 = msg.indexOf(’,’, c2+1);

if (c1 < 0 || c2 < 0 || c3 < 0) return false;

lat = msg.substring(c1+1, c2).toFloat();

lon = msg.substring(c2+1, c3).toFloat();

int c4 = msg.indexOf(’,’, c3+1);

t = (c4 > c3) ? msg.substring(c3+1, c4) : msg.substring(c3+1);

return true;

}

bool parseRemote(const String& msg, float& lat, float& lon, String& t,

             int& bw, int& sf, int& pwr) {

int c1 = msg.indexOf(’,’);

int c2 = msg.indexOf(’,’, c1+1);

int c3 = msg.indexOf(’,’, c2+1);

int c4 = msg.indexOf(’,’, c3+1);

int c5 = msg.indexOf(’,’, c4+1);

int c6 = msg.indexOf(’,’, c5+1);

if (c1<0||c2<0||c3<0||c4<0||c5<0||c6<0) return false;

lat = msg.substring(c1+1, c2).toFloat();

lon = msg.substring(c2+1, c3).toFloat();

t = msg.substring(c3+1, c4);

bw = msg.substring(c4+1, c5).toInt();

sf = msg.substring(c5+1, c6).toInt();

pwr = msg.substring(c6+1).toInt();

return true;

}

// ------------------ DISPLAY ------------------

void showBasePacket(const String& msg) {

float lat, lon; String t;

display.clear();

display.drawString(0, 0, “=== BASE DATA ===”);

if (parseBase(msg, lat, lon, t)) {

display.drawString(0, 10, "LAT: " + String(lat, 6));

display.drawString(0, 20, "LON: " + String(lon, 6));

display.drawString(0, 30, "TIME: " + t);

display.drawString(0, 40, "BW" + String(currentBW) +

                               " SF" + String(currentSF) +

                               " PWR" + String(currentTxPower));

} else {

display.drawString(0, 10, "PARSE ERR");

}

display.display();

display.displayOn();

}

void showRemotePacket(const String& msg) {

float lat, lon; String t; int bw, sf, pwr;

display.clear();

display.drawString(0, 0, “=== REMOTE DATA ===”);

if (parseRemote(msg, lat, lon, t, bw, sf, pwr)) {

display.drawString(0, 10, "LAT: " + String(lat, 6));

display.drawString(0, 20, "LON: " + String(lon, 6));

display.drawString(0, 30, "TIME: " + t);

display.drawString(0, 40, "BW" + String(currentBW) +

                               " SF" + String(currentSF) +

                               " PWR" + String(currentTxPower));

} else {

display.drawString(0, 10, "PARSE ERR");

}

display.display();

display.displayOn();

}

void showListening(const char* side) {

display.clear();

display.drawString(0, 0, “REPEATER”);

display.drawString(0, 12, String("Listening ") + side);

display.drawString(0, 24, “BW” + String(currentBW) +

                         " SF" + String(currentSF) +

                         " PWR" + String(currentTxPower));

display.display();

display.displayOn();

}

// ------------------ SETUP ------------------

void setup() {

heltec_setup();

// Enable OLED power rail (Vext) for both V3.1 and V3.2

// GPIO36 controls Vext on Heltec V3 - LOW enables power

pinMode(36, OUTPUT);

digitalWrite(36, LOW);

delay(50);

// Ensure display is powered and on

display.displayOn();

RADIOLIB_OR_HALT(radio.begin());

radio.setDio1Action(rxISR);

RADIOLIB_OR_HALT(radio.setBandwidth(currentBW));

RADIOLIB_OR_HALT(radio.setSpreadingFactor(currentSF));

RADIOLIB_OR_HALT(radio.setOutputPower((int8_t)currentTxPower));

setRadioRx(FROM_BASE_FREQ, RX_FROM_BASE);

showListening(“BASE”);

}

// ------------------ LOOP ------------------

void loop() {

heltec_loop();

// ---- 10s TIMER: alternate listen side ----

if (millis() - windowStartedAt > LISTEN_WINDOW_MS) {

if (currentRxSource == RX_FROM_BASE) {

  setRadioRx(FROM_REMOTE_FREQ, RX_FROM_REMOTE);

  showListening("REMOTE");

} else {

  setRadioRx(FROM_BASE_FREQ, RX_FROM_BASE);

  showListening("BASE");

}

rxFlag = false;  // discard any stale ISR from previous window

}

if (!rxFlag) return;

rxFlag = false;

rxData = “”;

int err = radio.readData(rxData);

if (err != RADIOLIB_ERR_NONE || rxData.length() == 0) {

if (currentRxSource == RX_FROM_BASE) setRadioRx(FROM_BASE_FREQ, RX_FROM_BASE);

else                                   setRadioRx(FROM_REMOTE_FREQ, RX_FROM_REMOTE);

return;

}

// ---------- BASE → REMOTE ----------

if (rxData.startsWith(BASE_ID) && currentRxSource == RX_FROM_BASE) {

lastBaseMsg = rxData;

showBasePacket(rxData);

setRadioTx(TO_REMOTE_FREQ);

radio.transmit(rxData.c_str());

radio.finishTransmit();

// re-arm on same side — timer will switch when 10s is up

setRadioRx(FROM_BASE_FREQ, RX_FROM_BASE);

return;

}

// ---------- REMOTE → BASE ----------

if (rxData.startsWith(REMOTE_ID) && currentRxSource == RX_FROM_REMOTE) {

float lat, lon; String t; int bw, sf, pwr;

if (parseRemote(rxData, lat, lon, t, bw, sf, pwr)) {

  applyRemoteSettings(bw, sf, pwr);

}

lastRemoteMsg = rxData;

showRemotePacket(rxData);

setRadioTx(TO_BASE_FREQ);

radio.transmit(rxData.c_str());

radio.finishTransmit();

// re-arm on same side — timer will switch when 10s is up

setRadioRx(FROM_REMOTE_FREQ, RX_FROM_REMOTE);

return;

}

// ---------- UNKNOWN / MISMATCH — re-arm ----------

if (currentRxSource == RX_FROM_BASE) setRadioRx(FROM_BASE_FREQ, RX_FROM_BASE);

else setRadioRx(FROM_REMOTE_FREQ, RX_FROM_REMOTE);

}