緊急車両 - ボタンとパッシブブザー音で2つのLEDを点滅させる

私の父と私はちょうど私の新しいUNOの使い方を学んでいます。

ボタンを押すだけでLEDを点滅させる方法を学びました。また、ボタンを押すだけでパッシブブザーを鳴らしたり、パトカーのように鳴らす方法も学びました。

ブザーコードとLEDコードを2回(青と赤のLED用に)組み合わせて使用​​すると、複数のループを実行できないことがわかりました。しかし、LEDの遅延がブザー音を損なっています。私たちにできることはありますか?

コードは以下の通りです。

ありがとうございました!

コード:

int buzzerPin = 9;   //the number of the buzzer pin
int BlueLEDpin = 5;  //the number of the blue LED pin
int RedLEDpin = 7;   //the number of the Red LED pin  
float sinVal;        //Define a variable to save sine value for buzzer
int toneVal;         //Define a variable to save sound frequency for buzzer

void setup() {
  pinMode(buzzerPin, OUTPUT);//Set Buzzer pin to output mode
  pinMode(BlueLEDpin, OUTPUT);//Set Blue LED pin to output mode
  pinMode(RedLEDpin, OUTPUT);//Set Red LED pin to output mode
}

void loop() { 
    Buzzer(); 
    BlueLED();
    RedLED();

}

void Buzzer() {
  for (int x = 0; x < 360; x++) {      //X from 0 degree->360 degree
    sinVal = sin(x * (PI/180));      //Calculate the sine of x
    toneVal = 2000 + sinVal * 500;     //Calculate sound frequency according to the sine of x
    tone(buzzerPin, toneVal);          //Output sound frequency to buzzerPin
    delay(1);
  }

 }

  void BlueLED() {
  digitalWrite(5, HIGH);  //turn the LED on (HIGH is the voltage level)
  delay(1);             //wait for a second
  digitalWrite(5, LOW);   //turn the LED off by making the voltage LOW
  delay(1);             //wait for a second
}

void RedLED() {
  digitalWrite(7, HIGH);  //turn the LED on (HIGH is the voltage level)
  delay(1);             //wait for a second
  digitalWrite(7, LOW);   //turn the LED off by making the voltage LOW
  delay(1);             //wait for a second
}
3
追加された
ビュー: 1
うわー、ありがとう。私達は今とても誇りに思っています。
追加された 著者 Steve S,
コメントとコードを別々にしておくことができれば、見栄えのするコードになります。
追加された 著者 jsotola,

5 答え

あなたの問題はあなたのBlueLED()とRedLED()呼び出しのdelay()です。より多くの「同時」アクティビティを取得するには、これらの遅延を実装するためにタイマー割り込みを使用する必要があります。概念的にははるかに複雑ですが、正しい方法です。

2
追加された
それは簡単な仕事でした!うまくいったことをうれしく思います。
追加された 著者 George Bailey,
Harperありがとうございます。それはとても役に立ちました。私たちはあなたのアドバイスに従っただけで解決しましたありがとうございます。
追加された 著者 Steve S,

私たちはそれをやりました。助けてくれたHarper Shelbyに感謝します。

Blink Without Delayの例を元のコードと組み合わせました。

int buzzerPin = 9;   //the number of the buzzer pin
const int BlueLEDpin = 5;
const int RedLEDpin = 7;    
float sinVal;        //Define a variable to save sine value
int toneVal;         //Define a variable to save sound frequency
int BlueLEDState = LOW; 
int RedLEDState = HIGH; 
unsigned long previousMillisBlue= 0;
unsigned long previousMillisRed= 0;
const long interval = 200; 

void setup() {
  pinMode(buzzerPin, OUTPUT);//Set Buzzer pin to output mode
  pinMode(BlueLEDpin, OUTPUT);
  pinMode(RedLEDpin, OUTPUT);
}

void loop() {
    Buzzer(); 
    BlueLED();
    RedLED();

}

void Buzzer() {
  for (int x = 0; x < 360; x++) {      //X from 0 degree->360 degree
    sinVal = sin(x * (PI/180));      //Calculate the sine of x
    toneVal = 2000 + sinVal * 500;     //Calculate sound frequency according to the sine of x
    tone(buzzerPin, toneVal);          //Output sound frequency to buzzerPin
    delay(1);
  }

 }

  void BlueLED() {
  unsigned long currentMillisBlue = millis();

  if (currentMillisBlue - previousMillisBlue >= interval) {
    previousMillisBlue = currentMillisBlue;
    if (BlueLEDState == LOW) {
      BlueLEDState = HIGH;
    } else {
      BlueLEDState = LOW;
    }

    digitalWrite(BlueLEDpin, BlueLEDState);
  }

}

void RedLED() {
  unsigned long currentMillisRed = millis();

  if (currentMillisRed - previousMillisRed >= interval) {
    previousMillisRed = currentMillisRed;
    if (RedLEDState == LOW) {
      RedLEDState = HIGH;
    } else {
      RedLEDState = LOW;
    }

    digitalWrite(RedLEDpin, RedLEDState);
  }

}
2
追加された

はじめにおめでとうございます。あなたはマイクロコントローラの非常にやりがいのある世界にあなたの最初の一歩を踏み出しました。私は地元の大学でロボット工学を教えているので、電球が点灯して人々が理解し始めるときを見るのはいつもいいことです。

上記のように、遅延コードなしの点滅は良いスタートです。良いコードは、後でもう一つのライトや10を追加したい場合に備えて拡張可能であるべきです、そしてこれは各行のコーディングが非常に大きくなることがあるところです。この種のタスクを実行する方法は他にもたくさんありますが、この一連のチュートリアルをご覧になることをお勧めします。 Arduinoでのマルチタスク

この例で使用されているステートマシンアプローチの利点は、後でコードを変更するのが非常に簡単になることです。もっと多くのライトを順番に点滅させたい場合(ナイトライダーライトのように)、またはもっと多くのサイレンが欲しい場合は、含めるのが簡単になります。 2番目のコードでは、void redLED()とvoid blueLED()のコードにはほとんど同じ行が含まれています。あなたは 'LED'と呼ばれるオブジェクトを作り、それからあなたが必要とするだけの数のこのインスタンスを作ることができます。コードの)。たとえば、4種類のサイレンをスイッチとしてプログラムすることもできます。経過時間が経過したら、それらを切り替えます。

もう1つのより高度な方法は、リアルタイムオペレーティングシステムを含めることです。 RTOSを使用すると、複数の独立したタスクを実行するのが非常に簡単になります。それぞれの光はそれ自身の仕事にあり、サイレンは3分の1にあるかもしれません、そしてシステムは効果的に同時に、それぞれが働くのを保つでしょう。このアプローチは、1つの照明のタイミングを変更したい場合に有利になります。コード全体を変更する必要なしに、一箇所で変更されます。 Arduino上のFreeRTOSに関する情報はこちらにありますページの下部に、点滅とアナログの両方の読み取り例を含む例があります。

これらはかなり高度なトピックですが、私はあなたとあなたのお父さんがそこに着くと思います。もう一度おめでとうございます。

1
追加された
ネイサンありがとうございます!私たちはこの次を調べます、そしてあなたが私たちに与えたウェブサイトのリンクは素晴らしく見えます。
追加された 著者 Steve S,

これはおそらく少し高度ですが...

基本クラスと派生LEDクラスおよびブザークラスへのポインタを使用して、ループ機能をループに減らすことができます。このレベルではそれほど多くは得られませんが、点滅するヘッドライトやミラーライトなどのオブジェクトを追加すると、背面のメッセージボードでさえも、自分の生活を楽にすることができます。

/*
Jacob & Dad’s Police Car light and sounds
*/

class BaseOutputObject
{
protected:
    int Pin;
public:
    BaseOutputObject(const int& pin)
        : Pin(pin)
    {
        pinMode(Pin, OUTPUT);
    }
    virtual void Update()
    {
    }
};

class FlashingLED : public BaseOutputObject
{
    long OnTime;
    long OffTime;
    int ledState;
    unsigned long previousMillis;
public:
    FlashingLED(const int& pin, const long& on, const long& off, const bool& startLow = true)
        : BaseOutputObject(pin)                    //Call base class constructor                      
        , OnTime(on)                           //Use initialisers rather than assignments 
        , OffTime(off)
        , ledState(startLow ? LOW : HIGH)
        , previousMillis(0)
    {
    }

    void Update()
    {
       //check to see if it's time to change the state of the LED
        const unsigned long currentMillis = millis();          //Make it const because it won't change within this call of the function.

        if (currentMillis - previousMillis >= OnTime)
        {
            ledState = (ledState == LOW ? HIGH : LOW); //Toggle the state.
            previousMillis = currentMillis; //Remember the time
            digitalWrite(Pin, ledState); //Update the actual LED
        }
    }
};

class Buzzer : public BaseOutputObject
{
    float SinValue;
    int ToneValue;
public:
    Buzzer(const int& pin)
        : BaseOutputObject(pin)
        , SinValue(0.0f)       //Always initialise variables, in case you change the code later.
        , ToneValue(0)
    {
    }

    void Update()
    {
        for (int x = 0; x < 360; x++)
        {
            SinValue = sin(x * (PI/180));
            ToneValue = 2000 + SinValue * 500;
            tone(Pin, ToneValue);
            delay(1);
        }
    }

};

// The objects could be declared dynamically, but thats not a great idea on embedded systems.
FlashingLED ledOne(5, 100, 400);
FlashingLED ledTwo(7, 100, 400);
Buzzer buzzer(9);
enum { LED_ONE, LED_TWO, BUZZER, MaxObjects };
// Have to have pointers to the objects to allow you to cast them down to the base objects.
BaseOutputObject* objects[MaxObjects] = {  &ledOne, &ledTwo, &buzzer};

void setup()
{
}

void loop()
{
    for (int index = 0; index < MaxObjects; ++index)
    {
        objects[index]->Update();
    }
}
0
追加された

私たちはネイサンの指針でそれを良くしました。

私たちはクラスの作り方を学びましたがLEDが一緒に点滅したので、私たちは別のクラスを作る方法を学びました(クラスのPublicとVoid Updateで - 最初にそのビットを見つけました)。一方のクラスは状態HIGHで開始し、もう一方のクラスは状態LOWで開始するため、LEDは交互に点灯します。 3つのボタンをすべて押すと、ツートーンブザーとLEDが交互に点灯します。

この方法を使うと、好きなだけ新しいLEDを追加できます。

これが私たちが書いたコードです。

/*
  Jacob & Dad’s Police Car light and sounds
*/

int buzzerPin = 9;    
float sinVal;         
int toneVal;         

class FlashingLED_A
{
    int ledPin;     
    long OnTime;     
    long OffTime;    
    int ledState;                   
    unsigned long previousMillis;   
  public:
  FlashingLED_A(int pin, long on, long off)
  {
    ledPin = pin;
    pinMode(ledPin, OUTPUT);     
    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;   
      digitalWrite(ledPin, ledState);     
    }
  }

};

class FlashingLED_B
{
    int ledPin;  
    long OnTime;    
    long OffTime;   
    int ledState;                   
    unsigned long previousMillis;   
  public:
  FlashingLED_B(int pin, long on, long off)
  {
    ledPin = pin;
    pinMode(ledPin, OUTPUT);     
    OnTime = on;
    OffTime = off;
    ledState = HIGH; 
    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;   
      digitalWrite(ledPin, ledState);    
    }
  }

};

FlashingLED_A led1(5, 100, 400);
FlashingLED_B led2(7, 100, 400);

void setup() {
  pinMode(buzzerPin, OUTPUT);
}

void loop() {
  Buzzer(); 
    led1.Update();
    led2.Update();
}

void Buzzer() {
  for (int x = 0; x < 360; x++) {      
    sinVal = sin(x * (PI/180));       
    toneVal = 2000 + sinVal * 500;    
    tone(buzzerPin, toneVal);          
    delay(1);
  }
 }
0
追加された
FlashingLED_AFlashingLED_B の唯一の違いは、AがLOWから始まりBがHIGHから始まることです。もしそうなら、私はクラスコンストラクタに追加のパラメータを追加し、単にクラスのいずれかを使用します。
追加された 著者 Thomas Myron,