Изменение порядка мигания светодиодов одним нажатием кнопки

led
2 голоса | спросил Bro JJ 1 +03002017-10-01T21:43:45+03:00312017bEurope/MoscowSun, 01 Oct 2017 21:43:45 +0300 2017, 21:43:45

2 ответа


3

Проще всего использовать «режим», который является логическим, который сохраняет состояние, если он мигает правильно, назовем его blinkToRight. Первоначально это верно.

Оператор if будет использоваться для изменения порядка.

Итак, программа будет чем-то вроде (не проверена):

глобальные:

bool blinkToRight = true;

в программе установки:

pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
pinMode(2,INPUT);

В цикле:

// Check if loop is reversed
blinkToRight = checkReverse(); 

if (blinkToRight)
{
   show(true, false, false);
   show(false, true, false);
   show(false, false, true);
}
else
{
   show(false, false, true);
   show(false, true, false);
   show(true, false, false);
}


void show(bool led1, bool led2, bool led3)
{
   digitalWrite(2, led1);
   digitalWrite(3, led2);
   digitalWrite(4, led3);
   delay(200);
}

checkReverse проверит кнопку ввода и вернет true, если режим должен быть отменен.

Однако вы не можете просто проверить состояние кнопки. Проблема подпрыгивает. Но проверьте примеры Arduino на примере дебюта для этой проблемы, и программа должна работать как ожидалось.

См. пример: Пример отладки

Поскольку только один светодиод будет включен, вы также можете использовать следующие функции для Loop и показать:

В цикле:

// Check if loop is reversed
blinkToRight = checkReverse(); 

if (blinkToRight)
{
   show(3);
   show(4);
   show(5);
}
else
{
   show(5);
   show(4);
   show(3);
}

Показать:

void show(int ledOn)
{
   digitalWrite(ledOn == 3);
   digitalWrite(ledOn == 4);
   digitalWrite(ledOn == 5);
   delay(200);
}

И еще лучше использовать константы:

const int LED1   = 3
const int LED2   = 4
const int LED3   = 5
const int BUTTON = 2

Настройка:

pinMode(LED1  , OUTPUT);
pinMode(LED2  , OUTPUT);
pinMode(LED3  , OUTPUT);
pinMode(BUTTON, INPUT);

Петля

// Check if loop is reversed
blinkToRight = checkReverse(); 

if (blinkToRight)
{
   show(LED1);
   show(LED2);
   show(LED3);
}
else
{
   show(LED3);
   show(LED2);
   show(LED1);
}

Показать:

void show(int ledOn)
{
   digitalWrite(ledOn == LED1);
   digitalWrite(ledOn == LED2);
   digitalWrite(ledOn == LED3);
   delay(200);
}
ответил Michel Keijzers 1 +03002017-10-01T21:56:12+03:00312017bEurope/MoscowSun, 01 Oct 2017 21:56:12 +0300 2017, 21:56:12
0

По-моему, есть две вещи, которые я бы изменил. Первый заключается в том, что функции задержки следует избегать, когда это возможно, а другое - в том, что коммутатор отскакивает.

Чтобы решить отскоки, вам придется подождать некоторое время, чтобы стабилизировать сигнал:

if (debouncedValueOfButton != (digitalRead(button_pin) == HIGH))
{ // Is there a change?
    if (((byte)currMillis) - lastMillisForButton) >= millisButtonDebounce)
    { // Yes, without bounces
        debouncedValueOfButton = !debouncedValueOfButton;
        if (debouncedValueOfButton)
        { // Rising edge
            if (increment > 1)
                increment = 1; // Go in one direction
            else
                increment = 2; // Go in the other direction
        }
    }
}
else
    lastMillisForButton = (byte)currMillis;

Итак, если значение отличается от того, которое я думаю, я буду ждать несколько миллисекунд; если он стабилен, я изменяю значение, которое, как я думаю, есть.

Что касается удаления задержки, я думаю, что лучше использовать подход, похожий на эскиз «мигать без задержки»:

if ((((uint16_t)currMillis) - lastMillisForBlink) >= millisBetweenBlinks)
{
    lastMillisForBlink += millisBetweenBlinks;
    currentLed = (currentLed + increment) % 3;

    digitalWrite(led0_pin, currentLed == 0);
    digitalWrite(led1_pin, currentLed == 1);
    digitalWrite(led2_pin, currentLed == 2);
}

В этой реализации вы используете приращение переменной, чтобы решить, нужно ли вам идти вперед или назад; когда приращение равно 1, цвет должен быть 0 -> 1 -> 2 -> (3)0 -> 1 ...; когда это 2, светодиод 0 -> 2 -> (4)1 -> (3)0 -> 2 ....

Полный код (ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: NOT TESTED)

const byte led0_pin = 3;
const byte led1_pin = 4;
const byte led2_pin = 5;
const byte button_pin = 2;

int8_t currentLed, increment;
unsigned int lastMillisForBlink;
const unsigned int millisBetweenBlinks = 200;

bool debouncedValueOfButton;
byte lastMillisForButton;
const byte millisButtonDebounce = 50;

void setup() {
    pinMode(led0_pin,OUTPUT);
    pinMode(led1_pin,OUTPUT);
    pinMode(led2_pin,OUTPUT);
    pinMode(button_pin,INPUT);

    increment = 1;
    currentLed = 2; // At first run, currentLed will be increased by 1, so it starts at 0
    lastMillisForBlink = millis() - millisBetweenBlinks; // trigger a refresh at first loop

    debouncedValueOfButton = (digitalRead(button_pin);
}

void loop() {
    unsigned long currMillis = millis();

    if ((((uint16_t)currMillis) - lastMillisForBlink) >= millisBetweenBlinks)
    {
        lastMillisForBlink += millisBetweenBlinks;
        currentLed = (currentLed + increment) % 3;

        digitalWrite(led0_pin, currentLed == 0);
        digitalWrite(led1_pin, currentLed == 1);
        digitalWrite(led2_pin, currentLed == 2);
    }

    if (debouncedValueOfButton != (digitalRead(button_pin) == HIGH))
    { // Is there a change?
        if (((byte)currMillis) - lastMillisForButton) >= millisButtonDebounce)
        { // Yes, without bounces
            debouncedValueOfButton = !debouncedValueOfButton;
            if (debouncedValueOfButton)
            { // Rising edge
                if (increment > 1)
                    increment = 1; // Go in one direction
                else
                    increment = 2; // Go in the other direction
            }
        }
    }
    else
        lastMillisForButton = (byte)currMillis;
}
ответил frarugi87 2 +03002017-10-02T13:14:06+03:00312017bEurope/MoscowMon, 02 Oct 2017 13:14:06 +0300 2017, 13:14:06

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132