Logging macro in best practices

Looking at the examples in [GitHub - RAKWireless/RUI3-Best-Practice: This repo provides additional examples for RUI3. It focuses on low power consumption and practical examples for range tests, location tracking and sensing applications using the WisBlock Modular System.], I see the following logging macro used in most cases:

#define MYLOG(tag, ...)                  \
	do                                   \
	{                                    \
		if (tag)                         \
			Serial.printf("[%s] ", tag); \
		Serial.printf(__VA_ARGS__);      \
		Serial.printf("\n");             \
	} while (0);                         \
	delay(100)

I have a few questions:

  1. Why is delay(100) placed outside the do...while(0) block?
  2. Why is Serial.flush(); is added — what’s the reason for this addition?
  3. When Serial.flush(); is used, why is delay(100) still necessary?

Thank you for your help.

P.S. Are you still planning to support PlatformIO? Any idea when it might be available?

  1. The delay is outside of the do-while to give the MCU time to flush the TX queue. Depending on the MCU, the TX buffer might not be flushed because the MCU goes into sleep mode as fast as possible.

  2. Flush is added to force to send out everything in the TX buffer

  3. Answered in 1), make sure the TX buffer is flushed before MCU goes into sleep.

No support for PlatformIO planned from our side.

There is a branch of the STM32 PIO platform for RAK3172 from Max Gerhard that supports RUI3, but it is not maintained by us.

I tested it and it works. To use it your platformio.ini must specify that specific branch:

[env:RAK3172-PIO-Kit-1]
platform = https://github.com/maxgerhardt/platform-ststm32.git#rak3172
board = rak3172_evalboard
framework = arduino
build_flags = 
	-DREGION_AS923_3=1
	-DSUPPORT_LORA=1
	-DSW_VERSION_1=1 ; major version increase on API change / not backwards compatible
	-DSW_VERSION_2=0 ; minor version increase on API change / backward compatible
	-DSW_VERSION_3=2 ; patch version increase on bugfix, no affect on API
lib_deps = 
	electroniccats/CayenneLPP
	closedcube/ClosedCube OPT3001
	pilotak/LPS35HW

Here is a complete PIO project. It is for our WisBlock Kit 1 with
RAK1901, RAK1902, RAK1903 WisBlock sensors
RAK19007 Base Board
RAK3372 Core module (replacing the original RAK4631).

RUI3-RAK3172-PIO-Kit-1.zip (21.4 KB)

Thank you for the response.

I understand that delay(100) is used to give the UART time to flush the TX buffer before the MCU goes to sleep.

However, I’m still unclear on two points:

1. Why is delay(100) placed outside the do...while(0) block?

Since the do...while(0) is not a loop but a common C macro pattern for safely grouping statements, placing delay(100) outside means that if MYLOG is used inside an if statement without braces, the delay still executes even when the condition is false.

Wouldn’t it be safer and more consistent to place the delay inside the block?

2. Why is Serial.flush(); not used in all examples?

Some examples include Serial.flush(); after Serial.printf("\n");, while others don’t. Is this due to platform-specific behavior, or just a matter of example evolution?

If flushing the buffer is important, shouldn’t it be included consistently?


Thanks again for the clarification, and for all the work on the RUI3 platform!

Flushing is not important, it just might be that you see the log output not immediately, but you see it when the MCU wakes up next time.

Thanks for the clarification!

Just to confirm — if Serial.flush(); is not important and logs can wait until the MCU wakes up, does that not mean that delay(100) is also optional in most cases? How does delay(100) help without Serial.flush();? (I am using a RAK3172)

One more thing I’m still unclear about:
Why is delay(100) placed outside the do { ... } while (0) block? Since that block is used to safely group the macro contents into a single statement, putting delay(100) outside makes MYLOG() unsafe to use in if statements without braces. Is there a specific reason for keeping it outside the block?

I’m trying to understand both the timing behavior and the macro structure. Thanks again!

I didn’t put much thought into this. Using it since ever, some examples I saw debug message coming delays, so I added the delay. Other examples don’t have it.

It is just a debug output.

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