我们还能用它做什么?

让我们将相同的原则应用到一些伺服代码中,并进行一些操作。

首先在面包板上挂上几个伺服器,如下图所示。既然我们已经在做了,让我们连接第三个LED。

microcontrollers_Lights_and_Action_bb.png

这是标准的伺服扫描代码。注意,它调用了可怕的delay()。我们将从它中提取所需的部分来创建一个“Sweeper”状态机。

//扫描// by BARRAGAN  //这个示例代码在公共域。#include 伺服myservo;//创建伺服对象来控制伺服//最多可以创建八个伺服对象int pos = 0;//变量存储伺服位置void setup() {myservo.attach(9);//将引脚9上的伺服附加到伺服对象}void loop() {for(pos = 0;Pos < 180;Pos += 1) //从0度到180度{//在1度的步骤myservo.write(Pos);//告诉伺服去的位置在可变'pos'延迟(15);//等待15ms伺服到达位置}for(pos = 180;pos > = 1; pos-=1) // goes from 180 degrees to 0 degrees { myservo.write(pos); // tell servo to go to position in variable 'pos' delay(15); // waits 15ms for the servo to reach the position } }

下面的Sweeper类封装了扫描动作,但是使用millis()函数来计时,就像Flasher类对led所做的一样。

我们还需要添加Attach()和Detach()函数来将伺服与特定的引脚关联起来:

类扫地机{伺服伺服;//伺服int pos;//当前伺服位置int增量;//增加每个间隔的移动//更新间隔unsigned long lastUpdate;//最后一次更新位置public: Sweeper(int interval) {updateInterval = interval;增量= 1;} void Attach(int pin) {servo.attach(pin);} void Detach() {servo.detach();} void Update() {if((millis() - lastUpdate) > updateInterval) //更新时间{lastUpdate = millis(); pos += increment; servo.write(pos); Serial.println(pos); if ((pos >= 180) || (pos <= 0)) // end of sweep { // reverse direction increment = -increment; } } } };

你想要多少?

现在我们可以根据需要实例化尽可能多的flasher和sweeper。

Flasher的每个实例需要2行代码:

  • 一个用于声明实例
  • 一个在循环中调用update

每个Sweeper实例只需要3行代码:

  • 一个用于声明实例
  • 在安装过程中把它固定在大头针上
  • 循环中还有一个更新调用
#include  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 } } }; class Sweeper { Servo servo; // the servo int pos; // current servo position int increment; // increment to move for each interval int updateInterval; // interval between updates unsigned long lastUpdate; // last update of position public: Sweeper(int interval) { updateInterval = interval; increment = 1; } void Attach(int pin) { servo.attach(pin); } void Detach() { servo.detach(); } void Update() { if((millis() - lastUpdate) > updateInterval) // time to update { lastUpdate = millis(); pos += increment; servo.write(pos); Serial.println(pos); if ((pos >= 180) || (pos <= 0)) // end of sweep { // reverse direction increment = -increment; } } } }; Flasher led1(11, 123, 400); Flasher led2(12, 350, 350); Flasher led3(13, 200, 222); Sweeper sweeper1(15); Sweeper sweeper2(25); void setup() { Serial.begin(9600); sweeper1.Attach(9); sweeper2.Attach(10); } void loop() { sweeper1.Update(); sweeper2.Update(); led1.Update(); led2.Update(); led3.Update(); }

现在我们有5个独立的任务不间断地运行,没有干扰。我们的loop()只有5行代码!接下来,我们将添加一个按钮,以便与其中一些任务进行交互。

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

本页(彻底清除)最后更新于2014年10月27日。

文本编辑器tinymce