Аварійний автомобіль - Зробіть два світлодіоди спалахом кнопками, а пасивний звуковий сигнал змінить звук

Мій тато і я просто вчимося використовувати мій новий ООН.

Ми навчилися робити спалах світлодіодів одним натисненням кнопки. Ми також навчилися робити пасивний звуковий сигнал за допомогою натискання кнопки і змінювати тон, щоб звучати як поліцейська машина.

Ми тільки що дізналися, що ми не можемо працювати більше, ніж один цикл, тому ми двічі поєднували код зумер та код світлодіода (для синього та червоного світлодіодів), і це працює ... але затримка на світлодіодах руйнує звуковий сигнал. Чи можемо ми щось зробити?

Код наведено нижче.

Дякую!

Код:

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
Вау, дякую. Ми зараз дуже пишаємося.
додано Автор Steve S, джерело
+1 для красиво відформатованого коду ... дасть вам інше, якщо я можу, для зберігання коментарів і коду окремо ... код, який є радістю дивитися на
додано Автор jsotola, джерело

5 Відповіді

Вашою проблемою є затримка() у викликах BlueLED() і RedLED (). Щоб отримати більше "одночасних" дій, потрібно використати переривання таймера для реалізації цих затримок. Це набагато складніше концептуально, але правильний спосіб це зробити.

2
додано
Це була швидка робота! Радий, що ви це зробили.
додано Автор George Bailey, джерело
Дуже дякуємо Харперу; це було дуже корисно. Ми дотримувалися вашої поради та тільки що вирішили це !!! Дякую!
додано Автор Steve S, джерело

Ми це зробили. Дякуємо за допомогу Харперу Шелбі.

Ми об'єднали приклад 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.

Користь для підходу державного апарату, який використовується в цьому прикладі, згодом стає дуже легким для зміни коду; якщо ви хочете мати більше світлових проблисків у послідовності (наприклад, вогні ридер-вершника) або більше сирен, стає легше включати. У вашому другому коді коди void redLED() і void blueLED() містять в основному однакові лінії; Ви могли б зробити об'єкт під назвою 'LED', а потім просто зробити стільки випадків, скільки вам потрібно, всі працюють на різних швидкостях і різних контактах (приклад на сайті повинен надати це багато чого. коду). Можна також, наприклад, запрограмувати 4 різні типи сирени як перемикач: випадок, а після закінчення часу, перемикатися між ними.

Іншим більш просунутим методом буде включення операційної системи реального часу. RTOS робить дуже легко мати кілька незалежних завдань. Кожне світло може бути на своєму власному завданні, а сирена на третю, і система буде підтримувати кожну роботу одночасно. Цей підхід тоді має переваги, якщо ви хочете змінити час одного світла; вона змінюється в одному місці, не боячись змінити весь код. Інформацію про FreeRTOS на arduino можна знайти тут У нижній частині сторінки є приклад, який містить як приклади читання Blink, так і приклади читання з аналогом.

Це досить просунуті теми, але я думаю, що ви і ваш батько потрапите туди. Ще раз вітаю.

1
додано
Велике спасибі Натан! Ми подивимося на це далі, і посилання на сайт, яке ви нам дали, виглядає чудово.
додано Автор Steve S, джерело

Можливо, це трохи просунуто, але ...

Ви можете використовувати базовий клас і покажчики для похідних класів світлодіодів і зумер для зменшення функції циклу до циклу. Ви не отримаєте багато на цьому рівні, але, як ви додаєте більше об'єктів, таких як мигаючі фари і дзеркальні ліхтарі, може бути, навіть задня обличчям дошка оголошень ви будете полегшувати життя для себе.

/*
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
додано

Ми зробили краще з покажчиком Натана.

Ми довідалися як зробити клас але LEDS спалахнули разом таким чином ми довідалися як зробити інший клас (з Громадським та Порожнім Оновленням у класі - caught нас спочатку що шматочок). Один клас починається зі стану HIGH, а інший - зі значенням LOW, так що світлодіоди чергуються. При натисканні всіх трьох кнопок ми отримуємо дзвінок з двома тонами і змінні світлодіоди.

За допомогою цього методу ми можемо додати стільки нових світлодіодів, скільки хочемо.

Ось код, який ми написали:

/*
  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_A і FlashingLED_B тим, що A починає LOW, а B починається HIGH? Якщо так, то я б додав додатковий параметр до конструктора класу і просто використаю один з класів.
додано Автор Thomas Myron, джерело