RAK13010 SDI12 LoRa and deep sleep

i am trying to use RAK4631, RAK13010 on RAK19007.
AT+VER=RUI_4.2.3_RAK4631
OS Windows

i use the code below to measure TDR315 and send data to gateway RAK7268CV2
when i use USB cable i see packet received in the gateway server.
when i try to use battery instead nothing is received in the gateway server.
i tried both internal and external 12V supply to the SDI12 sensor.
i saw in this forum that there was also issues with deep Sleep power. is this already been fixed?
thank you for your response

#include “RAK13010_SDI12.h”

#define TX_PIN WB_IO6
#define RX_PIN WB_IO5
#define OE WB_IO4
#define SENSOR_ADDRESS ‘A’

RAK_SDI12 mySDI12(RX_PIN, TX_PIN, OE);

// ── Reading interval ──────────────────────────────
#define SEND_INTERVAL_MS 60000 // 1 minutes

#define LORAWAN_FPORT 2

uint8_t payload[10];
bool joinDone = false;

// ────────────────────────────────────────────────
void setup() {
pinMode(WB_IO2, OUTPUT);
digitalWrite(WB_IO2, HIGH);
delay(500);

Serial.begin(115200);
delay(2000);

mySDI12.begin();
delay(500);

Serial.println(“TDR-315 + LoRaWAN | Boot”);
}

// ────────────────────────────────────────────────
void loop() {
mySDI12.clearBuffer();

// ── Step 1: M! ───────────────────────────────
String cmd = String(SENSOR_ADDRESS) + “M!”;
Serial.print("Sending: "); Serial.println(cmd);
mySDI12.sendCommand(cmd);
delay(1000);

String response = “”;
while (mySDI12.available()) {
char c = mySDI12.read();
if (c == ‘\r’ || c == ‘\n’) break;
response += c;
}
Serial.print("M! response: "); Serial.println(response);

if (response.length() < 2) {
Serial.println(“M! failed — retrying”);
delay(3000);
return;
}

int waitTime = response.substring(1, 4).toInt();
Serial.print("Sensor ready in: "); Serial.print(waitTime); Serial.println(“s”);
delay(waitTime * 1000 + 3000);
mySDI12.clearBuffer();

// ── Step 2: D0! ───────────────────────────────
String dataCmd = String(SENSOR_ADDRESS) + “D0!”;
Serial.print("Sending: "); Serial.println(dataCmd);
mySDI12.sendCommand(dataCmd);
delay(1000);

String data = “”;
while (mySDI12.available()) {
char c = mySDI12.read();
if (c == ‘\r’ || c == ‘\n’) break;
data += c;
}
Serial.print("Raw data: "); Serial.println(data);

if (data.length() < 2) {
Serial.println(“D0! failed — retrying”);
delay(3000);
return;
}

// ── Step 3: Parse 5 values ────────────────────
float values[5] = {0, 0, 0, 0, 0};
int idx = 0, pos = 1;
while (pos < (int)data.length() && idx < 5) {
int next = pos;
while (next < (int)data.length() && data[next] != ‘+’ && data[next] != ‘-’) next++;
if (next >= (int)data.length()) break;
int end = next + 1;
while (end < (int)data.length() && data[end] != ‘+’ && data[end] != ‘-’) end++;
values[idx++] = data.substring(next, end).toFloat();
pos = end;
}

float vwc = values[0];
float temp = values[1];
float ec = values[2];
float perm = values[3];
float period = values[4];

Serial.println(“──────────────────────────────────”);
Serial.print(“VWC : “); Serial.print(vwc, 3); Serial.println(” %”);
Serial.print(“Temperature : “); Serial.print(temp, 1); Serial.println(” C”);
Serial.print(“Bulk EC : “); Serial.print(ec, 1); Serial.println(” uS/cm”);
Serial.print(“Permittivity : “); Serial.print(perm, 2); Serial.println(””);
Serial.print(“Period : “); Serial.print(period, 0); Serial.println(” us”);
Serial.println(“──────────────────────────────────”);

// ── Step 4: Join ─────────────────────────────
if (!joinDone) {
Serial.println(“Joining LoRaWAN…”);
api.lorawan.join();

for (int i = 0; i < 15; i++) {
  delay(1000);
  Serial.print(".");
  if (api.lorawan.njs.get()) break;
}
Serial.println();

if (api.lorawan.njs.get()) {
  Serial.println("Joined!");
  delay(2000);
  joinDone = true;
} else {
  Serial.println("Join failed — will retry next cycle.");
}

}

// ── Step 5: Send uplink ───────────────────────
if (api.lorawan.njs.get()) {
uint16_t vwc_enc = (uint16_t)(vwc * 100);
int16_t temp_enc = (int16_t) (temp * 10);
uint16_t ec_enc = (uint16_t)(ec);
uint16_t perm_enc = (uint16_t)(perm * 100);
uint16_t period_enc = (uint16_t)(period);

payload[0] = (vwc_enc    >> 8) & 0xFF;  payload[1] = vwc_enc    & 0xFF;
payload[2] = (temp_enc   >> 8) & 0xFF;  payload[3] = temp_enc   & 0xFF;
payload[4] = (ec_enc     >> 8) & 0xFF;  payload[5] = ec_enc     & 0xFF;
payload[6] = (perm_enc   >> 8) & 0xFF;  payload[7] = perm_enc   & 0xFF;
payload[8] = (period_enc >> 8) & 0xFF;  payload[9] = period_enc & 0xFF;

// Send — ignore return value (RUI3 bug: returns false even on success)
api.lorawan.send(10, payload, LORAWAN_FPORT, false, 0);
Serial.println("Uplink transmitted.");
delay(5000);  // wait for TX_DONE

}

// ── Step 6: Sleep ─────────────────────────────
Serial.print(“Sleeping “);
Serial.print(SEND_INTERVAL_MS / 60000);
Serial.println(” min…”);
delay(100);

api.system.sleep.all(SEND_INTERVAL_MS);
joinDone = false; // rejoin after every sleep
}

Hi @yuv ,

If USB is connected, you can see all Serial output to be ok right? You can try to remove serial output if the issue is related to USB connection. Also, you can use the built-in LED to check where the code stopped running.

As for low power consumption, if you are using the module as an LoRa modem via AT commands, there should be no problem. But if you use it with custom application, it depends on how you implement your code. For use case with multiple routines, it is advisable to run them in tasks and not in an infinite loop.

i will focus on sdi12 reading (power consumption is the other big issue) -
i did some tests using RAK4631 RUI ( AT+VER=RUI_4.2.3_RAK4631 ) and ARDUINO. i have connected each of them to the same TDR315 address ‘A’ through RAK13010. i used the example RAK13010_SDI_12_Basic_Data_Request.ino, and changed these lines accoringlly-
// Serial.begin(115200,RAK_CUSTOM_MODE); // Uncomment if using RUI BSP.
Serial.begin(115200);
on the serial i see good result when using board as Arduino
Picture3

but no answer when using board as RUI.

Picture2

i used oscilloscope on the sdi12 data to try and understand better. it seems that RUI sends data as expected but maybe no answer from sensor? maybe problem with pin WB_IO4 (OE)?

when using board as arduino the oscilloscope shows data back and forth

what am i missing here?

Hi @carlrowan,

I have an important update regarding my setup. I’ve migrated my code from RUI3 to the Arduino BSP (using the latest RAK4631 Arduino board support package) to gain more flexibility with the SDI-12 implementation.

However, I’ve encountered a persistent power-related issue when the node is disconnected from the USB cable:

  1. The Core Issue: When running the node on a 3.7V Li-Ion battery (measured at 3.85V) and even with external 12V DC input (using j2 ), the SDI-12 sensor fails to return data, and the LoRaWAN Uplink is not sent.
  2. The “USB Factor”: As soon as I plug in the USB cable, the SDI-12 reading works perfectly, and the data is received at the Gateway.
  3. Validation: I performed a “Dummy Data” test (sending a hardcoded string instead of reading the sensor). In this mode, the node works perfectly on battery/DC power, confirming the LoRaWAN stack and Join process are stable on the Arduino BSP.

Power Observations on RAK13010: I monitored the 12V output terminal of the RAK13010 and noticed:

  • When active, the internal boost converter correctly steps up to 12.6V.
  • During sleep, the voltage drops only to ~4V (tracking the battery voltage) instead of 0V.

It seems that after moving to the Arduino BSP, the SDI-12 communication or the RAK13010’s initialization behaves differently when the 5V USB rail is missing. It’s as if the battery alone (3.85V) isn’t providing enough stability for the SDI-12 logic or the boost converter’s startup sequence.

Questions:

  • Since I’m now using the Arduino BSP, are there specific GPIO configurations or delays required for the RAK13010 when running on battery to ensure the boost converter is stable before communication?
  • Is the ~4V “leakage” on the 12V terminal during sleep expected, and could it be preventing the sensor from a proper Power-On Reset (POR) when not on USB?

I’d appreciate any guidance on how to make the SDI-12 reading reliable on battery power with the Arduino environment.


Hi @yuv ,

Let me provide some insights.

  1. There are two IO pins that are important: IO2 which enables the 12V Boost as well as the 5V DCDC and the IO4 for that controls the direction of the data bus. This is handled by the SDI library and you can see on the example code.

  1. Regarding the 4V leakage, if this affects your operation, then an external 12V might be needed. The boost converter as a “direct” connection from VIN to VOUT with the boost inductor and output diode in series. There is no electrical cut off mechanism that disconnect this boost off time in the circuit.