Skip to content

fix(heltec_t096): battery life improvement - fix lna_enable in LoRaFEMControl and code cleanup#2633

Open
NickDunklee wants to merge 1 commit into
meshcore-dev:devfrom
NickDunklee:heltec-t096-power-improvements
Open

fix(heltec_t096): battery life improvement - fix lna_enable in LoRaFEMControl and code cleanup#2633
NickDunklee wants to merge 1 commit into
meshcore-dev:devfrom
NickDunklee:heltec-t096-power-improvements

Conversation

@NickDunklee
Copy link
Copy Markdown

@NickDunklee NickDunklee commented May 27, 2026

Minor change for Heltec T096, it seemed to be consuming more power than what other nRF52-based boards do. Looks like a Heltec v4 optimization needed to be added. Also removed a few lines of dead code that doesn't apply to nRF52.

Update:

Initial assumption was that the PA was being kept on, but it appears according to the schematic, that DIO2 on SX1262 calls CPS on KCT8103L. That triggers if the PA is on or not. The actual improvement is enabling the LNA on by default. This results in roughly 21dB of RX gain. There seem to be some PRs in the queue to eventually add control to the LNA via a CLI command, but that code is not updated/merged yet, nor does it seem there would be any good reason to turn off/bypass the LNA given how bad the battery life suffers when the LNA is disabled.

TL;DR: T096 should have KCT8103L RX amplifiers turned ON by default when booted, which is the one-liner in this PR outside of the dead code cleanup. Otherwise RX suffers significantly and battery drain is pretty terrible unless one is in a lab environment surrounded by nodes. Likely the same behavior should be applied to Heltec v4.3 which seems to have the external LNA disabled by default as well, but I don't have that hardware to test with.

Fix:

  • Set lna_enabled=true in LoRaFEMControl so KCT8103L enters boosted RX/LNA mode (CTX=LOW) during receive instead of remaining in TX mode. Matching Heltec V4 default for the same chip. Reduces idle power draw during the dominant receive state. Which actually marginally increases idle power draw by running the LNA, but the radio has an easier time parsing traffic, which results in a net board power consumption drop in real-world scenarios.
  • Remove setRxModeEnableWhenMCUSleep() — dead code on nRF52. Unlike ESP32 deep sleep, nRF52 preserves GPIO state automatically.

Test:

Tested on Heltec T096 - battery life was significantly improved.

- Set lna_enabled=true in LoRaFEMControl so KCT8103L enters RX/LNA
  mode (CTX=LOW) during receive instead of remaining in TX mode.
  Matching Heltec V4 default for the same chip. Reduces idle power
  draw during the dominant receive state.

- Remove setRxModeEnableWhenMCUSleep() — dead code on nRF52. Unlike
  ESP32 deep sleep, nRF52 preserves GPIO state automatically.
@oltaco oltaco self-assigned this Jun 1, 2026
@oltaco
Copy link
Copy Markdown
Member

oltaco commented Jun 1, 2026

I can check this one out later today on the lab power supply.

I'm not sure what the correct default state of lna_enabled should be. It was changed a couple of months ago in 696aae6

@Quency-D can you comment?

@IoTThinks
Copy link
Copy Markdown
Contributor

@NickDunklee I'm going to fix this too.
So lucky you discover it.

Does your PR help T096 to reach 5.9mA in powersaving on?

@NickDunklee
Copy link
Copy Markdown
Author

The problem is deeper, from what I've read. As I understand, without this change, the TX amp is on pointlessly during RX, which wastes power, and also makes RX worse because it is messing with the RX path. This fixes that. Black box engineering seeing runtime go from heltec v4 territory to 6+ days uptime, (tired of waiting and will probably just start recharging the node soon) and there's probably a more subtle code problem going on, but, either way I'm keeping the change locally regardless of PR acceptance because it works so good regardless. @oltaco had an observable capability I do not, would be curious to see those results, I try to share graphs all the time as it shows some modicum of data. I could very well be wrong, but I borrowed from the Heltec v4 config for the PA, which should be more proven out despite the esp32 vs nrf52 differences behind the PA, and...my node keeps running via magic.

To be clear though, I would love to see a real answer, as my physical world says one thing. I'm totally cool with being proven wrong, just the same.

@NickDunklee
Copy link
Copy Markdown
Author

NickDunklee commented Jun 4, 2026

t096 Speaking of graphs. (Drops due to back-end service code changes, color change due to node config change.)

@IoTThinks
Copy link
Copy Markdown
Contributor

Lna_enable is to set the default value to enable lna in FEM only.

It actually uses extra 9.7 mA compared to lna_enable=false.

You may try the CLI
set radio.fem.rxgain on/off.

@NickDunklee
Copy link
Copy Markdown
Author

NickDunklee commented Jun 4, 2026

@IoTThinks - Looks like that cli option does not exist, and is not a merged commit yet and is still in a stale PR. Adding two separate RX gain variables seems like it could make for some very weird RX path configurations and some more consideration would need to be made. Or simplify it to an optimal RX gain mapping table that changes both LNAs through one variable.

@oltaco - Been tracing through the schematic today and command flow as well as PR history. Seems MeshCore code behavior on this board has flicked back and forth several times. It also looks like my assumption on keeping TX on was incorrect. It looks like DIO2 on SX1262 calls CPS on KCT8103L. PA power is completely dependent on what the radio chooses to do.

Likely, I saw battery life improve just because the LNA path was turned back on. It provides ~21dB RX gain making the TX/RX power more balanced and making the node do less work on the mesh side. Users with very nearby nodes likely wouldn't notice as much difference.

There also seems a fix in the dev branch that may address some of that configuration behavior and I have been sitting on my own build so long that time has passed. I'm going to rebase to current dev and check through the initialization flow. This board is so new and it seems code changes are happening quick! Cool to see.

@NickDunklee
Copy link
Copy Markdown
Author

Updated the PR desc. The tl;dr seems to be leaving the LNA off in real world (what I saw in real world) makes the board waste power elsewhere. Both T096 and Heltec v4.3 should have it turned on by default. Really see no reason it should ever be turned off on a high-powered node board as otherwise one has unbalanced TX/RX power and it reduces the effective range/usefulness, but given a hammer, nails are fun to hit. Wondering now if the selective LNA code fragments like lna_can_control and setLnaCanControl should just be removed. Making the board perform worse as a whole seems bad. Not part of this PR though.

Ok, what a rabbit hole this was, @oltaco curious to see your results. If you can simulate a real-world link where say, two nodes are 5 miles apart and they both see weak signal from each other and compare this flag on/off, you will likely see the power draw difference. Likely a lab-quality signal scenario won't surface this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants