Диммер ???
- Войдите на сайт для отправки комментариев
Вс, 18/08/2019 - 18:18
Привожу часть программы
#define f_base 13000
unsigned int du = 0, du_OCR = f_base;
void setup() {
// ====================================================================
Serial.begin(57600);
// ====================================================================
DDRD = B00011000;
PORTD = B00100000;
DDRB = B000010;
PORTB = B000000;
// TCCR1A = (1<<COM1A1)|(1<<COM1A0)|(1<<WGM11);
// TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS10); // mode 14 1110 = Fast Pwm to ICR1
// TCCR1A = 0xC2; TCCR1B = 0x19;
cli (); TCCR1A = 0; TCCR1B = 0; ICR1 = f_base; sei ();
}
void loop() {
if ((PIND&(1<<PIND5))==0) { soft_start(); }
}
void soft_start() { cli(); TCCR1A = 0xC2; TCCR1B = 0x19; sei();
label:
OCR1A = du_OCR; du_OCR = du_OCR-130; delay (25);
Serial.print(du_OCR,1);Serial.println(" stp ");
if (du_OCR > 100 && (PIND&(1<<PIND5))==0){ goto label;}
cli (); TCCR1A = 0; TCCR1B = 0; ICR1 = f_base; sei ();
du_OCR = f_base;
}
проблема в том, что после подаче питания на ардуину и нажатии кнопки (пин 5) ШИМ не работает
хотя в монитор идут
данные !?!?!
если несколько раз нажать "ресет" перед нажатием кнопки, тогда появляется сигнал на пин 9 ...
вопрос - где я косячу ???
да практически везде. Весь код - какое-то недоразумение.
Зачем в процедуре из пяти строк делать переход по метке? - нормально не можете написать?
По поводу "не работает" - вы нажимаете кнопку, таймер запускается. пулей пролетает Вашу процедуру soft_start и в строке 28 выключается. Оно будет работать только если держать кнопку или нажимать ее часто...
да практически везде. Весь код - какое-то недоразумение.
Зачем в процедуре из пяти строк делать переход по метке? - нормально не можете написать?
По поводу "не работает" - вы нажимаете кнопку, таймер запускается. пулей пролетает Вашу процедуру soft_start и в строке 28 выключается. Оно будет работать только если держать кнопку или нажимать ее часто...
Про переход по метке сделаю другой пост, т.к. есть смысл такого решения...
Естественно я имел ввиду УДЕРЖАНИЕ нажатой кнопки !!! Проблем в том, что цикл работает, в "сериал" идет информация с изменяющимися значениями, а вот таймер не запускается !!! Нужно после подачи питания на плату несколько раз нажать ресет, вот после такой процедуры при удержании нажатой кнопки появляется ШИМ сигнал на 9 ножке ....
Про переход по метке сделаю другой пост, т.к. есть смысл такого решения...
Даже интересно стало :)
Естественно я имел ввиду УДЕРЖАНИЕ нажатой кнопки !!!
Сделайте запуск таймера при нажатии и остановку при отпускании, не надо постоянно все там передергивать. Ну хотя... может и как то так можно. А зачем это условие du_OCR > 100 ? Проверьте тогда что при нажатой кнопке оно из цикла по label не вываливается, а если вываливается - объясните зачем.
Про переход по метке сделаю другой пост, т.к. есть смысл такого решения...
Даже интересно стало :)
Дико присоединяюсь.
Может религия такая или..
Адвентисты гоу ту?
зачем это условие du_OCR > 100 ?
О. это я пропустил :) Сделать декремент цикла 130, а контроль окончания - du_OCR > 100 - это прям самому себе поставленный капкан...
Реношник, а может вы четче напишите, что вы такое пытаетесь родить? вроде как ШИм в одну строчку делается...
Когда писал на бейсике и asm тоже недоумевал как так без goto и зачем собственно так мучиться ? )
Естественно я имел ввиду УДЕРЖАНИЕ нажатой кнопки !!!
Сделайте запуск таймера при нажатии и остановку при отпускании, не надо постоянно все там передергивать. Ну хотя... может и как то так можно. А зачем это условие du_OCR > 100 ? Проверьте тогда что при нажатой кнопке оно из цикла по label не вываливается, а если вываливается - объясните зачем.
А зачем это условие du_OCR > 100 ? = в цикле идет плавное заполнение ШИМ ....
Сделайте запуск таймера при нажатии и остановку при отпускании, не надо постоянно все там передергивать. Ну хотя... = вроди бы так и сделано, поканажата кнопка в цикле идет плавное заполненение ШИМ.
Проверьте тогда что при нажатой кнопке оно из цикла по label не вываливается = НЕ вываливается оно никуда... при нажатой кнопке цикл РАБОТАЕТ - в "сериал" идут изменяющиеся значения !!! а вот ШИМ сигнал ОТСУТСТВУЕТ...
Если после подачи питания на плату ардуины несколько раз нажать ресет, то тогда цикл начинает работать как записано в программе - и в сериал идет информация и есть изменяющийся ШИМ !!!!
Реношник, то есть вы настаиваете, что этот кривой код трогать не нужно, все работает верно, проблема только в РЕСЕТ?
нуну
Реношник, то есть вы настаиваете, что этот кривой код трогать не нужно, все работает верно, проблема только в РЕСЕТ?
нуну
я НЕ натаиваю, я просил подсказать где я натупил, почему без ресета не запускается шим ...
Вы осциллографом смотрели ? Потому как у меня запускается - при замыкании 5й ноги на землю появляется ШИМ на 9й ноге, сначала узкий импульс 0->1, потом он расширяется в течении ~2.5 сек и снова сбрасывается на узкий, повторяя цикл (частота ~1.225 кГц), если 5ю ногу отпустить - ШИМ отключается и запускается снова с 5й ноги безо всяких reset'ов. Так задумывалось ? Плата UNO обычная китайская с 328p мегой.
Вы осциллографом смотрели ? Потому как у меня запускается - при замыкании 5й ноги на землю появляется ШИМ на 9й ноге, сначала узкий импульс 0->1, потом он расширяется в течении ~2.5 сек и снова сбрасывается на узкий, повторяя цикл (частота ~1.225 кГц), если 5ю ногу отпустить - ШИМ отключается и запускается снова с 5й ноги безо всяких reset'ов. Так задумывалось ? Плата UNO обычная китайская с 328p мегой.
== да, смотрю осциллографом.
== алгоритм работы именно такой.
получается у меня проблемма с "железом" ... хотя пробовал на двух ПроМини (от одного продавца) ...
какая то странная проблема, но получается так, попробую на nano вечером на всякий случай
какая то странная проблема, но получается так, попробую на nano вечером на всякий случай
В том-то и загвоздка...
Хотя если верить этому ->
нуну
может мои проблеммы из-за кривизны кода. остается понять в чем тут кривизна ... буду копать дальше ...
вопрос - где я косячу ???
Допустим нажата и удерживается кнопка, тогда раскроем скобки, циклы и переходы:
void loop() { cli(); TCCR1A = 0xC2; TCCR1B = 0x19; sei(); do { OCR1A = du_OCR; du_OCR = du_OCR-130; delay (25); Serial.print(du_OCR,1); Serial.println(" stp "); } while (du_OCR > 100); cli (); TCCR1A = 0; TCCR1B = 0; ICR1 = f_base; sei (); du_OCR = f_base; }на первый взгляд ничего важного нет, что может помешать работать. Стоит только грамотно написать атомарные операции (с сохранением SREG):
void loop() { uint8_t sreg: sreg = SREG; cli(); TCCR1A = 0xC2; TCCR1B = 0x19; SREG = sreg; do { OCR1A = du_OCR; du_OCR = du_OCR-130; delay (25); Serial.print(du_OCR,1); Serial.println(" stp "); } while (du_OCR > 100); sreg = SREG; cli (); TCCR1A = 0; TCCR1B = 0; ICR1 = f_base; SREG = sreg; du_OCR = f_base; }ну и OCR1A - 16-ти битный. Его бы тоже записывать атомарно.
Больше, пока, ничего не заметил.
Я поправил кривизну немного, убрал голимые понты использования регистров там, где это не нужно. Убрал смешной goto.
Использована обычная нанка.
#define f_base 13000 unsigned int du = 0, du_OCR = f_base; void setup() { uint8_t sreg; Serial.begin(57600); pinMode (3, OUTPUT); pinMode (4, OUTPUT); pinMode (5, INPUT_PULLUP); pinMode (9, OUTPUT); digitalWrite (9, LOW); // TCCR1A = (1<<COM1A1)|(1<<COM1A0)|(1<<WGM11); // TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS10); // mode 14 1110 = Fast Pwm to ICR1 // TCCR1A = 0xC2; TCCR1B = 0x19; sreg = SREG; cli (); TCCR1A = 0; TCCR1B = 0; ICR1 = f_base; SREG = sreg; } void loop() { uint8_t sreg; if (!digitalRead(5)) { TCCR1A = 0xC2; TCCR1B = 0x19; do { sreg = SREG; cli(); OCR1A = du_OCR; SREG = sreg; du_OCR = du_OCR - 130; delay (25); Serial.print(du_OCR, 1); Serial.println(" stp "); } while (du_OCR > 100); TCCR1A = 0; TCCR1B = 0; du_OCR = f_base; } }Запускается по включению питания и никаких сбоев.
Убрал смешной goto.
Он не смешной! ТС сказал, что
есть смысл такого решения...
И обещал объяснить его (смысл). Я вот всё жду.
Убрал смешной goto.
Он не смешной! ТС сказал, что
есть смысл такого решения...
И обещал объяснить его (смысл). Я вот всё жду.
Ок. раз обещал тогда объясняю....
Признаю. что поспешил с выводом т.к. при отладке из-за опипаста создалось ошибочное впечатление, что
do { OCR1A = du_OCR; du_OCR = du_OCR-130; delay (25); } while (du_OCR > 100 && (PIND&(1<<PIND5))==0);работает не корректно. Когда прописал переход по метке, баг пропал.
Потом почистил код избегая копипастов и do { } while ( ); заняло свое место....
но с другой стороны переход по метке. для меня это ностальгия по студенчекому прошлому времен фортрана ... :-)
Я тоже с децтва фортранец, но про гото забыл как страшный сон Дейкстры
Я поправил кривизну немного, убрал голимые понты использования регистров там, где это не нужно. Убрал смешной goto.
Использована обычная нанка.
#define f_base 13000 unsigned int du = 0, du_OCR = f_base; void setup() { uint8_t sreg; Serial.begin(57600); pinMode (3, OUTPUT); pinMode (4, OUTPUT); pinMode (5, INPUT_PULLUP); pinMode (9, OUTPUT); digitalWrite (9, LOW); // TCCR1A = (1<<COM1A1)|(1<<COM1A0)|(1<<WGM11); // TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS10); // mode 14 1110 = Fast Pwm to ICR1 // TCCR1A = 0xC2; TCCR1B = 0x19; sreg = SREG; cli (); TCCR1A = 0; TCCR1B = 0; ICR1 = f_base; SREG = sreg; } void loop() { uint8_t sreg; if (!digitalRead(5)) { TCCR1A = 0xC2; TCCR1B = 0x19; do { sreg = SREG; cli(); OCR1A = du_OCR; SREG = sreg; du_OCR = du_OCR - 130; delay (25); Serial.print(du_OCR, 1); Serial.println(" stp "); } while (du_OCR > 100); TCCR1A = 0; TCCR1B = 0; du_OCR = f_base; } }Запускается по включению питания и никаких сбоев.
Видимо действительно у меня проблеммы с "железом"...
если закомментировать строки 28 и 46 то после загрузки программы осциллограф показывает нужную картинку... НО ... через какоето время (до одной минуты) частота увеличивается...
если загружаю программу как есть то на кнопку она НЕ реагирует... решается проблемма ресетом при зажатой кнопке... после этого появляется неакция на кнопку НО... после нескольких нажатий (до 10 раз) частота снова увеличивается ....
Видимо действительно у меня проблеммы с "железом"...
Плата случаем не wavgat?
Видимо действительно у меня проблеммы с "железом"...
Плата случаем не wavgat?
нет, классическая ProMini ..
#define f_base 13000 unsigned int du_OCR = f_base; void setup() { DDRD = B00011000; PORTD = B00100000; DDRB = B000010; PORTB = B000000; TCCR1A = 0; TCCR1B = 0; ICR1 = f_base; } void loop() { if ((PIND&(1<<PIND5))==0) { soft_start(); } } void soft_start() { TCCR1A = 0xC2; TCCR1B = 0x19; du_OCR = f_base; do { OCR1A = du_OCR; du_OCR = du_OCR-130; delay (25); } while (du_OCR > 100 && (PIND&(1<<PIND5))==0); TCCR1A = 0; TCCR1B = 0; ICR1 = f_base; }на данный момент это самый удачный у меня вариант...
хотя иногда при нажатии кнопки ИНОГДА первый проход идет на случайной частоте но потом при удержании кнопки все происходит по алгоритму...
Вот у вас условие есть: du_ocr > 100. Что с ним будет при начальном значении 110 и декременте 130?
Я же тебе написал: как правильно.
ICR1 - 16битный регистр, ты пишешь туда число длиннее байта - 13000. Нужно писать атомарно.
Я же тебе написал: как правильно.
ICR1 - 16битный регистр, ты пишешь туда число длиннее байта - 13000. Нужно писать атомарно.
Если я правильно понял, то должно выглядеть так :
#define f_base 13000 unsigned int du_OCR = f_base; void setup() { uint8_t sreg; DDRD = B00011000; PORTD = B00100000; DDRB = B000010; PORTB = B000000; sreg = SREG; cli (); TCCR1A = 0; TCCR1B = 0; ICR1 = f_base; SREG = sreg; } void loop() { if ((PIND&(1<<PIND5))==0) { soft_start(); } } void soft_start() { uint8_t sreg; TCCR1A = 0xC2; TCCR1B = 0x19; du_OCR = f_base; do { sreg = SREG; cli(); OCR1A = du_OCR; SREG = sreg; du_OCR = du_OCR-130; delay (25); } while (du_OCR > 100 && (PIND&(1<<PIND5))==0); TCCR1A = 0; TCCR1B = 0; ICR1 = f_base; }но баг остается...
https://youtu.be/7G9jbh4twKQ
Похоже, что проблемма решена...
#define f_base 13000 volatile uint16_t du_OCR = f_base; void setup() { DDRD = B00011000; PORTD = B00100000; DDRB = B000010; PORTB = B000000; cli(); TCCR1A = 0; TCCR1B = 0; ICR1 = f_base; sei(); } void loop() { if ((PIND&(1<<PIND5))==0) { soft_start(); } } void soft_start() { cli(); TCCR1A = 0xC2; TCCR1B = 0x19; du_OCR = f_base; ICR1 = f_base; do { OCR1A = du_OCR; du_OCR = du_OCR-130; sei(); delay (25); } while (du_OCR > 100 && (PIND&(1<<PIND5))==0); cli(); TCCR1A = 0; TCCR1B = 0; ICR1 = f_base; sei(); }добавление в строку 14 , ICR1 = f_base; решило проблему
кроме того, что частота перестала прыгать, так и диммер включается сразу после нажатия кнопки. на видео в предыдущем сообщении видно, что после первого нажатия кнопки проходит достаточно длительное время прежде чем появляется сигнал...
решил поэкспериментировать с атомарностью...
#define f_base 13000 volatile uint16_t du_OCR = f_base; void setup() { DDRD = B00011000; PORTD = B00100000; DDRB = B000010; PORTB = B000000; TCCR1A = 0; TCCR1B = 0; ICR1 = f_base; } void loop() { if ((PIND&(1<<PIND5))==0) { soft_start(); } } void soft_start() { TCCR1A = 0xC2; TCCR1B = 0x19; du_OCR = f_base; ICR1 = f_base; do { OCR1A = du_OCR; du_OCR = du_OCR-130; delay (25); } while (du_OCR > 100 && (PIND&(1<<PIND5))==0); TCCR1A = 0; TCCR1B = 0; ICR1 = f_base; }ухудшения работоспособности пока не заметил...