首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Arduino代码设计的接口

Arduino代码设计的接口
EN

Code Review用户
提问于 2018-09-10 04:00:27
回答 1查看 67关注 0票数 -1

编写代码可分为三个部分。

1.接口结构

在这个阶段,程序员应该描述在他的项目中使用的所有设备。当然,只有那些Arduino编程交互的人(例如传感器、芯片而不是中间电阻器)。在这个阶段,每个设备都由一个类描述类表示.描述类具有特殊的成员函数-引脚函数.这些函数是纯虚拟的,每个函数都打算从Arduino引号集合中返回8位无符号整数值。引脚功能在Arduino和外围设备之间起着导线的作用.Description类还应该包含用于此具体设备的Arduino指令函数。

Arduino也有一个description类,但现在它被用作带有常量的命名空间。到目前为止,不需要这个类的对象。

下面是一个使用该接口的示例。

  • 控制器: Arduino Uno R3
  • 外围:超声波传感器HC-SR04 04

1.1 Arduino Uno R3类-description

Arduino Uno R3 description-类仅由静态常量组成,这些常数是引脚号.

1.1.1 Uno.h

代码语言:javascript
运行
复制
#ifndef UNO_H
#define UNO_H

#include <inttypes.h>

class Uno
{
    public :
        //Digital pins
        static const uint8_t D0 = 0;
        static const uint8_t D1 = 1;
        static const uint8_t D2 = 2;
        static const uint8_t D3 = 3;
        static const uint8_t D4 = 4;
        static const uint8_t D5 = 5;
        static const uint8_t D6 = 6;
        static const uint8_t D7 = 7;
        static const uint8_t D8 = 8;
        static const uint8_t D9 = 9;
        static const uint8_t D10 = 10;
        static const uint8_t D11 = 11;
        static const uint8_t D12 = 12;
        static const uint8_t D13 = 13;
        //Analog pins
        static const uint8_t A0 = 0;
        static const uint8_t A1 = 0;
        static const uint8_t A2 = 0;
        static const uint8_t A3 = 0;
        static const uint8_t A4 = 0;
        static const uint8_t A5 = 0;
        //SPI
        static const uint8_t SS = D10;
        static const uint8_t MOSI = D11;
        static const uint8_t MISO = D12;
        static const uint8_t SCK = D13;
        //I2C
        static const uint8_t SDA = A4;
        static const uint8_t SCL = A5;
        //Serial
        static const uint8_t TX = D0;
        static const uint8_t RX = D1;
};
#endif

1.2.超声波传感器类.描述(抽象设备)

在这个例子中,我选择使用超声波传感器HC-SR04。它有四个引脚:VCCGNDTRIGECHO。尽管在现实中(不管是什么),所有四个引脚都连接到了Arduino,但是程序中只使用了TRIGECHO。到目前为止我不知道该怎么处理这些别针。也许他们不应该出现在代码中。

1.2.1 HC_SR04.h

代码语言:javascript
运行
复制
#ifndef HC_SR04_H
#define HC_SR04_H

#include <inttypes.h>

#include <Arduino.h>

class HC_SR04
{
    public :
        //pin-functions
        virtual uint8_t VCC() = 0;//???
        virtual uint8_t TRIG() = 0;
        virtual uint8_t ECHO() = 0;
        virtual uint8_t GND() = 0;//???
        //device specific functions
        void setup();

        long get_distance();
};
#endif

1.2.2 HC_SR04.cpp

代码语言:javascript
运行
复制
#include "HC_SR04.h"

void HC_SR04::setup()
{
    pinMode( TRIG(), OUTPUT );
    pinMode( ECHO(), INPUT );
}


long HC_SR04::get_distance()
{
    digitalWrite( TRIG(), LOW );
    delayMicroseconds( 2 );
    digitalWrite( TRIG(), HIGH );
    delayMicroseconds( 10 );
    digitalWrite( TRIG(), HIGH );

    return 0.017 * pulseIn( ECHO(), HIGH );
}

2.描述

在这个阶段,程序员应该“插入”表上的所有实际设备,方法是在派生自相应的类描述的子类中重载引脚函数。

2.1超声波传感器(实设备)

2.1.1 US.cpp

代码语言:javascript
运行
复制
#include "Uno.h"
#include "HC_SR04.h"

class US : public HC_SR04
{
    public :
        uint8_t VCC() { return 0; }//What to do with this pin
        uint8_t GND() { return 0; }//What to do with this pin
        uint8_t TRIG() { return Uno::D10; }//wire between TRIG-pin on US and 10th digital pin on Uno
        uint8_t ECHO() { return Uno::D11; }//...
};

3.主文件(.ino文件)

代码语言:javascript
运行
复制
#include "US.cpp"//bad line?

US us;//Create ultrasonic device plugged in as descripted in US.cpp file

void setup()
{
    Serial.begin( 9600 );

    us.setup();
}


void loop()
{
    Serial.println( us.get_distance() );
    delay( 1000 );
}

4.项目目录结构

5.讨论

下面是我对上述方法的看法。当然,可能是错的。

缺点:

  • 额外的抽象级别=(可能)对低内存控制器不利
  • 整个程序分为几个部分。各部分负责与具体设备的通信。(可能)对有依赖设备的项目不利

优势:

  • 整个程序分为几个部分。各部分负责与具体设备的通信。适合于具有许多独立外设的项目。
  • 自描述代码
  • 用于类似设备或具有相同设备的其他项目的可重用代码

请告诉我你怎么想的。一如既往,任何想法、更正、批评等都将不胜感激。

要将程序上传到Arduino,我使用Arduino的Makefile

EN

回答 1

Code Review用户

发布于 2018-09-10 06:10:50

你描述了你做了什么,但你没有充分描述你为什么这么做。你想通过你的设计来解决什么问题?我在你的设计中发现了一些主要的问题。

Uno.h

  • 不需要inttypes.huint8_tstdint.h
  • 名称空间而不是类就足够了。将这些常量定义为纯int constexpr
  • 永远不要将像A0这样的引脚定义为A5不完整、虚假和/或重叠。这会在运行时编译并产生严重的错误。如果你不知道密码,或者你的董事会不支持一些,你想知道在编译时。

主文件(.ino文件)

#include "US.cpp"//bad line? --答案是“是”。但这并不是你的错,因为阿迪诺套房“要求”这一点。对于常规设计(可以使用普通的cpp套件),您可以拆分头文件和cpp文件以获得编译速度。然而,arduino并没有提供一个make项目,但是建议您应该在一个文件中工作,并且只包含一个文件。您可以将此大小的项目的代码放在头文件中。参见下面的示例(构造函数、安装程序)。

HC_SR04.h

  • virtual uint8_t VCC() = 0;//??? --即使你也不知道它会是什么。其他人应该怎么做?你想解决什么问题?除非您想自动绘制示意图,否则不需要电源引脚号,并且应该删除???-lines。
  • virtual uint8_t TRIG() = 0;,如果它是专为继承而设计的,那么它应该是protected。但在这里,我们再次错过了这种继承设计的理由。我更喜欢在建筑时间设置一个简单的私人会员。

HC_SR04.cpp

  • 在中,最后一个digitalWrite( _trig_pin, HIGH );是冗余的

继承-这样的设计.

..。都坏了。

  • 板上的第二个感应器要求你写第二类。
  • 不同板上的同一传感器要求您用相同的代码编写另一个类,但为板编写一个修改后的包含行。

你最终会得到一个完整的矩阵,所有的板针组合类。对于不同的传感器,同样的矩阵。

如果您想要将多个传感器连接到一个单板上,您肯定不希望在一个类层次结构中编写多个类,这些类只根据引脚号不同。您需要多次实例化具有不同参数的单个类。

所以我们改变了传感器计划

  • 对板和/或销完全不可知
  • 在最后一个可能的级别上对模块进行耦合。在我们的例子中,这是(测试)应用程序级别。

我们将类更改为

代码语言:javascript
运行
复制
class HC_SR04
{
    public :
        HC_SR04(int trig_pin, echo_pin)
            : _trig_pin(trig_pin)
            , _echo_pin(echo_pin)
        {}
        //device specific functions
        void setup() {
            pinMode( _trig_pin, OUTPUT );
            pinMode( _echo_pin, INPUT );
        }
        long get_distance() {
            digitalWrite( _trig_pin, LOW );
            delayMicroseconds( 2 );
            digitalWrite( _trig_pin, HIGH );
            delayMicroseconds( 10 );
            return 0.017 * pulseIn( _echo_pin, HIGH );
        }
    private:
        int _trig_pin;
        int _echo_pin;
};

然后把它当作

代码语言:javascript
运行
复制
#include "HC_SR04.h"

HC_SR04 us(Uno::D10, Uno::D11);
票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/203439

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档