пытаюсь использовать millis()

Я учусь использовать функцию millis(). Вместо того, чтобы размещать его в основной части программы, я хотел поместить его в функцию, чтобы можно было изменить интервал времени, с которым будет мигать светодиод. Я изменил кодblinkWithoutDelay. Мой код ниже. На выходе я получаю светодиод, который всегда включен. Я распечатал вывод светодиодного состояния на последовательный монитор. Он неоднократно переключается с включения на выключение. Поэтому я думаю, что светодиод действительно мерцает слишком быстро, чтобы его можно было увидеть. Я сделал скриншот с последовательного монитора. Вывод ниже.

const int LED2 = 2;
int ledState2 = LOW;

void timeCheck(int interval)
{
    unsigned long cMillis = millis();
    unsigned long pMillis;

    if (cMillis - pMillis > interval)
    {
        pMillis = cMillis;

        if (ledState2 == LOW)
        {
            ledState2 = HIGH;
        }
        else
        {
            ledState2 = LOW;
        }
        digitalWrite(LED2, ledState2);
        Serial.println(ledState2);
    }
}

void setup()
{
    Serial.begin(9600);
    pinMode(LED2, OUTPUT); 
}

void loop()
{
    unsigned long flashtime = 1000;
    timeCheck(flashtime);
}

, 👍1


3 ответа


Лучший ответ:

2

Проблема в том, что переменные, которые вы объявляете в своей функции, не являются статическими. Остальная часть кода работает как положено.

То, где вы объявляете переменные в начале вашей функции, правильно. Однако речь идет только об одной переменной, поскольку она является причиной ошибки, которую вы видите.

Что вам нужно сделать, это изменить переменную

unsigned long pMillis;

в

static unsigned long pMillis = 0;

Из-за отсутствия pMillis в качестве статической переменной каждый раз, когда вызывается функция, значение pMillis не определено, что означает, что невозможно предсказать, будет ли ( cMillis - pMillis > интервал) будет иметь значение true или false. Но благодаря объявлению static Arduino знает, что предыдущее значение сохранится при следующем вызове функции.

Отрывок из Википедии:

В компьютерном программировании статическая переменная — это переменная, которая была выделена статически, время жизни или «объем» которой не превышает 100%. распространяется на весь период работы программы....

Статическая локальная переменная отличается от локальной переменной. Он инициализируется только один раз, независимо от того, сколько раз вызывается функция, в которой он находится.

,

каждый раз, когда функция вызывается, pMillis устанавливается в 0 - на самом деле оно не определено, а не равно нулю., @Nick Gammon

@NickGammon, спасибо, это немного точнее, но все равно теряет ту ценность, которая была раньше., @RSM

Абсолютно. Я просто хотел уточнить, что нельзя полагаться на то, что начальное значение этого объявления равно нулю. Фактически, если вы сделаете его статическим, то его начальное значение *будет* равно нулю, что может помочь., @Nick Gammon

@NickGammon спасибо, Ник. Я изменил его, чтобы сделать его более ясным/точным., @RSM

Кажется, вы все еще не поняли, что pMillis не определен. Написав «_это означает, что if (cMillis - pMillis > интервал) всегда будет истинным._», вы делаете неявные предположения относительно pMillis. Я отредактировал ответ, чтобы дать понять, что вы не можете знать результат теста., @Edgar Bonet

Спасибо всем за ваш вклад. Раньше я читал об объявлении статической переменной, но для меня это не имело смысла. Я понимаю, как это работает сейчас, и вижу это в действии. Еще раз спасибо., @Michael Niebauer


0

Выпустите это, чтобы оно было глобальным. LedStaye должно иметь значение bool: const int LED2 = 2; boolledState2 = НИЗКИЙ; беззнаковый длинный pMillis;

void timeCheck (интервал целого числа) { if (миллис() - пмиллис > интервал) { пМиллис = миллис(); ...

,

Вы это проверяли? Я не думаю, что millis() можно вызывать внутри логического теста if., @MichaelT


0

Вы использовали переменную pMillis локально. Вот почему, когда вы вызываете функцию, pMillis инициализируется как 0. Поэтому установите переменную pMillis глобально.

,