Мигать несколькими светодиодами

Kontra
Offline
Зарегистрирован: 10.07.2013

Доброго дня.

Надо поморгать двумя светиками без delay(). Алгоритм такой примерно: зажигается первый светодиод, потом гаснет, через какое то время загорается второй светодиод, снова гаснет все на время и по кругу.

Читал/пробовал не работает никак.

Помогите, плз.

Так как сделано в коде ниже - не рабоает.

const int ledPin8 =  8;      // the number of the LED pin
const int ledPin9 =  9;      // the number of the LED pin


// Variables will change:
int ledState8 = LOW;             // ledState used to set the LED
int ledState9 = LOW;             // ledState used to set the LED

long previousMillis = 0;        // will store last time LED was updated

long interval = 3000;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(ledPin8, OUTPUT);    
  pinMode(ledPin9, OUTPUT);    
     
}

void loop()
{
  unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED 
    if(currentMillis - previousMillis > 1*interval/4) {
      FirstLap;
    }
    if(currentMillis - previousMillis > 2*interval/4) {
      AllDown;
    }
    if(currentMillis - previousMillis > 3*interval/4) {
      SecondLap;
    }
    if(currentMillis - previousMillis > 4*interval/4) {
      AllDown;
    }  
    previousMillis = currentMillis;   
  }
}

// Первый цикл
void FirstLap(){
  digitalWrite(ledPin8, HIGH);
}

//Второй цикл
void SecondLap(){
  digitalWrite(ledPin9, HIGH);
}

// Гасим все

void AllDown(){
  digitalWrite(ledPin8, LOW);
  digitalWrite(ledPin9, LOW);
}

 

Garry
Garry аватар
Offline
Зарегистрирован: 07.04.2012

1) Про static переменные в функции loop() и про мигание читаем тут.

2) if(currentMillis - previousMillis > interval) - если выполнится это условие, то все внутренние условия правдивы (true).

3) Использование переменных разного типа для millis() и операции над ними - прямая дорога к багам.

 

ites
Offline
Зарегистрирован: 26.12.2013

Garry пишет:

3) Использование переменных разного типа для millis() и операции над ними - прямая дорога к багам.

К каким именно? Автоматическое преобразование типов подразумевает только расширение разрядности, unsigned long при этом имеет максимальную. Хотелось бы видеть про какие именно типичные баги речь.

Kontra
Offline
Зарегистрирован: 10.07.2013

Огромное спасибо Лешему.

Все завелось даже на три диода. Ошибку свою понял.

Рабочий код ниже, вдруг понадобится кому.

#define LED_PIN8  8      // номер выхода,подключенного к светодиоду
#define LED_PIN9  9      // номер выхода,подключенного к светодиоду
#define LED_PIN10  10    // номер выхода,подключенного к светодиоду
#define  INTERVAL  10000UL           // интервал между включение/выключением светодиода (1 секунда)
 
void setup() {
  // задаем режим выхода для порта, подключенного к светодиоду
  pinMode(LED_PIN8, OUTPUT);   
  pinMode(LED_PIN9, OUTPUT);
  pinMode(LED_PIN10, OUTPUT);  
}
 
void loop()
{
  // здесь будет код, который будет работать постоянно
  // и который не должен останавливаться на время между переключениями свето

  // обратите внимание на слово static   
  static unsigned long previousMillis = 0;        // храним время последнего переключения светодиода
  //проверяем не прошел ли нужный интервал, если прошел то
  if(millis() - previousMillis > INTERVAL) {
    // сохраняем время последнего переключения
    previousMillis = millis();  
  }
  
  if(millis() - previousMillis > 0*INTERVAL/6&&millis() - previousMillis < 1*INTERVAL/6) {
    digitalWrite(LED_PIN9,HIGH);
  }
  if(millis() - previousMillis > 1*INTERVAL/6&&millis() - previousMillis < 2*INTERVAL/6) {
    digitalWrite(LED_PIN9,LOW);
  }
  if(millis() - previousMillis > 2*INTERVAL/6&&millis() - previousMillis < 3*INTERVAL/6) {
    digitalWrite(LED_PIN10,HIGH);
  }
  if(millis() - previousMillis > 3*INTERVAL/6&&millis() - previousMillis < 4*INTERVAL/6) {
    digitalWrite(LED_PIN10,LOW);
  }
  if(millis() - previousMillis > 4*INTERVAL/6&&millis() - previousMillis < 5*INTERVAL/6) {
    digitalWrite(LED_PIN8,HIGH);
  }
  if(millis() - previousMillis > 5*INTERVAL/6&&millis() - previousMillis < 6*INTERVAL/6) {
    digitalWrite(LED_PIN8,LOW);
  }  
}

 

Garry
Garry аватар
Offline
Зарегистрирован: 07.04.2012

ites пишет:

Garry пишет:

3) Использование переменных разного типа для millis() и операции над ними - прямая дорога к багам.

К каким именно? Автоматическое преобразование типов подразумевает только расширение разрядности, unsigned long при этом имеет максимальную. Хотелось бы видеть про какие именно типичные баги речь.

long previousMillis = 0;

unsigned long currentMillis = millis();

...

previousMillis = currentMillis;

if(currentMillis - previousMillis > interval)

Тут видимо проблем нет у вас?

 

ites
Offline
Зарегистрирован: 26.12.2013

Garry пишет:

Тут видимо проблем нет у вас?

Есть предупреждение компилятора. Но если его проигнорировать и посмотреть на ассемблерный выход, будут проблемы?

Garry
Garry аватар
Offline
Зарегистрирован: 07.04.2012

ites пишет:

Есть предупреждение компилятора. Но если его проигнорировать и посмотреть на ассемблерный выход, будут проблемы?

В относительной величине нет, но в абсолютном знчении с какого-то момента prev может стать отрицательной величиной и если prev будет испоьзоваться в других вычислениях (скорость изменения чего-либо) или как метка локального времени в логах, то тут появляются проблемы.

ites
Offline
Зарегистрирован: 26.12.2013

Garry пишет:

ites пишет:

Есть предупреждение компилятора. Но если его проигнорировать и посмотреть на ассемблерный выход, будут проблемы?

В относительной величине нет, но в абсолютном знчении с какого-то момента prev может стать отрицательной величиной и если prev будет испоьзоваться в других вычислениях (скорость изменения чего-либо) или как метка локального времени в логах, то тут появляются проблемы.

Я говорил о конкретном коде. В логи вряд ли кто то будет выводить сырой миллис. В общем, я согласен про "неаккуратненько", но реализация арифметики в дополнительном коде скрывает многие проблемы и некоторые даже разрешает.

Kontra
Offline
Зарегистрирован: 10.07.2013

Еще вопрос возник, друзья.

Каким образом я могу при такой конструкции как у Лешего динамически менять параметр INTERVAL, например при нажатии на кнопку?

Спасибо!