#51 2024-03-20 00:59:23

просто зайшов
Гість

Re: Нужна помощь начинающему!!! 3-х режимный фонарик

sxstalker пише:

може мені краще дійде на цьому малюнку?
https://forum.arduino.ua/img/members/3773/nesinkhronnoe-migaenie-svetodiodom-v-Arduino_20240319-2122.png

без millis() по системному тику 1 мс.

volatile unsigned char flag_1ms =0; // флаг : пройшла 1 мілісекунда

ISR(TIMER0_COMPA_vect) { // прерівание по совпадению таймера0 период 1мс.
  flag_1ms =1;
}

void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW); 
 // Timer/Counter 0 Interrupt(s) initialization
  bitSet(TIMSK0, OCIE0A); // вмикаєм прерівание по совпадению таймера0
}



void loop() {
  static unsigned int  count_timer=0; // лічильник мілісекунд
  static unsigned char task=0;
if( flag_1ms){
  flag_1ms =0; 
    switch (task)
      {
	    case 0:  
	       digitalWrite(13, HIGH); // вмикаєм 
           if (count_timer==300) { // пройшло 300 мс ?
		      count_timer=0;
			  task=1;
		   }else{count_timer++;}
           break; 
        case 1: 
           digitalWrite(13, LOW); // вимикаєм       
           if (count_timer==370) { // пройшло 370 мс ?
		      count_timer=0;
			  task=2;
		   }else{count_timer++;}
           break; 
        case 2:    
           digitalWrite(13, HIGH); // вмикаєм	
           if (count_timer==180) { // пройшло 180 мс ?
		      count_timer=0;
			  task=3;
		   }else{count_timer++;}
           break; 
        case 3: 
           digitalWrite(13, LOW); // вимикаєм	
           if (count_timer==410) { // пройшло 410 мс ?
		      count_timer=0;
			  task=4;
		   }else{count_timer++;}
           break; 
        case 4:  
           digitalWrite(13, HIGH); // вмикаєм	
           if (count_timer==110) { // пройшло 110 мс ?
		      count_timer=0;
			  task=5;
		   }else{count_timer++;}
           break; 
        case 5:
           digitalWrite(13, LOW); // вимикаєм	
           if (count_timer==190) { // пройшло 190 мс ?
		      count_timer=0;
			  task=6;
		   }else{count_timer++;}
           break; 
        case 6:
           digitalWrite(13, HIGH); // вимикаєм	
           if (count_timer==650) { // пройшло 650 мс ?
		      count_timer=0;
			  task=7;
		   }else{count_timer++;}
           break; 	
        case 7:
           digitalWrite(13, LOW); // вимикаєм	
           if (count_timer==3000) { // пройшло 3000 мс ?
		      count_timer=0;
			  task=0;
		   }else{count_timer++;}
           break; 		   
    default :
	       task=0;
          break; 	
    } 
}

}

#52 2024-03-20 01:06:57

просто зайшов
Гість

Re: Нужна помощь начинающему!!! 3-х режимный фонарик

sxstalker пише:

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

исправил

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;
       task=1;
       }
       break; 
    case 1: 
          digitalWrite(13, LOW); // вимикаєм       
       if (now - last_time >= 200) { // пройшло 300 мс ?
          last_time = now;
          task=2;
          }
       break; 
    case 2:   
          digitalWrite(13, HIGH); // вмикаєм	
       if (now - last_time >= 500) { // пройшло 1000 мс ?
          last_time = now;
          task=3;
        }
       break; 
    case 3: 
           digitalWrite(13, LOW); // вимикаєм	
        if (now - last_time >= 2000) { // пройшло 300 мс ?
           last_time = now;
           task=0;
        }
       break; 
    default :
          task=0;
       break; 	
  } 


}

#53 2024-03-20 03:48:42

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 130

Re: Нужна помощь начинающему!!! 3-х режимный фонарик

sxstalker пише:

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

Так ви позаміняли там затримки і додали ще один стан. То вже не мій код.

sxstalker пише:
case 0:
   if (now - last_time >= 10) { // LED має світити 2000 мс? вірно?
        digitalWrite(13, HIGH);

Після старту LED не світить 10 мс, потім вмикається. Навряд чи ви помітите цю затримку в 10 мс після старту.

sxstalker пише:
case 1:
   if (now - last_time >= 4000) { // LED має не світити 200 мс? вірно?
        digitalWrite(13, LOW);

Продовжує світитись 4 секунди. Вимикається.

sxstalker пише:
case 2:
  if (now - last_time >= 1000) { // LED має світити 500 мс? вірно?
    digitalWrite(13, HIGH);

Через 1 секунду вмикається

sxstalker пише:
    case 3:
      if (now - last_time >= 2000) { // LED має не світити 2000 мс? вірно?
        digitalWrite(13, LOW);
        last_time = now;
        state = 4; // переходим в початковий стан "0"
      }
      break;

І через 2 секунди вимикається.

sxstalker пише:
      case 4:
      if (now - last_time >= 2000) { // LED має не світити 2000 мс? вірно?
        digitalWrite(13, LOW);
        last_time = now;
        state = 0; // переходим в початковий стан "0"
      }

Продовжує бути вимкненим ще 2 секунди.

В станах 0 і 4 світлодіод вимкнено, вони зливаються в один період 2 с 10 мс, коли світлодіод не світить. Паттерн виходить такий:
4 с світить, 1 с не світить, 2 с світить, 2.01 с не світить.

sxstalker пише:

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

dur[state] вказує, скільки триває стан state.
led[state] вказує, яке значення має подаватись на пін світлодіода при переході в наступний, в state+1 стан.

Ви замінили початкове значення світлодіода на HIGH, і при переході зі стану "0" в "1" також виставляєься HIGH. В самій першій ітерації в станах "0" і "1" світлодіод HIGH, вони зливаються. Далі працює як там і написано: короткий блим в 200 мс, пауза 1.5 с, довгий блим 2 с, пауза 3 с і т.д..

Активний

#54 2024-03-20 04:53:15

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 130

Re: Нужна помощь начинающему!!! 3-х режимный фонарик

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

вообще millis(); очень неудобная функция для 8ми битных микроконтроллеров ,  мало того что не точная, так еще и занимает кучу времени на обработку 32-х битной математики.

Так вся ця ардуіна - навчальний проект для початківців. Яка там ефективність чи оптимізація...
Що може бути простіше "кількість мілісекунд від початку роботи"? Цікавості починаються через 24 або 49 діб, при знаковому або беззнаковому переповненні лічильника, якщо код кривий smile

Щодо точності - у них є компенсація лічильника, яка ціла для 8 і 16 МГц, тобто довгострокова точність відповідає кварцу. Але джиттер.

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

Что мешало разрабам добавить для пользователей глобальный флаг в обработчик прерывания по таймеру0 не понятно...
Хотя это решается включением прерывания по совпадению TIMER0_COMPA_vect .

На AVRках замість флага можна читати молодший байт timer0_overflow_count, якщо трошки похуліганити:

extern volatile unsigned long timer0_overflow_count;
static inline uint8_t overflows() {
  return *reinterpret_cast<volatile uint8_t *>(&timer0_overflow_count);
}

Ну а там, де потрібна оптимізація за швидкодією або розміром, то бібліотеці ардуіно взагалі не місце.

Остання редакція dimich (2024-03-20 05:01:16)

Активний

#55 2024-03-20 09:30:10

Васятко
Гість

Re: Нужна помощь начинающему!!! 3-х режимный фонарик

dimich пише:

Цікавості починаються через 24 або 49 діб, при знаковому або беззнаковому переповненні лічильника,

Ще один адепт секти Свідків Переповнення Великого Міліс?

#56 2024-03-20 10:07:51

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 130

Re: Нужна помощь начинающему!!! 3-х режимный фонарик

Васятко пише:
dimich пише:

Цікавості починаються через 24 або 49 діб, при знаковому або беззнаковому переповненні лічильника,

Ще один адепт секти Свідків Переповнення Великого Міліс?

"якщо код кривий" пропустили? Звісно, при нормально написаному коді переповнення ні до яких збоїв не призводить.

Активний

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

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