#1 2025-02-09 13:36:49

vigor53
Учасник
Зареєстрований: 2015-11-15
Повідомлень: 7

Прблема в скетче ?

Ребята сделал генератор для дома ( нужен для экспериментов) - на Ардуино НАНО Скетч компилируется нормально , залил в Арду , все хорошо - только энкодер не работает Кнопка срабатывает а энкодер нет .
Проверил сам энкодер - работает.Мне думается что в скетче не прописана сама работа этой штуки.Но в программировании я не спец,только начинаю.
Может кто подсказать в чем проблема ? Причем иногда что то меняется ( показания)Думаю что проблема в строчке :Rotary r = Rotary(2,3); // sets the pins the rotary encoder uses. Must be interrupt pins.
sketch_test2.zipGenerato.zip- Нашел еще код для того же генератора - но так же не работает энкодер (через раз)

Неактивний

#2 2025-02-09 14:49:42

jokeer
Гість

Re: Прблема в скетче ?

Для початку відтворіть демку з енкодером. Разом з резисторами в конденсаторами

#3 2025-02-09 15:09:15

vigor53
Учасник
Зареєстрований: 2015-11-15
Повідомлень: 7

Re: Прблема в скетче ?

Что именно надо сделать? Физически собрать схему - так я пробовал , энкодер работает ( осциллограф показывает импульсы со смещением). А вот по поводу демки - я уже сказал что только начинаю осваивать Ардуино.

Неактивний

#4 2025-02-09 16:10:14

jokeer
Гість

Re: Прблема в скетче ?

Як правило разом з лібою для енкодера є демо-програма. Очікується що вона працює.

#5 2025-02-09 16:44:03

vigor53
Учасник
Зареєстрований: 2015-11-15
Повідомлень: 7

Re: Прблема в скетче ?

Положим что энкодер - нормально. Что по поводу самого скетча? В двух вариантах программного кода  - по разному прописано работа энкодера , и в обоих случаях нет четкого срабатывания . Вопрос именно - в чем причина ?

Неактивний

#6 2025-02-09 17:40:38

jokeer
Гість

Re: Прблема в скетче ?

конденсатори напаяли, як в букварі намальовано?

#7 2025-02-09 18:41:56

vigor53
Учасник
Зареєстрований: 2015-11-15
Повідомлень: 7

Re: Прблема в скетче ?

Все что было необходимо я напаял ! Вопрос остается - правильно ли прописана работа энкодера в скетче ??
Вы вообще то скетч смотрели ?

Остання редакція vigor53 (2025-02-09 18:43:55)

Неактивний

#8 2025-02-09 19:30:47

г0cть
Гість

Re: Прблема в скетче ?

vigor53 пише:

Вы вообще то скетч смотрели ?

А вы сделали что вас спрашивали?

jokeer пише:

Як правило разом з лібою для енкодера є демо-програма. Очікується що вона працює.

В папке с библиотекой есть пример Interrupt.ino. Вы его загружали?

#9 2025-02-09 20:13:35

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

Re: Прблема в скетче ?

vigor53 пише:

Думаю что проблема в строчке :Rotary r = Rotary(2,3); // sets the pins the rotary encoder uses. Must be interrupt pins.

У вас енкодер підключений до пінів D2 та D3? Зовнішні підтяжки на них є? Якщо немає, макрос ENABLE_PULLUPS був визначений на момент компіляції бібліотеки? У вас бібліотека в архіві в трьох екземплярах. Який із двох Rotary.h інклудився при компіляції Rotary.cpp, той що Rotary/Rotary.h чи Rotary-1.0.0/src/Rotary.h ?

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

Якщо компілюєте в IDE, увімкніть "Show verbose output: compile" і показуйте вивод. Окрім вас ніхто не може знати, що там у вас як компілюється. Крім того, arduino IDE кешує артефакти компіляції.

Створіть окремий скетч, в якому просто читайте енкодер і пишіть в послідовний порт, що повертає Rotary::process(). Для початку без усяких переривань.

Доречі, у вас операції зі змінними, які апдейтяться в обробнику переривань, неатомарні. Це помилка. Навіть якщо енкодер працюватиме правильно, результат буде непередбачуваним. Якщо, як самі кажете, тільки починаєте, то не звʼязуйтесь із перериваннями. В Rotary є приклад циклічного опитування (polling). Впевніться в стабільній роботі цього приклада, потім інтегруйте його у свій скетч.

Неактивний

#10 2025-02-09 20:14:43

jokeer
Гість

Re: Прблема в скетче ?

якщо немає четкого срабатывания - скоріше за все брязкіт контактів. Звичайно його душать rc фільтром. Тому і спитав. А щодо коду - ви ж його з прикладу скопіювали, правда? приклад робочий.

#11 2025-02-09 21:11:39

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

Re: Прблема в скетче ?

Доречі, перевірте сам енкодер. Мені зустрічались екземпляри, у яких загальний вивод (GND) не посередині як на цьому фото, а збоку. Тобто послідовно йдуть: GND, OutA, OutB. Якщо продзвонювати кожний пін окремо, то при обертанні виглядає наче все ок. Але в схемі, де їх стани читаються одночасно, звісно що зчитується фігня. Колись витратив мабуть із годину, поки не виявив таку невідповідність розпіновки.

Неактивний

#12 2025-02-09 21:26:24

vigor53
Учасник
Зареєстрований: 2015-11-15
Повідомлень: 7

Re: Прблема в скетче ?

ОК - буду пробовать. Столько всего непонятного написали smile На дребег проверял - ставил емкости.К плюсу тоже подтягивал . Счас переставлю контакты ....

Остання редакція vigor53 (2025-02-09 21:29:39)

Неактивний

#13 2025-02-09 21:43:22

vigor53
Учасник
Зареєстрований: 2015-11-15
Повідомлень: 7

Re: Прблема в скетче ?

Блин - я хренею без баяна!!! Переставил концы на кодере и все пошло .... Таки да! Центральный с края
Спасибо Всем ОГРОМНОЕ !!!!!!

Неактивний

#14 2025-02-09 22:52:08

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

Re: Прблема в скетче ?

Але помилки при роботі з глобальними змінними раджу все-таки виправити. Переривання може виникнути (і виникне) посередині читання глобальної змінної, і змінить її значення. Прочитане значення буде некоректним. Це призведе до неправильної роботи, а за законом Мерфі це станеться в самий критичний момент  hmm Крім того, компілятор взагалі може заоптимізувати звернення до них, вважаючи, що їх значення ніколи не змінюються. Тому потрібні atomic-блоки та volatile.
Краще винести всю ту логіку із ISR в основний цикл, а в ISR тільки репортувати події від енкодера у змінну з атомарним доступом (на AVR8 це 8-бітні типи). А у вашому випадку краще взагалі обійтись без переривань.

Неактивний

#15 2025-02-09 23:13:22

jokeR
Учасник
Зареєстрований: 2024-12-12
Повідомлень: 31

Re: Прблема в скетче ?

ISR(PCINT2_vect) {
  unsigned char result = r.process();

Так робити стрьомно. ISR повинно виконуватись максимально швидко, а тут викликається якийсь метод з ліби енкодера, хз що він робитиме. Якщо всередині Serial.print, буде ой.
Як правило, регулярні дії (process(), tick(), ..) викликають в loop - там воно точно спрацює як треба.
Якщо в ISR ви щось робите з глобальною змінною, яка більша ніж uint8_t - на цей час треба забороняти переривання.  Приблизно так:

ISR()
..
cli();
do_some_sheet
sei();
loop()
..
cli();
do_some_sheet
sei();

Неактивний

#16 2025-02-09 23:37:12

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

Re: Прблема в скетче ?

jokeR пише:

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

Rotary::process() лише читає стани пінів та перемикає стан внутрішнього конечного автомата. Викликати той Rotary::process() в ISR - норм. Хоча в програмі топікстартера взагалі немає особливого сенсу використовувати переривання.

jokeR пише:

Якщо всередині Serial.print, буде ой.

Якщо не змішувати з викликами до Serial поза контекстом цього ISR, то буде працювати. HardwareSerial::write() не робить нічого такого, чого не можна робити в ISR.

jokeR пише:

Приблизно так:

ISR()
..
cli();
do_some_sheet
sei();

Не робіть так. ISR() викликається з уже вимкненими перериваннями. sei() їх увімкне і дозволить переривати цей обробник.

Остання редакція dimich (2025-02-09 23:40:54)

Неактивний

#17 2025-02-10 00:00:48

vigor53
Учасник
Зареєстрований: 2015-11-15
Повідомлень: 7

Re: Прблема в скетче ?

Честно? Ничего не понял... Я ведь только учусь smile Но все равно спасибо!

Неактивний

#18 2025-02-10 11:14:06

jokeR
Учасник
Зареєстрований: 2024-12-12
Повідомлень: 31

Re: Прблема в скетче ?

Заміть 1000 слів - дивіться як зроблено в Arduino

НЯП всередині ISR присідання з атомарністю не потрібні, бо переривання забороняється автоматично.

#if defined(TIM0_OVF_vect)
ISR(TIM0_OVF_vect)
#else
ISR(TIMER0_OVF_vect)
#endif
{
	// copy these to local variables so they can be stored in registers
	// (volatile variables must be read from memory on every access)
	unsigned long m = timer0_millis;
	unsigned char f = timer0_fract;

	m += MILLIS_INC;
	f += FRACT_INC;
	if (f >= FRACT_MAX) {
		f -= FRACT_MAX;
		m += 1;
	}

	timer0_fract = f;
	timer0_millis = m;
	timer0_overflow_count++;
}

А ззовні - читайте коментар до коду

unsigned long millis()
{
  unsigned long m;
  uint8_t oldSREG = SREG;

  // disable interrupts while we read millis_timer_millis or we might get an
  // inconsistent value (e.g. in the middle of a write to millis_timer_millis)
  cli();
  m = millis_timer_millis;
  SREG = oldSREG;

  return m;
}

Неактивний

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

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

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