Опять про чтение PWM , но про подключение.
- Войдите на сайт для отправки комментариев
Ср, 27/03/2019 - 13:06
Стоит задача прочитать с Pwm выхода Ардуины сигнал pwm цифровым пином другой ардуины. С кодом проблем нет, но не работает ) В мониторе цифры хоть и не хаотические, но бредово беспорядочные. Пробовал по всякому: и pulseIn и внешним прерыванием, результат одинаковый.
,Я подключаю проводом pwm выход одной платы напрямую к цифровому пину другой, земля общая.
Вопрос: а не надо ли эту линию подтягивать к земле или питанию? Каким номиналом резистора? Я в этом не разираюсь, и от слова "подтягивающий резистор" мне делаеца дурно)
Заранее спасибо!
Шим сигнал (PWM) для начала интегрировать нужно.
Нет. Не нужно.ь Можно воспользоваться стандартной функцией pulseIn, или по внешнему прерыванию посчитать период высокого и низкого уровня.
тоись, тебе не в аналоговый пин нужно вводить?
На данный момент пытаюсь в цифровой. Городить интегрирующую цепочку не хочу, да и не очень умею. Да и не надо..)
Странно. Никогда проблем не было. Цифровой выход на цифровой вход без всяких подтягивающих резисторов и pulseIn всегда устойчиво работало.
какие параметры ШИМ - частота, скважность? Я принимаю до 12 ШИМ сигналов с радиопультов (там не совсем ШИМ, но не будем о тонкостях)- все нормально, через внешние прерывания. Без всяких подтягивающих резисторов.
Вот код. Вернул pulseIn, проверил все подключения, в мониторе 0. Устойчивый ноль. Единичку/нолик с цифрового пина исходной ардуинки на 3ю ножку получает нормально, а PWM не видит. При этом выход pwm работает - если подключить диодик с резистором - все нормально, меняет яркость.
параметры ШИМ - не знаю. Вероятнее всего частота - стандартная для Arduino, а скважность я меняю. Визуально диод от самого тусклого, до ярко-яркого. Ни тот ни другой никак не отзывается.
Самое странное, что я проверил - перекинул с PWM выхода проводок на другой выход, который отдает импульсы на драйвер шагового двигателя. С него pulseIn честно прочитала ширину импульса в 10 мкс. Все работает, а с PWM нет. Хотя диод на PWM реагирует....где тут смайлик "чешу репу" ??
Самое странное, что я проверил - перекинул с PWM выхода проводок на другой выход, который отдает импульсы на драйвер шагового двигателя. С него pulseIn честно прочитала ширину импульса в 10 мкс. Все работает, а с PWM нет. Хотя диод на PWM реагирует....где тут смайлик "чешу репу" ??
А если дать на источинике analogWrite(x,1) будет измерять? Это и будет примерно 10 или 5 мкс (в зависимости от пина выхода). Или дайте функции pulseIn() дождаться спада импульса, а потом печатайте. Достаточно будет 2 мс с запасом. Мысля такая, что короткие импульсы успевает обработать, а спады длинных уходят на delay() и стираются при cледующем запуске pulseIn().
дык а какая тут схема? Пин 11 с Uno - проводок - пин 2 на Нано. Земля Uno - проводок - земля Нано. Я не умею схему проводка рисовать )
Сама Uno - 3 осевой GRBL контроллер, поэтому поменять что-то в ней я не могу. Могу только G-кодами давать ей команды. Две оси заняты, а третья и выход PWM на шпиндель свободны. Нужно передать число с контроллера на удаленную ардуинку, чтобы та управляла своим локальным параметром на каретке станке. Хотелось бы чтобы это можно было делать пряямо в G-код программе. Типа часть программы сделали - параметр поменяли. Можно конечно это делать через останови вручную - но это фу, некультурно как-то.
Собственно была идея через PWM выход. Я какбе задаю обороты шпинделя из программы, а по сути это передаваемый параметр. Это можно длеать как угодно в управляющей программе. Но вот что-то не работает...
а с внешним прерыванием пробовали?
Я читаю два канала ШИМ вот так:
Бред какой-то - поставил явным образом тайм аут в функцции pulseIn - все заработало, потом убрал на умолчание (1 сек) все продолжает работать...
Бред какой-то - поставил явным образом тайм аут в функцции pulseIn - все заработало, потом убрал на умолчание (1 сек) все продолжает работать...
Это не баг, это фичи многих библиотек для Arduino IDE - необходимость танцев с бубном. Воспользуйтесь функцией внешнего прерывания attachInterrupt, или , что много лучше, используйте "родные" прерывания Atmega328, тогда точно такого рода сюрпризов не будет. Это функции
Вы объявляете, по каким пинам будет прерывание обрабатываться, у меня это С0-С2
EICRA = 0x00; // INT0 INT1 Type didn't matter
EIMSK = 0x00; // INT0 INT1 disabled
PCMSK0 = 0x00;
PCMSK1 = 0x07; // Pin change mask pins C0 C1 C2 ENABLE any change
PCMSK2 = 0x00;
PCIFR = 0x02; //PCINT 14-8 Flag clear
PCICR = 0x02; //Pins C0 - C5 interruptions enable
и считаете в функции обработки прерывания
ISR (PCINT1_vect)// pin change interrupt for A0 to A5
Я так глубоко, вот штоп с векторами и всё такое в программирование пока не погрузился . Но с внешними прерыванием я могу. Попробую.
Мне кажется мои закомментаренные строчки кода, из библиотеки, они как раз по внешнему прерыванию работают. Взято отсюбда https://github.com/xkam1x/Arduino-PWM-Reader
Я читаю два канала ШИМ вот так:
У меня тоже пульт, но с 3 каналами, так что использовал родную функцию прерывания.
дык а какая тут схема? Пин 11 с Uno - проводок - пин 2 на Нано. Земля Uno - проводок - земля Нано. Я не умею схему проводка рисовать )
Я читаю два канала ШИМ вот так:
У меня тоже пульт, но с 3 каналами, так что использовал родную функцию прерывания.
Это как?
«Неважно, что что-то идёт неправильно. Возможно, это хорошо выглядит» — Первый закон Скотта
ua6em: Это как?
Выходы RC приемника подключены к пинам А0-А2, в мк они С0-С2, настраиваем прерывания на сработку от любого изменения состояний пинов С0-С2
потом в прерывании считаем микросекунды (сделано для школьников, поэтому использовал ардуинскую ф-ю micros();
ua6em: Это как?
Выходы RC приемника подключены к пинам А0-А2, в мк они С0-С2, настраиваем прерывания на сработку от любого изменения состояний пинов С0-С2
потом в прерывании считаем микросекунды (сделано для школьников, поэтому использовал ардуинскую ф-ю micros();
а то же самое на пинах 2,3 и 12 можно сделать?
«Неважно, что что-то идёт неправильно. Возможно, это хорошо выглядит» — Первый закон Скотта
Ну да, библиотека не эталон точности. но тележка и на ней ездит )))
Интересно, а Вашу библиотеку TimeMeasure.h можно использовать для этих целей?
а то же самое на пинах 2,3 и 12 можно сделать?
Конечно можно. При этом Вы можете оставить свои ардуиновские функции внешнего прерывания, а добавить только подсчет времени импульса по пину 12, это вроде В4 в мк, и разрешить прерывания только по этому пину, не запрещая прерываний по пинам 2 и 3
вроде этого
и считать время в функции ISR (PCINT0_vect)
Ну или можно все функции переписать, тогда нужно будет разрешать прерывания по d2,d3 и b4.
Вобщем победил. Всем спасибо, при помощи таки pulseIn. Возможно какой-то мусор оставался на плате после теста вотчдога на ней, или предыдущих скетчей с прерыванием по таймеру, или что, непонятно. Явным образом указываю таймаут в функции pulseIn, после этого можно не указывать, она ставит по умолчанию, все встает на свои места.
И если кому интересно - отказался от идеи передавать число через PWM )) Неточно. Непропорционально увеличивается ширина импульса. Подстраиваешь коэффициент пропрциональности под малую скважность, врет на большой и наоборот. Немного, но неприятно.
Использовал свободную ось Z. Изобразил какбе асинхронную передачу на ней. По ножке, которая указывает направление вращение шпинделя, передаю единичку(командой "вращать по часовой стрелке") и по внешнему прерыванию начинаю читать импульсы, которые GRBL командой "проедь по оси Z столько-то" отдает в ось Z. Потом передаю смену направления вращения шпинделя, получатель видит нолик, заканчивает прием и смотрит сколько импульсов пришло. Получается не слишком быстро, десятые секунды, но мне этого достаточно. Зато диапазон передаваемых значений практически неограничен. Ну и точно, импульс потерять это надо постараться ))
Вобщем победил.
Победил - это когда удалось реализовать поставленную задачу, а всего-то надо было воспользоваться библиотекой от Евгения Петровича, точность измерения - десятые доли микросекунд )))
Точность измерения - это хорошо. Но я не уверен в точности отправителя. Получается так: я говорю контроллеру отправителю "вкл шпиндель на 200 об", тот выдает некий pwm. Я читаю ширину импульса, запоминаю соотношение, потом шлю команду "1000 об", читаю ширину импульса, делю на запомненное соотношение и результат - 1006. Некритично, но некультурно. Если опять дать 200, прочитается точно 200. Опять 1000, опять 1006. То есть неточность не в канале, неточно , а точнее нелинейно во всем диапазоне, делает pwm именно отправитель, в работу которого я не могу вмешаться.
Точность измерения - это хорошо. Но я не уверен в точности отправителя. Получается так: я говорю контроллеру отправителю "вкл шпиндель на 200 об", тот выдает некий pwm. Я читаю ширину импульса, запоминаю соотношение, потом шлю команду "1000 об", читаю ширину импульса, делю на запомненное соотношение и результат - 1006. Некритично, но некультурно. Если опять дать 200, прочитается точно 200. Опять 1000, опять 1006. То есть неточность не в канале, неточно , а точнее нелинейно во всем диапазоне, делает pwm именно отправитель, в работу которого я не могу вмешаться.
для начала загрузите правильную программу, а потом можно о чём-то говорить, ваш метод имеет точность 4 микросекунды и таки да, после этого составляете в приёмнике массив оборотов и всё, берём из массива
Что такое "правильная"? Чем GRBL 0.9 "неправильный"? И каким извиите образом, в него грузить "массив". Составить свою таблицу...и имея в голове эти поправки отправлять g коды, можно наверно. Но это гемморой. Получилось все проще и без выкрутасов.
Что такое "правильная"?
я о точности применительно к пульсеин