单片机打印日志的独特操作技巧,惊艳四座,让同事刮目相看!

大家好,我是麦鸽,这次分享一个小技巧,打印带颜色编码的日志,希望对你有所帮助。

log的重要性

在项目开发中,日志可以帮助我们调试和发现产品中潜藏的问题,比如在发生错误的时候,打印相应的日志,定位发生错误的位置,通常我们需要日志满足以下这些功能:

  • 不同的日志级别(TraceWarningInfoErrorfatal);

  • 能够设置日志级别;

  • 基于日志级别的颜色编码;

  • 占用空间小;

  • 可配置,可以完全禁用它;

  • 时间戳;

  • 易于集成;

  • 下面我们介绍一下如何在串口上打印出不同颜色的字符串。

    打印彩色的log

    在Stack Overflow上有人提出过类似的问题,如何在终端打印出彩色的字符?

    这里给出了一个很简单的C程序demo,我测试了一下,确实可以实现;

    #include <stdio.h>
    
    #define ANSI_COLOR_RED     "\x1b[31m"
    #define ANSI_COLOR_GREEN   "\x1b[32m"
    #define ANSI_COLOR_YELLOW  "\x1b[33m"
    #define ANSI_COLOR_BLUE    "\x1b[34m"
    #define ANSI_COLOR_MAGENTA "\x1b[35m"
    #define ANSI_COLOR_CYAN    "\x1b[36m"
    #define ANSI_COLOR_RESET   "\x1b[0m"
    
    int main (int argc, char const *argv[]) {
            
            printf(ANSI_COLOR_RED     "This text is RED!"     ANSI_COLOR_RESET "\r\n");
            printf(ANSI_COLOR_GREEN   "This text is GREEN!"   ANSI_COLOR_RESET "\r\n");
            printf(ANSI_COLOR_YELLOW  "This text is YELLOW!"  ANSI_COLOR_RESET "\r\n");
            printf(ANSI_COLOR_BLUE    "This text is BLUE!"    ANSI_COLOR_RESET "\r\n");
            printf(ANSI_COLOR_MAGENTA "This text is MAGENTA!" ANSI_COLOR_RESET "\r\n");
            printf(ANSI_COLOR_CYAN    "This text is CYAN!"    ANSI_COLOR_RESET "\r\n");
    
            return 0;
    }

    最终编译之后运行得到的结果如下,发现打印的字符颜色发生了变化;

    输出结果

    ANSI转义序列

    ANSI转义序列(ANSI escape sequences)是一种带内信号的转义序列标准,用于控制视频文本终端上的光标位置颜色其他选项。在文本中嵌入确定的字节序列,大部分以ESC转义字符"["字符开始,终端会把这些字节序列解释为相应的指令,而不是普通的字符编码

    所以这里我们查了一下ascii码表,可以发现ESC的码值是十进制的27,也就是十六进制的0x1b,具体如下所示;

    ascii码表

    所以转义序列的格式如下;

    转自wiki

    可以参考文档:https://invisible-island.net/xterm/ctlseqs/ctlseqs.html

    所以这里简单举个例子,设置不同的背景色;

    #include <stdio.h>
    
    int main(){
    
            for(int i = 0; i < 256; i++){
    
                    printf("\x1b[48;5;%dm %03d \x1b[0m", i, i);
    
                    if( i % 10 == 0){
                            printf("\r\n");
                    }
            }
            return 0;
    }

    重点是这一句:printf("\x1b[48;5;%dm %03d \x1b[0m", i, i);简单分析一下;

  • 其中\x1b[ 是起始指令,后面的48表示设置背景色,38是前景色;

  • 48后面通常会跟一个;5;,这个是文档中规定的,第一个%d,是设置色号,最后以m结尾;

  • 参数设置
  • 第二个%03d是中间需要显示的文本;

  • 最后以\x1b[0m结束;

  • 测试系统是Ubuntu 1804,最终的运行结果如下所示;

    运行结果

    单片机中实现

    单片机可以将日志通过串口打印出来,这时候需要显示彩色字符,需要一个前提,就是串口终端软件需要支持解析ANSI转义序列

    下面我做了简单的实验,通过STM32的串口,发送相应的字符,然后在PC端使用MobaXterm软件打开串口并接收数据;因为这个软件是支持ANSI序列的,所以最终可以显示出不同颜色的字符串。具体如下所示;

    moba xterm中的结果

    最后

    本文介绍了如何打印彩色字符串,其中简单介绍了ANSI转义序列,并且给出了几个小的实验结果,并在单片机上发送字符串到PC上,使用xterm串口终端,可以正常显示设置前景色的字符串,结果符合预期。

    其实已经有一些日志库可以支持彩色的打印。后面再来推荐一波。

    另外

    🫵兄弟们!一个人单打独斗确实能冲得挺快,但要想走得更远、更稳,还得靠一群志同道合的伙伴啊!

    👊 麦鸽的知识星球现在已经聚集了一波人,大家都在这里互相学习、共同进步。

    如果你也想找个靠谱的学习圈子,赶紧   戳链接 🔗 加入我们吧!

    在这里,你能读到星球专栏的干货,优质教程,练手项目,随时向麦鸽提问,还能帮你定制学习计划。别犹豫了,兄弟,一起冲!💪

    往期推荐

    嵌入式大神私藏的4个高效开发工具,很小众,用完真香

    真没想到还可以这样写状态机!QP嵌入式实时框架

    手把手教你写一个简易的嵌入式日志系统

    推荐一个实用的嵌入式日志开源项目 dbuglib

    调试利器!一款轻量级日志库 log.c

    作者:小麦大叔

    物联沃分享整理
    物联沃-IOTWORD物联网 » 单片机打印日志的独特操作技巧,惊艳四座,让同事刮目相看!

    发表回复