#1 Re: Програмування Arduino » Нужна помощь начинающему!!! 3-х режимный фонарик » 2024-03-20 00:39:42

dimich, змінивши трохи ваш код нарешті я здається допер як воно все працює
задача:
лед світить 4000 мс
лед не світить 1000 мс
лед світить 2000 мс
лед не світить 2000 мс
====================================================

int state = 0; // поточний стан. з початку - "0";
unsigned long last_time;

void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW); 
}

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

  switch (state)
  {
    case 0: // додав цей кейс
      if (now - last_time >= 10) { // LED має світити 2000 мс? вірно?
        digitalWrite(13, HIGH);
        last_time = now;
        state = 1;
      }
      break;
    case 1:
      if (now - last_time >= 4000) { // LED має не світити 200 мс? вірно?
        digitalWrite(13, LOW);
        last_time = now;
        state = 2;
      }
      break;
    case 2:
      if (now - last_time >= 1000) { // LED має світити 500 мс? вірно?
        digitalWrite(13, HIGH);
        last_time = now;
        state = 3;
      }
      break;
    case 3:
      if (now - last_time >= 2000) { // LED має не світити 2000 мс? вірно?
        digitalWrite(13, LOW);
        last_time = now;
        state = 4; // переходим в початковий стан "0"
      }
      break;
      case 4:
      if (now - last_time >= 2000) { // LED має не світити 2000 мс? вірно?
        digitalWrite(13, LOW);
        last_time = now;
        state = 0; // переходим в початковий стан "0"
      }
      break;
  }
}

#2 Re: Програмування Arduino » Нужна помощь начинающему!!! 3-х режимный фонарик » 2024-03-20 00:27:55

нашел ошибку case : 0  , исправил на case 0: и так далее но лед теперь все время светится
==================================================

просто зайшов пише:
sxstalker пише:

заменил digitalWrite(13, LOW); на digitalWrite(13, HIGH);  в самом начале
первый цикл все работает верно

ладно если Вам это сложно, может так будет проще для понимания

unsigned long last_time;

void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW); 

}

bool on = false; // поточний стан. з початку - вимкнено;

void loop() {
  unsigned long now = millis();
  static unsigned char task=0;
switch (task)
  {
	case : 0  
	   digitalWrite(13, HIGH); // вмикаєм 
       if (now - last_time >= 2000) { // пройшло 1000 мс ?
       last_time = now;
       on = true; // зберігаєм поточний стан, що увімкнено
       }
       break; 
    case : 1 
          digitalWrite(13, LOW); // вимикаєм       
       if (now - last_time >= 200) { // пройшло 300 мс ?
          last_time = now;
          on = false; // зберігаєм поточний стан, що вимкнено
          }
       break; 
    case : 2    
          digitalWrite(13, HIGH); // вмикаєм	
       if (now - last_time >= 500) { // пройшло 1000 мс ?
          last_time = now;
          on = true; // зберігаєм поточний стан, що увімкнено
        }
       break; 
    case : 3 
           digitalWrite(13, LOW); // вимикаєм	
        if (now - last_time >= 2000) { // пройшло 300 мс ?
           last_time = now;
           on = false; // зберігаєм поточний стан, що вимкнено
        }
       break; 
    default :
       break; 	
  } 


}

#3 Re: Програмування Arduino » Нужна помощь начинающему!!! 3-х режимный фонарик » 2024-03-20 00:10:50

выбивает ошибку при запуске
OShIBKA.png
OShIBKA_2.png
==================================================

просто зайшов пише:
sxstalker пише:

заменил digitalWrite(13, LOW); на digitalWrite(13, HIGH);  в самом начале
первый цикл все работает верно

ладно если Вам это сложно, может так будет проще для понимания

unsigned long last_time;

void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW); 

}

bool on = false; // поточний стан. з початку - вимкнено;

void loop() {
  unsigned long now = millis();
  static unsigned char task=0;
switch (task)
  {
	case : 0  
	   digitalWrite(13, HIGH); // вмикаєм 
       if (now - last_time >= 2000) { // пройшло 1000 мс ?
       last_time = now;
       on = true; // зберігаєм поточний стан, що увімкнено
       }
       break; 
    case : 1 
          digitalWrite(13, LOW); // вимикаєм       
       if (now - last_time >= 200) { // пройшло 300 мс ?
          last_time = now;
          on = false; // зберігаєм поточний стан, що вимкнено
          }
       break; 
    case : 2    
          digitalWrite(13, HIGH); // вмикаєм	
       if (now - last_time >= 500) { // пройшло 1000 мс ?
          last_time = now;
          on = true; // зберігаєм поточний стан, що увімкнено
        }
       break; 
    case : 3 
           digitalWrite(13, LOW); // вимикаєм	
        if (now - last_time >= 2000) { // пройшло 300 мс ?
           last_time = now;
           on = false; // зберігаєм поточний стан, що вимкнено
        }
       break; 
    default :
       break; 	
  } 


}

#4 Re: Програмування Arduino » Нужна помощь начинающему!!! 3-х режимный фонарик » 2024-03-19 23:49:36

ух, боюсь я тут пока вас не пойму еще, для меня это все пока за ширмой неизведанного smile
но если есть какой-то способ более правильный мигать лед так как я хочу то я только за чтобы научится новому
==========================================================================

просто зайшов пише:

вообще millis(); очень неудобная функция для 8ми битных микроконтроллеров ,  мало того что не точная, так еще и занимает кучу времени на обработку 32-х битной математики.
Что мешало разрабам добавить для пользователей глобальный флаг в обработчик прерывания по таймеру0 не понятно...
Хотя это решается включением прерывания по совпадению TIMER0_COMPA_vect .

#5 Re: Програмування Arduino » Нужна помощь начинающему!!! 3-х режимный фонарик » 2024-03-19 23:46:48

dimich , в цьому прикладі точно така ж біла в мене, перший цикл проходить все вірно а потім є блимання лед які зовсім по інтервалу не заявлені в масиві, можливо то глюк цієї віртуалки? чи я десь все ж таки щось не зрозумів?
https://wokwi.com/projects/392819629072839681
===================================================================

unsigned int dur[4] = { 3000, 200, 1500, 2000 };  // масив тривалостей (duration) для кожного стану
byte led[4] = { HIGH, LOW, HIGH, LOW };          // масив значень digitalWrite для кожного стану
int state = 0; // поточний стан. з початку - "0";
unsigned long last_time;

void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH); 
}

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

  if (now - last_time >= dur[state]) { // якщо час поточного стану вийшов
    digitalWrite(13, led[state]);      // вмикаєм або вимикаєм світлодіод
    last_time = now;
    state = state + 1; // переходим у наступний стан
    // але максимально можливий номер стану - "3"
    // якщо це був останній - переходим у початковий стан "0"
    if (state > 3) {
      state = 0;
    }
   }
}

#6 Re: Програмування Arduino » Нужна помощь начинающему!!! 3-х режимный фонарик » 2024-03-19 23:38:06

заменил digitalWrite(13, LOW); на digitalWrite(13, HIGH);  в самом начале
первый цикл все работает верно
но как переходит к выполнению по второму кругу мигания то
со светодиодом какие-то происходят не заявленные мигания
где я что-то не понял возможно?
==================================================

просто зайшов пише:
sxstalker пише:

попробовал ваш код, но я так понимаю нужно инвертировать !HIGH и !LOW ? так как сейчас LED мигает наоборот smile

нет, мигает он правильно...
начальное значение LED=LOW, задача0 отсчитывает 2000мс, по истечению счета переключается на задачу1 и включает LED=HIGH
,  задача1 отсчитывает 200мс, по истечению счета переключается на задачу2 и выключает LED=LOW, и тд.

#7 Re: Програмування Arduino » Нужна помощь начинающему!!! 3-х режимный фонарик » 2024-03-19 23:18:57

dimich, спробував також і ваш код і також лед мигає навпаки smile
https://wokwi.com/projects/392817187868217345
=====================================================

dimich пише:

Ця конструкція:

sxstalker пише:
  if (!on) {
...
  } else if (on) {
...
  } else if (!on) {
...
  } else if (on) {
...
  } 

не має сенсу. Якщо перша умова "if (!on)" виконалась, то решта вже не виконуються. А якщо не виконалась, то обовʼязково виконається друга - "if (on)", бо вона протилежна першій. А дві останні - ніколи не виконаються.

В попередньому прикладі у вас було всього два стани: світлодіод вимкнено, і світлодіод увімкнено. Тому було достатньо змінної типу bool, у якої всього два можливих значення.

В останньому прикладі у вас чотири стани:
* вимкнено перший раз (на 2000 мс)
* увімкнено перший раз (на 200 мс)
* вимкнено другий раз (на 500 мс)
* увімкнено другий раз (на 2000 мс)

Тому для збереження стану потрібна змінна такого типу, щоб могла приймати як мінімум 4 значення. Для простоти візьмем int. Стани будем нумерувати від 0 до 3. І для ясності перейменуєм змінну з "on" на "state".

int state = 0; // поточний стан. з початку - "0";

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

  if (state == 0) { // в стані "0"?
    if (now - last_time >= 2000) {
      digitalWrite(13, HIGH);
      last_time = now;
      state = 1; // переходим в стан "1"
    }
  } else if (state == 1) { // в стані "1"?
     if (now - last_time >= 200) {
      digitalWrite(13, LOW);
      last_time = now;
      state = 2; // переходим в стан "2"
    }
  } else if (state == 2) { // в стані "2"?
    if (now - last_time >= 500) {
      digitalWrite(13, HIGH);
      last_time = now;
      state = 3; // переходим в стан "3"
    }
  } else if (state == 3) { // в стані "3" ?
     if (now - last_time >= 2000) {
        digitalWrite(13, LOW);
       last_time = now;
       state = 0; // переходим в початковий стан "0"
    }
  }
}

Абсолютно те ж саме, тільки switch/case замість if/else. Так більш читабельно:

int state = 0; // поточний стан. з початку - "0";

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

  switch (state)
  {
    case 0:
      if (now - last_time >= 2000) {
        digitalWrite(13, HIGH);
        last_time = now;
        state = 1;
      }
      break;
    case 1:
      if (now - last_time >= 200) {
        digitalWrite(13, LOW);
        last_time = now;
        state = 2;
      }
      break;
    case 2:
      if (now - last_time >= 500) {
        digitalWrite(13, HIGH);
        last_time = now;
        state = 3;
      }
      break;
    case 3:
      if (now - last_time >= 2000) {
        digitalWrite(13, LOW);
        last_time = now;
        state = 0; // переходим в початковий стан "0"
      }
      break;
  }
}

Тепер зверніть увагу на те, що дії при переході між станами практично однакові. Відрізняються тільки
тривалості: 2000, 200, 500, 2000
значення, що передається у digitalWrite: HIGH, LOW, HIGH, LOW
номер наступного стану: 1, 2, 3, 0, 1, 2 ...

Таким чином можна використати один і той же код для циклічного переходу між станами. Тривалості та значення для digitalWrite помістимо у масиви, а значення з масивів вибиратимем по номеру стану:

unsigned int dur[4] = { 2000, 200, 500, 2000 };  // масив тривалостей (duration) для кожного стану
byte led[4] = { HIGH, LOW, HIGH, LOW };          // масив значень digitalWrite для кожного стану
int state = 0; // поточний стан. з початку - "0";

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

  if (now - last_time >= dur[state]) { // якщо час поточного стану вийшов
    digitalWrite(13, led[state]);      // вмикаєм або вимикаєм світлодіод
    last_time = now;
    state = state + 1; // переходим у наступний стан
    // але максимально можливий номер стану - "3"
    // якщо це був останній - переходим у початковий стан "0"
    if (state > 3) {
      state = 0;
    }
   }
}

Тепер зверніть увагу, що в масиві led всього два варіанти значень для digitalWrite: HIGH і LOW, і вони чергуються. Можна обійтись без цього масиву. Як його позбутись - вам в якості самостійного завдання smile

#8 Re: Програмування Arduino » Нужна помощь начинающему!!! 3-х режимный фонарик » 2024-03-19 23:12:10

спасибо! я обязательно посмотрю! smile
=========================================

просто зайшов пише:

рекомендую изучить "полный справочник по С" Герберт Шилдт
https://glagolew2010.narod.ru/
квалификаторы типов
и области видимости.

#9 Re: Програмування Arduino » Нужна помощь начинающему!!! 3-х режимный фонарик » 2024-03-19 23:11:06

попробовал ваш код, но я так понимаю нужно инвертировать !HIGH и !LOW ? так как сейчас LED мигает наоборот smile
вот проект https://wokwi.com/projects/392815604378833921
==============================================

просто зайшов пише:

как-то так...

unsigned long last_time;

void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW); 

}

bool on = false; // поточний стан. з початку - вимкнено;

void loop() {
  unsigned long now = millis();
  static unsigned char task=0;
switch (task)
  {
	  case 0:   
       if (now - last_time >= 2000) { // пройшло 1000 мс ?
          digitalWrite(13, HIGH); // вмикаєм
          last_time = now;
          task=1; // переходим к следующей задаче
        }
       break; 
    case 1:   
       if (now - last_time >= 200) { // пройшло 300 мс ?
          digitalWrite(13, LOW); // вимикаєм
          last_time = now;
          task=2; 
        }
       break; 
    case 2:     
       if (now - last_time >= 500) { // пройшло 1000 мс ?
          digitalWrite(13, HIGH); // вмикаєм
          last_time = now;
          task=3;
        }
       break; 
    case 3: 
        if (now - last_time >= 2000) { // пройшло 300 мс ?
           digitalWrite(13, LOW); // вимикаєм
           last_time = now;
           task=0;
        }
       break; 
    default :
       break; 	
  } 


}

#10 Re: Програмування Arduino » Нужна помощь начинающему!!! 3-х режимный фонарик » 2024-03-19 22:58:47

огромное спасибо вам! я еще почитаю тогда об этом smile
=================================

просто зайшов пише:

"static unsigned char task=0; // це ми тут оголошуємо змінну ? вірно?"
нет, не верно
тут мы присваиваем начальное значение при запуске программы,
если убрать static , то переменная будет устанавливаться каждый раз при вызове функции.

#11 Re: Програмування Arduino » Нужна помощь начинающему!!! 3-х режимный фонарик » 2024-03-19 22:56:11

ой, низький вам усім уклін за вашу доброту та допомогу
до мене нарешті трохи починає доходити smile
тепер все перепробую, потренуюсь та спробую виконати ваше завдання smile
=============================================

dimich пише:

Ця конструкція:

sxstalker пише:
  if (!on) {
...
  } else if (on) {
...
  } else if (!on) {
...
  } else if (on) {
...
  } 

не має сенсу. Якщо перша умова "if (!on)" виконалась, то решта вже не виконуються. А якщо не виконалась, то обовʼязково виконається друга - "if (on)", бо вона протилежна першій. А дві останні - ніколи не виконаються.

В попередньому прикладі у вас було всього два стани: світлодіод вимкнено, і світлодіод увімкнено. Тому було достатньо змінної типу bool, у якої всього два можливих значення.

В останньому прикладі у вас чотири стани:
* вимкнено перший раз (на 2000 мс)
* увімкнено перший раз (на 200 мс)
* вимкнено другий раз (на 500 мс)
* увімкнено другий раз (на 2000 мс)

Тому для збереження стану потрібна змінна такого типу, щоб могла приймати як мінімум 4 значення. Для простоти візьмем int. Стани будем нумерувати від 0 до 3. І для ясності перейменуєм змінну з "on" на "state".

int state = 0; // поточний стан. з початку - "0";

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

  if (state == 0) { // в стані "0"?
    if (now - last_time >= 2000) {
      digitalWrite(13, HIGH);
      last_time = now;
      state = 1; // переходим в стан "1"
    }
  } else if (state == 1) { // в стані "1"?
     if (now - last_time >= 200) {
      digitalWrite(13, LOW);
      last_time = now;
      state = 2; // переходим в стан "2"
    }
  } else if (state == 2) { // в стані "2"?
    if (now - last_time >= 500) {
      digitalWrite(13, HIGH);
      last_time = now;
      state = 3; // переходим в стан "3"
    }
  } else if (state == 3) { // в стані "3" ?
     if (now - last_time >= 2000) {
        digitalWrite(13, LOW);
       last_time = now;
       state = 0; // переходим в початковий стан "0"
    }
  }
}

Абсолютно те ж саме, тільки switch/case замість if/else. Так більш читабельно:

int state = 0; // поточний стан. з початку - "0";

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

  switch (state)
  {
    case 0:
      if (now - last_time >= 2000) {
        digitalWrite(13, HIGH);
        last_time = now;
        state = 1;
      }
      break;
    case 1:
      if (now - last_time >= 200) {
        digitalWrite(13, LOW);
        last_time = now;
        state = 2;
      }
      break;
    case 2:
      if (now - last_time >= 500) {
        digitalWrite(13, HIGH);
        last_time = now;
        state = 3;
      }
      break;
    case 3:
      if (now - last_time >= 2000) {
        digitalWrite(13, LOW);
        last_time = now;
        state = 0; // переходим в початковий стан "0"
      }
      break;
  }
}

Тепер зверніть увагу на те, що дії при переході між станами практично однакові. Відрізняються тільки
тривалості: 2000, 200, 500, 2000
значення, що передається у digitalWrite: HIGH, LOW, HIGH, LOW
номер наступного стану: 1, 2, 3, 0, 1, 2 ...

Таким чином можна використати один і той же код для циклічного переходу між станами. Тривалості та значення для digitalWrite помістимо у масиви, а значення з масивів вибиратимем по номеру стану:

unsigned int dur[4] = { 2000, 200, 500, 2000 };  // масив тривалостей (duration) для кожного стану
byte led[4] = { HIGH, LOW, HIGH, LOW };          // масив значень digitalWrite для кожного стану
int state = 0; // поточний стан. з початку - "0";

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

  if (now - last_time >= dur[state]) { // якщо час поточного стану вийшов
    digitalWrite(13, led[state]);      // вмикаєм або вимикаєм світлодіод
    last_time = now;
    state = state + 1; // переходим у наступний стан
    // але максимально можливий номер стану - "3"
    // якщо це був останній - переходим у початковий стан "0"
    if (state > 3) {
      state = 0;
    }
   }
}

Тепер зверніть увагу, що в масиві led всього два варіанти значень для digitalWrite: HIGH і LOW, і вони чергуються. Можна обійтись без цього масиву. Як його позбутись - вам в якості самостійного завдання smile

#12 Re: Програмування Arduino » Нужна помощь начинающему!!! 3-х режимный фонарик » 2024-03-19 22:44:37

блін, це ж просто дійсно smile я чомусь собі вбив в голову що case можна використовувати тільки напрклад при опитуванні кнопки, і ось цей код не зрозумів поки що
static unsigned char task=0; // це ми тут оголошуємо змінну ? вірно?
switch (task)
=========================================================

просто зайшов пише:

как-то так...

unsigned long last_time;

void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW); 

}

bool on = false; // поточний стан. з початку - вимкнено;

void loop() {
  unsigned long now = millis();
  static unsigned char task=0;
switch (task)
  {
	  case 0:   
       if (now - last_time >= 2000) { // пройшло 1000 мс ?
          digitalWrite(13, HIGH); // вмикаєм
          last_time = now;
          task=1; // переходим к следующей задаче
        }
       break; 
    case 1:   
       if (now - last_time >= 200) { // пройшло 300 мс ?
          digitalWrite(13, LOW); // вимикаєм
          last_time = now;
          task=2; 
        }
       break; 
    case 2:     
       if (now - last_time >= 500) { // пройшло 1000 мс ?
          digitalWrite(13, HIGH); // вмикаєм
          last_time = now;
          task=3;
        }
       break; 
    case 3: 
        if (now - last_time >= 2000) { // пройшло 300 мс ?
           digitalWrite(13, LOW); // вимикаєм
           last_time = now;
           task=0;
        }
       break; 
    default :
       break; 	
  } 


}

#13 Re: Програмування Arduino » Нужна помощь начинающему!!! 3-х режимный фонарик » 2024-03-19 22:34:33

як правильно написати код для такого мигання LED? можливо треба використати масив?

#15 Re: Програмування Arduino » Нужна помощь начинающему!!! 3-х режимный фонарик » 2024-03-19 21:16:48

dimich, дуже дякую вам за допомогу  smile  ваш код мені вже більш зрозумілий став
захтів трохи поексперементувати з ним але знову в мене граблі якісь, вибачте що так тяжко мені заходить smile
захотів продовжити миготіння led але додавши ще різні значення терміну милис але знову в мене фіаско ))))

unsigned long last_time;

void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW); 

}

bool on = false; // поточний стан. з початку - вимкнено;

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

  if (!on) { // світлодіод вимкнено ?
    if (now - last_time >= 2000) { // пройшло 1000 мс ?
      digitalWrite(13, HIGH); // вмикаєм
      last_time = now;
      on = true; // зберігаєм поточний стан, що увімкнено
    }
  } 

  else if (on) { // світлодіод увімкнено ?
     if (now - last_time >= 200) { // пройшло 300 мс ?
        digitalWrite(13, LOW); // вимикаєм
       last_time = now;
       on = false; // зберігаєм поточний стан, що вимкнено
    }
  } 

  else if (!on) { // світлодіод вимкнено ?
    if (now - last_time >= 500) { // пройшло 1000 мс ?
      digitalWrite(13, HIGH); // вмикаєм
      last_time = now;
      on = true; // зберігаєм поточний стан, що увімкнено
    }
  } 

  else if (on) { // світлодіод увімкнено ?
     if (now - last_time >= 2000) { // пройшло 300 мс ?
        digitalWrite(13, LOW); // вимикаєм
       last_time = now;
       on = false; // зберігаєм поточний стан, що вимкнено
    }
  } 
/*
    else { // світлодіод увімкнено ?
      if (now - last_time >= 200) { // пройшло 300 мс ?
        digitalWrite(13, LOW); // вимикаєм
       last_time = now;
       on = false; // зберігаєм поточний стан, що вимкнено
    }   
  }
*/

}

#16 Re: Програмування Arduino » Нужна помощь начинающему!!! 3-х режимный фонарик » 2024-03-19 00:00:46

і знову я із своїм світлодіодом))
дійсно всі приклади вище для мене поки що мегаскладні нажаль
---
підкинула код гарна людина начебто для мене зрозумілий
АЛЕ
якщо я хочу виставити час світіння наприклад 300 а час несвітіння 1000 то код перестає працювати

unsigned long last_time;

void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
}

void loop() {
 

   if (millis() - last_time >= 300) {
     digitalWrite(13, HIGH);
     last_time = millis();
    }
      
    if (millis() - last_time >= 1000) {
     digitalWrite(13, LOW);
     last_time = millis();
    }
     
} 

підкажіть будь-ласка чому він падлюка не працює? :-)

#17 Re: Програмування Arduino » Нужна помощь начинающему!!! 3-х режимный фонарик » 2024-02-20 02:06:43

Всім дуже дякую за допомогу, обов'язково роздивлюсь усі варіанти та мабудь буду задавати ще питання :-)

#18 Re: Програмування Arduino » Нужна помощь начинающему!!! 3-х режимный фонарик » 2024-02-18 18:12:58

Блин, застрял я с этим millis (), запутался окончательно :-(
Казалось бы вроде, несложный должен быть код сигнала SOS, три точки, три тире, три точки, пауза, повтор предыдущего, короче цикл. Но у меня уже просто опустились руки, пересмотрел кучу роликов и сайтов, везде все описано бегло, как будо-то объясняют не для чайников а себе :-)
Отзовитесь у кого есть терпение объяснить и научить меня неумного мигать светодиодом без delay ()
Задача: научится мигать светодиодом с далеко не одним заданным интервалом. Большинство примеров что я видел с одним заданным параметром, тоесть светит и не светит  одинаковое время.
Я хочу попробовать понять на простом примере
Led светит 1 секунду
Led не светит 0.5 секунды
Повторить две команды 3 раза
Пауза номер 1 длительностью 5 секунд
Led светит 2 секунды
Led не светит 5 секунд
Повторить две команды 2 раза
Пауза номер 2  длительностью 10 секунд
Led светит 0.5 секунды
Led не светит 1.5 секунды
Led светит 1 секунду
Led не светит 2 секунды
Без повтора
---
Можем начать конечно с какого-то простого примера
Готов заплатить за помощь
Мне не нужно само решение, нужно научить меня самому понимать что я делаю :-)
Готов на любую форму обучения, режим связи с демонстрацией экрана по Скайп или текстовое общение, как вам будет удобно
Задавать могу много тупых вопросов :-)
Вроде немного но понимаю и иногда использую html. css а тут совсем присел от беспомощности двигаться дальше
Помогите пожалуйста разобраться
Розумію та спілкуюся також і Українською мовою звісно ж, але  в програмуванні можу тупити бо раніше все ж таки вивчав не по Українськи, так що вибачте якщо когось дратує моя мова!

#19 Re: Програмування Arduino » Нужна помощь начинающему!!! 3-х режимный фонарик » 2024-02-13 22:21:36

г0cть пише:
sxstalker пише:

ви мабудь видадили код з цієї сторінки?

Ні

===
ваша ссылка работает, простите, я лол запутался немного  smile

#20 Re: Програмування Arduino » Нужна помощь начинающему!!! 3-х режимный фонарик » 2024-02-13 22:15:37

г0cть пише:
sxstalker пише:

Здрравствуйте! Вы оставили пустым

void blinkSOS() {

}
я решил добавить туда простое мигание лед имитацию SOS

void blinkSOS() {
analogWrite(ledPin, brightness);
delay(100);
analogWrite(ledPin, brightness /2);
delay(100);
analogWrite(ledPin, brightness /4);
delay(100);
analogWrite(ledPin, 0);
delay(100);
}
но теперь прервать мигание не могу :-)

Гуглите блинк без delay

[code]

uint32_t t; // тут тоже не понимаю
uint32_t period=500; // тут мы присваиваем значение 500?

...


void blinkSOS() {
if(millis()-t>=period) {
t=millis();
digitalWrite(ledPin,!digitalRead(ledPin)); // тут мне совсем непонятно
}
}
[/code]

===
пожалуйста объясните мне эту часть кода если вам не сложно
---
---
можете набросать простой код мигающего светодиода без delay с такой последовательностью мигания
напрмиер:
светодиод горит 1 секунду, далее
светодиод не горит 2 секунды, далее
светодиод горит 0.5 секунды, далее
светодиод не горит 3 секунды
возможно так мне быстрее дойдет как работает мигалка без delay
смотрел на разных сайтах мигалки без delay но увы все с примером но без детального описания каждого оператора
---
может также посоветуете какой-то ресурс где разжовывают все очень подробно для новичков? буду вам очень благодарен

#21 Re: Програмування Arduino » Нужна помощь начинающему!!! 3-х режимный фонарик » 2024-02-11 01:00:41

г0cть пише:

https://wokwi.com/projects/389161053025161217

===
ви мабудь видадили код з цієї сторінки?
я нажаль не можу більше на неї попасти

#22 Re: Програмування Arduino » Нужна помощь начинающему!!! 3-х режимный фонарик » 2024-02-11 00:45:02

sxstalker пише:
dimich пише:

Якщо мета - розібратись як обробляти натискання кнопки і асинхронно блимати світлодіодом, не заморочуючись на оптимізації споживання, то пропоную такий варіант:

constexpr byte PIN_LED = 11;
constexpr byte PIN_BUTTON = 8;

constexpr byte DEBOUNCE_MS = 20;
constexpr byte DIM_BRIGHTNESS = 64;

constexpr unsigned int DIT_MS = 180;
constexpr unsigned int DAH_MS = DIT_MS * 3;
constexpr unsigned int WORD_SEP_MS = DIT_MS * 7;

const unsigned int sos_pattern[] = {
  DIT_MS, DIT_MS, DIT_MS, DIT_MS, DIT_MS, DIT_MS,
  DAH_MS, DIT_MS, DAH_MS, DIT_MS, DAH_MS, DIT_MS,
  DIT_MS, DIT_MS, DIT_MS, DIT_MS, DIT_MS, WORD_SEP_MS
};

void setup()
{
  pinMode(PIN_BUTTON, INPUT_PULLUP);
  pinMode(PIN_LED, OUTPUT);
}

static inline bool buttonPressed()
{
  return digitalRead(PIN_BUTTON) == LOW; // active low
}

static inline void ledOn(bool on)
{
  digitalWrite(PIN_LED, on); // active high
}

void loop()
{
  static struct {
    bool pressed { false };
    bool debounce { false };
    unsigned long last_press { 0 };
  } button;

  static struct state {
    enum mode {
      OFF = 0,
      ON,
      DIM,
      SOS,
      INVALID
    };
    mode active { mode::OFF };
    bool changed { true };
  } state;

  if (button.debounce) {
    if (millis() - button.last_press >= DEBOUNCE_MS) {
      button.debounce = false;
    }
  }

  bool button_state = buttonPressed();

  if ((button_state != button.pressed) && !button.debounce) {
    button.last_press = millis();
    button.debounce = true;
    button.pressed = button_state;

    if (button_state) {
      state.active = static_cast<state::mode>(state.active + 1);
      if (state.active >= state::mode::INVALID) {
        state.active = state::mode::OFF;
      }

      state.changed = true;
    }
  }

  static struct {
    unsigned long last_change;
    unsigned int pause;
    byte idx;
    bool led;
  } sos;

  if (state.changed) {
    switch (state.active) {
      case state::mode::OFF:
        ledOn(false);
        break;
      case state::mode::ON:
        ledOn(true);
        break;
      case state::mode::DIM:
        analogWrite(PIN_LED, DIM_BRIGHTNESS);
        break;
      case state::mode::SOS:
        sos.led = false;
        ledOn(sos.led);
        sos.idx = 0;
        sos.pause = 100;  // pause before start
        sos.last_change = millis();
        break;
      default: break;
    }
    state.changed = false;
  }

  if (state.active == state::mode::SOS) {
    unsigned long now = millis();
    if (now - sos.last_change >= sos.pause) {
      sos.led = !sos.led;
      ledOn(sos.led);
      sos.pause = sos_pattern[sos.idx++];
      if (sos.idx >= sizeof(sos_pattern) / sizeof(*sos_pattern)) {
        sos.idx = 0;
      }
      sos.last_change = now;
    }
  }
}

Тут кнопка active low, тобто пін підтягнутий до живлення внутрішнім pull-up і замикається кнопкою на землю.
Якщо у вас навпаки, пін 8 підтягнутий зовнішнім резистором до землі і замикається на живлення, замініть вміст buttonPressed() на

return digitalRead(PIN_BUTTON) == HIGH;

і в setup() INPUT_PULLUP замініть на INPUT:

  pinMode(PIN_BUTTON, INPUT);

===
Доброго дня! Ваш код на https://wokwi.com/projects/389279504810611713 повністью і бездоганно працює, потім ще спробую на реальній ардуінці, дуже вам дякую, шкода тільки що такий код для мене поки що заскладний, буду намагатися по операторам вивчати що воно таке, якщо буду задавати дурноваті питання не гнівайтеся на мене дуже будь-ласка  smile

===
перевірив. ваш код прекрасно працює !!! дуже дякую. але боюсь для мене заскладний як для новенького smile
може хтось з вас взявся би мене вчити бовдура?
наприклад даючи простеньке завдання
я в свою чергу буду намагатися його виконати на https://wokwi.com/

#23 Re: Програмування Arduino » Нужна помощь начинающему!!! 3-х режимный фонарик » 2024-02-09 21:58:41

dimich пише:

Якщо мета - розібратись як обробляти натискання кнопки і асинхронно блимати світлодіодом, не заморочуючись на оптимізації споживання, то пропоную такий варіант:

constexpr byte PIN_LED = 11;
constexpr byte PIN_BUTTON = 8;

constexpr byte DEBOUNCE_MS = 20;
constexpr byte DIM_BRIGHTNESS = 64;

constexpr unsigned int DIT_MS = 180;
constexpr unsigned int DAH_MS = DIT_MS * 3;
constexpr unsigned int WORD_SEP_MS = DIT_MS * 7;

const unsigned int sos_pattern[] = {
  DIT_MS, DIT_MS, DIT_MS, DIT_MS, DIT_MS, DIT_MS,
  DAH_MS, DIT_MS, DAH_MS, DIT_MS, DAH_MS, DIT_MS,
  DIT_MS, DIT_MS, DIT_MS, DIT_MS, DIT_MS, WORD_SEP_MS
};

void setup()
{
  pinMode(PIN_BUTTON, INPUT_PULLUP);
  pinMode(PIN_LED, OUTPUT);
}

static inline bool buttonPressed()
{
  return digitalRead(PIN_BUTTON) == LOW; // active low
}

static inline void ledOn(bool on)
{
  digitalWrite(PIN_LED, on); // active high
}

void loop()
{
  static struct {
    bool pressed { false };
    bool debounce { false };
    unsigned long last_press { 0 };
  } button;

  static struct state {
    enum mode {
      OFF = 0,
      ON,
      DIM,
      SOS,
      INVALID
    };
    mode active { mode::OFF };
    bool changed { true };
  } state;

  if (button.debounce) {
    if (millis() - button.last_press >= DEBOUNCE_MS) {
      button.debounce = false;
    }
  }

  bool button_state = buttonPressed();

  if ((button_state != button.pressed) && !button.debounce) {
    button.last_press = millis();
    button.debounce = true;
    button.pressed = button_state;

    if (button_state) {
      state.active = static_cast<state::mode>(state.active + 1);
      if (state.active >= state::mode::INVALID) {
        state.active = state::mode::OFF;
      }

      state.changed = true;
    }
  }

  static struct {
    unsigned long last_change;
    unsigned int pause;
    byte idx;
    bool led;
  } sos;

  if (state.changed) {
    switch (state.active) {
      case state::mode::OFF:
        ledOn(false);
        break;
      case state::mode::ON:
        ledOn(true);
        break;
      case state::mode::DIM:
        analogWrite(PIN_LED, DIM_BRIGHTNESS);
        break;
      case state::mode::SOS:
        sos.led = false;
        ledOn(sos.led);
        sos.idx = 0;
        sos.pause = 100;  // pause before start
        sos.last_change = millis();
        break;
      default: break;
    }
    state.changed = false;
  }

  if (state.active == state::mode::SOS) {
    unsigned long now = millis();
    if (now - sos.last_change >= sos.pause) {
      sos.led = !sos.led;
      ledOn(sos.led);
      sos.pause = sos_pattern[sos.idx++];
      if (sos.idx >= sizeof(sos_pattern) / sizeof(*sos_pattern)) {
        sos.idx = 0;
      }
      sos.last_change = now;
    }
  }
}

Тут кнопка active low, тобто пін підтягнутий до живлення внутрішнім pull-up і замикається кнопкою на землю.
Якщо у вас навпаки, пін 8 підтягнутий зовнішнім резистором до землі і замикається на живлення, замініть вміст buttonPressed() на

return digitalRead(PIN_BUTTON) == HIGH;

і в setup() INPUT_PULLUP замініть на INPUT:

  pinMode(PIN_BUTTON, INPUT);

===
Доброго дня! Ваш код на https://wokwi.com/projects/389279504810611713 повністью і бездоганно працює, потім ще спробую на реальній ардуінці, дуже вам дякую, шкода тільки що такий код для мене поки що заскладний, буду намагатися по операторам вивчати що воно таке, якщо буду задавати дурноваті питання не гнівайтеся на мене дуже будь-ласка  smile

#24 Re: Програмування Arduino » Нужна помощь начинающему!!! 3-х режимный фонарик » 2024-02-09 21:49:44

г0cть пише:

https://wokwi.com/projects/389161053025161217

===
Здрравствуйте! Вы оставили пустым

void blinkSOS() {

}
я решил добавить туда простое мигание лед имитацию SOS

void blinkSOS() {
analogWrite(ledPin, brightness);
delay(100);
analogWrite(ledPin, brightness /2);
delay(100);
analogWrite(ledPin, brightness /4);
delay(100);
analogWrite(ledPin, 0);
delay(100);
}
но теперь прервать мигание не могу :-) верне могу но только удержанием кнопки а хотелось бы обычным нажатием)
а вообще ваш код очень интересный и я его обязательно попробую разобрать на винтики  smile

#25 Re: Програмування Arduino » Нужна помощь начинающему!!! 3-х режимный фонарик » 2024-02-09 18:26:04

dimich пише:
sxstalker пише:

1. нажимать кнопку нужно специфически немного удерживая чтобы все работало правильно. это ужасно бесит((

У вашій програмі затримки по 150 мс і більше. В цей час процесор не опитує стан кнопки. Для придушення брязкоту контактів у більшості випадків достатньо кількох міллісекунд. А щоб не реагувати на утримання кнопки як на натиснення, потрібно перевіряти зміну стану кнопки з LOW в HIGH.

Для виміру проміжків часу асинхронно бібліотека ардуіно надає функцію millis(). Але нею теж потрібно правильно користуватись, щоб уникнути багів з переповненням.

sxstalker пише:
          analogWrite(ledPin, brightness); // а от тут зовсім не зрозумів чому analog, ну і встановлюэмо яскравість лед на 255

Яскравість регулюється широтно-імпульсною модуляцією. analogWrite() реалізує програмну ШІМ.

sxstalker пише:
  // for (int i = 0; i <= 99999999; i++) { 

Розмір int в AVR gcc - 16 біт, максимальне значення - 32767.

sxstalker пише:
    if (digitalRead(buttonPin) == HIGH) {
      goto bailout;

Для дострокового виходу з циклу достатньо break.

sxstalker пише:

Помогите пожалуйста доработать код правильно. Это мне поможет двигаться далее.

Спочатку реалізуйте просте увімкнення/вимкнення світлодіода по натисненню, щоб воно працювало стабільно. Потім уже додавайте режими, яскравість і т.д.

У вас два логічних потоки: обробка натиснення кнопки і виміри проміжків часу, тому це простіше реалізувати за допомогою скінченного автомата. Ваш switch(mode) / case по суті ним і є, тільки прибрати довгі delay(), а час вимірювати за допомогою millis().

І деякі загальні міркування.
Atmega328 сама по собі в активному режимі на частоті 16 МГц при живленні 5 В споживає близько 10 мА. У вашій програмі процесор постійно активний. У вимкненому стані при ємності джерела живлення в 2500 мА*год воно розрядиться за час порядка 250 годин.

Для мінімізації споживання у вимкненому стані процессор має бути в режимі PowerDown, а натиснення кнопки викликатиме зовнішне переривання. В увімкненому стані потрібно використовувати апаратну ШІМ, а процесор переводити в Idle. Також відключити всю непотрібну периферію, таку як ADC, а тактову частоту знизити. 16 МГц для обробки натиснення кнопки - це перебор.

Також цікаво, як ви збираєтесь реалізувати апаратну частину, особливо в плані живлення. Два Li-Ion аккумулятора? На платі ардуіно лінійний стабілізатор, при живленні 7.5 вольт ККД буде лише 66%. Якщо світлодіод яскравий, його потрібно живити напряму, і бажано через драйвер, щоб напруга живлення не впливала на яскравість.

===
дуже дякую за вашу відповідь, поки що задача в мене розібратися з програмною частиною, робити фонарик самостійно на ардуіно якось зовсім не хочеться, тоді як їх повно недорогих ) хочеться на прикладі розібратися з кодом і  нарешті почати рухатися в плані створення моїх задумок, звичайні блималки на лед та просто вкл/викл я вже робив і вони всі працюють прекрасно а от тут стикнувся з халепою як для новачка )))

Підвал форуму