HTCC-AB01 RadioLib OTAA join request fails (+ SOLUTION)

OK, got it now. Thanks.

I recall back in '20 or so ST announced they would come with - in my view - superior MCU + LoRa radio device compared to the ASR650x. Loved it, but didn’t want to wait for that, besides it would probably also mean spending €€€ on things like Segger J-Link and professional dev tools. Plus big learning curve.

So yes, I totally agree with you there are way better (= more robust/stable, well documented & supported, open sourced, …), solutions out there than EOL’d HTCC AB0x’s, but as a - meanwhile - hobbyist with 6 already on the shelf and sufficient time now, I didn’t want to trash these yet.

So far, yes, it looks like it.

Activity over last 18hrs of one of two CubeCell nodes running a RadioLib LoRaWAN App.
Both nodes uplink ambient temp. and battery voltage every 15 minutes.

TTS dashboard:
Last activity7 minutes ago

86 up / 7 (Nwk) down

(Nwk = frame count value)
Chunk of terminal output by CubeCell node:
Just showing the part with last two downlinks received. The other 6 ones were also received.

...
18:16:51.380441 Sending uplink
18:16:56.513048 transceive - RadioLib state: 1
18:16:56.513245 Received a downlink
18:16:56.518859 <MAC commands only>
18:16:56.518977 [LoRaWAN] RSSI: -60.00 dBm
18:16:56.519017 [LoRaWAN] SNR: 9.00 dB
18:16:56.523974 [LoRaWAN] Event information:
18:16:56.524092 [LoRaWAN] Confirmed: 0
18:16:56.529854 [LoRaWAN] Confirming: 0
18:16:56.529960 [LoRaWAN] Datarate: 5
18:16:56.534810 [LoRaWAN] Frequency: 867.300 MHz
18:16:56.534885 [LoRaWAN] Frame count: 6
18:16:56.534921 [LoRaWAN] Port: 0
18:16:56.538761 [LoRaWAN] Time-on-air: 51 ms
18:16:56.538831 [LoRaWAN] Rx window: 1
18:31:51.431573 temp. 19.55°C, DevEUI=0x002722450c3a7530&packet=BscJfQ==
18:31:51.431747 Sending uplink
18:31:56.566627 transceive - RadioLib state: 1
18:31:56.566826 Received a downlink
18:31:56.572442 <MAC commands only>
18:31:56.572554 [LoRaWAN] RSSI: -59.00 dBm
18:31:56.572592 [LoRaWAN] SNR: 9.25 dB
18:31:56.578434 [LoRaWAN] Event information:
18:31:56.578523 [LoRaWAN] Confirmed: 0
18:31:56.583462 [LoRaWAN] Confirming: 0
18:31:56.583569 [LoRaWAN] Datarate: 5
18:31:56.589409 [LoRaWAN] Frequency: 867.900 MHz
18:31:56.589504 [LoRaWAN] Frame count: 7
18:31:56.589544 [LoRaWAN] Port: 0
18:31:56.593411 [LoRaWAN] Time-on-air: 51 ms
18:31:56.593474 [LoRaWAN] Rx window: 1
18:46:51.483312 temp. 19.51°C, DevEUI=0x002722450c3a7530&packet=BsEJfQ==
18:46:51.483487 Sending uplink
...

My wrap-up and findings.

Yes, it is possible to use RadioLib LoRaWAN 1.10/1.04 for OTAA and uplinks on CubeCell boards v1/v2.

RadioLib could be made working on 6 out of 6 CubeCells (4 x v1 and 2 x v2).

CUBECELL CLOCK DRIFT

HTCC AB01 has two clock sources: a HFCLK (driving the 48MHz) and LFCLK (32768kHz).
The HFCLK clock can be off by 2% or 20ppt, while the LFCLK clock is doing ok (< 1ppt off).

Drift values vary per board:
2x v1 (2021): 11ms, 12ms
2x v1 (2022): 16ms, 18ms
2x v2 (2025): 6ms, 10ms
(all at 20˚C)

EFFECT ON TIMING FUNCTIONS & QUICK HACK

Heltec firmware uses the accurate LFCLK for millis() and Timer_t events, while using the inferior HFCLK for delay(), delayMicroseconds() and micros().

RadioLib can apply a correction to the 4 timing functions it uses, by enabling and setting RADIOLIB_CLOCK_DRIFT_MS (BuildOpt.h).
Or (when using PlatformIO) add it to your project’s platformio.ini:

build_flags =
  -D RADIOLIB_CLOCK_DRIFT_MS=xx

Because CubeCell millis() is accurate enough, it should be excluded from correction.
A quick hack for this in AppHAL.cpp (PlatformIO: in appropriate local .pio/libdeps entry):

RadioLibTime_t inline ArduinoHal::millis() {
// #if !defined(RADIOLIB_CLOCK_DRIFT_MS)
return(::millis());
// #else
// return (RadioLibTime_t)((uint64_t)::millis() * 1000ULL / (1000ULL + (uint64_t)RADIOLIB_CLOCK_DRIFT_MS));
// #endif
}

BTW, be sure to use RL ^7.6.0 which contains an important fix (uint64_t) for drift correction calculations. In earlier versions, uplinks would stop after approximately 1h:12m.

DEEP SLEEP
Code below shows the use of an accurate timer in combination with deep sleep lowPowerHandler() to replace delay() in RadioLib’s LoRaWAN_Starter.ino example.

void wakeup(void);
TimerEvent_t interval;

void setup() {
  .
  . (initialise radio, join network,...)
  .
  TimerInit(&interval, wakeup);
}

void wakeup() {
}

void loop() {
  TimerSetValue(&interval, uplinkIntervalSeconds * 1000);
  TimerStart(&interval);
  .
  . (gather sensor inputs, sending uplink,...)
  .
  // Wait until next uplink - observing legal & TTN FUP constraints
  Serial.flush();
  uint32_t t0 = micros();
  while (micros() - t0 < 125) {
    ;
  }
  lowPowerHandler();
  // delay(uplinkIntervalSeconds * 1000UL);  // delay needs milli-seconds
}

TEMPERATURE EFFECT
Just a heads up: when CubeCells are used in environments with fluctuating temperatures, a fixed drift setting may not suffice.

See results of a quick freezer test (n = 1).

Haven’t done same for temperatures above 20oC.

1 Like