为什么全局对象构造函数只打印Arduino中的前2个字符?

时间:2015-01-29 10:11:50

标签: c++ arduino

我创建了一个名为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函数中声明了对象,它就能正常工作。

3 个答案:

答案 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();
}

希望这有帮助。