让我们再看一下最后的草图。正如你所看到的,这是非常重复的。对于每个闪烁的LED,相同的代码几乎一字不差地重复。唯一(轻微)改变的是变量名。

这段代码是一个主要的候选人ObjectOrientedP编程(OOP)。

在循环中加入一点OOP。

Arduino语言是c++的变体,支持面向对象编程。使用该语言的面向对象特性,我们可以将闪烁LED的所有状态变量和功能聚集在一起c++类

这并不难做到。我们已经为它编写了所有的代码。我们只需要把它重新打包成一个类。

定义一个类:

我们首先声明一个“Flasher”类:

然后我们加入FlashWithoutDelay中的所有变量。因为它们是类的一部分,所以它们被称为成员变量

class Flasher{//类成员变量//这些在启动时初始化int ledPin;// LED引脚长OnTime的个数;// on-time长OffTime毫秒;//毫秒off-time //这些保持当前状态int ledState;// ledState用来设置LED的unsigned long previous smillis;//将存储上一次LED更新的时间};

接下来我们添加构造函数。构造函数具有与类相同的名称,它的任务是初始化所有变量。

class Flasher{//类成员变量//这些在启动时初始化int ledPin;// LED引脚长OnTime的个数;// on-time长OffTime毫秒;//毫秒off-time //这些保持当前状态int ledState;// ledState用来设置LED的unsigned long previous smillis;//将存储最后一次LED被更新//构造函数-创建一个Flasher //并初始化成员变量和状态public: Flasher(int pin, long on, long off) {ledPin = pin;pinMode (ledPin、输出);OnTime = on;OffTime = off;ledState = LOW; previousMillis = 0; } };

最后,我们将循环转换为成员函数称为“Update()”。注意,这与我们最初的void循环()相同。只是名字变了。

class Flasher{//类成员变量//这些在启动时初始化int ledPin;// LED引脚长OnTime的个数;// on-time长OffTime毫秒;//毫秒off-time //这些保持当前状态int ledState;// ledState用来设置LED的unsigned long previous smillis;//将存储最后一次LED被更新//构造函数-创建一个Flasher //并初始化成员变量和状态public: Flasher(int pin, long on, long off) {ledPin = pin;pinMode (ledPin、输出);OnTime = on;OffTime = off;ledState = LOW; previousMillis = 0; } void Update() { // check to see if it's time to change the state of the LED unsigned long currentMillis = millis(); if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime)) { ledState = LOW; // Turn it off previousMillis = currentMillis; // Remember the time digitalWrite(ledPin, ledState); // Update the actual LED } else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime)) { ledState = HIGH; // turn it on previousMillis = currentMillis; // Remember the time digitalWrite(ledPin, ledState); // Update the actual LED } } };

通过简单地将现有代码重新排列到Flasher类中,我们已经封装了所有变量状态)和功能(the)用于闪烁LED。

现在让我们使用它:

现在,对于每个我们想要闪光的LED,我们创建一个实例类的构造函数.在每次循环中,我们只需要为Flasher的每个实例调用Update()。

不再需要复制整个状态机代码。我们只需要请求Flasher类的另一个实例!

class Flasher{//类成员变量//这些在启动时初始化int ledPin;// LED引脚长OnTime的个数;// on-time长OffTime毫秒;//毫秒off-time //这些保持当前状态int ledState;// ledState用来设置LED的unsigned long previous smillis;//将存储最后一次LED被更新//构造函数-创建一个Flasher //并初始化成员变量和状态public: Flasher(int pin, long on, long off) {ledPin = pin;pinMode (ledPin、输出);OnTime = on;OffTime = off;ledState = LOW; previousMillis = 0; } void Update() { // check to see if it's time to change the state of the LED unsigned long currentMillis = millis(); if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime)) { ledState = LOW; // Turn it off previousMillis = currentMillis; // Remember the time digitalWrite(ledPin, ledState); // Update the actual LED } else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime)) { ledState = HIGH; // turn it on previousMillis = currentMillis; // Remember the time digitalWrite(ledPin, ledState); // Update the actual LED } } }; Flasher led1(12, 100, 400); Flasher led2(13, 350, 350); void setup() { } void loop() { led1.Update(); led2.Update(); }

少即是多!

就是这样——每个额外的LED只需要两行代码!

这段代码更短,更容易阅读。而且,由于没有重复的代码,它还编译得更小!那就留给你更宝贵的记忆去做其他的事情!

本指南首次发布于2014年11月3日。最后更新于2014年10月27日。

本页(一个经典的解决方案)最后更新于2014年10月27日。

文本编辑器tinymce