| Форум РадиоКот https://radiokot.ru/forum/ |
|
| странное поведение ШИМ,возможно дело в коде https://radiokot.ru/forum/viewtopic.php?f=62&t=193663 |
Страница 1 из 1 |
| Автор: | sanitar_zaz [ Пн июн 03, 2024 22:55:05 ] |
| Заголовок сообщения: | странное поведение ШИМ,возможно дело в коде |
добрый день всем.сразу говорю,возможно я выбрал не верный раздел,но не увидел раздела по кодингу. итак,задача: из игрового руля на 270 градусов сделать руль с возможностью изменения угла реализация я взял руль Thrustmaster Rallye GT Force Feedback Clutch,вынул из него потенциометр,поставил вместо него абсолютный энкодер BOURNS EAW0J-B24-AE0128L его показания получаю в atmega8,считаю количество пройденных пинов и умножаю их на множитель(про него дальше) для получения значения,которое устанавливаю в OCR1A про множитель для начала надо повторить базовую реализацию угла в 270 градусов.у энкодера позиции 0-127,т.е. 360 градусов равняется 128 пинам.простой математикой получаем что угол 270 градусов это 96 пинов.ещё раз считаем и получаем что 1 пин равняется 2.83 градуса.вот соответственно множитель и устанавливаем в 2.83 но практика показала что 2.83 это и близко не то значение.реально я сейчас подобрал что примерно 5.5 это близкое значение,но и то это ещё не оно.это проблема номер раз а проблема номер два это то что оно выходит на крайнее левое и крайнее правое значение при абсолютно разных значениях пройденных пинов.у руля есть штатная прога для калибровки,где наглядно можно наблюдать куда я его поворачиваю ![]() я добавил кнопку програмной центровки руля,и пробовал центровать нормально,повёрнутым вправо,повёрнутым влево и повёрнутым на 180 градусов.вообще разное количество пинов от крайнего левого до крайнего правого положения.за середину при центровке всегда задаётся 48 пинов(якобы уже пройдено)-потому что 96\2: Цитата: крайнее левое: физический пин:114 пинов пройдено от 0:24 значение OCR1A:132 крайнее правое: физический пин:38 пинов пройдено от 0:76 значение OCR1A:418 крайнее левое: физический пин:11 пинов пройдено от 0:21 значение OCR1A:115 крайнее правое: физический пин:69 пинов пройдено от 0:79 значение OCR1A:434 крайнее левое: физический пин:121 пинов пройдено от 0:22 значение OCR1A:121 крайнее правое: физический пин:69 пинов пройдено от 0:98 значение OCR1A:539 разброс мягко говоря бредовый. я не могу понять чем это обусловлено.вполне допускаю что я что-то не правильно указал в настройках ШИМа,поэтому я уже замахался искать сам проблему,прошу помощи у более опытных людей.ниже код проги,в ней много отладочного кода,тот-же вывод показаний на трёхциферный семисегментный индикатор пришлось сделать,чтоб увидеть в железе как оно считает.HELP Код: /* * main.c * * Created: 1/4/2024 9:10:34 PM * Author: sanitar */ #define F_CPU 8000000UL //#define pin_per_angle 2.8 #include <avr/pgmspace.h> #include <math.h> //массив соответствия номера пина к его двоичному коду const uint8_t pos_table[128] PROGMEM = {127,63,62,58,56,184,152,24,8,72,73,77,79,15,47,175,191,159,31,29,28,92,76,12,4,36,164,166,167,135,151,215,223,207,143,142,14,46,38,6,2,18,82,83,211,195,203,235,239,231,199,71,7,23,19,3,1,9,41,169,233,225,229,245,247,243,227,163,131,139,137,129,128,132,148,212,244,240,242,250,251,249,241,209,193,197,196,192,64,66,74,106,122,120,121,125,253,252,248,232,224,226,98,96,32,33,37,53,61,60,188,190,254,126,124,116,112,113,49,48,16,144,146,154,158,30,94,95}; int A1,A2,A3; void number(int numb) { //список портов для каждой цифры в индикаторе switch (numb) { case 0: PORTC |= 1<<0; PORTB |= 1<<5; PORTB |= 1<<2; PORTC |= 1<<4; PORTC |= 1<<3; PORTC |= 1<<5; break; case 1: PORTC |= 1<<5; PORTB |= 1<<2; break; case 2: PORTC |= 1<<0; PORTB |= 1<<2; PORTD |= 1<<0; PORTC |= 1<<4; PORTC |= 1<<3; break; case 3: PORTC |= 1<<0; PORTB |= 1<<2; PORTD |= 1<<0; PORTC |= 1<<5; PORTC |= 1<<3; break; case 4: PORTB |= 1<<5; PORTD |= 1<<0; PORTB |= 1<<2; PORTC |= 1<<5; break; case 5: PORTC |= 1<<0; PORTB |= 1<<5; PORTD |= 1<<0; PORTC |= 1<<5; PORTC |= 1<<3; break; case 6: PORTC |= 1<<0; PORTB |= 1<<5; PORTD |= 1<<0; PORTC |= 1<<4; PORTC |= 1<<5; PORTC |= 1<<3; break; case 7: PORTC |= 1<<0; PORTB |= 1<<2; PORTC |= 1<<5; break; case 8: PORTC |= 1<<0; PORTB |= 1<<5; PORTD |= 1<<0; PORTB |= 1<<2; PORTC |= 1<<4; PORTC |= 1<<5; PORTC |= 1<<3; break; case 9: PORTC |= 1<<0; PORTB |= 1<<5; PORTD |= 1<<0; PORTB |= 1<<2; PORTC |= 1<<5; PORTC |= 1<<3; break; } } void blackout() { //гасим транзисторы PORTD&=~(1<<1); PORTC&=~(1<<1); PORTC&=~(1<<2); ///// //гасим сегменты PORTC&=~(1<<0); PORTB&=~(1<<5); PORTD&=~(1<<0); PORTB&=~(1<<2); PORTC&=~(1<<4); PORTC&=~(1<<5); PORTC&=~(1<<3); //// } void show_digit(int pos) { //цифровой индикатор A1=pos%10; // 1ый разряд A2=(pos%100)/10; // 2ой разряд A3=pos/100; // 3ий разряд blackout(); if (pos<10) { number(pos); PORTC|=1<<1; } if ((pos>=10) && (pos<100)) { number(A1); PORTC|=1<<1; blackout(); number(A2); PORTC|=1<<2; blackout(); } if (pos>=100) { number(A1); PORTC|=1<<1; blackout(); number(A2); PORTC|=1<<2; blackout(); number(A3); PORTD|=1<<1; } } int main(void) { char initialisation,can_toggle_angle,angle_toggler_itter; int p[8],tmp,forwarded,enc_pos,last_enc_pos,wheel_pos,electricity_pos,wheel_center,max_perm_pins; float voltage_modifier; initialisation=0; last_enc_pos=0; enc_pos=0; wheel_pos=0; electricity_pos=0; wheel_center=48; max_perm_pins=96; voltage_modifier=5.5; angle_toggler_itter=0; DDRD=0x00; DDRB&=~(1<<0); //PB0 read DDRB|=1<<1; //PB1 write DDRB&=~(1<<2); //PB3 read DDRB&=~(1<<3); //PB4 read DDRB&=~(1<<5); //PB6 read DDRB&=~(1<<6); //PB7 read PORTB |= 0<<1; PORTB |= 0<<0; TCCR1A = 0b10000010; TCCR1B = 0b00011001; ICR1=0x21C; OCR1A=0x00; //порты для индикатора DDRD|=1<<0; DDRB|=1<<2; DDRB|=1<<5; DDRC|=1<<0; DDRC|=1<<3; DDRC|=1<<4; DDRC|=1<<5; //порты для транзисторов DDRD|=1<<1; DDRC|=1<<1; DDRC|=1<<2; p[0]=0; p[1]=0; p[2]=0; p[3]=0; p[4]=0; p[5]=0; p[6]=0; p[7]=0; while (1) { tmp=0; if (!bit_is_clear(PINB,4)) { initialisation=0; } if (bit_is_clear(PINB,3)) { can_toggle_angle=1; } /* закоменчено ибо не могу 270 добиться,куда мне больший угол if (!bit_is_clear(PINB,3)) { if (can_toggle_angle==1) { angle_toggler_itter++; initialisation=0; if (angle_toggler_itter>3) { angle_toggler_itter=0; } if (angle_toggler_itter==0) { //angle 270 voltage_modifier=5.45; wheel_center=48; max_perm_pins=96; } if (angle_toggler_itter==1) { //angle 360 voltage_modifier=5.3; wheel_center=48; max_perm_pins=96; } if (angle_toggler_itter==2) { //angle 900 voltage_modifier=5.2; wheel_center=48; max_perm_pins=96; } if (angle_toggler_itter==3) { //angle 1080 voltage_modifier=5.1; wheel_center=48; max_perm_pins=96; } } can_toggle_angle=0; } */ //считывание позиции энкодера по 8 ногам if (!bit_is_clear(PINB,0)) { p[0]=1; } else { p[0]=0; } if (!bit_is_clear(PIND,7)) { p[1]=1; } else { p[1]=0; } if (!bit_is_clear(PIND,6)) { p[2]=1; } else { p[2]=0; } if (!bit_is_clear(PIND,5)) { p[3]=1; } else { p[3]=0; } if (!bit_is_clear(PINB,7)) { p[4]=1; } else { p[4]=0; } if (!bit_is_clear(PINB,6)) { p[5]=1; } else { p[5]=0; } if (!bit_is_clear(PIND,3)) { p[6]=1; } else { p[6]=0; } if (!bit_is_clear(PIND,4)) { p[7]=1; } else { p[7]=0; } for (int i = 0; i < 8; i++) { //перевод из двоичной в десятичную int x=(8-i)-2; forwarded=2; if (i==7) { forwarded=1; } while (x>0) { forwarded=forwarded*2; x--; } ; tmp=tmp+p[i]*forwarded; } for (int i = 0; i < 128; i++) { //получение позиции энкодера по таблице соответствия if (pgm_read_byte(&pos_table[i])==tmp) { enc_pos=i; break; } } if (initialisation==0) { //инициализационный сброс(центровка) last_enc_pos=enc_pos; initialisation=1; wheel_pos=wheel_center; electricity_pos=0x10E; } if (enc_pos>last_enc_pos) { if ((last_enc_pos>=0) && (last_enc_pos<30) && (enc_pos<=127) && (enc_pos>100)) { wheel_pos=wheel_pos-(last_enc_pos+(128-enc_pos)); } else { wheel_pos=wheel_pos+(enc_pos-last_enc_pos); } } if (enc_pos<last_enc_pos) { if ((last_enc_pos>100) && (last_enc_pos<=127) && (enc_pos>=0) && (enc_pos<30)) { wheel_pos=wheel_pos+((128-last_enc_pos)+enc_pos); } else { wheel_pos=wheel_pos-(last_enc_pos-enc_pos); } } /* ограничители закоменчено специально для отладки if (wheel_pos>max_perm_pins) { wheel_pos=max_perm_pins; } if (wheel_pos<0) { wheel_pos=0; } */ last_enc_pos=enc_pos; electricity_pos=floor(wheel_pos*voltage_modifier); //код для вывода данных на индикатор if (!bit_is_clear(PINB,3)) { if (can_toggle_angle==1) { angle_toggler_itter++; if (angle_toggler_itter>2) { angle_toggler_itter=0; } can_toggle_angle=0; } } if (angle_toggler_itter==0) { show_digit(enc_pos); } if (angle_toggler_itter==1) { show_digit(wheel_pos); } if (angle_toggler_itter==2) { show_digit(electricity_pos); } //конец вывода // OCR1A=electricity_pos; } } Добавлено after 14 minutes 4 seconds: да.совсем забыл,могу дать проект в протеусе.хотя не знаю нужен-ли,ведь по железу всё работает. UPD2:а может и в железе.на ноге ШИМа ещё стоит ФНЧ такого типа,и только после этого идёт уже питание в управляющую схему руля
|
|
| Автор: | sanitar_zaz [ Чт июн 06, 2024 00:31:09 ] |
| Заголовок сообщения: | Re: странное поведение ШИМ,возможно дело в коде |
всем спасибо,тему можно удалять)))) |
|
| Автор: | Jack_A [ Чт июн 06, 2024 07:28:19 ] |
| Заголовок сообщения: | Re: странное поведение ШИМ,возможно дело в коде |
Ну вот - только заинтересовал - и сразу удалять. Поделился бы. |
|
| Автор: | Martian [ Чт июн 06, 2024 08:29:39 ] |
| Заголовок сообщения: | Re: странное поведение ШИМ,возможно дело в коде |
так он поделился... примером, как не надо программировать. и проектировать. Так перемешать энкодер и индикатор, и затем преодолевать трудности - это надо постараться. А ведь вся программа могла свестить к полсотни строчек... |
|
| Автор: | Martian [ Вт июн 18, 2024 00:22:41 ] |
| Заголовок сообщения: | Re: странное поведение ШИМ,возможно дело в коде |
если б вы внимательно читали-то увидели б что индикатор туда добавлен для отладки.в рабочем варианте он вообще там не нужен. тогда нахрена его сюда было постить?и тема удалена, забыл? Добавлено after 8 minutes 11 seconds: вольтаж, круглость цифр, график разности... пойду спать, делать тут явно нечего. |
|
| Автор: | sanitar_zaz [ Вт июн 18, 2024 01:25:28 ] |
| Заголовок сообщения: | Re: странное поведение ШИМ,возможно дело в коде |
Martian, ну вот к чему весь этот пафос?видите где я иду не в ту сторону-ну подскажите. если вам так царапает глаз индикатор-вот код без оного. Код: /* * main.c * * Created: 1/4/2024 9:10:34 PM * Author: sanitar */ #define F_CPU 8000000UL //#define pin_per_angle 2.8 #include <avr/pgmspace.h> #include <math.h> //массив соответствия номера пина к его двоичному коду const uint8_t pos_table[128] PROGMEM = {127,63,62,58,56,184,152,24,8,72,73,77,79,15,47,175,191,159,31,29,28,92,76,12,4,36,164,166,167,135,151,215,223,207,143,142,14,46,38,6,2,18,82,83,211,195,203,235,239,231,199,71,7,23,19,3,1,9,41,169,233,225,229,245,247,243,227,163,131,139,137,129,128,132,148,212,244,240,242,250,251,249,241,209,193,197,196,192,64,66,74,106,122,120,121,125,253,252,248,232,224,226,98,96,32,33,37,53,61,60,188,190,254,126,124,116,112,113,49,48,16,144,146,154,158,30,94,95}; int main(void) { char initialisation,can_toggle_angle,angle_toggler_itter; int p[8],tmp,forwarded,enc_pos,last_enc_pos,wheel_pos,electricity_pos,wheel_center,max_perm_pins; float voltage_modifier; initialisation=0; last_enc_pos=0; enc_pos=0; wheel_pos=0; electricity_pos=0; wheel_center=48; max_perm_pins=96; voltage_modifier=5.5; angle_toggler_itter=0; DDRD=0x00; DDRB&=~(1<<0); //PB0 read DDRB|=1<<1; //PB1 write DDRB&=~(1<<2); //PB3 read DDRB&=~(1<<3); //PB4 read DDRB&=~(1<<5); //PB6 read DDRB&=~(1<<6); //PB7 read PORTB |= 0<<1; PORTB |= 0<<0; TCCR1A = 0b10000010; TCCR1B = 0b00011001; ICR1=0x21C; OCR1A=0x00; //порты для индикатора DDRD|=1<<0; DDRB|=1<<2; DDRB|=1<<5; DDRC|=1<<0; DDRC|=1<<3; DDRC|=1<<4; DDRC|=1<<5; //порты для транзисторов DDRD|=1<<1; DDRC|=1<<1; DDRC|=1<<2; p[0]=0; p[1]=0; p[2]=0; p[3]=0; p[4]=0; p[5]=0; p[6]=0; p[7]=0; while (1) { tmp=0; if (!bit_is_clear(PINB,4)) { initialisation=0; } if (bit_is_clear(PINB,3)) { can_toggle_angle=1; } /* закоменчено ибо не могу 270 добиться,куда мне больший угол if (!bit_is_clear(PINB,3)) { if (can_toggle_angle==1) { angle_toggler_itter++; initialisation=0; if (angle_toggler_itter>3) { angle_toggler_itter=0; } if (angle_toggler_itter==0) { //angle 270 voltage_modifier=5.45; wheel_center=48; max_perm_pins=96; } if (angle_toggler_itter==1) { //angle 360 voltage_modifier=5.3; wheel_center=48; max_perm_pins=96; } if (angle_toggler_itter==2) { //angle 900 voltage_modifier=5.2; wheel_center=48; max_perm_pins=96; } if (angle_toggler_itter==3) { //angle 1080 voltage_modifier=5.1; wheel_center=48; max_perm_pins=96; } } can_toggle_angle=0; } */ //считывание позиции энкодера по 8 ногам if (!bit_is_clear(PINB,0)) { p[0]=1; } else { p[0]=0; } if (!bit_is_clear(PIND,7)) { p[1]=1; } else { p[1]=0; } if (!bit_is_clear(PIND,6)) { p[2]=1; } else { p[2]=0; } if (!bit_is_clear(PIND,5)) { p[3]=1; } else { p[3]=0; } if (!bit_is_clear(PINB,7)) { p[4]=1; } else { p[4]=0; } if (!bit_is_clear(PINB,6)) { p[5]=1; } else { p[5]=0; } if (!bit_is_clear(PIND,3)) { p[6]=1; } else { p[6]=0; } if (!bit_is_clear(PIND,4)) { p[7]=1; } else { p[7]=0; } for (int i = 0; i < 8; i++) { //перевод из двоичной в десятичную int x=(8-i)-2; forwarded=2; if (i==7) { forwarded=1; } while (x>0) { forwarded=forwarded*2; x--; } ; tmp=tmp+p[i]*forwarded; } for (int i = 0; i < 128; i++) { //получение позиции энкодера по таблице соответствия if (pgm_read_byte(&pos_table[i])==tmp) { enc_pos=i; break; } } if (initialisation==0) { //инициализационный сброс(центровка) last_enc_pos=enc_pos; initialisation=1; wheel_pos=wheel_center; electricity_pos=0x10E; } if (enc_pos>last_enc_pos) { if ((last_enc_pos>=0) && (last_enc_pos<30) && (enc_pos<=127) && (enc_pos>100)) { wheel_pos=wheel_pos-(last_enc_pos+(128-enc_pos)); } else { wheel_pos=wheel_pos+(enc_pos-last_enc_pos); } } if (enc_pos<last_enc_pos) { if ((last_enc_pos>100) && (last_enc_pos<=127) && (enc_pos>=0) && (enc_pos<30)) { wheel_pos=wheel_pos+((128-last_enc_pos)+enc_pos); } else { wheel_pos=wheel_pos-(last_enc_pos-enc_pos); } } /* ограничители закоменчено специально для отладки if (wheel_pos>max_perm_pins) { wheel_pos=max_perm_pins; } if (wheel_pos<0) { wheel_pos=0; } */ last_enc_pos=enc_pos; electricity_pos=floor(wheel_pos*voltage_modifier); OCR1A=electricity_pos; } } я весь внимание. Цитата: вольтаж, круглость цифр, график разности ииии?в чём проблема? |
|
| Автор: | sanitar_zaz [ Вт июн 18, 2024 14:20:59 ] |
| Заголовок сообщения: | Re: странное поведение ШИМ,возможно дело в коде |
я и через процентное соотношение пробовал вычислять.например: 4.95В это 100% 4.95/100=0.0495,следовательно 1% это 0.0495 3.85/0.0495=77.77(3.85В это 77.77% от полного напряжения) OCR1A 430 это 3.85В и это 96 пинов 96/77.77=1.23(столько пинов составляют 1%) теперь берём,к примеру,положение 32 пина 32/1.23=26.01% 540(ICR1)/26.01=20.76 т.е. получается что при OCR1A=21 у меня должно быть 1.85 вольта,в то время как оно такое при 205 |
|
| Автор: | jcxz [ Ср июн 19, 2024 13:01:05 ] |
| Заголовок сообщения: | Re: странное поведение ШИМ,возможно дело в коде |
я весь внимание. Ужоснах! Вряд-ли кто в таком быдлокоде разбираться захочет. Каша какая-то, а не код.Особенно с такими перлами: Код: p[0]=0; p[1]=0; p[2]=0; p[3]=0; p[4]=0; p[5]=0; p[6]=0; p[7]=0; ![]() Да и остальное не лучше.... Добавлено after 5 minutes 20 seconds: Код: //считывание позиции энкодера по 8 ногам if (!bit_is_clear(PINB,0)) { p[0]=1; } else { p[0]=0; } if (!bit_is_clear(PIND,7)) { p[1]=1; } else { p[1]=0; } if (!bit_is_clear(PIND,6)) { p[2]=1; } else { p[2]=0; } if (!bit_is_clear(PIND,5)) { p[3]=1; } else { p[3]=0; } if (!bit_is_clear(PINB,7)) { p[4]=1; } else { p[4]=0; } if (!bit_is_clear(PINB,6)) { p[5]=1; } else { p[5]=0; } if (!bit_is_clear(PIND,3)) { p[6]=1; } else { p[6]=0; } if (!bit_is_clear(PIND,4)) { p[7]=1; } else { p[7]=0; }} Вроде как должно быть очевидно, что такое "чтение энкодера" работать правильно не может в принципе. Уж не говоря о том, что автор похоже даже не знает что такое циклы.... |
|
| Автор: | Starichok51 [ Ср июн 19, 2024 16:51:03 ] |
| Заголовок сообщения: | Re: странное поведение ШИМ,возможно дело в коде |
а прочитать сразу ВЕСЬ порт и сразу получить двоичный код ума не хватает? |
|
| Автор: | jcxz [ Ср июн 19, 2024 17:38:39 ] |
| Заголовок сообщения: | Re: странное поведение ШИМ,возможно дело в коде |
это начальная инициализация значений элементов массива.оставлять переменные без начального значения,"на авось"-ещё больший быдлокодинг Во-первых: Исходя из того как вы используете тот массив, его вполне можно сделать статическим. А статические переменные инициализуруются нулями сишным стартап-кодом. Достаточно объявить массив как:static int p[8] = {0}; всё. И кода никакого в main() не надо. А если нужна именно автоматическая переменная (на стеке), то для этого есть memset(...). Или, на худой конец - цикл. Ну и - использовать для хранения значений 0 и 1 переменные типа int на 8-битном контроллере!.... тут даже слов не находится Уж не говоря о том, что там и массив то никакой не нужен. А можно сразу прочитать все ноги. нет,я не вижу проблем в том что я написал. 1. Вы читаете не все пины энкодера одновременно, а отдельные пины в разное время. Что при вращении энкодера может давать "неожиданные" результаты. Тем более скорость прохода цикла main() у вас никак не фиксирована, а значит крутится он быстро, читая отдельные ноги в разное время.Какой смысл в таком? Почему не прочитать сразу все ноги одной-двумя операциями чтения порта? 2. Скорость прохода цикла тоже никак не фиксирована. И может болтаться в разные стороны. 3. (Самое главное) У вас энкодер - механический? Что такое дребезг контактов - знаете? В реальных механических энкодерах это серьёзная проблема. И если сначала (пока он новый и контакты не ушатанные) вы её можете не замечать (только редкие глюки), то потом дела ухудшатся. Нормальная реализация чтения позиции энкодера (программная) - например: Периодическое прерывание (от таймера). В котором с фиксированной известной частотой читаются сигналы энкодера (все сразу). Делается их анализ (на корректность). Делается подавление дребезга. Делается анализ на корректность изменения состояний энкодера (при вращении в любую сторону есть определённый порядок смены состояний сигналов; ПО должно его контролировать; и при нарушении - сбрасывать алгоритм работы в исходное состояние). |
|
| Автор: | sanitar_zaz [ Ср июн 19, 2024 22:32:01 ] |
| Заголовок сообщения: | Re: странное поведение ШИМ,возможно дело в коде |
а прочитать сразу ВЕСЬ порт и сразу получить двоичный код ума не хватает? посмотрите внимательно,3 ноги на порту B,4 ноги на порту D Цитата: Ну и - использовать для хранения значений 0 и 1 переменные типа int на 8-битном контроллере ну тут спорить не буду,мой проёбище. Цитата: 1. Вы читаете не все пины энкодера одновременно, а отдельные пины в разное время. Что при вращении энкодера может давать "неожиданные" результаты. Тем более скорость прохода цикла main() у вас никак не фиксирована, а значит крутится он быстро, читая отдельные ноги в разное время. Какой смысл в таком? Почему не прочитать сразу все ноги одной-двумя операциями чтения порта? хм,я не думал в такой плоскости.я как-то воспринимал что скорость одной итерации main на столько велика,что физически невозможно крутануть энкодер быстрее,чем он снимет показания со всех ног. Цитата: У вас энкодер - механический? Что такое дребезг контактов - знаете? В реальных механических энкодерах это серьёзная проблема. И если сначала (пока он новый и контакты не ушатанные) вы её можете не замечать (только редкие глюки), то потом дела ухудшатся. знаю конечно.энкодер механический.со временем перейду на оптический.пока этот есть,и пока он новый-вопрос дребезга можем игнорировать. Цитата: Нормальная реализация чтения позиции энкодера (программная) - например: Периодическое прерывание (от таймера). В котором с фиксированной известной частотой читаются сигналы энкодера (все сразу). Делается их анализ (на корректность). Делается подавление дребезга. Делается анализ на корректность изменения состояний энкодера (при вращении в любую сторону есть определённый порядок смены состояний сигналов; ПО должно его контролировать; и при нарушении - сбрасывать алгоритм работы в исходное состояние). спасибо,я подумаю над этим. но давайте представим сферического коня в вакууме что позиции энкодера считает нормально.что дальше с ШИМом?почему при вроде линейности данных,которые отдаёт потенциометр(в 3-м сообщении описывал),значение длительности импульса для достижения нужного вольтажа такое разное,что не видно закономерности,на что умножить кол-во пройденных пинов? |
|
| Автор: | akl [ Чт июн 20, 2024 08:16:52 ] |
| Заголовок сообщения: | Re: странное поведение ШИМ,возможно дело в коде |
Как вариант. ICR1=540 соответствует максимальному числу шагов энкодера OCR1A=K*N/256 или K=540*256/128=1080 середина N=64 OCR1A=1080*64/256=270 минимальное N=64-48 OCR1A=1080*16/256=67 максимальное N=64+48 OCR1A=1080*112/256=472 |
|
| Автор: | jcxz [ Чт июн 20, 2024 12:02:44 ] |
| Заголовок сообщения: | Re: странное поведение ШИМ,возможно дело в коде |
посмотрите внимательно,3 ноги на порту B,4 ноги на порту D Сделать 2 чтения, кэп? а потом соединить данные. Нет, никак? хм,я не думал в такой плоскости.я как-то воспринимал что скорость одной итерации main на столько велика,что физически невозможно крутануть энкодер быстрее,чем он снимет показания со всех ног. Причём тут "снимет показания со всех ног"? Я говорил о том, что у вас отдельные сигналы общей параллельной шины снимаются в разное время. Без какого-то синхросигнала. При наличии даже минимального дребезга можете получать странные значения.значение длительности импульса для достижения нужного вольтажа такое разное,что не видно закономерности,на что умножить кол-во пройденных пинов? Сначала вам нужно привести код в порядок. Та куча, что у вас навалена - совершенно нечитаема. Сначала код нужно нормально оформить (со всем нужным форматированием; убиранием закомментированного мусора; убиранием портянок линейного код вместо циклов и т.д.). Тогда и может и проблема станет сразу видна. А в вашей куче почти ничего не видно.
|
|
| Автор: | Energizer-A [ Чт июн 20, 2024 13:09:13 ] |
| Заголовок сообщения: | Re: странное поведение ШИМ,возможно дело в коде |
jcxz писал(а): Без какого-то синхросигнала. При наличии даже минимального дребезга можете получать странные значения. Мой скромный опыт пробы пера с энкодером, говорит ровно тоже.. дребезг большущая проблема и если есть вариант сделать фильтрацию за пределами контролёра - это нужно сделать. |
|
| Автор: | sanitar_zaz [ Чт июн 20, 2024 21:16:15 ] |
| Заголовок сообщения: | Re: странное поведение ШИМ,возможно дело в коде |
Как вариант. ICR1=540 соответствует максимальному числу шагов энкодера OCR1A=K*N/256 или K=540*256/128=1080 середина N=64 OCR1A=1080*64/256=270 минимальное N=64-48 OCR1A=1080*16/256=67 максимальное N=64+48 OCR1A=1080*112/256=472 спасибо,но не совсем.во-первых 256 это что? во-вторых если брать максимальное значение,то там 96 пинов,и OCR1A=1080*96/256=405,а в свою очередь OCR1A=405 даёт 3.64В,в то время как при 96 пинах должно быть 3.85В и про минимальное я тоже не понял,почему у нас минимальный угол поворота составляет 16 пинов?16 пинов это мы уже на 45 градусов повернули энкодер. Цитата: Сделать 2 чтения, кэп? а потом соединить данные. Нет, никак? та "как",конечно,чего ж никак)) если успею-сегодня переделаю и выложу. |
|
| Автор: | akl [ Пт июн 21, 2024 07:02:43 ] |
| Заголовок сообщения: | Re: странное поведение ШИМ,возможно дело в коде |
sanitar_zaz писал(а): ...256 это что? Типовой прием ухода от дробных значений. Вряд ли удобнее умножать 1080/256=4,21875.Как следует из картинки и текста программы берется кодировка без смещения, т.е. середина положения энкодера 64 шага, а не 48. Как вариант, сместить таблицу кодировки на 16 шагов. Мой опыт применения такого энкодера - резисторы уменьшить до 1к и опрос осуществлять импульсом |_| лапой, подключенной к (C)COM. Вложение:
|
|
| Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|




