странное поведение ШИМ,возможно дело в коде

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
sanitar_zaz
Первый раз сказал Мяу!
Сообщения: 37
Зарегистрирован: Сб янв 13, 2024 04:32:14

странное поведение ШИМ,возможно дело в коде

Сообщение sanitar_zaz »

добрый день всем.сразу говорю,возможно я выбрал не верный раздел,но не увидел раздела по кодингу.
итак,задача:
из игрового руля на 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
Первый раз сказал Мяу!
Сообщения: 37
Зарегистрирован: Сб янв 13, 2024 04:32:14

Re: странное поведение ШИМ,возможно дело в коде

Сообщение sanitar_zaz »

всем спасибо,тему можно удалять))))
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6307
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Re: странное поведение ШИМ,возможно дело в коде

Сообщение Jack_A »

Ну вот - только заинтересовал - и сразу удалять. Поделился бы.
Изображение
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: странное поведение ШИМ,возможно дело в коде

Сообщение Martian »

так он поделился... примером, как не надо программировать. и проектировать. Так перемешать энкодер и индикатор, и затем преодолевать трудности - это надо постараться. А ведь вся программа могла свестить к полсотни строчек...
sanitar_zaz
Первый раз сказал Мяу!
Сообщения: 37
Зарегистрирован: Сб янв 13, 2024 04:32:14

Re: странное поведение ШИМ,возможно дело в коде

Сообщение sanitar_zaz »

[uquote="Martian",url="/forum/viewtopic.php?p=4588038#p4588038"]Так перемешать энкодер и индикатор[/uquote]

если б вы внимательно читали-то увидели б что индикатор туда добавлен для отладки.в рабочем варианте он вообще там не нужен.
Ну вот - только заинтересовал - и сразу удалять. Поделился бы.
весь прикол оказался в том,что родная схема руля ждала от энкодера значения не от 0В(крайнее левое положение) до 4.9В(крайнее правое),а от 0.15В до 3.85В,соответственно преобразовывая значения в угол поворота руля.
я подпаялся к потенциометру в педалях,и снимал с него показания вольтажа,нажимая педаль и глядя как руль крутится в программе тестирования.снял таблицу показаний при разных углах.
Изображение
возможна некоторая погрешность,но в целом видно более-менее линейное изменение уменьшения шага множителя по мере увеличения угла поворота.осталось обернуть это в формулу.
sanitar_zaz
Первый раз сказал Мяу!
Сообщения: 37
Зарегистрирован: Сб янв 13, 2024 04:32:14

Re: странное поведение ШИМ,возможно дело в коде

Сообщение sanitar_zaz »

что-то не могу я подобрать параметры ШИМа.пробовал и только по длительности импульса подбирать шаг,и сразу по частоте ещё-не получается.
не могу понять на что умножать количество пройденных пинов,для получения нужного тока.
может у кого голова светлее моей,и накинет идею как это посчитать?
я вывел усреднёно что 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 раз.
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: странное поведение ШИМ,возможно дело в коде

Сообщение Martian »

[uquote="sanitar_zaz",url="/forum/viewtopic.php?p=4589259#p4589259"]если б вы внимательно читали-то увидели б что индикатор туда добавлен для отладки.в рабочем варианте он вообще там не нужен.[/uquote] тогда нахрена его сюда было постить?

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

Добавлено after 8 minutes 11 seconds:
вольтаж, круглость цифр, график разности... пойду спать, делать тут явно нечего.
sanitar_zaz
Первый раз сказал Мяу!
Сообщения: 37
Зарегистрирован: Сб янв 13, 2024 04:32:14

Re: странное поведение ШИМ,возможно дело в коде

Сообщение sanitar_zaz »

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
Первый раз сказал Мяу!
Сообщения: 37
Зарегистрирован: Сб янв 13, 2024 04:32:14

Re: странное поведение ШИМ,возможно дело в коде

Сообщение sanitar_zaz »

я и через процентное соотношение пробовал вычислять.например:
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
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: странное поведение ШИМ,возможно дело в коде

Сообщение jcxz »

[uquote="sanitar_zaz",url="/forum/viewtopic.php?p=4592279#p4592279"]я весь внимание.[/uquote]Ужоснах! Вряд-ли кто в таком быдлокоде разбираться захочет. Каша какая-то, а не код.
Особенно с такими перлами:
[uquote="sanitar_zaz",url="/forum/viewtopic.php?p=4592279#p4592279"]

Код: Выделить всё

p[0]=0;
p[1]=0;
p[2]=0;
p[3]=0;
p[4]=0;
p[5]=0;
p[6]=0;
p[7]=0;
[/uquote] :facepalm:
Да и остальное не лучше....

Добавлено after 5 minutes 20 seconds:
[uquote="sanitar_zaz",url="/forum/viewtopic.php?p=4592279#p4592279"]

Код: Выделить всё

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

Уж не говоря о том, что автор похоже даже не знает что такое циклы....
sanitar_zaz
Первый раз сказал Мяу!
Сообщения: 37
Зарегистрирован: Сб янв 13, 2024 04:32:14

Re: странное поведение ШИМ,возможно дело в коде

Сообщение sanitar_zaz »

давайте я аргументирую.итак:

[uquote="jcxz",url="/forum/viewtopic.php?p=4592816#p4592816"]Особенно с такими перлами:
[uquote="sanitar_zaz",url="/forum/viewtopic.php?p=4592279#p4592279"]

Код: Выделить всё

p[0]=0;
p[1]=0;
p[2]=0;
p[3]=0;
p[4]=0;
p[5]=0;
p[6]=0;
p[7]=0;
[/uquote] :facepalm:
Да и остальное не лучше....[/uquote]

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



[uquote="jcxz",url="/forum/viewtopic.php?p=4592816#p4592816"][uquote="sanitar_zaz",url="/forum/viewtopic.php?p=4592279#p4592279"]

Код: Выделить всё

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

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


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

каждый проход основного цикла программы опрашиваем 7 ног микрухи,чтоб знать низкое/высокое значение сейчас на каждом пине,собрать это значение в двоичный код и дальше по таблице получить позицию энкодера.
нет,я не вижу проблем в том что я написал.
если вы знаете как по-другому решить эту задачу-поделитесь пожалуйста,мне будет интересно(без сарказма)
и если что-индикатор показал что код определения позиции энкодера работает верно.проблема дальше,с ШИМ.
Аватара пользователя
Starichok51
Модератор
Сообщения: 19039
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: странное поведение ШИМ,возможно дело в коде

Сообщение Starichok51 »

а прочитать сразу ВЕСЬ порт и сразу получить двоичный код ума не хватает?
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
jcxz
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: странное поведение ШИМ,возможно дело в коде

Сообщение jcxz »

[uquote="sanitar_zaz",url="/forum/viewtopic.php?p=4592873#p4592873"]это начальная инициализация значений элементов массива.оставлять переменные без начального значения,"на авось"-ещё больший быдлокодинг[/uquote]Во-первых: Исходя из того как вы используете тот массив, его вполне можно сделать статическим. А статические переменные инициализуруются нулями сишным стартап-кодом. Достаточно объявить массив как:
static int p[8] = {0};
всё. И кода никакого в main() не надо.
А если нужна именно автоматическая переменная (на стеке), то для этого есть memset(...). Или, на худой конец - цикл.
Ну и - использовать для хранения значений 0 и 1 переменные типа int на 8-битном контроллере!.... тут даже слов не находится :facepalm:
Уж не говоря о том, что там и массив то никакой не нужен. А можно сразу прочитать все ноги.

[uquote="sanitar_zaz",url="/forum/viewtopic.php?p=4592873#p4592873"]нет,я не вижу проблем в том что я написал.[/uquote]1. Вы читаете не все пины энкодера одновременно, а отдельные пины в разное время. Что при вращении энкодера может давать "неожиданные" результаты. Тем более скорость прохода цикла main() у вас никак не фиксирована, а значит крутится он быстро, читая отдельные ноги в разное время.
Какой смысл в таком? Почему не прочитать сразу все ноги одной-двумя операциями чтения порта?
2. Скорость прохода цикла тоже никак не фиксирована. И может болтаться в разные стороны.
3. (Самое главное) У вас энкодер - механический? Что такое дребезг контактов - знаете? В реальных механических энкодерах это серьёзная проблема. И если сначала (пока он новый и контакты не ушатанные) вы её можете не замечать (только редкие глюки), то потом дела ухудшатся.

Нормальная реализация чтения позиции энкодера (программная) - например: Периодическое прерывание (от таймера). В котором с фиксированной известной частотой читаются сигналы энкодера (все сразу). Делается их анализ (на корректность). Делается подавление дребезга. Делается анализ на корректность изменения состояний энкодера (при вращении в любую сторону есть определённый порядок смены состояний сигналов; ПО должно его контролировать; и при нарушении - сбрасывать алгоритм работы в исходное состояние).
sanitar_zaz
Первый раз сказал Мяу!
Сообщения: 37
Зарегистрирован: Сб янв 13, 2024 04:32:14

Re: странное поведение ШИМ,возможно дело в коде

Сообщение sanitar_zaz »

[uquote="Starichok51",url="/forum/viewtopic.php?p=4592878#p4592878"]а прочитать сразу ВЕСЬ порт и сразу получить двоичный код ума не хватает?[/uquote]


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


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

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

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

но давайте представим сферического коня в вакууме что позиции энкодера считает нормально.что дальше с ШИМом?почему при вроде линейности данных,которые отдаёт потенциометр(в 3-м сообщении описывал),значение длительности импульса для достижения нужного вольтажа такое разное,что не видно закономерности,на что умножить кол-во пройденных пинов?
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: странное поведение ШИМ,возможно дело в коде

Сообщение akl »

Как вариант.
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
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: странное поведение ШИМ,возможно дело в коде

Сообщение jcxz »

[uquote="sanitar_zaz",url="/forum/viewtopic.php?p=4593008#p4593008"]посмотрите внимательно,3 ноги на порту B,4 ноги на порту D[/uquote]Сделать 2 чтения, кэп? а потом соединить данные. Нет, никак? :)

[uquote="sanitar_zaz",url="/forum/viewtopic.php?p=4593008#p4593008"]хм,я не думал в такой плоскости.я как-то воспринимал что скорость одной итерации main на столько велика,что физически невозможно крутануть энкодер быстрее,чем он снимет показания со всех ног.[/uquote]Причём тут "снимет показания со всех ног"? Я говорил о том, что у вас отдельные сигналы общей параллельной шины снимаются в разное время. Без какого-то синхросигнала. При наличии даже минимального дребезга можете получать странные значения.

[uquote="sanitar_zaz",url="/forum/viewtopic.php?p=4593008#p4593008"]значение длительности импульса для достижения нужного вольтажа такое разное,что не видно закономерности,на что умножить кол-во пройденных пинов?[/uquote]Сначала вам нужно привести код в порядок. Та куча, что у вас навалена - совершенно нечитаема. Сначала код нужно нормально оформить (со всем нужным форматированием; убиранием закомментированного мусора; убиранием портянок линейного код вместо циклов и т.д.). Тогда и может и проблема станет сразу видна. А в вашей куче почти ничего не видно.
Аватара пользователя
Energizer-A
Вымогатель припоя
Сообщения: 617
Зарегистрирован: Вт мар 03, 2015 20:13:46
Откуда: рядом с "не резиновой" живу в деревне

Re: странное поведение ШИМ,возможно дело в коде

Сообщение Energizer-A »

jcxz писал(а):Без какого-то синхросигнала. При наличии даже минимального дребезга можете получать странные значения.
Мой скромный опыт пробы пера с энкодером, говорит ровно тоже.. дребезг большущая проблема и если есть вариант сделать фильтрацию за пределами контролёра - это нужно сделать.
sanitar_zaz
Первый раз сказал Мяу!
Сообщения: 37
Зарегистрирован: Сб янв 13, 2024 04:32:14

Re: странное поведение ШИМ,возможно дело в коде

Сообщение sanitar_zaz »

[uquote="akl",url="/forum/viewtopic.php?p=4593074#p4593074"]Как вариант.
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[/uquote]


спасибо,но не совсем.во-первых 256 это что?
во-вторых если брать максимальное значение,то там 96 пинов,и OCR1A=1080*96/256=405,а в свою очередь OCR1A=405 даёт 3.64В,в то время как при 96 пинах должно быть 3.85В
и про минимальное я тоже не понял,почему у нас минимальный угол поворота составляет 16 пинов?16 пинов это мы уже на 45 градусов повернули энкодер.

Сделать 2 чтения, кэп? а потом соединить данные. Нет, никак?
та "как",конечно,чего ж никак))
если успею-сегодня переделаю и выложу.
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: странное поведение ШИМ,возможно дело в коде

Сообщение akl »

sanitar_zaz писал(а):...256 это что?
Типовой прием ухода от дробных значений. Вряд ли удобнее умножать 1080/256=4,21875.
Как следует из картинки и текста программы берется кодировка без смещения, т.е. середина положения энкодера 64 шага, а не 48. Как вариант, сместить таблицу кодировки на 16 шагов.
Мой опыт применения такого энкодера - резисторы уменьшить до 1к и опрос осуществлять импульсом |_| лапой, подключенной к (C)COM.
EAW0J_01.jpg
(76.13 КБ) 66 скачиваний
Ответить

Вернуться в «Разные вопросы по МК»