срезать каждый 20 импульс
- Войдите на сайт для отправки комментариев
Ср, 22/04/2020 - 23:15
Доброе
допустим на 13й пин приходит пакет из 50-ти импульсов частотой 3 кГц, нужно продублировать их на 14й пин, но убрав каждый 20й и 33й. Как их посчитать я понимаю, а вот как выводить соблюдая ту же входную частоту? в голове только вариант типа
digitalWrite(14, HIGH); delay(1000); digitalWrite(14, LOW); delay(1000);
но это не правильно
Головоломка, однако. Интервал увеличится, а частота должна остаться прежней.
А импульсы чистые? Дребезг на фронте есть? Если нет то какие проблемы - считываете в цикле состояние ноги и проверяете изменилось или нет, если изменилось то считаете в отдельном счетчике количество изменений и выдаёте на выходную ногу тот же уровень что и на входной ноге кроме изменения номер 40 и 41 и 66 и 67.
думаю параметры импульсов меняться не будут. Задачу электронщик загадал, разговора про меняющиеся параметры не было.
А почему читать в цикле, я думал лучше отрабатывать по прерыванию, нет? Так даже легче будет: пришел фронт импульса, делаешь сразу digitalWrite(14, HIGH); ждешь нужный тайминг и digitalWrite(14, LOW); и заного ловишь прерывание. Конечно нужно заранее подсчитать буду ли я попадать в нужный интервал по частоте импульсов...
У меня вопрос был больше в другом: есть ли какой другой вариант кроме записи в регистр хай и лоу для имитации импульсов на выходе?
Ловить в прерывании оба фронта и лишние пропускать ...
Писать напрямую а регистр без digitalWriye ...
digitalWrite(14, digtalRead(13));
Например
Доброе
допустим на 13й пин приходит пакет из 50-ти импульсов частотой 3 кГц, нужно продублировать их на 14й пин, но убрав каждый 20й и 33й.
Да как два пальца... Берете СТМ32... любой копеечный... 030... к примеру... заводите сигнал на вход таймера... выход таймера настраиваете как OD... и соединяете его с входом таймера через резистор... Таймер настраиваете на старт по фронту на входе... в режиме one pulse... период выставляете чуть больше чем "от первого входного импульса до 20го импульса... а длительность от "чуть раньше 20го импульса до чуть больше чем заканчивается 20й импульс"... т.е. по сути вы просто вырезаете 20й импульс... Т.к. в таймерах СТМ32 регистры имеют пребуфер... то можно уже во время вырезания 20го импульса загнать данные для выррезания 33го импульса... Заюзав другой таймер как таймаут... получаете полухардварное решение... Добавив ДМА... получите полностю хардварное решение... МК будет полностью свободен... для решения других задач...
спасибо за идеи! завтра буду пробовать.
const int ReadPin = 2; const int OutPin = 3; volatile int buttonState = 0; int counter = 0; void setup() { pinMode(OutPin, OUTPUT); pinMode(ReadPin, INPUT); attachInterrupt(0, pin_ISR, CHANGE); } void loop() { // put your main code here, to run repeatedly: } void pin_ISR() { buttonState = digitalRead(ReadPin); if (counter > 50) counter = 0; if (counter != 20 && counter != 33) { digitalWrite(OutPin, buttonState); } if (buttonState == HIGH) counter ++; }const int ReadPin = 2; const int OutPin = 3; volatile int buttonState = 0; int counter = 0; void setup() { pinMode(OutPin, OUTPUT); pinMode(ReadPin, INPUT); attachInterrupt(0, pin_ISR, CHANGE); } void loop() { // put your main code here, to run repeatedly: } void pin_ISR() { buttonState = digitalRead(ReadPin); if (counter > 50) counter = 0; if (counter != 20 && counter != 33) { digitalWrite(OutPin, buttonState); } if (buttonState == HIGH) counter ++; }Очень достойно, хотя нет - надо использовать оператор ИЛИ в строке 21. Не, дурак - все правильно.
Опять нет - не выходит циклического вызова подпрограммы pin_ISR(). В луп ее надо
RizONE - у вас прерывание по изменению, оно будет срабатывать дважды на каждый импульс, и соответственно 20-й по счетчику сигнал - это только десятый импульс
и еще - проверьте, все ли вы описали как volatile, что меняется в прерывании
RizONE - у вас прерывание по изменению, оно будет срабатывать дважды на каждый импульс, и соответственно 20-й по счетчику сигнал - это только десятый импульс
и еще - проверьте, все ли вы описали как volatile, что меняется в прерывании
А нахера прерывания на килогерцы? А если надо очень быстро - то считывайте из портов. Без разной херни типа проверок.
Опять нет - не выходит циклического вызова подпрограммы pin_ISR(). В луп ее надо
почему? При каждом изменении хай/лоу будет срабатывать подпрограмма
RizONE - у вас прерывание по изменению, оно будет срабатывать дважды на каждый импульс, и соответственно 20-й по счетчику сигнал - это только десятый импульс
и еще - проверьте, все ли вы описали как volatile, что меняется в прерывании
почему? у меня ж там счетчик меняется только при приходе хай т.е. на импульс один раз. Хотя ISR срабатывает дважды
А нахера прерывания на килогерцы? А если надо очень быстро - то считывайте из портов. Без разной херни типа проверок.
да я точно частоту входящих импульсов не знаю...
почему? у меня ж там счетчик меняется только при приходе хай т.е. на импульс один раз. Хотя ISR срабатывает дважды
да, сорри.
а счетчик все же стоит сделать волатильным...
Если кто знает хороший мануал про работу с прерываниями через
был бы благодарен, а то поиск заводит вообще в непонятные дебри
а счетчик все же стоит сделать волатильным...
Ок
Если кто знает хороший мануал про работу с прерываниями через
лучший мануал - это даташит контроллера
digital read / write внутри прерывания - жуткая жуть
digital read / write внутри прерывания - жуткая жуть
как будет правильнее подскажите или пример кода покажите
http://arduino.ru/Tutorial/Upravlenie_portami_cherez_registry
Счётчик частоты и скважности ШИМ тут есть в темах.
Ищущий, да обрящет.
Останется только пересчитать и вывести их с учётом выбрасывания ненужных.
Дело было вечером... Без прерываний получилось.
const int ReadPin = 2; const int OutPin = 3; int buttonState; int counter = 0; int oldState; void setup() { pinMode(OutPin, OUTPUT); pinMode(ReadPin, INPUT); buttonState = oldState = digitalRead(ReadPin); } void loop() { while (buttonState == oldState ) buttonState = digitalRead(ReadPin); if (!(counter == 40 || counter == 41 || counter == 66 || counter == 67)) digitalWrite(OutPin, buttonState); oldState = buttonState; counter++; if (counter > 67) counter=0; }