Такой вопрос у меня родился в связи с попыткой написать функцию, которая мигает одним цветом RGB светодиода с заданным интервалом. Однако иногда мне нужно не мигать, а просто зажечь светодиод, а значит выполнить действие лишь один раз. Первое что пришло в голову - передать при вызове некое булево значение runOnce. Но поскольку функция вызывается бесконечно много раз, то она будет вызываться с runOnce равным единице, то есть не будет флажок опускаться никогда.
Есть какой-то вариант сделать такое без использования (глобальных переменных/переменных более высокого уровня относительно функции) или нет?
Код условный. И он отражает мои мягко говоря несовершенные навыки программирования. Приведён лишь в качестве примера.
boolean LEDrunOnce = 1;
unsigned long blinkMillis = 0;
void setup(){
}
void loop(){
blinkFunction(0, 0, 0, 1); // intervalTime,R,G,B
}
void blinkFunction(int intervalTime, bool R, bool G, bool B) {
if (intervalTime != 0) {
if (millis() - blinkMillis > intervalTime) {
blinkMillis = millis();
if (R) {
rState = !rState;
digitalWrite(RED, rState);
}
if (G) {
gState = !gState;
digitalWrite(GREEN, gState);
}
if (B) {
bState = !bState;
digitalWrite(BLUE, bState);
}
}
}
else {
if (LEDrunOnce) {
digitalWrite(RED, R);
digitalWrite(GREEN, G);
digitalWrite(BLUE, B);
LEDrunOnce = 0;
if (massage)Serial.print(F("Светодиодам задано состояние один раз."));
}
}
}
Другие языки программирования и технологии
Возможно ли выполнить действие 1 раз внутри функции, вызываемой в бесконечном цикле, с помощью её аргумента?
Как я понимаю у вас будет несколько состояний программы на которые должен указывать светодиод. Ну я конечно не совсем себе представляю почему цикл не должен крутиться именно в этом состоянии и делать то что нужно как с светодиодами, так и с другими вещами пока не программа не перейдет в другое состояние. Ну да ладно. Например можно использовать указатель на функцию.
void(*p_state)(); //указатель на функцию типа void
void blinkFunction(int intervalTime, bool R, bool G, bool B) {
if (millis() - blinkMillis > intervalTime) {
blinkMillis = millis();
if (R) {
rState = !rState;
digitalWrite(RED, rState);
}
if (G) {
gState = !gState;
digitalWrite(GREEN, gState);
}
if (B) {
bState = !bState;
digitalWrite(BLUE, bState);
}
}
void blink500()
{
blinkFunction(500, 1, 1, 0);
}
void nop() {}
void led_on()
{
digitalWrite(RED, 1);
digitalWrite(GREEN, 1);
digitalWrite(BLUE, 1);
p_state = nop;
}
void led_off()
{
digitalWrite(RED, 0);
digitalWrite(GREEN, 0);
digitalWrite(BLUE, 0);
p_state = nop;
}
void setup(){
p_state = blink500;
}
void loop(){
p_state();
...
...
if(other_state) p_state = led_on;
if(another_state) p_state = led_off;
}
не самый лучший но как вариант
void(*p_state)(); //указатель на функцию типа void
void blinkFunction(int intervalTime, bool R, bool G, bool B) {
if (millis() - blinkMillis > intervalTime) {
blinkMillis = millis();
if (R) {
rState = !rState;
digitalWrite(RED, rState);
}
if (G) {
gState = !gState;
digitalWrite(GREEN, gState);
}
if (B) {
bState = !bState;
digitalWrite(BLUE, bState);
}
}
void blink500()
{
blinkFunction(500, 1, 1, 0);
}
void nop() {}
void led_on()
{
digitalWrite(RED, 1);
digitalWrite(GREEN, 1);
digitalWrite(BLUE, 1);
p_state = nop;
}
void led_off()
{
digitalWrite(RED, 0);
digitalWrite(GREEN, 0);
digitalWrite(BLUE, 0);
p_state = nop;
}
void setup(){
p_state = blink500;
}
void loop(){
p_state();
...
...
if(other_state) p_state = led_on;
if(another_state) p_state = led_off;
}
не самый лучший но как вариант
Jeeper Проходимец
if (massage) - А кто у вас там масаж то делает и зачем об этом нужно говорить через последовательный порт!? Может имелось в виду message?
Эм... в этом микроконтроллере нет таймеров? Так понимаю, вы постоянно берете текущее время и сравниваете сколько прошло? Мягко говоря, нецелесообразная трата аппаратных ресурсов...
Есть вариант - использовать для мигания и постоянного зажигания разные функции, и не повторять в цикле одно и то же независимо от всего.
Есть вариант - использовать для мигания и постоянного зажигания разные функции, и не повторять в цикле одно и то же независимо от всего.
Сергей Шубин
Хорошо. Я понял что Вы имеете в виду. Это Arduino Nano (ATmega328) и вроде бы там есть таймеры и по ним даже доступны прерывания. Но мой уровень пока что находится на другой отметке. Я только-только отошёл от delay и стал осознавать, что некоторые действия нужно выполнять единожды и стал использовать флажки для этого.
Но мой вопрос-то был не про тайминги или про трату аппаратных ресурсов.
Я уверен Вы уже можете знать ответ на основной вопрос. То есть есть ли возможность выполнить функцию единожды в бесконечном цикле, передав ей в качестве аргумента просьбу выполниться один раз (без использования глобальной переменной)?
Хорошо. Вы предложили использовать разные функции для этих задач. Я понял. Спасибо.
Но мой вопрос-то был не про тайминги или про трату аппаратных ресурсов.
Я уверен Вы уже можете знать ответ на основной вопрос. То есть есть ли возможность выполнить функцию единожды в бесконечном цикле, передав ей в качестве аргумента просьбу выполниться один раз (без использования глобальной переменной)?
Хорошо. Вы предложили использовать разные функции для этих задач. Я понял. Спасибо.
Похожие вопросы
- Выход из бесконечного цикла С++
- Delphi!? Repeat Unitl... бесконечный цикл (вся прога зависает)?
- Хорошо ли использовать бесконечный цикл for в C++?
- Каким образом зациклить програму? суть бесконечного цикла?
- Создание объекта внутри функции C++
- Вирус на компе, возможно Trojan.winlock.97(полное описание внутри, картинки загруж через 2мин.) Пожалуйста помогите...
- Для аргумента x, изменяющегося от –0.6 с шагом 0.05 вычислить 20 значений функций.
- C++ Везде написано, что sizeof() с массивом в качестве аргумента возвращает полный размер. А в данной функции не так.
- Помогите построить график функции y=sinx, xЄ[-1;1] с шагом изменения аргумента h =0,1 C++ VisualStudio
- PASCAL. В чем отличие процедур от функций. И любую ли задачу можно решить с помощью функции?