【问题标题】:Arduino: How to print out value of defined constants?Arduino:如何打印定义常量的值?
【发布时间】:2015-12-01 15:50:47
【问题描述】:

我正在 Arduino (1.6.5) 环境中编写代码。在我的代码中,我希望能够定义一个字符串值,然后使用它并将它的 Serial.println() 发送到串行控制台。

例如:

#define THEVAL 12345      // Define the value
...
v = v + THEVAL;     // Use the value in code.
...
Serial.println("The value is: #THEVAL");      // Show the value to user (for debugging)

但是,编译器不会替换带引号的字符串中的常量。我还尝试了this(C++ 字符串化),这表明您将常量 放在 带引号的字符串

#define THEVAL 12345
...
Serial.println("This is the value: " #THEVAL);

但这会在编译器中产生“Stray # character”错误。

如果有任何见解,我将不胜感激!谢谢!

编辑:奇怪的行为

在测试中,我发现了以下内容: (注意:IP 地址使用逗号分隔八位字节,因为每个八位字节都作为单独的参数传递给 EthernetServer.begin 字节数组(字节 ip[] = { a, b, c, d })

#define IP_ADDRESS 192,168,1,1
#define IP_ADDRESS_STRING(a,b,c,d) xstr(a)"."xstr(b)"."xstr(c)"."xstr(d)
#define xstr(a) str(a)
#define str(a) #a

如果我执行以下操作,我会收到错误“IP_ADDRESS_STRING 需要 4 个参数,但只给定一个”

debug("IP Address is: " IP_ADDRESS_STRING(IP_ADDRESS));

但如果我执行以下操作,我会收到错误“宏'str'传递了 4 个参数,但只需要 1 个”

debug("IP ADDRESS: " xstr(IP_ADDRESS));

但如果我这样做,它会起作用:

String ipAddressString(int a, int b, int c, int d)
{
    return String(a) + "." + String(b) + "." + String(c) + "." + String(d);
}

debug("IP Address is: " + ipAddressString(IP_ADDRESS));

我很困惑 - 为什么一个宏将 IP_ADDRESS 视为单个参数,而另一个宏将其视为 4 个参数,而函数正常工作:它看到 4 个参数?

【问题讨论】:

  • 我发现了这个:stackoverflow.com/questions/2653214/… 但如果常量有逗号,它就不起作用。例如:#define THEVAL 1,2,3
  • this 可能会有所帮助。
  • 嗨,尤金,这与我在原始评论中发布的链接相同...

标签: c arduino constants arduino-ide


【解决方案1】:
#define XSTR(s) STR(s)
#define STR(s) #s
....
#define THEVAL 12345
....
Serial.println("The value of " STR(THEVAL) " is " XSTR(THEVAL));

这将输出:

The value of THEVAL is 12345

【讨论】:

  • 但如果 THEVAL 设置为 123,456 则会失败。
【解决方案2】:
#define XSTR(s) STR(s)
#define STR(s) #s
....
#define THEVAL 12345
....
Serial.println("The value of " STR(THEVAL) " is " XSTR(THEVAL));

但如果 THEVAL 设置为 123,456,则会失败。

稍作修改也可以使用:

#define STR(...) #__VA_ARGS__

【讨论】:

    【解决方案3】:

    建议

    Serial.print("This is the value: ");
    Serial.println( THEVAL );
    

    int x = THEVAL;
    Serial.print("This is the value: ");
    Serial.println( x );
    

    【讨论】:

    • 如果 THEVAL 包含逗号怎么办?例如:#define THEVAL 123,456
    • 然后使用类似 sprintf() 的东西将值写入 char 缓冲区[100],然后使用类似 Serial.println(buffer) 的东西写入缓冲区;
    【解决方案4】:

    我很困惑 - 为什么一个宏将 IP_ADDRESS 视为单个宏 参数,而另一个宏将其视为 4 个参数,而 函数正常工作:它看到 4 个参数?

    在调用IP_ADDRESS_STRING(IP_ADDRESS) 中,显然只有一个参数IP_ADDRESS,无论IP_ADDRESS 是如何定义的,这都是正确的,因为会发生参数替换 只有在 确定调用类函数宏的参数之后 (ISO/IEC 9899:201x)。

    在定义为#define xstr(a) str(a) 的调用xstr(IP_ADDRESS) 中,根据上述参数a 然后被一个参数IP_ADDRESS 替换之后 该宏已经扩展宏替换),产生str(192,168,1,1),所以str被传递了4个参数。

    与第一种情况相比,在函数调用ipAddressString(IP_ADDRESS) 中,IP_ADDRESS 的替换不是在函数调用的参数被识别之后,而是在之前进行。

    您可以使用与xstr()/str() 相同的两阶段技术来使用宏:

    #define IP_ADDRESS 192,168,1,1
    #define XIP_ADDRESS_STRING(abcd) IP_ADDRESS_STRING(abcd)
    #define IP_ADDRESS_STRING(a,b,c,d) xstr(a)"."xstr(b)"."xstr(c)"."xstr(d)
    #define xstr(a) str(a)
    #define str(a) #a
    debug("IP Address is: " XIP_ADDRESS_STRING(IP_ADDRESS));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-06
      • 2011-02-12
      • 2018-11-19
      • 2021-05-06
      相关资源
      最近更新 更多