我创建了一个名为Fred的类,这里是.h和.cpp文件:
Fred.h
#ifndef Fred_h
#define Fred_h
#include "Arduino.h"
class Fred
{
public:
Fred();
};
#endif
Fred.cpp
#include "Fred.h"
Fred::Fred()
{
Serial.begin(115200);
Serial.println("Hello Arduino!");
}
在草图中我只是全局初始化了类对象:
#include <Fred.h>
Fred a;
void setup()
{}
void loop()
{}
它应该打印Hello Arduino!在串行终端,但它只打印前两个字节&#34;他&#34;,这是非常熟的!我读过有关SIOF(静态初始化命令Fiasco)它可能是问题,但如果是这样,为什么它打印2字节而不是根本不打印。如果我在setup函数中声明了对象,它就能正常工作。
答案 0 :(得分:2)
您无法从静态对象的构造函数访问Serial
,因为无法保证Serial
将被设置。你不想做任何&#34;真正的工作&#34;直到您输入main
。
在arduino的串口实现中,硬件缓冲可能只有两个字符。一旦发送了前两个,其余的就会被丢弃,因为排队它们和安排中断服务的必要逻辑可能还没有设置好。
所以第一个角色立即开始被发送出去。第二个字符位于硬件缓冲区中,等待第一个字符完成。其余的字符应该传递给一个中断处理程序(这样每次缓冲区为空时因为前一个字符已经完全发送,一个新字符就可以开始发送),但显然还没有设置。
答案 1 :(得分:1)
首先,由于SIOF,尝试在另一个单例的构造函数中调用单例的方法是错误的。在此对象可能尚未构造的情况下调用对象的方法很糟糕,并且可能导致奇怪的行为。因此,如果通过避免串行和Fred上的SIOF问题消失,您不需要质疑它为什么打印2个字节。
编辑: 如何避免SIOF?有很多方法可以做到这一点。但是如果你想为Fred保留单身,你应该使用COFU(https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Construct_On_First_Use)
答案 2 :(得分:0)
为了避免SIOF,您可以这样做:
我创建了一个名为Fred的类,这里是.h和.cpp文件:
Fred.h
#ifndef Fred_h
#define Fred_h
#include "Arduino.h"
class Fred
{
public:
Fred();
void printMessage();
};
#endif
Fred.cpp
#include "Fred.h"
Fred::Fred()
{
// nothing to do here
}
void Fred::printMessage()
{
Serial.println("Hello Arduino!");
}
并在草图中:
#include <Fred.h>
Fred a;
void setup()
{
Serial.begin(9600);
}
void loop()
{
a.printMessage();
}
希望这有帮助。