#pragma once #include /* Define ENABLE_SERIAL_LOG to enable logging Can be set in platformio.ini build_flags or as a compile definition Define LOG_LEVEL to control log verbosity: 0 = ERR only 1 = ERR + INF 2 = ERR + INF + DBG If not defined, defaults to 0 If you have a legitimate need for raw Serial access (e.g., binary data, special formatting), use the underlying logSerial object directly: logSerial.printf("Special case: %d\n", value); logSerial.write(binaryData, length); The logSerial reference (defined below) points to the real Serial object and won't trigger deprecation warnings. */ #ifndef LOG_LEVEL #define LOG_LEVEL 0 #endif static HWCDC& logSerial = Serial; void logPrintf(const char* level, const char* origin, const char* format, ...); #ifdef ENABLE_SERIAL_LOG #if LOG_LEVEL >= 0 #define LOG_ERR(origin, format, ...) logPrintf("[ERR]", origin, format "\n", ##__VA_ARGS__) #else #define LOG_ERR(origin, format, ...) #endif #if LOG_LEVEL >= 1 #define LOG_INF(origin, format, ...) logPrintf("[INF]", origin, format "\n", ##__VA_ARGS__) #else #define LOG_INF(origin, format, ...) #endif #if LOG_LEVEL >= 2 #define LOG_DBG(origin, format, ...) logPrintf("[DBG]", origin, format "\n", ##__VA_ARGS__) #else #define LOG_DBG(origin, format, ...) #endif #else #define LOG_DBG(origin, format, ...) #define LOG_ERR(origin, format, ...) #define LOG_INF(origin, format, ...) #endif class MySerialImpl : public Print { public: void begin(unsigned long baud) { logSerial.begin(baud); } // Support boolean conversion for compatibility with code like: // if (Serial) or while (!Serial) operator bool() const { return logSerial; } __attribute__((deprecated("Use LOG_* macro instead"))) size_t printf(const char* format, ...); size_t write(uint8_t b) override; size_t write(const uint8_t* buffer, size_t size) override; void flush() override; static MySerialImpl instance; }; #define Serial MySerialImpl::instance