Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » "Проскакивание" значения АЦП


"Проскакивание" значения АЦП

Сообщений 1 страница 12 из 12

1

Имеем некое устройство "мотор-потенциометр".
Направление вращения определяется МК ATMega16 (как - не суть важно).
Для остановки в определенных точках имеем таблицу значений (вольт).
Считывание потенциометра ведется внутренним АЦП (пин А0).

Допустим, сейчас привод стоит в положении "5" (2,9в).
Поступила команда "меньше", мотор поехал в нужную сторону.
АЦП, "поймав" 2,2в, должен дать команду остановки.
Подобное произойдет при вращении "больше", но до порога 3,2в.

Только "произойдет" получается как-то нестабильно...
Можно пять минут туда-сюда крутить до разных порогов, а можно уже на первой же команде обломиться.
Облом состоит в том, что АЦП "проскакивает" пороговые значения и МК маслает мотор до упора...  8-)

Замедление мотора до 0,05 об/мин спасает ситуацию, но физический агрегат крутится быстрее...

Напрашивается ускорение считывания АЦП... Чем ?
МК работает на 4 МГц

Фрагмент кода

' Таблица значений
dod1(1)=0.7
dod1(2)=1.1
dod1(3)=1.6
dod1(4)=2.2
dod1(5)=2.9
dod1(6)=3.2
dod1(7)=3.4
dod1(8)=3.5
dod1(9)=3.6
'--------------------------
'  ... что-то там еще ...
'--------------------------
sub acp1()
Config Adc = Single, Prescaler = Auto, Reference = AVCC
Start Adc

do
dacp = Getadc(0)
z=dacp/1023
z=z*5                                                         ' До этого места все понятно...
s=Fusing(z , "##.##")                                 'Форматируем значение для корректного сравнения с табличным
z=val(s)
if z=dod1(dev) then exit do                          'При совпадении текущего с табличным уходим к остановке
loop
Stop Adc
a=0
end sub

Отредактировано Nord (2016-02-04 22:42:13)

0

2

Думаю, не хватает разрядности АЦП, и как следствие, точности.
Вот тут:Ссылка sasha_1973 показал, как программным способом её повысить. Есть ещё один момент. То, что мотор сходит с ума, это нормально, т.к. при таком подходе программа тоже переходит в "качели". Тут нужен ПИД регулятор, точнее его расчёт. По сути это сумма воздействий пропорциональной, интегральной, дифф. составляющих. Качели уёдут сами по себе. Проблема в том, что воздействие на мотор и получение сигнала обратной связи разведены по времени (задержка). На таких регуляторах делают и нагреватели и двигатели с обратной связью и много чего.

Отредактировано Tankor (2016-02-04 22:57:51)

0

3

Tankor написал(а):

Думаю, не хватает разрядности АЦП, и как следствие, точности.Вот тут:Ссылка sasha_1973 показал, как программным способом её повысить.

10 битного мало ?!  :flirt:
Мне "на выходе" достаточно округления до 0,1в...
Не нашел функции округления, пришлось через Fusing корячиться...

Tankor написал(а):

Есть ещё один момент. То, что мотор сходит с ума, это нормально, т.к. при таком подходе программа тоже переходит в "качели". Тут нужен ПИД регулятор, точнее его расчёт. По сути это сумма воздействий пропорциональной, интегральной, дифф. составляющих. Качели уёдут сами по себе.

Были мысли...
Физическое устройство - обычный автомобильный моторредуктор отопителя...
Приходится отталкиваться при моделировании от его возможностей...

0

4

Nord написал(а):

10 битного мало ?!  
Мне "на выходе" достаточно округления до 0,1в...
Не нашел функции округления, пришлось через Fusing корячиться...

Если Вам хватает, то только ПИД.

0

5

Никак поворотное устройство делаете :)
В качестве датчика резистор?

0

6

У Вас -   s=Fusing(z , "##.##")
А точность хотите 0.1, может так s=Fusing(z , "##.#")

0

7

Geolog написал(а):

Никак поворотное устройство делаете
В качестве датчика резистор?

Может антенну крутить собрались?  :D
Если обычной резистор, он такого там шума-гама наделает.

Отредактировано Tankor (2016-02-04 23:14:03)

0

8

CONFIG SINGLE = SCIENTIFIC , DIGITS = 1
Это вам поможет не извращаться с переводом в String и обратно.

0

9

Если Вам нужна скорость, зачем-же так тормозить?

Nord написал(а):

z=dacp/1023
z=z*5                                                         ' До этого места все понятно...
s=Fusing(z , "##.##")                                 'Форматируем значение для корректного сравнения с табличным
z=val(s)

оперируйте сырыми данными АЦП.

0

10

Tankor написал(а):

CONFIG SINGLE = SCIENTIFIC , DIGITS = 1Это вам поможет не извращаться с переводом в String и обратно.

Можно и без "стрингов"...  8-)
z=dacp/1023
z=z*50
z=Int (z)
z=z/10

Про точность.
Уже после написания сюда это было замечено и исправлено.
Полегчало, но ненамного.
Сегодня замеряю фактическое сопротивление резистора в приводе, а то в моделировании использую 1кОм.
Если фактическое больше, то меня это спасет, т.к. погрешность снизится.

Антенну крутить не собираюсь, потому шумы от привода меня не волнуют... 8-)

sasha_1973 написал(а):

Если Вам нужна скорость, зачем-же так тормозить?
оперируйте сырыми данными АЦП.

Тоже думал в этом направлении.
Возможно, так и сделаю, только надо сначала сварганить табличку пересчетную...

Добавлено.
Покумекал в Excel...
Придется все-таки округляться, лучше до двух знаков...
Для примера:
сырое      пересчет
709    3,47
710    3,47
711    3,48
712    3,48
713    3,48
714    3,49
715    3,49
716    3,50
717    3,50
718    3,51
719    3,51
720    3,52
721    3,52
722    3,53
723    3,53

Как видим, минимум два соседних значения АЦП дают искомый результат.
При условии, что в аппаратном варианте мне важна точность позиции остановки, то просто в массиве буду использовать два знака, а не один.

Возможно, даже придется указывать "вилку" +- х.хХ при сравнении...

Отредактировано Nord (2016-02-05 08:08:18)

0

11

Александр, правильно подсказал.
Оперируйте сырым значением АЦП и приводите его к градусам. Т.е. 1023 это Х градусов ну и т.д.

73!

Отредактировано Geolog (2016-02-05 12:29:27)

0

12

Geolog написал(а):

Александр, правильно подсказал.Оперируйте сырым значением АЦП и приводите его к градусам. Т.е. 1023 это Х градусов ну и т.д.
            73!

Не спорю, но, учитывая точность привода (автомобильная, а не медицинская  :rolleyes: ), придется с любыми значениями "вилку" организовывать...

Подозреваю, что в момент вычислений МК "пропускает" считывание.
Используя сырые, можно отказаться от операций перевычислений, но от IF... или подобного не уйти, но это всяко повысит вероятность "попадания".

И вам Удачи !  :)

Добавлено.
Результат изменений...

Увеличил разрядность после запятой до двух знаков и сделал разброс в сравнении +-0.01в - ошибок стало в разы меньше, но ситуация сохранилась.
Проверка с "сырыми" данными и соответствующей "вилкой" дает те же результаты, так что - фиолетов, чем оперировать...
Ошибки возникают при движении в "+"...
В сторону уменьшения отрабатывает четко от края до края...

Обновлено.
Увеличение разрядности после запятой до трех знаков и разбросе в +-0,015 оказалось достаточным.
Проверено в железе - отрабатывает четко при фактических 2 об/мин механизма.
Точность остановки достаточная.

Всем спасибо за участие !

Отредактировано Nord (2016-02-06 13:46:17)

0


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » "Проскакивание" значения АЦП