Например TDA7294

Форум РадиоКот • Просмотр темы - странное поведение ШИМ,возможно дело в коде
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Пн дек 29, 2025 10:40:59

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 19 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: странное поведение ШИМ,возможно дело в коде
СообщениеДобавлено: Пн июн 03, 2024 22:55:05 
Первый раз сказал Мяу!

Зарегистрирован: Сб янв 13, 2024 04:32:14
Сообщений: 37
Рейтинг сообщения: 0
добрый день всем.сразу говорю,возможно я выбрал не верный раздел,но не увидел раздела по кодингу.
итак,задача:
из игрового руля на 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:а может и в железе.на ноге ШИМа ещё стоит ФНЧ такого типа,и только после этого идёт уже питание в управляющую схему руля
Изображение


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: странное поведение ШИМ,возможно дело в коде
СообщениеДобавлено: Чт июн 06, 2024 00:31:09 
Первый раз сказал Мяу!

Зарегистрирован: Сб янв 13, 2024 04:32:14
Сообщений: 37
Рейтинг сообщения: 0
всем спасибо,тему можно удалять))))


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: странное поведение ШИМ,возможно дело в коде
СообщениеДобавлено: Чт июн 06, 2024 07:28:19 
Друг Кота
Аватар пользователя

Карма: 62
Рейтинг сообщений: 889
Зарегистрирован: Вт апр 24, 2007 07:45:40
Сообщений: 6215
Откуда: Minsk
Рейтинг сообщения: 0
Ну вот - только заинтересовал - и сразу удалять. Поделился бы.

_________________
Изображение


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: странное поведение ШИМ,возможно дело в коде
СообщениеДобавлено: Чт июн 06, 2024 08:29:39 
Друг Кота

Карма: 67
Рейтинг сообщений: 1964
Зарегистрирован: Сб дек 18, 2021 19:25:32
Сообщений: 12867
Рейтинг сообщения: 0
так он поделился... примером, как не надо программировать. и проектировать. Так перемешать энкодер и индикатор, и затем преодолевать трудности - это надо постараться. А ведь вся программа могла свестить к полсотни строчек...


Вернуться наверх
 
Эиком - электронные компоненты и радиодетали
Не в сети
 Заголовок сообщения: Re: странное поведение ШИМ,возможно дело в коде
СообщениеДобавлено: Вс июн 09, 2024 17:04:26 
Первый раз сказал Мяу!

Зарегистрирован: Сб янв 13, 2024 04:32:14
Сообщений: 37
Рейтинг сообщения: 0
Так перемешать энкодер и индикатор


если б вы внимательно читали-то увидели б что индикатор туда добавлен для отладки.в рабочем варианте он вообще там не нужен.

Цитата:
Ну вот - только заинтересовал - и сразу удалять. Поделился бы.


весь прикол оказался в том,что родная схема руля ждала от энкодера значения не от 0В(крайнее левое положение) до 4.9В(крайнее правое),а от 0.15В до 3.85В,соответственно преобразовывая значения в угол поворота руля.
я подпаялся к потенциометру в педалях,и снимал с него показания вольтажа,нажимая педаль и глядя как руль крутится в программе тестирования.снял таблицу показаний при разных углах.
Изображение
возможна некоторая погрешность,но в целом видно более-менее линейное изменение уменьшения шага множителя по мере увеличения угла поворота.осталось обернуть это в формулу.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: странное поведение ШИМ,возможно дело в коде
СообщениеДобавлено: Пн июн 17, 2024 23:10:45 
Первый раз сказал Мяу!

Зарегистрирован: Сб янв 13, 2024 04:32:14
Сообщений: 37
Рейтинг сообщения: 0
что-то не могу я подобрать параметры ШИМа.пробовал и только по длительности импульса подбирать шаг,и сразу по частоте ещё-не получается.
не могу понять на что умножать количество пройденных пинов,для получения нужного тока.
может у кого голова светлее моей,и накинет идею как это посчитать?
я вывел усреднёно что 45 градусов это 0.96В,90 градусов это 1.85В,135 это 2.47В,180 это 2.99В,225 это 3.34В,270 это 3.85В
для круглости цифр поставил ICR1 в 1000,набросал вот таблицу
Изображение
составил график разницы значений
Изображение
это ни на что не похоже адекватное.
как?хелп.


Последний раз редактировалось sanitar_zaz Вт июн 18, 2024 00:17:47, всего редактировалось 1 раз.

Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: странное поведение ШИМ,возможно дело в коде
СообщениеДобавлено: Вт июн 18, 2024 00:22:41 
Друг Кота

Карма: 67
Рейтинг сообщений: 1964
Зарегистрирован: Сб дек 18, 2021 19:25:32
Сообщений: 12867
Рейтинг сообщения: 0
если б вы внимательно читали-то увидели б что индикатор туда добавлен для отладки.в рабочем варианте он вообще там не нужен.
тогда нахрена его сюда было постить?

и тема удалена, забыл?

Добавлено after 8 minutes 11 seconds:
вольтаж, круглость цифр, график разности... пойду спать, делать тут явно нечего.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: странное поведение ШИМ,возможно дело в коде
СообщениеДобавлено: Вт июн 18, 2024 01:25:28 
Первый раз сказал Мяу!

Зарегистрирован: Сб янв 13, 2024 04:32:14
Сообщений: 37
Рейтинг сообщения: 0
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;


}
}


я весь внимание.


Цитата:
вольтаж, круглость цифр, график разности


ииии?в чём проблема?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: странное поведение ШИМ,возможно дело в коде
СообщениеДобавлено: Вт июн 18, 2024 14:20:59 
Первый раз сказал Мяу!

Зарегистрирован: Сб янв 13, 2024 04:32:14
Сообщений: 37
Рейтинг сообщения: 0
я и через процентное соотношение пробовал вычислять.например:
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


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: странное поведение ШИМ,возможно дело в коде
СообщениеДобавлено: Ср июн 19, 2024 13:01:05 
Говорящий с текстолитом

Карма: -7
Рейтинг сообщений: 187
Зарегистрирован: Вт авг 15, 2017 10:51:13
Сообщений: 1661
Рейтинг сообщения: 0
я весь внимание.
Ужоснах! Вряд-ли кто в таком быдлокоде разбираться захочет. Каша какая-то, а не код.
Особенно с такими перлами:
Код:
p[0]=0;
p[1]=0;
p[2]=0;
p[3]=0;
p[4]=0;
p[5]=0;
p[6]=0;
p[7]=0;
:facepalm:
Да и остальное не лучше....

Добавлено 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;
}}
Здесь вы как бы совсем не видите проблемы?
Вроде как должно быть очевидно, что такое "чтение энкодера" работать правильно не может в принципе.

Уж не говоря о том, что автор похоже даже не знает что такое циклы....


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: странное поведение ШИМ,возможно дело в коде
СообщениеДобавлено: Ср июн 19, 2024 16:37:18 
Первый раз сказал Мяу!

Зарегистрирован: Сб янв 13, 2024 04:32:14
Сообщений: 37
Рейтинг сообщения: 0
давайте я аргументирую.итак:

Особенно с такими перлами:
Код:
p[0]=0;
p[1]=0;
p[2]=0;
p[3]=0;
p[4]=0;
p[5]=0;
p[6]=0;
p[7]=0;
:facepalm:
Да и остальное не лучше....


это начальная инициализация значений элементов массива.оставлять переменные без начального значения,"на авось"-ещё больший быдлокодинг.



Код:
//считывание позиции энкодера по 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;
}}
Здесь вы как бы совсем не видите проблемы?
Вроде как должно быть очевидно, что такое "чтение энкодера" работать правильно не может в принципе.

Уж не говоря о том, что автор похоже даже не знает что такое циклы....



очевидно?что ж,давайте обратимся к даташиту на энкодер:
Изображение Изображение

каждый проход основного цикла программы опрашиваем 7 ног микрухи,чтоб знать низкое/высокое значение сейчас на каждом пине,собрать это значение в двоичный код и дальше по таблице получить позицию энкодера.
нет,я не вижу проблем в том что я написал.
если вы знаете как по-другому решить эту задачу-поделитесь пожалуйста,мне будет интересно(без сарказма)
и если что-индикатор показал что код определения позиции энкодера работает верно.проблема дальше,с ШИМ.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: странное поведение ШИМ,возможно дело в коде
СообщениеДобавлено: Ср июн 19, 2024 16:51:03 
Модератор
Аватар пользователя

Карма: 153
Рейтинг сообщений: 2927
Зарегистрирован: Сб авг 14, 2010 15:05:51
Сообщений: 18893
Откуда: г. Озерск, Челябинская обл.
Рейтинг сообщения: 6
Медали: 1
Лучший человек Форума 2017 (1)
а прочитать сразу ВЕСЬ порт и сразу получить двоичный код ума не хватает?

_________________
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: странное поведение ШИМ,возможно дело в коде
СообщениеДобавлено: Ср июн 19, 2024 17:38:39 
Говорящий с текстолитом

Карма: -7
Рейтинг сообщений: 187
Зарегистрирован: Вт авг 15, 2017 10:51:13
Сообщений: 1661
Рейтинг сообщения: 4
это начальная инициализация значений элементов массива.оставлять переменные без начального значения,"на авось"-ещё больший быдлокодинг
Во-первых: Исходя из того как вы используете тот массив, его вполне можно сделать статическим. А статические переменные инициализуруются нулями сишным стартап-кодом. Достаточно объявить массив как:
static int p[8] = {0};
всё. И кода никакого в main() не надо.
А если нужна именно автоматическая переменная (на стеке), то для этого есть memset(...). Или, на худой конец - цикл.
Ну и - использовать для хранения значений 0 и 1 переменные типа int на 8-битном контроллере!.... тут даже слов не находится :facepalm:
Уж не говоря о том, что там и массив то никакой не нужен. А можно сразу прочитать все ноги.

нет,я не вижу проблем в том что я написал.
1. Вы читаете не все пины энкодера одновременно, а отдельные пины в разное время. Что при вращении энкодера может давать "неожиданные" результаты. Тем более скорость прохода цикла main() у вас никак не фиксирована, а значит крутится он быстро, читая отдельные ноги в разное время.
Какой смысл в таком? Почему не прочитать сразу все ноги одной-двумя операциями чтения порта?
2. Скорость прохода цикла тоже никак не фиксирована. И может болтаться в разные стороны.
3. (Самое главное) У вас энкодер - механический? Что такое дребезг контактов - знаете? В реальных механических энкодерах это серьёзная проблема. И если сначала (пока он новый и контакты не ушатанные) вы её можете не замечать (только редкие глюки), то потом дела ухудшатся.

Нормальная реализация чтения позиции энкодера (программная) - например: Периодическое прерывание (от таймера). В котором с фиксированной известной частотой читаются сигналы энкодера (все сразу). Делается их анализ (на корректность). Делается подавление дребезга. Делается анализ на корректность изменения состояний энкодера (при вращении в любую сторону есть определённый порядок смены состояний сигналов; ПО должно его контролировать; и при нарушении - сбрасывать алгоритм работы в исходное состояние).


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: странное поведение ШИМ,возможно дело в коде
СообщениеДобавлено: Ср июн 19, 2024 22:32:01 
Первый раз сказал Мяу!

Зарегистрирован: Сб янв 13, 2024 04:32:14
Сообщений: 37
Рейтинг сообщения: 0
а прочитать сразу ВЕСЬ порт и сразу получить двоичный код ума не хватает?



посмотрите внимательно,3 ноги на порту B,4 ноги на порту D



Цитата:
Ну и - использовать для хранения значений 0 и 1 переменные типа int на 8-битном контроллере


ну тут спорить не буду,мой проёбище.

Цитата:
1. Вы читаете не все пины энкодера одновременно, а отдельные пины в разное время. Что при вращении энкодера может давать "неожиданные" результаты. Тем более скорость прохода цикла main() у вас никак не фиксирована, а значит крутится он быстро, читая отдельные ноги в разное время.
Какой смысл в таком? Почему не прочитать сразу все ноги одной-двумя операциями чтения порта?


хм,я не думал в такой плоскости.я как-то воспринимал что скорость одной итерации main на столько велика,что физически невозможно крутануть энкодер быстрее,чем он снимет показания со всех ног.


Цитата:
У вас энкодер - механический? Что такое дребезг контактов - знаете? В реальных механических энкодерах это серьёзная проблема. И если сначала (пока он новый и контакты не ушатанные) вы её можете не замечать (только редкие глюки), то потом дела ухудшатся.


знаю конечно.энкодер механический.со временем перейду на оптический.пока этот есть,и пока он новый-вопрос дребезга можем игнорировать.


Цитата:
Нормальная реализация чтения позиции энкодера (программная) - например: Периодическое прерывание (от таймера). В котором с фиксированной известной частотой читаются сигналы энкодера (все сразу). Делается их анализ (на корректность). Делается подавление дребезга. Делается анализ на корректность изменения состояний энкодера (при вращении в любую сторону есть определённый порядок смены состояний сигналов; ПО должно его контролировать; и при нарушении - сбрасывать алгоритм работы в исходное состояние).


спасибо,я подумаю над этим.

но давайте представим сферического коня в вакууме что позиции энкодера считает нормально.что дальше с ШИМом?почему при вроде линейности данных,которые отдаёт потенциометр(в 3-м сообщении описывал),значение длительности импульса для достижения нужного вольтажа такое разное,что не видно закономерности,на что умножить кол-во пройденных пинов?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: странное поведение ШИМ,возможно дело в коде
СообщениеДобавлено: Чт июн 20, 2024 08:16:52 
Друг Кота

Карма: 64
Рейтинг сообщений: 1024
Зарегистрирован: Пт мар 07, 2008 06:54:43
Сообщений: 4376
Откуда: Ижевск
Рейтинг сообщения: 0
Как вариант.
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


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: странное поведение ШИМ,возможно дело в коде
СообщениеДобавлено: Чт июн 20, 2024 12:02:44 
Говорящий с текстолитом

Карма: -7
Рейтинг сообщений: 187
Зарегистрирован: Вт авг 15, 2017 10:51:13
Сообщений: 1661
Рейтинг сообщения: 0
посмотрите внимательно,3 ноги на порту B,4 ноги на порту D
Сделать 2 чтения, кэп? а потом соединить данные. Нет, никак? :)

хм,я не думал в такой плоскости.я как-то воспринимал что скорость одной итерации main на столько велика,что физически невозможно крутануть энкодер быстрее,чем он снимет показания со всех ног.
Причём тут "снимет показания со всех ног"? Я говорил о том, что у вас отдельные сигналы общей параллельной шины снимаются в разное время. Без какого-то синхросигнала. При наличии даже минимального дребезга можете получать странные значения.

значение длительности импульса для достижения нужного вольтажа такое разное,что не видно закономерности,на что умножить кол-во пройденных пинов?
Сначала вам нужно привести код в порядок. Та куча, что у вас навалена - совершенно нечитаема. Сначала код нужно нормально оформить (со всем нужным форматированием; убиранием закомментированного мусора; убиранием портянок линейного код вместо циклов и т.д.). Тогда и может и проблема станет сразу видна. А в вашей куче почти ничего не видно.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: странное поведение ШИМ,возможно дело в коде
СообщениеДобавлено: Чт июн 20, 2024 13:09:13 
Вымогатель припоя
Аватар пользователя

Карма: 1
Рейтинг сообщений: 129
Зарегистрирован: Вт мар 03, 2015 20:13:46
Сообщений: 617
Откуда: рядом с "не резиновой" живу в деревне
Рейтинг сообщения: 0
jcxz писал(а):
Без какого-то синхросигнала. При наличии даже минимального дребезга можете получать странные значения.

Мой скромный опыт пробы пера с энкодером, говорит ровно тоже.. дребезг большущая проблема и если есть вариант сделать фильтрацию за пределами контролёра - это нужно сделать.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: странное поведение ШИМ,возможно дело в коде
СообщениеДобавлено: Чт июн 20, 2024 21:16:15 
Первый раз сказал Мяу!

Зарегистрирован: Сб янв 13, 2024 04:32:14
Сообщений: 37
Рейтинг сообщения: 0
Как вариант.
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 чтения, кэп? а потом соединить данные. Нет, никак?


та "как",конечно,чего ж никак))
если успею-сегодня переделаю и выложу.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: странное поведение ШИМ,возможно дело в коде
СообщениеДобавлено: Пт июн 21, 2024 07:02:43 
Друг Кота

Карма: 64
Рейтинг сообщений: 1024
Зарегистрирован: Пт мар 07, 2008 06:54:43
Сообщений: 4376
Откуда: Ижевск
Рейтинг сообщения: 0
sanitar_zaz писал(а):
...256 это что?
Типовой прием ухода от дробных значений. Вряд ли удобнее умножать 1080/256=4,21875.
Как следует из картинки и текста программы берется кодировка без смещения, т.е. середина положения энкодера 64 шага, а не 48. Как вариант, сместить таблицу кодировки на 16 шагов.
Мой опыт применения такого энкодера - резисторы уменьшить до 1к и опрос осуществлять импульсом |_| лапой, подключенной к (C)COM.
Вложение:
EAW0J_01.jpg [76.13 KiB]
Скачиваний: 60


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 19 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 24


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y