Как обнулить счетчик при повторном обращении к функции в switch..case

dengeneral
Offline
Зарегистрирован: 04.05.2018

Всем привет! Такой вопрос: Как обнулить счетчик при повторном обращении к функции в switch..case. Функция Lights1 () не должна выполняться бесконечно, а всего лишь 1 раз, что собственно я и сделал, но должна выполнится еще раз когда я снова переключу режим о попаду в эту функцию. Режим переключается кнопкой по кругу.

 


bool FOG_BEAM_RIGHT = 0;
bool FOG_BEAM_LEFT = 0;
int TURNL_RIGHT = 0;
int TURNL_LEFT = 0;
int LOWBEAM_RIGHT = 0;
int LOWBEAM_LEFT = 0;
int HIGHTBEAM_RIGHT = 0;
int HIGHTBEAM_LEFT = 0;

boolean bStopFlag = false;

int g = 0;
int f = 0;
int s = 0;
int d = 75;

int ButPin = 8;  // Подключаем кнопку к выходу 4
int flag = 0;    // флаг состояния
int regim = 0;   // Переключалка

bool LEDflag = false; //Флаг состояния
//             0  1  2  3  4  5   6   7     
int Pins[] = { 2, 3, 5, 6, 9, 10, 11, 12 }; //Пины куда подключен све
bool flagB = false;
uint32_t btnTimer = 0;
uint32_t myTimerA; //Таймеры задержки
uint32_t myTimerB; //Таймеры задержки 
uint32_t myTimer;

int ledState = LOW;                // переменная, показывающая состояние светодиода
unsigned long previousMillis = 0;  //в этой переменной будем хранить время, когда светодиод последний раз мигнул
const long period = 35;

void setup()
{
	Serial.begin(9600);
	for (int i = 0; i <= 7; i++)
	{
		pinMode(Pins[i], OUTPUT);
	}
	pinMode(ButPin, INPUT_PULLUP);
}

void loop()
{
	int regim = buttonClick();	

	switch (regim)
	{
	case 0:
		Lights1();
		break;
	case 1:
		Lights2();
		break;
	case 2:
		Lights3();
		break;
	case 3:
		Lights4();
		break;
	default:
		break;
	}
}

int buttonClick()
{


	bool btnState = digitalRead(ButPin);
	if (btnState && !flagB && millis() - btnTimer > 50)
	{
		flagB = true;
		btnTimer = millis();
		f++;
		Serial.println(f);

	}
	if (!btnState && flagB && millis() - btnTimer > 50)
	{
		flagB = false;
		btnTimer = millis();
	}
	if (f > 3)
	{
		f = 0;
	}
	return f;
}

void Lights1()
{
	int i = 0;
	while (i < 1 && !bStopFlag)
	{
		for (int i = 7; i >= 0; i--)
		{
			digitalWrite(Pins[i], HIGH);
			delay(d);
			digitalWrite(Pins[i], LOW);
		}
		for (int i = 0; i <= 7; i++)
		{
			digitalWrite(Pins[i], HIGH);
			delay(d);
			digitalWrite(Pins[i], LOW);
		}
		for (int i = 7, j = 0; j <= 3, i >= 4; i--, j++)
		{
			digitalWrite(Pins[i], HIGH);
			digitalWrite(Pins[j], HIGH);
			delay(250);
		}
		for (int i = 7, j = 0; j <= 3, i >= 4; i--, j++)
		{
			digitalWrite(Pins[i], LOW);
			digitalWrite(Pins[j], LOW);
			delay(500);
		}
		i++;
	}
	bStopFlag = true;
}

void Lights2()
{
	int i = 0;

	while (i < 10)
	{
		unsigned long currentMillis = millis(); // сохраняем текущее время
		if (currentMillis - previousMillis >= period)  // проверяем прошли ли 1000ms 
		{
			previousMillis = currentMillis;   // сохраняем последнее время когда мигнул светодиод
			if (ledState == LOW) { //если светодиод выключен, то включаем его, и наоборот 
				ledState = HIGH;
			}
			else
			{
				ledState = LOW;
			}
			digitalWrite(Pins[0], ledState);//устанавливаем светодиод в состояние, определяемое переменной ledState
			i++;
		}
	}

	while (i < 20)
	{
		unsigned long currentMillis = millis(); // сохраняем текущее время
		if (currentMillis - previousMillis >= period)  // проверяем прошли ли 1000ms 
		{
			previousMillis = currentMillis;   // сохраняем последнее время когда мигнул светодиод
			if (ledState == LOW) { //если светодиод выключен, то включаем его, и наоборот 
				ledState = HIGH;
			}
			else
			{
				ledState = LOW;
			}
			digitalWrite(Pins[7], ledState);//устанавливаем светодиод в состояние, определяемое переменной ledState
			i++;
		}
	}
}

void Lights3()
{
	int i = 0;

	while (i < 10)
	{
		unsigned long currentMillis = millis(); // сохраняем текущее время
		if (currentMillis - previousMillis >= period)  // проверяем прошли ли 1000ms 
		{
			previousMillis = currentMillis;   // сохраняем последнее время когда мигнул светодиод
			if (ledState == LOW) { //если светодиод выключен, то включаем его, и наоборот 
				ledState = HIGH;
			}
			else
			{
				ledState = LOW;
			}
			digitalWrite(Pins[0], ledState);//устанавливаем светодиод в состояние, определяемое переменной ledState
			digitalWrite(Pins[5], ledState);
			i++;
		}
	}

	while (i < 20)
	{
		unsigned long currentMillis = millis(); // сохраняем текущее время
		if (currentMillis - previousMillis >= period)  // проверяем прошли ли 1000ms 
		{
			previousMillis = currentMillis;   // сохраняем последнее время когда мигнул светодиод
			if (ledState == LOW) { //если светодиод выключен, то включаем его, и наоборот 
				ledState = HIGH;
			}
			else
			{
				ledState = LOW;
			}
			digitalWrite(Pins[7], ledState);//устанавливаем светодиод в состояние, определяемое переменной ledState
			digitalWrite(Pins[2], ledState);
			i++;
		}
	}
}
void Lights4()
{
	int g = 1;
	do
	{
		for (int i = 7; i >= 0; i--)
		{
			digitalWrite(Pins[i], HIGH);
			delay(200);
			for (int i = 7; i >= 0; i--)
				digitalWrite(Pins[i], LOW);
		}
		g++;

	} while (g == 1);
}

 

nik182
Offline
Зарегистрирован: 04.05.2015

Вариантов много. Например, с минимальными переделками, можно по окончании процедуры которую нужно выполнить 1 раз присваивать regim любое значение за пределами case. Следующее присвоение номера одноразовой процедуры опять выполнит процедуру один раз. 

dengeneral
Offline
Зарегистрирован: 04.05.2018

Присваивать можно прямо в функции?

nik182
Offline
Зарегистрирован: 04.05.2015

У Вас он глобальный. Поэтому можно везде. И в функции тоже.

dengeneral
Offline
Зарегистрирован: 04.05.2018

nik182 пишет:

Вариантов много. Например, с минимальными переделками, можно по окончании процедуры которую нужно выполнить 1 раз присваивать regim любое значение за пределами case. Следующее присвоение номера одноразовой процедуры опять выполнит процедуру один раз. 

Функция зацикливается тогда почему то.

dengeneral
Offline
Зарегистрирован: 04.05.2018

Я даже делал вот так. Поидее функция должна выполнится 1 раз. Но она зацикливается (


void Lights4()
{
	do
	{
		for (int i = 7; i >= 0; i--)
		{
			digitalWrite(Pins[i], HIGH);
			delay(200);
			for (int i = 7; i >= 0; i--)
			digitalWrite(Pins[i], LOW);
		}
		g++;
		break;

	} while (g == 1);
}
v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

А вот так она сколько раз выполняется?

void Lights4()
{
		for (int i = 7; i >= 0; i--)
		{
			digitalWrite(Pins[i], HIGH);
			delay(200);
			for (int i = 7; i >= 0; i--)
			digitalWrite(Pins[i], LOW);
		}
}

 

dengeneral
Offline
Зарегистрирован: 04.05.2018

v258 пишет:

А вот так она сколько раз выполняется?

void Lights4()
{
		for (int i = 7; i >= 0; i--)
		{
			digitalWrite(Pins[i], HIGH);
			delay(200);
			for (int i = 7; i >= 0; i--)
			digitalWrite(Pins[i], LOW);
		}
}

 

Бесконечно, пока есть питание.

nik182
Offline
Зарегистрирован: 04.05.2015

Функция зацикливается потому что функция опроса кнопок всегда возвращает старое значение в не зависимости от нажатия. Нажатия не было, а regim опять получает старое значение, как его не меняй  - 46 строка. Надо сначала проверять нажата ли кнопка и если нажата, ждать отпускания и только потом менять режим. Если не нажата, режим менять не надо. 

dengeneral
Offline
Зарегистрирован: 04.05.2018

nik182 пишет:

Функция зацикливается потому что функция опроса кнопок всегда возвращает старое значение в не зависимости от нажатия. Нажатия не было, а regim опять получает старое значение, как его не меняй  - 46 строка. Надо сначала проверять нажата ли кнопка и если нажата, ждать отпускания и только потом менять режим. Если не нажата, режим менять не надо. 

Подскажите пожалуйста как это сделать? Получается делать f++ при отпускании кнопки?

 

nik182
Offline
Зарегистрирован: 04.05.2015

На форуме есть титановый велосипед для кнопки - библиотека для кнопок, которая может отслеживать много событий, в том числе и отпускание. Если её использовать, то просто можно организовать алгоритм - отпустили кнопку - изменили режим, крутанули цикл. Если кнопка не нажималась, то цикл не крутим или крутим тот же самый. Главное, изменение переменной regim или после отпускания кнопки или внутри однократной функции.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Оставь все как есть, просто в конце функции каждого из остальных режимов добавь
bStopFlag=0;

Хотя у тебя тупо инкремент по нажатию со сбросом по достижению значения 3+,
Можно просто один раз записать в следующем case.

dengeneral
Offline
Зарегистрирован: 04.05.2018

nik182 пишет:

Функция зацикливается потому что функция опроса кнопок всегда возвращает старое значение в не зависимости от нажатия. Нажатия не было, а regim опять получает старое значение, как его не меняй  - 46 строка. Надо сначала проверять нажата ли кнопка и если нажата, ждать отпускания и только потом менять режим. Если не нажата, режим менять не надо. 

Сделал вот так, перестал слушаться кнопку на 2 режиме ))

void loop()
{
	digitalRead(ButPin);
	if (digitalRead(ButPin) == HIGH)
	{
		regim = buttonClick();
	}
	switch (regim)
	{
	case 0:
		Lights1();
		break;
	case 1:
		Lights2();
		break;
	case 2:
		Lights3();
		break;
	case 3:
		Lights4();
		break;
	default:
		break;
	}
}

 

 

Kakmyc
Offline
Зарегистрирован: 15.01.2018

А вообще чтоб не было затыков по коду нужно функции правильно писать.
Т.е. твоя функция buttonClick() что делает ? Инкрементирует значение переменной.
Вот и возвращать она должна не ее состояние, а указание на то, нужно инкрементировать или нет.
Иначе смысл её объявлять не как void и требовать от нее возвращать что-то ?
Если она внутри себя глобальную переменную меняет.

dengeneral
Offline
Зарегистрирован: 04.05.2018

Блин, логично. только я сделал s = 0; т.к. стоп флаг и так уже false. Но теперь новый прикол, функция Lights4() тоже бесконечна хотя должна выполнится 1 раз. Мне вот интересно почему? я ведь переменную g инкрементирую и по сути условие больше не выполняется... Нипанятна )

dengeneral
Offline
Зарегистрирован: 04.05.2018

Ааа... т.е. ее нужно объявить как int? )

nik182
Offline
Зарегистрирован: 04.05.2015

dengeneral пишет:

Сделал вот так, перестал слушаться кнопку на 2 режиме ))

Он не может перестать слушаться. Он может выполнить один раз и ты это не замечаешь.

Если 4 режим тоже однократный, то и у него в конце надо regim присвоить например 10. 

buttonClick(); не надо вызывать и проверять ещё раз кнопку. Достаточно взять  строки 76 85-88 из неё и вставить под if.
 

 

dengeneral
Offline
Зарегистрирован: 04.05.2018

Тут немного не понял, пот if в loop?

nik182
Offline
Зарегистрирован: 04.05.2015

Да. Ты ж проверяешь в 4 строке кнопку? а вот что делает 3 строка я не понял.

dengeneral
Offline
Зарегистрирован: 04.05.2018

я так и не понял как это организовать в loop )

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

Попробуй вот так

#include <shButton.h> // https://github.com/VAleSh-Soft/shButton

bool FOG_BEAM_RIGHT = 0;
bool FOG_BEAM_LEFT = 0;
int TURNL_RIGHT = 0;
int TURNL_LEFT = 0;
int LOWBEAM_RIGHT = 0;
int LOWBEAM_LEFT = 0;
int HIGHTBEAM_RIGHT = 0;
int HIGHTBEAM_LEFT = 0;

boolean bStopFlag = false;

int g = 0;
int f = 0;
int s = 0;
int d = 75;

int ButPin = 8; // Подключаем кнопку к выходу 4
int flag = 0;   // флаг состояния
int regim = 0;  // Переключалка

shButton btn(ButPin, PULL_DOWN); // если кнопка замыкается на VCC,
                                 // иначе shButton btn(ButPin);

bool LEDflag = false; //Флаг состояния
//             0  1  2  3  4  5   6   7
int Pins[] = {2, 3, 5, 6, 9, 10, 11, 12}; //Пины куда подключен све
bool flagB = false;
uint32_t btnTimer = 0;
uint32_t myTimerA; //Таймеры задержки
uint32_t myTimerB; //Таймеры задержки
uint32_t myTimer;

int ledState = LOW;               // переменная, показывающая состояние светодиода
unsigned long previousMillis = 0; //в этой переменной будем хранить время, когда светодиод последний раз мигнул
const long period = 35;

void setup()
{
  Serial.begin(9600);
  for (int i = 0; i <= 7; i++)
  {
    pinMode(Pins[i], OUTPUT);
  }
  pinMode(ButPin, INPUT_PULLUP);
}

void loop()
{
  static byte regim = 0;

  if (btn.getButtonState() == BTN_DOWN)
  {
    if (++regim > 3)
    {
      regim = 0;
    }
  }

  switch (regim)
  {
  case 0:
    Lights1();
    break;
  case 1:
    Lights2();
    break;
  case 2:
    Lights3();
    break;
  case 3:
    Lights4();
    break;
  default:
    break;
  }
}

int buttonClick()
{

  bool btnState = digitalRead(ButPin);
  if (btnState && !flagB && millis() - btnTimer > 50)
  {
    flagB = true;
    btnTimer = millis();
    f++;
    Serial.println(f);
  }
  if (!btnState && flagB && millis() - btnTimer > 50)
  {
    flagB = false;
    btnTimer = millis();
  }
  if (f > 3)
  {
    f = 0;
  }
  return f;
}

void Lights1()
{
  int i = 0;
  while (i < 1 && !bStopFlag)
  {
    for (int i = 7; i >= 0; i--)
    {
      digitalWrite(Pins[i], HIGH);
      delay(d);
      digitalWrite(Pins[i], LOW);
    }
    for (int i = 0; i <= 7; i++)
    {
      digitalWrite(Pins[i], HIGH);
      delay(d);
      digitalWrite(Pins[i], LOW);
    }
    for (int i = 7, j = 0; j <= 3, i >= 4; i--, j++)
    {
      digitalWrite(Pins[i], HIGH);
      digitalWrite(Pins[j], HIGH);
      delay(250);
    }
    for (int i = 7, j = 0; j <= 3, i >= 4; i--, j++)
    {
      digitalWrite(Pins[i], LOW);
      digitalWrite(Pins[j], LOW);
      delay(500);
    }
    i++;
  }
  bStopFlag = true;
}

void Lights2()
{
  int i = 0;

  while (i < 10)
  {
    unsigned long currentMillis = millis();       // сохраняем текущее время
    if (currentMillis - previousMillis >= period) // проверяем прошли ли 1000ms
    {
      previousMillis = currentMillis; // сохраняем последнее время когда мигнул светодиод
      if (ledState == LOW)
      { //если светодиод выключен, то включаем его, и наоборот
        ledState = HIGH;
      }
      else
      {
        ledState = LOW;
      }
      digitalWrite(Pins[0], ledState); //устанавливаем светодиод в состояние, определяемое переменной ledState
      i++;
    }
  }

  while (i < 20)
  {
    unsigned long currentMillis = millis();       // сохраняем текущее время
    if (currentMillis - previousMillis >= period) // проверяем прошли ли 1000ms
    {
      previousMillis = currentMillis; // сохраняем последнее время когда мигнул светодиод
      if (ledState == LOW)
      { //если светодиод выключен, то включаем его, и наоборот
        ledState = HIGH;
      }
      else
      {
        ledState = LOW;
      }
      digitalWrite(Pins[7], ledState); //устанавливаем светодиод в состояние, определяемое переменной ledState
      i++;
    }
  }
}

void Lights3()
{
  int i = 0;

  while (i < 10)
  {
    unsigned long currentMillis = millis();       // сохраняем текущее время
    if (currentMillis - previousMillis >= period) // проверяем прошли ли 1000ms
    {
      previousMillis = currentMillis; // сохраняем последнее время когда мигнул светодиод
      if (ledState == LOW)
      { //если светодиод выключен, то включаем его, и наоборот
        ledState = HIGH;
      }
      else
      {
        ledState = LOW;
      }
      digitalWrite(Pins[0], ledState); //устанавливаем светодиод в состояние, определяемое переменной ledState
      digitalWrite(Pins[5], ledState);
      i++;
    }
  }

  while (i < 20)
  {
    unsigned long currentMillis = millis();       // сохраняем текущее время
    if (currentMillis - previousMillis >= period) // проверяем прошли ли 1000ms
    {
      previousMillis = currentMillis; // сохраняем последнее время когда мигнул светодиод
      if (ledState == LOW)
      { //если светодиод выключен, то включаем его, и наоборот
        ledState = HIGH;
      }
      else
      {
        ledState = LOW;
      }
      digitalWrite(Pins[7], ledState); //устанавливаем светодиод в состояние, определяемое переменной ledState
      digitalWrite(Pins[2], ledState);
      i++;
    }
  }
}
void Lights4()
{
  int g = 1;
  do
  {
    for (int i = 7; i >= 0; i--)
    {
      digitalWrite(Pins[i], HIGH);
      delay(200);
      for (int i = 7; i >= 0; i--)
        digitalWrite(Pins[i], LOW);
    }
    g++;

  } while (g == 1);
}

Ссылка на библиотеку в первой строке

dengeneral
Offline
Зарегистрирован: 04.05.2018

Не, так вообще не работает (

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

Не может быть. При каждом клике переменная regim меняет значение в интервале 0..3. Все, как ты и задумал. Если не работает, значит разбирайся с функциями Lights

ЗЫ: обрати внимание на комментарий в строках 23 и 24

nik182
Offline
Зарегистрирован: 04.05.2015

строка 51 лишняя.

А как подключена кнопка? Разомкнутый контакт чему соответствует LOW или HIGH?

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

По хорошему лишняя строка 21. Я не разбирался в скетче до упора, у ТС в лупе тоже regim объявлена

nik182
Offline
Зарегистрирован: 04.05.2015


#include <shButton.h>  // <a href="https://github.com/VAleSh-Soft/shButton" title="https://github.com/VAleSh-Soft/shButton" rel="nofollow">https://github.com/VAleSh-Soft/shButton</a>

bool FOG_BEAM_RIGHT = 0;
bool FOG_BEAM_LEFT = 0;
int TURNL_RIGHT = 0;
int TURNL_LEFT = 0;
int LOWBEAM_RIGHT = 0;
int LOWBEAM_LEFT = 0;
int HIGHTBEAM_RIGHT = 0;
int HIGHTBEAM_LEFT = 0;

boolean bStopFlag = false;

int g = 0;
int f = 0;
int s = 0;
int d = 75;

int ButPin = 8;  // Подключаем кнопку к выходу 4
int flag = 0;    // флаг состояния
int regim = 0;   // Переключалка
int regimC = 0;
shButton btn(ButPin, PULL_DOWN);  // если кнопка замыкается на VCC,
                                  // иначе shButton btn(ButPin);

bool LEDflag = false;  //Флаг состояния
//             0  1  2  3  4  5   6   7
int Pins[] = { 2, 3, 5, 6, 9, 10, 11, 12 };  //Пины куда подключен све
bool flagB = false;
uint32_t btnTimer = 0;
uint32_t myTimerA;  //Таймеры задержки
uint32_t myTimerB;  //Таймеры задержки
uint32_t myTimer;

int ledState = LOW;                // переменная, показывающая состояние светодиода
unsigned long previousMillis = 0;  //в этой переменной будем хранить время, когда светодиод последний раз мигнул
const long period = 35;

void setup() {
  Serial.begin(9600);
  for (int i = 0; i <= 7; i++) {
    pinMode(Pins[i], OUTPUT);
  }
  pinMode(ButPin, INPUT_PULLUP);
}

void loop() {
  

  if (btn.getButtonState() == BTN_DOWN) {
    if (++regimC > 3) {
      regimC = 0;
      
    }
    regim=regimC;
  }

  switch (regim) {
    case 0:
      Lights1();
      break;
    case 1:
      Lights2();
      break;
    case 2:
      Lights3();
      break;
    case 3:
      Lights4();
      break;
    default:
      break;
  }
}

int buttonClick() {

  bool btnState = digitalRead(ButPin);
  if (btnState && !flagB && millis() - btnTimer > 50) {
    flagB = true;
    btnTimer = millis();
    f++;
    Serial.println(f);
  }
  if (!btnState && flagB && millis() - btnTimer > 50) {
    flagB = false;
    btnTimer = millis();
  }
  if (f > 3) {
    f = 0;
  }
  return f;
}

void Lights1() {
  int i = 0;
  while (i < 1 && !bStopFlag) {
    for (int i = 7; i >= 0; i--) {
      digitalWrite(Pins[i], HIGH);
      delay(d);
      digitalWrite(Pins[i], LOW);
    }
    for (int i = 0; i <= 7; i++) {
      digitalWrite(Pins[i], HIGH);
      delay(d);
      digitalWrite(Pins[i], LOW);
    }
    for (int i = 7, j = 0; j <= 3, i >= 4; i--, j++) {
      digitalWrite(Pins[i], HIGH);
      digitalWrite(Pins[j], HIGH);
      delay(250);
    }
    for (int i = 7, j = 0; j <= 3, i >= 4; i--, j++) {
      digitalWrite(Pins[i], LOW);
      digitalWrite(Pins[j], LOW);
      delay(500);
    }
    i++;
  }
  bStopFlag = true;
}

void Lights2() {
  int i = 0;

  while (i < 10) {
    unsigned long currentMillis = millis();        // сохраняем текущее время
    if (currentMillis - previousMillis >= period)  // проверяем прошли ли 1000ms
    {
      previousMillis = currentMillis;  // сохраняем последнее время когда мигнул светодиод
      if (ledState == LOW) {           //если светодиод выключен, то включаем его, и наоборот
        ledState = HIGH;
      } else {
        ledState = LOW;
      }
      digitalWrite(Pins[0], ledState);  //устанавливаем светодиод в состояние, определяемое переменной ledState
      i++;
    }
  }

  while (i < 20) {
    unsigned long currentMillis = millis();        // сохраняем текущее время
    if (currentMillis - previousMillis >= period)  // проверяем прошли ли 1000ms
    {
      previousMillis = currentMillis;  // сохраняем последнее время когда мигнул светодиод
      if (ledState == LOW) {           //если светодиод выключен, то включаем его, и наоборот
        ledState = HIGH;
      } else {
        ledState = LOW;
      }
      digitalWrite(Pins[7], ledState);  //устанавливаем светодиод в состояние, определяемое переменной ledState
      i++;
    }
  }
}

void Lights3() {
  int i = 0;

  while (i < 10) {
    unsigned long currentMillis = millis();        // сохраняем текущее время
    if (currentMillis - previousMillis >= period)  // проверяем прошли ли 1000ms
    {
      previousMillis = currentMillis;  // сохраняем последнее время когда мигнул светодиод
      if (ledState == LOW) {           //если светодиод выключен, то включаем его, и наоборот
        ledState = HIGH;
      } else {
        ledState = LOW;
      }
      digitalWrite(Pins[0], ledState);  //устанавливаем светодиод в состояние, определяемое переменной ledState
      digitalWrite(Pins[5], ledState);
      i++;
    }
  }

  while (i < 20) {
    unsigned long currentMillis = millis();        // сохраняем текущее время
    if (currentMillis - previousMillis >= period)  // проверяем прошли ли 1000ms
    {
      previousMillis = currentMillis;  // сохраняем последнее время когда мигнул светодиод
      if (ledState == LOW) {           //если светодиод выключен, то включаем его, и наоборот
        ledState = HIGH;
      } else {
        ledState = LOW;
      }
      digitalWrite(Pins[7], ledState);  //устанавливаем светодиод в состояние, определяемое переменной ledState
      digitalWrite(Pins[2], ledState);
      i++;
    }
  }
}
void Lights4() {
  int g = 1;
  do {
    for (int i = 7; i >= 0; i--) {
      digitalWrite(Pins[i], HIGH);
      delay(200);
      for (int i = 7; i >= 0; i--)
        digitalWrite(Pins[i], LOW);
    }
    g++;

  } while (g == 1);
}

 

А так? 

 

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

Зачем?

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

Не нужно плодить сущности, их у ТС и так напложено (наплудено )))) овердохрена ))

#include <shButton.h> // https://github.com/VAleSh-Soft/shButton

bool FOG_BEAM_RIGHT = 0;
bool FOG_BEAM_LEFT = 0;
int TURNL_RIGHT = 0;
int TURNL_LEFT = 0;
int LOWBEAM_RIGHT = 0;
int LOWBEAM_LEFT = 0;
int HIGHTBEAM_RIGHT = 0;
int HIGHTBEAM_LEFT = 0;

boolean bStopFlag = false;

int g = 0;
int f = 0;
int s = 0;
int d = 75;

int ButPin = 8; // Подключаем кнопку к выходу 4
int flag = 0;   // флаг состояния
int regim = 0;  // Переключалка

shButton btn(ButPin);

bool LEDflag = false; //Флаг состояния
//             0  1  2  3  4  5   6   7
int Pins[] = {2, 3, 5, 6, 9, 10, 11, 12}; //Пины куда подключен све
bool flagB = false;
uint32_t btnTimer = 0;
uint32_t myTimerA; //Таймеры задержки
uint32_t myTimerB; //Таймеры задержки
uint32_t myTimer;

int ledState = LOW;               // переменная, показывающая состояние светодиода
unsigned long previousMillis = 0; //в этой переменной будем хранить время, когда светодиод последний раз мигнул
const long period = 35;

void setup()
{
  Serial.begin(9600);
  for (int i = 0; i <= 7; i++)
  {
    pinMode(Pins[i], OUTPUT);
  }
}

void loop()
{
  if (btn.getButtonState() == BTN_DOWN)
  {
    if (++regim > 3)
    {
      regim = 0;
    }
  }

  switch (regim)
  {
  case 0:
    Lights1();
    break;
  case 1:
    Lights2();
    break;
  case 2:
    Lights3();
    break;
  case 3:
    Lights4();
    break;
  default:
    break;
  }
}

void Lights1()
{
  int i = 0;
  while (i < 1 && !bStopFlag)
  {
    for (int i = 7; i >= 0; i--)
    {
      digitalWrite(Pins[i], HIGH);
      delay(d);
      digitalWrite(Pins[i], LOW);
    }
    for (int i = 0; i <= 7; i++)
    {
      digitalWrite(Pins[i], HIGH);
      delay(d);
      digitalWrite(Pins[i], LOW);
    }
    for (int i = 7, j = 0; j <= 3, i >= 4; i--, j++)
    {
      digitalWrite(Pins[i], HIGH);
      digitalWrite(Pins[j], HIGH);
      delay(250);
    }
    for (int i = 7, j = 0; j <= 3, i >= 4; i--, j++)
    {
      digitalWrite(Pins[i], LOW);
      digitalWrite(Pins[j], LOW);
      delay(500);
    }
    i++;
  }
  bStopFlag = true;
}

void Lights2()
{
  int i = 0;

  while (i < 10)
  {
    unsigned long currentMillis = millis();       // сохраняем текущее время
    if (currentMillis - previousMillis >= period) // проверяем прошли ли 1000ms
    {
      previousMillis = currentMillis; // сохраняем последнее время когда мигнул светодиод
      if (ledState == LOW)
      { //если светодиод выключен, то включаем его, и наоборот
        ledState = HIGH;
      }
      else
      {
        ledState = LOW;
      }
      digitalWrite(Pins[0], ledState); //устанавливаем светодиод в состояние, определяемое переменной ledState
      i++;
    }
  }

  while (i < 20)
  {
    unsigned long currentMillis = millis();       // сохраняем текущее время
    if (currentMillis - previousMillis >= period) // проверяем прошли ли 1000ms
    {
      previousMillis = currentMillis; // сохраняем последнее время когда мигнул светодиод
      if (ledState == LOW)
      { //если светодиод выключен, то включаем его, и наоборот
        ledState = HIGH;
      }
      else
      {
        ledState = LOW;
      }
      digitalWrite(Pins[7], ledState); //устанавливаем светодиод в состояние, определяемое переменной ledState
      i++;
    }
  }
}

void Lights3()
{
  int i = 0;

  while (i < 10)
  {
    unsigned long currentMillis = millis();       // сохраняем текущее время
    if (currentMillis - previousMillis >= period) // проверяем прошли ли 1000ms
    {
      previousMillis = currentMillis; // сохраняем последнее время когда мигнул светодиод
      if (ledState == LOW)
      { //если светодиод выключен, то включаем его, и наоборот
        ledState = HIGH;
      }
      else
      {
        ledState = LOW;
      }
      digitalWrite(Pins[0], ledState); //устанавливаем светодиод в состояние, определяемое переменной ledState
      digitalWrite(Pins[5], ledState);
      i++;
    }
  }

  while (i < 20)
  {
    unsigned long currentMillis = millis();       // сохраняем текущее время
    if (currentMillis - previousMillis >= period) // проверяем прошли ли 1000ms
    {
      previousMillis = currentMillis; // сохраняем последнее время когда мигнул светодиод
      if (ledState == LOW)
      { //если светодиод выключен, то включаем его, и наоборот
        ledState = HIGH;
      }
      else
      {
        ledState = LOW;
      }
      digitalWrite(Pins[7], ledState); //устанавливаем светодиод в состояние, определяемое переменной ledState
      digitalWrite(Pins[2], ledState);
      i++;
    }
  }
}
void Lights4()
{
  int g = 1;
  do
  {
    for (int i = 7; i >= 0; i--)
    {
      digitalWrite(Pins[i], HIGH);
      delay(200);
      for (int i = 7; i >= 0; i--)
        digitalWrite(Pins[i], LOW);
    }
    g++;

  } while (g == 1);
}

 

nik182
Offline
Зарегистрирован: 04.05.2015
/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
titanium bicycle for button. (version 14.0)
file Button.h - shell for to class Click, buttons.
<a data-cke-saved-href="https://klapautsiy.github.io/titanium-bicycle-for-button/" href="https://klapautsiy.github.io/titanium-bicycle-for-button/" rel="nofollow">https://klapautsiy.github.io/titanium-bicycle-for-button/</a>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

#include <Button.h>

Button test;


bool FOG_BEAM_RIGHT = 0;
bool FOG_BEAM_LEFT = 0;
int TURNL_RIGHT = 0;
int TURNL_LEFT = 0;
int LOWBEAM_RIGHT = 0;
int LOWBEAM_LEFT = 0;
int HIGHTBEAM_RIGHT = 0;
int HIGHTBEAM_LEFT = 0;

boolean bStopFlag = false;

int g = 0;
int f = 0;
int s = 0;
int d = 75;

int ButPin = 8;  // Подключаем кнопку к выходу 4
int flag = 0;    // флаг состояния
int regim = 0;   // Переключалка
int regimC = 0;

bool LEDflag = false;  //Флаг состояния
//             0  1  2  3  4  5   6   7
int Pins[] = { 2, 3, 5, 6, 9, 10, 11, 12 };  //Пины куда подключен све
bool flagB = false;
uint32_t btnTimer = 0;
uint32_t myTimerA;  //Таймеры задержки
uint32_t myTimerB;  //Таймеры задержки
uint32_t myTimer;

int ledState = LOW;                // переменная, показывающая состояние светодиода
unsigned long previousMillis = 0;  //в этой переменной будем хранить время, когда светодиод последний раз мигнул
const long period = 35;

void setup() {
    pinMode(ButPin, INPUT_PULLUP);
  test.NO(); // N.O. Normal Open
// test.NC(); // N.C. Normal Closed
test.pullUp();
// test.pullDn();
test.duration_bounce       (  50);
test.duration_click_Db     ( 250);
test.duration_inactivity_Up(5000);
test.duration_inactivity_Dn(1000);
test.duration_press        ( 500);
test.button( ButPin); // arduino pins connected to button

  Serial.begin(9600);
  for (int i = 0; i <= 7; i++) {
    pinMode(Pins[i], OUTPUT);
  }

}

void loop() {
  
  test.read();

  if (test.event_click_Up     (0) == 1) {
    if (++regimC > 3) {
      regimC = 0;
      
    }
    regim=regimC;
  }

  switch (regim) {
    case 0:
      Lights1();
      break;
    case 1:
      Lights2();
      break;
    case 2:
      Lights3();
      break;
    case 3:
      Lights4();
      break;
    default:
      break;
  }
}


void Lights1() {
  int i = 0;
  while (i < 1 && !bStopFlag) {
    for (int i = 7; i >= 0; i--) {
      digitalWrite(Pins[i], HIGH);
      delay(d);
      digitalWrite(Pins[i], LOW);
    }
    for (int i = 0; i <= 7; i++) {
      digitalWrite(Pins[i], HIGH);
      delay(d);
      digitalWrite(Pins[i], LOW);
    }
    for (int i = 7, j = 0; j <= 3, i >= 4; i--, j++) {
      digitalWrite(Pins[i], HIGH);
      digitalWrite(Pins[j], HIGH);
      delay(250);
    }
    for (int i = 7, j = 0; j <= 3, i >= 4; i--, j++) {
      digitalWrite(Pins[i], LOW);
      digitalWrite(Pins[j], LOW);
      delay(500);
    }
    i++;
  }
  bStopFlag = true;
  regim=10;
}

void Lights2() {
  int i = 0;

  while (i < 10) {
    unsigned long currentMillis = millis();        // сохраняем текущее время
    if (currentMillis - previousMillis >= period)  // проверяем прошли ли 1000ms
    {
      previousMillis = currentMillis;  // сохраняем последнее время когда мигнул светодиод
      if (ledState == LOW) {           //если светодиод выключен, то включаем его, и наоборот
        ledState = HIGH;
      } else {
        ledState = LOW;
      }
      digitalWrite(Pins[0], ledState);  //устанавливаем светодиод в состояние, определяемое переменной ledState
      i++;
    }
  }

  while (i < 20) {
    unsigned long currentMillis = millis();        // сохраняем текущее время
    if (currentMillis - previousMillis >= period)  // проверяем прошли ли 1000ms
    {
      previousMillis = currentMillis;  // сохраняем последнее время когда мигнул светодиод
      if (ledState == LOW) {           //если светодиод выключен, то включаем его, и наоборот
        ledState = HIGH;
      } else {
        ledState = LOW;
      }
      digitalWrite(Pins[7], ledState);  //устанавливаем светодиод в состояние, определяемое переменной ledState
      i++;
    }
  }
}

void Lights3() {
  int i = 0;

  while (i < 10) {
    unsigned long currentMillis = millis();        // сохраняем текущее время
    if (currentMillis - previousMillis >= period)  // проверяем прошли ли 1000ms
    {
      previousMillis = currentMillis;  // сохраняем последнее время когда мигнул светодиод
      if (ledState == LOW) {           //если светодиод выключен, то включаем его, и наоборот
        ledState = HIGH;
      } else {
        ledState = LOW;
      }
      digitalWrite(Pins[0], ledState);  //устанавливаем светодиод в состояние, определяемое переменной ledState
      digitalWrite(Pins[5], ledState);
      i++;
    }
  }

  while (i < 20) {
    unsigned long currentMillis = millis();        // сохраняем текущее время
    if (currentMillis - previousMillis >= period)  // проверяем прошли ли 1000ms
    {
      previousMillis = currentMillis;  // сохраняем последнее время когда мигнул светодиод
      if (ledState == LOW) {           //если светодиод выключен, то включаем его, и наоборот
        ledState = HIGH;
      } else {
        ledState = LOW;
      }
      digitalWrite(Pins[7], ledState);  //устанавливаем светодиод в состояние, определяемое переменной ledState
      digitalWrite(Pins[2], ledState);
      i++;
    }
  }
}
void Lights4() {
  int g = 1;
  do {
    for (int i = 7; i >= 0; i--) {
      digitalWrite(Pins[i], HIGH);
      delay(200);
      for (int i = 7; i >= 0; i--)
        digitalWrite(Pins[i], LOW);
    }
    g++;

  } while (g == 1);
  regim=10;
}

 

dengeneral
Offline
Зарегистрирован: 04.05.2018

В общем сделал вот так: Нашел скетч в сети и переделал немного под свой лад

int led1[] = { 3,4,5,6 };
int led2[] = { 9,10,11,12 };
//int buttonPin = 8;
int val = 0, stope = 1;
long previousMillis = 0;
int buttonState = 0;
long interval = 300;
int Pins[] = { 3, 4, 5, 6, 9, 10, 11, 12 }; //Пины куда подключен светодиоды
boolean bStopFlag = false;
int s = 0;
int d = 75; //задержка
int ledState = LOW;                // переменная, показывающая состояние светодиода
const long period = 35;


void setup() {
	Serial.begin(9600);
	delay(2);
	Serial.println(val);
	for (int i = 0; i <= 7; i++)
	{
		pinMode(Pins[i], OUTPUT);
	}

	//  pinMode (buttonPin, INPUT);   
	attachInterrupt(0, buttonPin, FALLING);
	while (!Serial);

}

void one()
{
	while (stope == 1)
	{
		while (s < 1 && !bStopFlag)
		{
			for (int i = 7; i >= 0; i--)
			{
				digitalWrite(Pins[i], HIGH);
				delay(d);
				digitalWrite(Pins[i], LOW);
			}
			for (int i = 0; i <= 7; i++)
			{
				digitalWrite(Pins[i], HIGH);
				delay(d);
				digitalWrite(Pins[i], LOW);
			}
			for (int i = 7, j = 0; j <= 3, i >= 4; i--, j++)
			{
				digitalWrite(Pins[i], HIGH);
				digitalWrite(Pins[j], HIGH);
				delay(250);
			}
			for (int i = 7, j = 0; j <= 3, i >= 4; i--, j++)
			{
				digitalWrite(Pins[i], LOW);
				digitalWrite(Pins[j], LOW);
				delay(500);
			}
			s++;
		}
		bStopFlag = false;
		if (Serial.available() > 0) stope = Serial.parseInt();
	}
	for (int i = 7; i >= 0; i--)
		digitalWrite(Pins[i], LOW);
}

void two()
{

	while (stope == 1)
	{
		int i = 0;

		while (i < 10)
		{
			unsigned long currentMillis = millis(); // сохраняем текущее время
			if (currentMillis - previousMillis >= period)  // проверяем прошли ли 1000ms 
			{
				previousMillis = currentMillis;   // сохраняем последнее время когда мигнул светодиод
				if (ledState == LOW) { //если светодиод выключен, то включаем его, и наоборот 
					ledState = HIGH;
				}
				else
				{
					ledState = LOW;
				}
				digitalWrite(Pins[0], ledState);//устанавливаем светодиод в состояние, определяемое переменной ledState
				i++;
			}
		}

		while (i < 20)
		{
			unsigned long currentMillis = millis(); // сохраняем текущее время
			if (currentMillis - previousMillis >= period)  // проверяем прошли ли 1000ms 
			{
				previousMillis = currentMillis;   // сохраняем последнее время когда мигнул светодиод
				if (ledState == LOW) { //если светодиод выключен, то включаем его, и наоборот 
					ledState = HIGH;
				}
				else
				{
					ledState = LOW;
				}
				digitalWrite(Pins[7], ledState);//устанавливаем светодиод в состояние, определяемое переменной ledState
				i++;
			}
		}
		bStopFlag = false;
		s = 0;
		if (Serial.available() > 0) stope = Serial.parseInt();
	}
	for (int i = 7; i >= 0; i--)
		digitalWrite(Pins[i], LOW);
	s = 0;
}
void three()
{
	
	while (stope == 1)
	{
		int i = 0;

		while (i < 10)
		{
			unsigned long currentMillis = millis(); // сохраняем текущее время
			if (currentMillis - previousMillis >= period)  // проверяем прошли ли 1000ms 
			{
				previousMillis = currentMillis;   // сохраняем последнее время когда мигнул светодиод
				if (ledState == LOW) { //если светодиод выключен, то включаем его, и наоборот 
					ledState = HIGH;
				}
				else
				{
					ledState = LOW;
				}
				digitalWrite(Pins[0], ledState);//устанавливаем светодиод в состояние, определяемое переменной ledState
				digitalWrite(Pins[5], ledState);
				i++;
			}
		}

		while (i < 20)
		{
			unsigned long currentMillis = millis(); // сохраняем текущее время
			if (currentMillis - previousMillis >= period)  // проверяем прошли ли 1000ms 
			{
				previousMillis = currentMillis;   // сохраняем последнее время когда мигнул светодиод
				if (ledState == LOW) { //если светодиод выключен, то включаем его, и наоборот 
					ledState = HIGH;
				}
				else
				{
					ledState = LOW;
				}
				digitalWrite(Pins[7], ledState);//устанавливаем светодиод в состояние, определяемое переменной ledState
				digitalWrite(Pins[2], ledState);
				i++;
			}
		}
		if (Serial.available() > 0) stope = Serial.parseInt();
		
		
	}
	for (int i = 7; i >= 0; i--)
		digitalWrite(Pins[i], LOW);
}
void smooth()
{
	while (stope == 1)
	{

		if (Serial.available() > 0) stope = Serial.parseInt();
	}
}
void smooth2()
{
	while (stope == 1)
	{

		if (Serial.available() > 0) stope = Serial.parseInt();
	}
}
void smooth3()
{
	while (stope == 1)
	{

		if (Serial.available() > 0) stope = Serial.parseInt();
	}
}

void loop() {
	if (Serial.available() > 0) val = Serial.parseInt();
	switch (val)
	{
	case 1:stope = 1; one(); break;
	case 2:stope = 1; two(); break;
	case 3:stope = 1; three(); break;
	case 4:stope = 1; smooth(); break;
	case 5:stope = 1; smooth2(); break;
	case 6:stope = 1; smooth3(); break;
	}
}
void buttonPin()
{
	static unsigned long millis_prev;
	if (millis() - 1000 > millis_prev)
	{
		stope = 1;
		delay(50);
		val++;
		delay(50);
		stope = 0;
		Serial.println(val);
		if (val == 7)val = 0;
	}
	millis_prev = millis();
}

 

Работает пока как мне нужно.
Спасибо парни за советы =)

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

Я смотрю, титановый лисапед для мазохистов писан )))

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

dengeneral пишет:

Я даже делал вот так. Поидее функция должна выполнится 1 раз. Но она зацикливается (


void Lights4()
{
	do
	{
		for (int i = 7; i >= 0; i--)
		{
			digitalWrite(Pins[i], HIGH);
			delay(200);
			for (int i = 7; i >= 0; i--)
			digitalWrite(Pins[i], LOW);
		}
		g++;
		break;

	} while (g == 1);
}

Вас не смущает, что в строках №№ 5 и 9 используется переменная i в обеих? Не то, чтобы так нельзя, но Вы точно понимаете, что делаете?

dengeneral
Offline
Зарегистрирован: 04.05.2018

ЕвгенийП пишет:

dengeneral пишет:

Я даже делал вот так. Поидее функция должна выполнится 1 раз. Но она зацикливается (


void Lights4()
{
	do
	{
		for (int i = 7; i >= 0; i--)
		{
			digitalWrite(Pins[i], HIGH);
			delay(200);
			for (int i = 7; i >= 0; i--)
			digitalWrite(Pins[i], LOW);
		}
		g++;
		break;

	} while (g == 1);
}

Вас не смущает, что в строках №№ 5 и 9 используется переменная i в обеих? Не то, чтобы так нельзя, но Вы точно понимаете, что делаете?

Так светодиоды бегут с лева направо загораясь по одному. Мне так и нужно по идее. Но не нужен вечный цикл

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

Имелось в виду две РАЗНЫЕ переменные с одинаковым именем

ЗЫ: строка 9 не нужна, и без нее зажженный светодиод будет отключаться

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

dengeneral пишет:

Так светодиоды бегут с лева направо загораясь по одному. Мне так и нужно по идее. Но не нужен вечный цикл

Повторяю вопрос, попробуйте внимательно прочитать: Вас не смущает, что в строках №№ 5 и 9 используется одна и та же (по имени) переменная i? Если не смущает, то я ничего - хозяин-барин.

b707
Offline
Зарегистрирован: 26.05.2017

dengeneral пишет:

Так светодиоды бегут с лева направо загораясь по одному. Мне так и нужно по идее.

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

dengeneral
Offline
Зарегистрирован: 04.05.2018

Нет, вы не поняли, они как бы пробегают по одному, с нулевого светодиода к 7 светодиоду, т.е. светодиод загорелся, погас, за ним следующий и так до конца и все... мне нужно было что бы они вот так пробежали от 0 до 7 и больше цикл не выполнялся)) Это как бы эффект отключения такой. Надеюсь я норм объяснил. Ну может я это неправильно реализовал ))

dengeneral
Offline
Зарегистрирован: 04.05.2018

v258 пишет:
Имелось в виду две РАЗНЫЕ переменные с одинаковым именем ЗЫ: строка 9 не нужна, и без нее зажженный светодиод будет отключаться

 

в смысле без 9 строки зажженный светодиод будет отключаться? А как контроллер поймет? Или я что то не догоняю ))). Ну хотя скорее всего я не догоняю)))))))))))))))))))

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

dengeneral пишет:

v258 пишет:
Имелось в виду две РАЗНЫЕ переменные с одинаковым именем ЗЫ: строка 9 не нужна, и без нее зажженный светодиод будет отключаться

 

в смысле без 9 строки зажженный светодиод будет отключаться? А как контроллер поймет? Или я что то не догоняю ))). Ну хотя скорее всего я не догоняю)))))))))))))))))))

Он никак не поймет. Он сделает то, что ему указано сделать. Смотри внимательно 

void Lights4()
{
	do
	{
		for (int i = 7; i >= 0; i--)
		{
			digitalWrite(Pins[i], HIGH);
			delay(200);
			digitalWrite(Pins[i], LOW);
		}
		g++;
		break;

	} while (g == 1);
}

Какой светодиод включается? С индексом i. А какой через 200 мс выключается? Тоже с индексом i. Т.е. тот же самый. Прикинь )))

dengeneral
Offline
Зарегистрирован: 04.05.2018

v258 пишет:

dengeneral пишет:

v258 пишет:
Имелось в виду две РАЗНЫЕ переменные с одинаковым именем ЗЫ: строка 9 не нужна, и без нее зажженный светодиод будет отключаться

 

в смысле без 9 строки зажженный светодиод будет отключаться? А как контроллер поймет? Или я что то не догоняю ))). Ну хотя скорее всего я не догоняю)))))))))))))))))))

Он никак не поймет. Он сделает то, что ему указано сделать. Смотри внимательно 

void Lights4()
{
	do
	{
		for (int i = 7; i >= 0; i--)
		{
			digitalWrite(Pins[i], HIGH);
			delay(200);
			digitalWrite(Pins[i], LOW);
		}
		g++;
		break;

	} while (g == 1);
}

Какой светодиод включается? С индексом i. А какой через 200 мс выключается? Тоже с индексом i. Т.е. тот же самый. Прикинь )))

Л - Логика ))). Спасибо за подсказку. Действительно )