Программный ШИМ управления сервой на PIC16F628A

Fotilla

Гуру! Подсобите в проекте: есть готовое устройство - термостат управления отопителем в автомобиле. Реализовано на 16Ф628А - рулит электроклапаном двумя ногами через транзисторы с открытым коллектором. Собственно задача - заменить исполнительный механизм на стандартную модельную серву. Вопрос в реализации программного ШИМ с периодом 20 мсек и шириной 1 - 2 мсек. Т.е. два крайних положения. Язык - АСМ. У самого мозгов не хватает. Изучил вопрос в Гуглях - но кроме вручную дергать ногой и считать период - ничего не осилил. Мысль такая - поднимаю ногу в 1 на 1 мсек, отпускаю, 19 мсек держу ее в нуле, снова поднимаю, и так по циклу… При 2 мсек - 18 мсек держу в нуле… Правильно? Но тогда вопрос о основной программе - ее тоже надо выполнять (мерять температуру, отображать на дисплее и т.д). Я в ступоре.
В общем - хелп! Или хотя бы примеры управления сервой на ПИКе из АСМ.

Tigra74
Fotilla:

…примеры управления сервой на ПИКе из АСМ.

Есть серва на 12F675 -можно попытаться считать программу(если не защищена) и срисовать схему,

Fotilla
V_Alex:

Похожая тема: rcopen.com/forum/f87/topic240587

Спасибо, ознакомился. Про генерацию ШИМ ниасилил - АВР асм пока не изучал.

Tigra74:

Есть серва на 12F675 -можно попытаться считать программу(если не защищена) и срисовать схему,

Да мне в готовое устройство на 16Ф628 интегрировать код надо. Дезассемблировать алгоритм сервы - вообще кошмар… Тем боле мне надо серву подцепить к термостату как исполнительный механизм (вкл\выкл подачу тосола).

Наваял вот такой код. Не знаю, как на эти куски отреагирует основной цикл программы, попробую в железе.

;*****************************************************************************
;Процедура генерирования ШИМ шириной 1 мсек 20 раз

DELAY_1MSEC
		MOVLW	.20					;помещаем значение 20 в F
		MOVWF 	PWM_N				;
DELAY_1	BSF		PA, 7	 			;поднимаем ногу в "1"
		CALL	MSEC_1				;зовем паузу 1 мсек
		BCF		PA, 7				;отпускаем ногу в "0"
		MOVLW	.19					;помещаем значение 19 в F
		MOVWF 	PWM					;
DEL_19	CALL 	MSEC_1				;зовем паузу 1 мсек
		DECFSZ 	PWM, F				;декрементируем
		GOTO 	DEL_19				;
		DECFSZ 	PWM_N, F			;и так 19 раз
		GOTO 	DELAY_1				;
		RETURN

MSEC_1	            MOVLW	.100				;ждем 100 раз по 10мксек
		CALL 	DELAY_10USEC		;
		RETURN

;*****************************************************************************
;Процедура генерирования ШИМ шириной 2 мсек 20 раз

DELAY_2MSEC
		MOVLW	.20					;помещаем значение 20 в F
		MOVWF 	PWM_N				;
DELAY_2	BSF		PA, 7	 			;поднимаем ногу в "1"
		CALL	MSEC_2				;зовем паузу 2 мсек
		BCF		PA, 7				;отпускаем ногу в "0"
		MOVLW	.18					;помещаем значение 18 в F
		MOVWF 	PWM					;
DEL_20  	CALL 	MSEC_1				;зовем паузу 1 мсек
		DECFSZ 	PWM, F				;декрементируем
		GOTO 	DEL_20				;
		DECFSZ 	PWM_N, F			;и так 18 раз
		GOTO 	DELAY_2				;
		RETURN

MSEC_2	            MOVLW	.200				;ждем 200 раз по 10мксек
		CALL 	DELAY_10USEC		;
		RETURN
Dj_smart

А может организовать счётчик с циклом 20мс, вроде стандарт для серв, по окончанию счёта уходим в прерывание из основной проги, выставляем нужную ширину импульса, в зависимости от того, что основная программа намеряла, и так по кругу…

blade
Fotilla:

Или хотя бы примеры управления сервой на ПИКе

Про ПИК не скажу- давно от них отказался.
А вот автопилот на Атмеге 8-делал.
Там главная засада- для приема и выдачи нагора ШИМ сигналов- очень желательно использовать аппаратно- заточенные под это входы (4,5 пин-в Дип корпусе) и выходы 15,16.
Иначе- замучаетесь дрожь сервы убирать.
А когда она дрожит, происходят две неприятности: питание жрет и- сгореть норовит 😦

Fotilla

В прерываниях я не очень силен, буду изучать. Наверное это не очень пойдет - прога в основном цикле опрашивает датчик температуры, выводит данные на экран. Хотя, можно посчитать время - возможно и хватит паузы между генерацией импульса.
По дрожанию - при возникновении условия изменения положения сервы, программа уходит 20 раз подряд (0,4 сек) в цикл, после чего, отпускает серву.
В любом случае, надо проверять работу в железе.

AndyBig
Dj_smart:

А может организовать счётчик с циклом 20мс, вроде стандарт для серв, по окончанию счёта уходим в прерывание из основной проги, выставляем нужную ширину импульса, в зависимости от того, что основная программа намеряла, и так по кругу…

20 мсек - этот период просто задать в настройках аппаратного ШИМ. А ширину импульса менять каждый период не стоит, зачем мучать серву? 😃 В этом приложении достаточно это делать раз в 5-10 секунд. Для термостата этого более чем достаточно, от него никто не ждет мгновенной реакции на повышение температуры на 0.1 градуса 😃 Например, измерения проводятся 1 раз в секунду с непрерывным усреднением по последним 10 результатам (элементарный фильтр), раз в 10 секунд в соответствии с текущим усредненным значением обновляем регистр скважности ШИМ.

Fotilla:

возможно и хватит паузы между генерацией импульса.

Не надо генерировать импульс софтом, используйте аппаратный таймер в режиме ШИМ. Вам правильно указали на большой джиттер при софтовой реализации ШИМа.

Fotilla

Про аппаратный ШИМ я понимаю. Есть нюанс - устройство готовое и работает. Нога аппаратного ШИМ занята. Тут два варианта - или с нуля переделывать устройство, или применять ШИМ софтовый. Но спасибо за советы!

Aleksey_Gorelikov

В прерывании по таймеру устаналвивать любую ногу в нужное состояние. Вон народ на альтернативной прошивке на турниджи летает и не жалуется на жужжание серв. 😃 Кстати, вот еще интересная тема, для тех, кому 1 сервы мало:) easyelectronics.ru/upravlenie-mnozhestvom-servomas…

slash_san

Простейший вариант - прерывание по таймеру TMR0 50 раз в секунду, генерация в подпрограмме обработки прерывания (ПОП) сигнала нужной длительности (1 мс или 2 мс), потом возврат из ПОП, сервы не дрожат, на основной цикл останется полно времени, аппаратный блок ШИМ для этого не очень нужен

Aleksey_Gorelikov

Все что нужно - это таймер. А аппаратный шим или самому в прерывании по совпадению таймера ногой дернуть - пофиг.

AndyBig
Aleksey_Gorelikov:

аппаратный шим или самому в прерывании по совпадению таймера ногой дернуть - пофиг.

Это только если не задействованы никакие другие прерывания.

Fotilla

Про другие прерывания - в точку! В прерываниях по таймеру кнопки опрашиваются и выводится динамическая индикация на семисегментник. Возможно, там же получится и генерировать ШИМ. Или проще посчитать пустое время основного цикла, и пол секунды, при необходимости, управлять сервой. На всякий случай выкладываю полный текст проги.

Term_PIC628_PWM.rar

AndyBig

Кстати, можно и питание серве отключать на время, когда ей не нужно менять положение. Тогда и дрожать впустую из-за джиттера она не будет 😉

mikki

В проге есть подпрограмма вывода на дисплей… померь сколько времени проходит от обращения до обращения к ней … наверняка 20мс±… не больше, иначе мерцание будет… вот сразу в ней перед выходом и воткни цикл по поднятию-опусканию ноги на рассчетное время… на работоспособности девайса лишняя 1-2мс не повлияют…
Только при расчете длины импульса введи небольшой гистерезис, чтобы серва не дрожала, как сказали выше…

AndyBig
mikki:

на работоспособности девайса лишняя 1-2мс не повлияют

Весь рабочий диапазон ширины импульса как раз составляет 1 мсек - от 1 до 2 мсек. Так что поднимать ногу еще можно раз в 20 мсек с плюс-минус парой мсек, а вот опускать ее надо в очень точно выверенный промежуток времени после поднятия. С нормальной сервой разница в пару мксек уже будет давать дрожание сервы.

mikki

1-2мс - это и есть диапазон поднятия-опускания ноги который нужно считать… я говорю что на общий цикл этот довесок не повлияет

Aleksey_Gorelikov
AndyBig:

Это только если не задействованы никакие другие прерывания.

Никто не мешает запретить другие прерывания, когда это нужно. А всякая некритичная ко времени фигня типа семисегментника и кнопок - может обрабатываться впору хоть в основном цикле или во время 20мс паузы. Ксто смотрел код “самодельного передатчика” - там вобще всего одно прерывание. 😃 Работает же. 😃

AndyBig

Да можно, конечно, кто спорит? Все можно, даже на мелкой логике собрать 😃