Help Needed: Can't Power Down Sensor on WisBlock RAK4631

Hi all,

I’m using a RAK4631 with the WisBlock base board 19007. I have a serial TTL sensor (3.3V) connected to RX1, directly on the board pins (no I/O module). I can successfully read data from the sensor on Serial1, save it to flash, and send it via LoRaWAN — but I can’t manage to power down the WisBlock board during sleep, so my sensor keeps drawing 2 mA.

Using digitalWrite(WB_IO2, LOW); has no effect. Even when the board wakes up (digitalWrite(WB_IO2, LOW); delay(30000);), I can’t seem to cut power to the sensor.

Am I missing something?

I’m considering using a MOSFET to control power to the sensor… does anyone have a better idea?

Hope someone can help.

Best regards,

  • What firmware are you using? (RUI3 or Arduino BSP or other IDE (e.g. STM32CubeIDE)?
    Arduino BSP + platformIO

  • What firmware version? Can it be obtained with AT+VER=?

AT+VER=WisBlock API 2.0.21

  • How can we replicate the problem?

Try digitalWrite(WB_IO2, LOW) and monitor voltage between GND and VDD pins.

  • Provide source code if custom firmware is used or link to example if RAKwireless example code is used.
void setup_app(void)
{
	Serial.begin(115200);
	time_t serial_timeout = millis();
	// On nRF52840 the USB serial is not available immediately
	while (!Serial)
	{
		if ((millis() - serial_timeout) < 5000)
		{
			delay(100);
			digitalWrite(LED_GREEN, !digitalRead(LED_GREEN));
		}
		else
		{
			break;
		}
	}
	digitalWrite(LED_GREEN, LOW);

	// Set firmware version
	api_set_version(SW_VERSION_1, SW_VERSION_2, SW_VERSION_3);

	MYLOG("APP", "Setup application");
	g_enable_ble = false;
}

/**
 * @brief Final setup of application  (after LoRaWAN and BLE setup)
 *
 * @return true
 * @return false
 */
bool init_app(void)
{
	pinMode(WB_IO2, OUTPUT); 	//WB_IO2 controls the supply voltage called 3V3_S.
	digitalWrite(WB_IO2, HIGH);

	init_custom_at();

	Wire.begin();

	MYLOG("APP", "Initialize RTC");

	init_rtc();  // Initialisation de l'RTC seulement une fois

	MYLOG("APP", "RTC ok");

	restart_advertising(15);

	MYLOG("APP", "Initialize application");

	digitalWrite(WB_IO2, LOW);
	
	return true;
}

/**
 * @brief Handle events
 * 		Events can be
 * 		- timer (setup with AT+SENDINT=xxx)
 * 		- interrupt events
 * 		- wake-up signals from other tasks
 */
void app_event_handler(void)
{
	MYLOG("APP", "app_event");

	// Timer triggered event
	if ((g_task_event_type & STATUS) == STATUS)
	{
		g_task_event_type &= N_STATUS;
		MYLOG("APP", "Timer wakeup");

		// Alimentation capteurs
		pinMode(WB_IO2, OUTPUT);
		digitalWrite(WB_IO2, HIGH);


		time_t timeout = millis();

		Serial1.begin(9600);
		while (!Serial1)
		{
			if ((millis() - timeout) < 5000)
			{
				delay(100);
			}
			else
			{
				break;
			}
		}

		delay(1000); // Stabilisation

		// Préparation payload
		payload.reset();
		read_rtc();         // Remplit sensor.unix_time
		readMB7389();       // Remplit sensor.us_distance

		// Lecture tension batterie (moyenne sur 10)
		float batt_level_f = 0.0;
		for (int i = 0; i < 10; i++)
		{
			batt_level_f += read_batt();
		}
		batt_level_f /= 10.0;
		sensor.batteryVoltage = (uint16_t)(batt_level_f);

		// Ajout au payload LoRa
		payload.addVoltage(LPP_CHANNEL_BATT, sensor.batteryVoltage);

		char iso_time[21];               // Buffer pour ISO 8601
	
		unixToIso8601(sensor.unix_time, iso_time, sizeof(iso_time));

		// Log format texte
		MYLOG("DATA", "time : %s, distance =%u mm, Batt=%.3f V",iso_time, sensor.us_distance, sensor.batteryVoltage/1000.0);

		// --- ENREGISTREMENT FLASH ---
		create_filename(); // Remplit pt_LOG_fileName (selon date/heure)

		initFlash();
		writeDataToFlash(pt_LOG_fileName);
		endFlash();

		// Log hex du payload
		char hexDump[512];
		for (int i = 0; i < payload.getSize(); i++)
		{
			sprintf(&hexDump[i * 2], "%02X", payload.getBuffer()[i]);
		}
		MYLOG("PAYLOAD", "Payload hex: %s", hexDump);

		// Transmission LoRa
		if (g_lorawan_settings.lorawan_enable)
		{
			if (g_lpwan_has_joined)
			{
				lmh_error_status result = send_lora_packet(payload.getBuffer(), payload.getSize());
				switch (result)
				{
				case LMH_SUCCESS:
					MYLOG("APP", "Packet enqueued");
					break;
				case LMH_BUSY:
					MYLOG("APP", "LoRa transceiver busy");
					break;
				case LMH_ERROR:
					MYLOG("APP", "Packet error (DR too low?)");
					break;
				}
			}
			else
			{
				MYLOG("APP", "Not joined, skip sending");
			}
		}

		Serial1.flush();  // Vide les transferts en cours (si tu en faisais)
		Serial1.end();

		digitalWrite(WB_IO2, LOW);

		MYLOG("APP", "down");
	}

}


WB_IO2 is only controlling the power to sensor and IO modules if they are using 3V3_S as supply.
How do you power your external sensor? If it is connected to VDD on the pin headers, you can’t control it with WB_IO2.

3V3_S is not available on any pin header. It is used directly on the modules or you can use the RAK13002, which has the option to control the 3.3V supply.

Thank you Bernd,
Yes, I’m connected to VDD. This was my guess… I will first try with a MOSFET to control the power, otherwise I will try with RAK13002.

Hello Bernd,
I’m back on this project. I ordered and tested the RAK13002 as a powering solution. It seems that the VCC on this module is not controlled by WB_IO2 (3V3_S).
I also tried with an N-channel MOSFET, but cutting the low side is not efficient because I still get leakage through the serial pin of my sensor.

The easiest solution I found is to power my sensor (nominal current 2.3 mA) with WB_IO1 and power down the RAK13002 with WB_IO2. According to the nRF52840 datasheet, this should be fine up to 9–14 mA.
Best practice would be to use a power transistor controlled by an IO, but I want (and need) to minimize as much as possible any soldering or adding of extra components.

Update: Powering the sensor from an IO pin is not suitable. I was able to get a few measurements, but it no longer works. I suspect the power is too low, since it works perfectly when powered from the VCC pin… but I can’t turn off the VCC pin of the RAK13002 during sleep.
Cutting the low side is not enough, because I get some leakage from the serial port… and cutting the high side requires too many extra components.

It seems there is no simple solution to handle a basic serial read and sleep with the RAK4631 and its ecosystem…?

Hi @peatlander,

If you look at the schematic for the RA13002 in the datasheet section, you’ll see that R1 is a zero ohm link and R2 is not loaded.

If you desolder R1 and move it to the R2 pads, the switchable 3V3_S power will be connected to the VDD pins rather than the unswitched 3v3 power.

RAK have used this trick often, but frustratingly it isn’t always an option (and I’ve moaned about it before).

It looks like the position to swap is in the upper right of this image:

Thanks a lot, Mark!
Switching the resistor was the trick! I had looked at the schematic before but didn’t pay enough attention to those resistors (and didn’t realize I could change them).

Powering with WB_IO3 (or 4, or…) was eventually suitable for my sensor’s power needs, but I needed to add a delay (500 ms) after switching the pin to HIGH and before initializing Serial1. However, during sleep I had leakage somewhere on the RAK4631 or RAK10007 board (300 µA vs. 30 µA), even after setting the pin LOW before sleep and/or enabling input pull-down.

Anyway, switching the resistor is a much better solution and fully meets my needs, so I’ll stick with it!

Greetings!

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.