Радиоуправлениe на модулях nRF24L01+

Обсуждаем приемники, передатчики, радиомикрофоны, жучки, генераторы, ВЧ-усилители, антенны и прочее радиохозяйство
Аватара пользователя
sashamelja
Говорящий с текстолитом
Сообщения: 1565
Зарегистрирован: Пт янв 20, 2012 16:25:02

Re: Радиоуправлениe на модулях nRF24L01+

Сообщение sashamelja »

Доброго времени суток у меня такое предложение к roman.com
сделай пожалуста изменение в прошивке чтоби PD4(вив6) управлял завоцкой китайской сервой (а PD5 будет про запас)
С остальним всем согласен,теске MASIK Привет БУДЕМ ПОВТОРЯТЬ
И опыт сын ошибок трудных и гений парадоксов друг
Реклама
roman.com
Друг Кота
Сообщения: 9157
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Re: Радиоуправлениe на модулях nRF24L01+

Сообщение roman.com »

sashamelja писал(а):чтоби PD4(вив6) управлял завоцкой китайской сервой
Эта схема для MASIK, заточена под самодельную серву. Если делать по нормальному, то надо перекинуть модуль nRF24L01+ и сделать нормальную ШИМ (можно с двуми сервами).. А вообще есть и другие варианты))
Реклама
Аватара пользователя
sashamelja
Говорящий с текстолитом
Сообщения: 1565
Зарегистрирован: Пт янв 20, 2012 16:25:02

Re: Радиоуправлениe на модулях nRF24L01+

Сообщение sashamelja »

ATmega8 TQFP можна ли зделать так
Вложения
1.7z
(204.89 КБ) 257 скачиваний
И опыт сын ошибок трудных и гений парадоксов друг
roman.com
Друг Кота
Сообщения: 9157
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Re: Радиоуправлениe на модулях nRF24L01+

Сообщение roman.com »

Схемки пошли)) :)
Теоретически можно всё)) Основная проблема - китайские сервы. Не знаю, на сколько ты хорошо зазбираешся в МК... Но "на пальцах" примерно так: схемка разработана по заказу MASIK..)) У него самодельная серва от принтера. Примерно такая:
1.jpg
(40.62 КБ) 622 скачивания
Самодельная серва - два вывода на двигатель и отдельно резистор обратной связи. Поэтому MASIKу всё равно на какие выводы МК подключать свою серву)) И сколько подключать самодельных серв - MASIKу тоже всё равно)) Сколько выводов в МК, столько можно подключить самодельных серв))
Вот ещё пример самодельной сервы))
2_3.jpg
(161.67 КБ) 537 скачиваний
Китайская серва работает чуть иначе... там всё внутри...
3.jpeg
(50.58 КБ) 529 скачиваний
Управление у китайской сервы по одному выводу с помощью импульсов ШИМ. https://ru.wikipedia.org/wiki/Сервомашинка

Так вот, сложность получить эти самые импульсы заданной точности. Если просто подключить 4 сервы к выводам например PC0, PC1, PC2, PC3 (или любым другим), то сложно обеспечить точно длительность этих самых управляющих импульсов. Т.к. придётся делать программный ШИМ и задействовать процессор МК, который будет включать/отключать последовательно выводы PC0, PC1, PC2, PC3...
Процессор МК не может абсолютно точно выдержать длительности всех импульсов для 4-х серв, да ещё одновременно... Поэтому добиться идеальной точности сервы не получится. И ещё есть опасность, что сервы будут "дрожать"... Хотя попытаться можно, но результат не гарантируется)))
8.JPG
(58.28 КБ) 350 скачиваний
Когда делали машинку, мы использовали аппаратный ШИМ, который работает от кварца и не зависит от работы процессора МК.
В МК ATmega8 есть два специальных вывода для этих целей:
выводы 15 и 16 - для двух китайских серв.
вывод 17 - для двигателя.
В этом случае гаратнируются импульсы практически идеальной длительности и стабильная работа сервы. Вот)) :tea:
4.JPG
(213.19 КБ) 493 скачивания
Сейчас к выводам 15, 16, 17 подключен радиомодуль, который можно перекинуть (т.е. подключить к любым другим свободным выводам МК).
Радиомодуль менее требовательный к импульсам))) Может работать и на программном SPI. Только скорость передачи в ~10 раз меньше, но это не критично))

Проблема в том, что тогда к ATmega8 можно подключить только две сервы... жаль... :(

Какие есть варианты? Целая куча...)))

1- поставить ATmega8 - две штуки )) Расточительно))
2- взять другой МК, у которого много ШИМ выводов. Дорого и ... всё переделывать под другую платформу...
3- оптимизировать программу и добиться работы сервы близкой к идеальному... (до идеала ещё не пробовали).
4- другие варианты...)))

датчик температуры цифровой с шиной 1-Wire. С таким ещё не работали, но думаю разобраться можно))

Остальное ..мелочи))
:roll:
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
botchin
Поставщик валерьянки для Кота
Сообщения: 2029
Зарегистрирован: Чт дек 27, 2012 20:46:09
Откуда: Болгария, г. Лом

Re: Радиоуправлениe на модулях nRF24L01+

Сообщение botchin »

roman.com писал(а): к ATmega8 можно подключить только две сервы... жаль... Какие есть варианты? Целая куча...)))
Я на одном аппаратном модуле ССР (Capture/Compare/PWM) делаю 6 въхода PPM. Так что - возможно. Код (C) вълагал здесь - правда на PIC-e.
Лом - ето город в Болгарии, а не инструмент юстировки електроники.
Реклама
Аватара пользователя
sashamelja
Говорящий с текстолитом
Сообщения: 1565
Зарегистрирован: Пт янв 20, 2012 16:25:02

Re: Радиоуправлениe на модулях nRF24L01+

Сообщение sashamelja »

Когда делали машинку, мы использовали аппаратный ШИМ, который работает от кварца и не зависит от работы процессора МК.
В МК ATmega8 есть два специальных вывода для этих целей:
выводы 15 и 16 - для двух китайских серв.
вывод 17 - для двигателя.
В этом случае гаратнируются импульсы практически идеальной длительности и стабильная работа сервы. Вот))
Не подходит усложняет конструкцыю катера,нада одна серва чтоби при включению занимала нулевое положение,на передатчике будем использовать джойсік от ардуино там резистор на 10К,дрожание не критично,главное чтоби связь не терялась а управление мотором такое как в Маsika
1- поставить ATmega8 - две штуки )) Расточительно))
2- взять другой МК, у которого много ШИМ выводов. Дорого и ... всё переделывать под другую платформу...
3- оптимизировать программу и добиться работы сервы близкой к идеальному... (до идеала ещё не пробовали).
4- другие варианты...)))
я за третий вариант,если ти согласен написать програму я все соберу и протестирую на практеке у меня все есть в наличие
Что ненужно виброси что надо добавь,что хочеш поменяй
Вот начем я буду тестить https://www.youtube.com/watch?v=WeZfOw78zCw
Вложения
2.7z
(70.43 КБ) 250 скачиваний
И опыт сын ошибок трудных и гений парадоксов друг
Реклама
roman.com
Друг Кота
Сообщения: 9157
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Re: Радиоуправлениe на модулях nRF24L01+

Сообщение roman.com »

botchin писал(а):Я на одном аппаратном модуле ССР (Capture/Compare/PWM) делаю 6 въхода PPM. Так что - возможно. Код (C) вълагал здесь - правда на PIC-e.
Такие комментарии нам очень помогают... ))) :))) опять... ни схемы, ни алгоритма, ни описания...

Мы можем подключить к одному МК и 20 серв... вопрос какой ценой ))
sashamelja писал(а):нада одна серва
Не понял... ты насхеме нарисовал 4 сервы... теперь одна? Ты определись... от этого зависит схема ипрограмма...
sashamelja писал(а):дрожание не критично,главное чтоби связь не терялась а управление мотором такое как в Маsika
Дрожание критично. Может перегреваться серва и самое с главное - повышенный разряд аккумулятора... Оно тебе надо? ))

3- оптимизировать программу и добиться работы сервы близкой к идеальному... (до идеала ещё не пробовали).
4- другие варианты...)))
sashamelja писал(а):я за третий вариант,если ти согласен написать програму я все соберу и протестирую на практеке у меня все есть в наличие
Третий вариант - это для 4 сервы (и больше)... программный ШИМ. Для одной сервы - идеально аппаратный ШИМ.
sashamelja писал(а):Что ненужно виброси что надо добавь,что хочеш поменяй
Так ты определись что ты хочешь... А то я сейчас всё повыкидываю... Потом тебе не понравится)) :)))
sashamelja писал(а):Вот начем я буду тестить https://www.youtube.com/watch?v=WeZfOw78zCw
Твой катер? Для начала нормальненько))

Тебе нужна нормальная, стабильная схема или "китайская" поделка)) ? Можно накидать всё "на скорую руку" б тогда всё будет работать чёрти как... Если делать по нормальному то надо все детальки собрать в кучку (что у нас есть), нарисовать нормальную схемку, затем написать к этой схемке программку))

Сейчас упёрлись в серву. Если одна серва - то лучше сделать по одной схеме. Если много серв, то лучше по другой схеме.
После того как соберём схемку, что-то менять будет сложно.. Поэтому надо сразу задавать все параметры (на стадии разработки), а потом рисовать и делать...

разрабатывать схемы и писать программы - это не пять минут работы)) Наберись терпения)) Щас подумаем... :tea:
Аватара пользователя
botchin
Поставщик валерьянки для Кота
Сообщения: 2029
Зарегистрирован: Чт дек 27, 2012 20:46:09
Откуда: Болгария, г. Лом

Re: Радиоуправлениe на модулях nRF24L01+

Сообщение botchin »

roman.com писал(а):Такие комментарии нам очень помогают... ))) опять... ни схемы, ни алгоритма, ни описания...
Как всегда!!!!? :kill:
На предъдущей странице есть файл Algol.png. Ссълку на файл дать, в ЛС отправить, опять загрузить или тъ сам найдеш. Все тебе не так .....

Да и сама идея настолько простая, что мне стъдно обсуждать ее.
Спойлер

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

#include	<pic.h>

__CONFIG(
 FCMEN_OFF	&		// Монитор генератора бесперебойной работы - отключен
 IESO_OFF	&		// Функция переключателя Internal/External генератор - отключена
					// Internal/External Switchover mode is disabled
 CLKOUTEN_OFF	&	// Фунцйия CLKOUT выхода тактовой частоты на вывод генератора - отключена
				// CLKOUT function is enabled. I/O or oscillator function on the CLKOUT pin
 BOREN_OFF	&		// Сброс по понижению питания отключен
					// Brown-out Reset disabled
 CPD_OFF	&		// Защитата на паметта (EPPROM) - изключена
 CP_OFF		&		// Защитата на програмата - изключена
 MCLRE_OFF	&		// вывод MCLR/VPP функция RA3
 PWRTE_ON	&		// Таймер задержки включения питания
					// PWRT disabled
 WDTE_OFF 	&			// Сторожевой таймер включен в рабочем режиме, выключен в режиме сна
					// WDT изключен
 FOSC_INTOSC  		// внутрений генератор, выводы генератора используются как порты ввода вывода
					//вътрешен ген. Изводите като вх/изх
 );		
					// Fail-Safe Clock Monitor is disabled
 
__CONFIG(
 LVP_OFF		&		// Низковольтное программирование отключено
 BORV_25 	&		// Уровень сброса по понижению питания установлен на 2.5V
 STVREN_OFF & 		// сброс по переполнению стека отключен 
 PLLEN_OFF 	&		// Внутренний умножитель 4x PLL - изключен
 WRT_ALL  			// Память программ - защищена от записи
);	

//_XTAL_FREQ=16000000;  //for __delay_ms();

// Register: CCPR1 -----  must be in pic16f1829.h
volatile unsigned int           CCPR1              @ 0x291;

// Register: CCPR2 -----  must be in pic16f1829.h
volatile unsigned int           CCPR2              @ 0x298;


#define test_

#define MASK_SI	0x58		//маска налагана върху входния сигнал за определяне дали е СИ
#define MASK_23	0xF0		//маска налагана на аналоговите данни за отхвърляне на големите разлики
		//с 0xF0 две стойности с разлика до 16 ще се приемат за равни - 16uS

//unsigned char Mode;
struct {
	volatile unsigned char _SiLoad:1;	//получен е СИ
	unsigned char _PWM4_On_PPM:1;	//
	unsigned char _PWM5_On_PPM:1;	//
	volatile unsigned char _start_2of3:1;	//
	volatile unsigned char _valid_data:2;	//брой сгрешени СИ
	volatile unsigned char free:2;	//
} Mode;

#define SiLoad 	(Mode._SiLoad)
#define ready_in 	(Mode._ready_in)
#define PWM4_On_PPM (Mode._PWM4_On_PPM)		//какво да се извежда PPM или PWM
#define PWM5_On_PPM (Mode._PWM5_On_PPM)
#define St2of3	(Mode._start_2of3)
#define ValidData	(Mode._valid_data)

typedef struct {
	unsigned char a[6];		//6 аналогови (0 - 255) команди. 
	unsigned char d:6;		//+ 6 дискретни (цифрови)
	unsigned char rx:1;		//дали пакета е получен. Използва се за установяване на St2of3
	unsigned char err:1;		//дали пакета е маркиран като грешен
} _buff_in;

_buff_in Buff2Of3[4] @0x20; //масив от последните две приети стойности за логика 2от3
_buff_in 	*ToOut,		// след 2of3 тук ще се укажат от къде ще се извеждат данните
		*BuffIn;		//указател къде ще се въвежда инфо от CCP1
_buff_in    *buffarr[] = {&Buff2Of3[0],&Buff2Of3[1],&Buff2Of3[2],&Buff2Of3[3]};
volatile unsigned char  BuffWork;  //

volatile unsigned char cnt @0x70; //брояч за приетите 
volatile unsigned char iNextPPM @0x71;	//номер на текущо стартираната PPM машинка
volatile unsigned char cNextPPM @0x72;	//маска на текущо стартираната PPM машинка
unsigned char Tmp;

unsigned int iTmp;
// //////////////////////////////////////////////////////////////////////
unsigned char rrrr;   //използва се в ASM за прехвърляне на буферите
unsigned int rrrrr; //хептем временна променлива за тест
//unsigned char eecnt; //тестови брояч за записа в EEPROM
//unsigned char ee_old;


 //unsigned int  _buff_TMR1[14] @0xA0; // буфер за стойностите от CCPR1H:CCPR1L при захват

unsigned int TI  ;   		//изчислена ширина на импулса
unsigned int PrevCCP;	//предишно сработване на CCP1 - за изчисляванена TI 
unsigned char dMask;	//маска за дискретните команди при приемане - бягаща единица
unsigned char CheckSt2of3(void);
void toDOut(void);

//void TestStart(unsigned int);

unsigned char asm_1;		// използват се 
unsigned char asm_2;		// в
unsigned char asm_3;		// асемблерните модули
unsigned char asm_1i;	// използват се в асемблерните модули
unsigned char asm_2i;	// interrupt
// //////////////////////
unsigned char eecnt;
//unsigned char __tmp;
//unsigned int  rcrc;
// //////////////////////
//_buff_in *BuffNext(_buff_in *);     //връща следващия буфер където ще се записва
_buff_in *BuffNext(void);     //връща следващия буфер където ще се записва
_buff_in *NextOut23(void);     //връща следващия буфер от където ще се извежда
unsigned char check23(unsigned char ,unsigned char );

void Init(void)
{
	OSCCON = 0b01111010;		//16MHz 

	CM1CON0 = 0;	//изключване на компаратор 1
	CM2CON0 = 0;	//изключване на компаратор 2
	LATA=LATB=LATC = 0;
	TRISA = 0xCB; /*	0 - вход за управление на RC6, 1 - аналог вход - цифров изход
					2 - изход PPM/PWM  (PWM3), 3 - вход за управление на RA2
					4,5 кварц, 6 и 7 - не са реализирини в желязото */
	TRISB = 0x0f;	 /* 4 изхода за PPM команди (4,5,6,7),  0,1,2,3 - не са реализирини в желязото*/
#ifdef test
	TRISC = 0x00; /* Изходи за дискретни команди- (0,1,2,3,4,7), изход PPM/PWM - (6) Вход - (5)*/
#else
	TRISC = 0x20; /* Изходи за дискретни команди- (0,1,2,3,4,7), изход PPM/PWM - (6) Вход - (5)*/
#endif
	ANSELB = 0x00;	//no analog input
	ANSELC = 0x00;	//no analog input

	nWPUEN  = 0;		//GLOBAL enable WPU
	WPUB = 0x00;		//pull up 
	WPUC = 0x00;	//pull up 

/*	
	ANSELA = 0x02;	//RA1 as analog input
	ADCON1 = 0b00010000;	//ляво подравнено, Fosc/8, Vref = Vdd
	ADCON0 = 0b00001001;	//ADC chanel 1, ADC ON
// ???? pull_up

	ADGO = 1;
	while (ADGO)NOP();	//вземаме инфо от AN1 (RA1)
// ще анализираме ADC_RA1 за да определим как ще се управлява PWM1/2
	ADC_RA1	=	ADRESH;
*/
	ADCON0 = 0;		//ADC OFF
	TRISA = 0xC9; 	// RA1 става цифров изход
	ANSELA = 0x00;	// RA1 as digital out
	WPUA = 0x09;	//pull up  RA0, RA3
//TMR0 - предделител 64, Fosc/4 - 4.096mS
	OPTION_REG	= 0b00000101;
// 16MHz	 --------------TMR1------------------------
	T1CON = 0b00100000;	// Fosc/4, прескалер 4
// 4MHz	PR2 = 118;
// ще стартираме следващата PPM машинка през интервал от 3,3mS	
// 4MHz	T2CON = 0x31;	//postscaler 7; prevscaler 4 -> 4*7*(118+1)mS  = 3.3mS
// 16MHz	  -----------------TMR2-------------------
	PR2 = 51;
	T2CON = 0x7a;	//postscaler 16; prevscaler 16 -> 16*16*(51 + 1)/Fosc*4  = 3.3mS

	iNextPPM = 0;
	cNextPPM = 0x01;	//ще се стартира първата машинка
////////////

// как да се обработват PPM4/PWM0 и PPM5/PWM1
	if (RA3)
		PWM4_On_PPM=1;
	else
		PWM4_On_PPM=0;
//	PWM4_On_PPM = RA3;	//ако е 1 - PPM, ако е 0 - PWM
	if (RA0)
		PWM5_On_PPM=1;
	else
		PWM5_On_PPM=0;
//	PWM5_On_PPM = RA0;	//ако е 1 - PPM, ако е 0 - PWM
// PWM4_On_PPM = 1;	//ако е 1 - PPM, ако е 0 - PWM
// PWM5_On_PPM = 1;	//ако е 1 - PPM, ако е 0 - PWM

rrrrr=0;
eecnt = 0;
ValidData = 0;		//нямаме сгрешени СИ
BuffWork = 3;
BuffIn = BuffNext();
// BuffIn = &Buff2Of3[3];
BuffIn ->d = 0;
BuffIn ->rx = 0;
Buff2Of3[0].rx=Buff2Of3[1].rx=Buff2Of3[2].rx= 0;

//засега мажоритарната логика няма да работи. След проемането на третия пакет се включва
	St2of3 = 0;
	PEIE =1;
	CCP1IE = 1;		//разрешаваме прекъсване при получаване на импулс на входа
	TMR0IE	= 1;		//разрешаваме прекъсване при загуба на сигнала
	CCP1CON = 0x04;
	ei ();
	cnt = 0;
	TMR1ON = 1;
	TMR1GE = 0;  //старт TMR1
// test start

}

void interrupt bbb(void)
{
	if (CCP1IF && CCP1IE)
	{
		TMR0 = 0;		//допълнителна задръжка за удължаване на (евентуално) пропускания импулс (шум)
		NOP();		//		
		NOP();		//	
		NOP();		//	
		NOP();		//   1uS	
		NOP();		//	
		NOP();		//	
		NOP();		//	
		NOP();		//  1uS	
		NOP();		//	
		NOP();		//	
		NOP();		//	
		NOP();		//   1uS	
		Tmp = PORTC;	//вземаме текущата стойност на PORTC
		asm("swapf _Tmp,f");  
		asm("rrf _Tmp,f");  // в младшия бит стойността на RC5
		Tmp &= 0x01;
		CCP1IF=0;
		if (Tmp == (CCP1CON & 0x01))
		{ // входа е с валидна стойност - не е шум
			CCP1CON ^=1; //сменяме фронта на захвата

//			_buff_TMR1[cnt] = CCPR1-PrevCCP;
			TI = CCPR1-PrevCCP;
			if(!SiLoad || cnt == 13)
			{	//не сме приели SI или сме приели и чакаме втори SI
				Tmp = TI  >> 4;
				Tmp =  Tmp & 0x00f8 ; //Привеждане на приетото в един байт 0x05C0 => 0x5C
/*237:               				if ((Tmp ^ MASK_SI) == 0 )	//Приели сме СИ
  0039    0840     MOVF 0x40, W
  003A    3A58     XORLW 0x58
  003B    1D03     BTFSS 0x3, 0x2
  003C    283F     GOTO 0x3f
*/
				if (Tmp ^ MASK_SI )
				{		//Не сме приели СИ
					if(cnt == 13)
						ValidData ++;
					cnt = 0;
					SiLoad = 0;
				}
				else
				{	//Приели сме СИ
					SiLoad = 1;
					if (cnt == 13)
					{	//SI след вече приет SI => приели сме пакет
						ValidData = 0;	;//нямаме сгрешен СИ
						cnt = 1; 	// после ще има cnt++;
						BuffIn->rx = 1;	//маркираме буфера като приет
						BuffIn->d ^= 0x3f;	//инвертираме дискретните. 1 при натиснат бутон
						BuffIn = BuffNext();
						BuffIn->rx = 0;	//веднага си маркираме буфера като невалиден
						BuffIn->d = 0;		//и изчистваме дискретните команди
						St2of3 = CheckSt2of3();  //установяваме St2of3 ako са приети 3 пакета
						if (St2of3)	//приети са три пакета
						{
							ToOut = NextOut23();		//засега
							if (ToOut)  // Имаме валидни данни (минали 2of3)
						// какво да правим ако нямаме . Как да спреме PPM?????
							{
								TMR2IE= 1;
								CCP2IE = 1;
								TMR2ON = 1; //и пускаме PPM-а и PWM-a
								ValidData = 0; //нямаме сгрешени СИ
							}
							else		//нямаме валидна информация
							{
	//							TMR2IE= 0;
	//							CCP2IE = 0;
								if (ValidData ==2)
									TMR2ON = 0; //и спираме PPM-а и PWM-a
							}
						}	
					}
					cnt = 1;	 // ще следва аналогова
				}
				dMask = 0x01;  //маска за дискретните команди
			}	
			else
			{   //имаме SI и се намираме някъде в "приемане на пакет"
				if (cnt & 0x01)  	//нечетно - аналогов 
				{
//						BuffIn->a[cnt /2] = (TI <  0x200)?0x00:(TI > 0x3ff)?0xFF:(TI-0x200)/2;
					TI -= 0x200;
					TI >>= 1;
					if(TI >= 0x0100)
						asm_1i	= 0xff;
					else if (TI & 0x8000)
						asm_1i	= 0x00;
					else	
					{
						asm("movf  _TI,w");
						asm("movwf  _asm_1i");
					}
					BuffIn->a[cnt /2] = asm_1i;
/*
//						BuffIn->a[cnt /2] = (TI <  0x200)?0x00:(TI > 0x3ff)?0xFF:(TI-0x200)/2;
					#asm
					movlb 	0
					decfsz	_TI+1,f		// _TI - 0x100	
					goto	analog_cont		//< 0x1ff
					movlw	0
					goto 	end_aa
analog_cont	 		movlw	0xff
					decf	_TI+1,f
					decfsz	_TI+1,f		//TI - 0x100
					goto 	end_aa		// > 0x3ff
					incf		_TI+1,f
					lsrf		_TI+1,f
					rrf		_TI,w		//TI  / 2
end_aa				movwf	_asm_1i

					#endasm
					BuffIn->a[cnt /2] = asm_1i;
*/
				}
				else				//дискретни команди
				{
//						BuffIn->d |=  ((_buff_TMR1[cnt] /512 ) & 0x01) << cnt /2 -1;
					#asm
					movlb 	0
					lsrf		_TI+1,f	//старшата част /2
					movf 	_dMask,w
					btfss		_TI+1,0	//имаме ли 1
					movlw 	0
					movwf	_asm_1i
					lslf		_dMask,f
					#endasm
					BuffIn->d |= asm_1i;
/*
					#asm
					movlb 	0
					lsrf		_TI+1,w	//старшата част /2
					andlw	0x01			// в W:0 дискретната команда	
				btfss		WREG,Z
					movwf	_asm_1i		//същото в _asm_1
					lsrf		_cnt,w
					movwf	_asm_2i		// колко пъти трябва да го умножим
loop_ss			
					lslf		_asm_1i,f
					decfsz	_asm_2i,f
					goto		loop_ss
					lsrf		_asm_1i,f	//едно назад
					#endasm
					BuffIn->d |= asm_1i;	//предварително да е нулирано
*/
				}
				cnt++;					
			}
/*
//			Tmp &= 0xF8;	//маскираме младшите три бита
			if ((Tmp ^ MASK_SI) == 0 && cnt == 0)	//Приели сме СИ
{
				SiLoad = 1;
//if (_buff_TMR1[cnt] > 0x05c0)	//приели сме по-широк СИ
//	OSCTUNE--;
//if (_buff_TMR1[cnt] < 0x05c0)	//приели сме по-тесен СИ
//	OSCTUNE++;
}

			if (SiLoad) 	//ако сме получили валиден СИ
			{
				if((cnt > 0) && (cnt < 0x0d))
					if (cnt & 0x01)  	//нечетно - аналогов 
					{
//						BuffIn->a[cnt /2] = min((_buff_TMR1[cnt] - 0x200) /2,0xff);
						#asm
						movlb 	0
						movlw	__buff_TMR1
						movwf	fsr0l
						clrf		fsr0h
						lslf		_cnt,w	//cnt*2
						addwf	fsr0l,f
						incf		fsr0l,f	//на старшата част на аналогова
						decf 	indf0,f
						decf 	indf0,f		//-0x200
						lsrf		indf0,f
						decf		fsr0l,f						
						rrf		indf0,f	//аналоговата команда  /2
						moviw 	++fsr0	//на старшата част
						btfss 	status,2		//zero
						movlw	0xff
						decf 	fsr0l,f
						iorwf 	indf0,w	//аналоговата команда
						movwf	_asm_1i
						#endasm
						BuffIn->a[cnt /2] = asm_1i;
					}
					else				//дискретни команди
					{
//						BuffIn->d |=  ((_buff_TMR1[cnt] /512 ) & 0x01) << cnt /2 -1;
						#asm
						movlb 	0
						movlw	__buff_TMR1
						movwf	fsr0l
						clrf		fsr0h
						lslf		_cnt,w
						addwf	fsr0l,f
						incf		fsr0l,f
						lsrf		indf0,w
						andlw	0x01			// в W:0 дискретната команда	
						movwf	_asm_1i		//същото в _asm_1
						lsrf		_cnt,w
						movwf	_asm_2i		// колко пъти трябва да го умножим
loop_ss			
						lslf		_asm_1i,f
						decfsz	_asm_2i,f
						goto	loop_ss
						lsrf		_asm_1i,f	//едно назад
//						movlw	0x3f
//						xorwf	_asm_1i,f		//инвертираме
						#endasm
						BuffIn->d |= asm_1i;	//предварително да е нулирано
					}
				cnt++;
			}
			if(cnt == 14)	//време е пак да получим СИ
				if(Tmp & MASK_SI ) 
				{ 	//получили сме СИ
					BuffIn->rx = 1;	//маркираме буфера като приет
					BuffIn->d ^= 0x3f;	//инвертираме дискретните. 1 при натиснат бутон
					BuffIn = BuffNext(BuffIn);
					BuffIn->rx = 0;	//веднага си маркираме буфера като невалиден
					BuffIn->d = 0;		//и изчистваме дискретните команди
					St2of3 = CheckSt2of3();  //установяваме St2of3 ako са приети 3 пакета
					if (St2of3)	//приети са три пакета
					{
						ToOut = NextOut23(BuffIn);		//засега
						// указателя към валидната инфо е в ToOut
						if (ToOut)  // Имаме валидни данни (минали 2of3)
					// какво да правим ако нямаме . Как да спреме PPM?????
						{
							TMR2IE= 1;
							CCP2IE = 1;
							TMR2ON = 1; //и пускаме PPM-а и PWM-a
							ValidData = 0; //нямаме сгрешени СИ
						}
						else		//нямаме валидна информация
						{
//							TMR2IE= 0;
//							CCP2IE = 0;
							if (ValidData ==2)
								TMR2ON = 0; //и спираме PPM-а и PWM-a
						}
						
					}
					cnt = 1;		// следващия ще е 1-ви аналогов
//					ready_in = 1;	//заявка за прехвърляне на информацията
				}
				else		//СИ не се е оказал на място
				{
					cnt = 0;		//започваме от търсене на СИ
					SiLoad = 0;	//
					ValidData++;  //увеличаваме брояча на сгрешените СИ
//					ready_in = 0;	//
					if (ValidData ==3)
					{
						ToOut = 0;
						TMR2ON = 0; //и спираме PPM-а и PWM-a
					}
				}	
*/
			PrevCCP = CCPR1;
//			if (CCP1IF) cnt = 0;	//???????????????
		}
	}				

	if (CCP2IE && CCP2IF)
//ако е свършила работата на машинката стоп
	{
		CCP2IF = 0;
		CCP2CON =0;	
		PORTB = 0;	//спиране на всички машинки на PORTB
		if (PWM4_On_PPM)RC6=0;
		if (PWM5_On_PPM)RA2=0;
		if(iNextPPM & 0x01)
			toDOut();		//извеждаме дискретните
	}
	if(TMR2IE && TMR2IF)
//прекъсване на всеки 3,3mS и запуск на следващата машинка. Спирането чрез CCP2
	{
		TMR2IF = 0;
		iTmp = TMR1 + 735;
//		iTmp = TMR1 + 1000;	//
// всички до 4 - се пускат; 4 и 5 се пускат само ако са PPM. 
//		if((iNextPPM<4) || (iNextPPM == 4 && PWM4_On_PPM) || (iNextPPM == 5 && PWM5_On_PPM))
//		{
			if(ToOut)		//имаме валидни данни за извеждане
			{	
				CCPR2 = iTmp;	//минималния сигнал 1mS после ще добавим и останалото
				CCP2CON = 0x0A;	//пускане на CCP2
				#asm
				movlb 	0
				swapf 	_cNextPPM,w
				movwf	_PORTB		//четирите младши бита отиват на RB7 - RB4
				#endasm
				if(PWM4_On_PPM && (iNextPPM ==4))RC6=1;
				if(PWM5_On_PPM && (iNextPPM ==5))RA2=1;

			//изчисляваме къде трябва да спре PPM-а.
		  		//end = in*4 + in*2 + in/4 + TMR1
			//би трябвало обхвата на PPM да е от .7 до 2.3mS
//				iTmp = ToOut->a[iNextPPM] *6 +ToOut->a[iNextPPM] /4;
//				iTmp = ToOut->a[iNextPPM] *6;
//				iTmp = ToOut->a[iNextPPM] *5;	
//				iTmp = ToOut->a[iNextPPM] *4;	//1.0 mS +    ???

//				if (RC0)
//					CCPR2 += 6*0+ 0/4;
//				else if (RC1) 
//					CCPR2 += 6*128+ 128/4;
//				else if (RC2) 
//					CCPR2 += 6*255+ 252/4;
//				else
				iTmp =ToOut->a[iNextPPM] *6; 		// + ToOut->a[iNextPPM] /4;
				CCPR2 += iTmp;
		}	
//		}
		iNextPPM++;
		cNextPPM <<= 1;
//		if (NextPPM == 4 && PWM4_On_PPM==0) NextPPM++;	//ако обработката на PPM4 ще е на PWM0
//		if (NextPPM == 5 && PWM5_On_PPM==0) NextPPM++;	//ако обработката на PPM5 ще е на PWM1
		if(iNextPPM > 5) {iNextPPM = 0;cNextPPM = 0x01;}
//NextPPM=0;
	}
	if(TMR0IE && TMR0IF)
	{	//TMR0 е настроен да сработва на всеки 2mS. 
	//Ако сработи значи за това време не е постъпвал входен сигнал.
	//най вероятна причина - загуба на сигнала
		TMR0IF = 0;
//		ToOut = 0;
//аналоговите (PPM) ще спрат всяка по свое време
//аналоговите (PWM)	????
		toDOut();		//нулираме дискретните
	}
}

//връща следващия буфер който ще се използва за въвеждане от CCP
//_buff_in *BuffNext(_buff_in *ex)
_buff_in *BuffNext(void)
{
	BuffWork ++;
	BuffWork &= 0x03;
	return (buffarr[BuffWork]);
/*
	if(ex == &Buff2Of3[3])
		return(&Buff2Of3[0]);
	else
		return(ex+1);
*/
}

unsigned char CheckSt2of3(void)
//проверяваме дали и трите пакета в Buff2Of3 са приети. 
//Ако да - вдигаме си флага St2Of3 с което разрешаваме работата на мажоритарната логика
{
//	unsigned char ret;
	asm_2 = sizeof(_buff_in);
//	asm_1 = Buff2Of3[0].rx + Buff2Of3[1].rx + Buff2Of3[2].rx + Buff2Of3[3].rx;
	#asm
	movlw	_Buff2Of3
	addlw	6	//отстъп до .rx
	movwf	fsr0l		// в fsr0 (indf0) Buff2Of3
	movlw	_asm_1
	movwf	fsr1l		// в fsr1 (indf1) asm_1
	clrf		indf1,f	//
	btfsc		indf0,6
	incf		indf1,f	//if (Buff2Of3[0].rx == 1) asm_1++;
	movf	_asm_2,w		//sizeof(_buff_in)
	addwf	fsr0l,f
	btfsc		indf0,6
	incf		indf1,f	//if (Buff2Of3[1].rx == 1) asm_1++;
	movf	_asm_2,w		//sizeof(_buff_in)
	addwf	fsr0l,f
	btfsc		indf0,6
	incf		indf1,f	//if (Buff2Of3[2].rx == 1) asm_1++;
	movf	_asm_2,w		//sizeof(_buff_in)
	addwf	fsr0l,f
	btfsc		indf0,6
	incf		indf1,f	//if (Buff2Of3[3].rx == 1) asm_1++;
	movf	indf1,w
	movwf	_asm_1
	#endasm
	return (asm_1>2);
}

//извеждане на информацията на изходите на МК
void toDOut(void)
{
// дискретни
	if (ToOut)
 		rrrr = ToOut->d;
	else
		rrrr = 0;		//загуба на връзка, лоши пакети и др.
// задачата е да преместим бит 5 на позиция 7 - 0b001xxxxx  да стане 0b100xxxxx
	#asm
	movlb	0
	movlw 	0x80
	btfss 	_rrrr,5
	movlw 	0x00
	iorwf	_rrrr,f
	movlw 	0xdf;
	andwf	_rrrr,w
	movwf	_PORTC ,f
	#endasm
//PPM се извежда в прекъсването TMR2 CCP2
	return;
}

//връща 0 - при неравенство на структурите и 1 - при равенство
//за равни се приемат структури с равенство на дискретните части и
//равенство на старшите части на аналоговата част.
//Аналоговата част се "маскира" с маска MASK_23
//Чрез нея стойностите 0x57 и 0x5a ще са равни
//(0x57 & 0xf0) ^ (0x5a & 0xf0)  = 0x00
//допустимата разлика е до 16 uS  +/- 8uS
unsigned char check23(unsigned char s1,unsigned char s2)
{   	// 137 машинни инструкции  ASM
	// 215 машинни инструкции  C
//	asm_1 = (unsigned char)&(Buff2Of3[s1].a[0]);
//	asm_2 = (unsigned char)&(Buff2Of3[s2].a[0]);
	asm_1 = (unsigned char)(buffarr[s1]->a[0]);
	asm_2 = (unsigned char)(buffarr[s2]->a[0]);
	asm_3 = MASK_23;
	#asm
		movf		_asm_1,w
		movwf	fsr0l		//*n
		clrf		fsr0h
		movf		_asm_2,w
		movwf	fsr1l		//*n
		clrf		fsr1h
		movlw	6
		addwf	fsr0l
		addwf	fsr1l		//на ->d - дискретните
//	i = (*(n+6) & 0x3f) ^ (*(v+6) & 0x3f);	//цифровата част - десните 6 бита
		movf		indf0,w
		andlw	0x3f
		movwf	_asm_1	// (n+6) & 0x3f
		movf		indf1,w
		andlw	0x3f		// W = (v+6) & 0x3f 
		xorwf		_asm_1,f	// (n+6) & 0x3f ^  (v+6) & 0x3f 

		btfss		status,2	//zero ?
		goto		check23_exit
//дискретните са равни => продължаваме
//	for(a1=0;asm_1==0 && a1<6;a1++)
		movlw	6
		subwf	fsr0l
		subwf	fsr1l		//връщаме се в началото на масивите
		movwf	_asm_2   //ще въртиме за 6 променливи		
//	asm_1 = (*n++ & MASK_23) ^  (*v++ & MASK_23);
check23_loop
		moviw	fsr0++
		andwf	_asm_3,w	//MASK_23
		movwf	_asm_1	// (n+x) & 0xf0
		moviw	fsr1++
		andwf	_asm_3,w	//MASK_23
		xorwf		_asm_1,f	// (n+6) & 0x3f ^  (v+6) & 0x3f 
		btfss		status,2	//zero ?
		goto		check23_exit
		decfsz	_asm_2
		goto		check23_loop		
check23_exit
	#endasm
	return(!asm_1);
/*
// горното на С
	unsigned char a1,*n,*v;
	unsigned char	i;
	n = &(Buff2Of3[s1].a[0]);
	v = &(Buff2Of3[s2].a[0]);
	i = (*(n+6) & 0x3f) ^ (*(v+6) & 0x3f);	//цифровата част - десните 6 бита
	for(a1=0;i==0 && a1<6;a1++)
		i += (*n++ & MASK_23) ^  (*v++ & MASK_23);
	return(!i);
*/
}

//връща указател към структура от където ще се извежда информацията
//изключва се ex структурата - обикновенно там се въвежда инфо от CCP
//останалите структури се подлагат на мажоритарно решение от къде ще се извежда инфото
_buff_in *NextOut23()
{	//231 машинни цикъла
	unsigned char a1,a2;
	for(a1=0;a1<3;a1++)
	{

		if(BuffWork == a1)
			continue;
		for(a2=a1+1;a2<4;a2++)
		{
			if( BuffWork == a2)
				continue;
			if(check23(a1,a2))
				return(buffarr[a2]);
		}
	}
	return(0);		//да се проверява при използване
/*
	for(a1=0;a1<3;a1++)
	{
		if(ex == buffarr[a1])
			continue;
		for(a2=a1+1;a2<4;a2++)
		{
			if(ex == buffarr[a2])
				continue;
			if(check23(a1,a2))
				return(buffarr[a2]);
		}
	}
	return(0);		//да се проверява при използване
*/
}

void TestStart(unsigned int delay)
{
	#ifdef test
		TMR1 = delay + CCPR1;
		RC5 = !((CCP1CON ^ 0x01) & 0x01);	//педизвиква CCP1IF	=1;
	#else
		asm("nop");
	#endif
	return;
}


void main(void)
{
// Register: CCPR1 -----  must be in pic16f1829.h
// volatile unsigned int           CCPR1              @ 0x291;

	#asm
	movlb	0		//bank 0
	movlw high (_CCPR1)	// in bank 5
	movwf		fsr0h
	movlw  low(_CCPR1)		// in bank 5
	movwf		fsr0l
	moviw		fsr0++
// store  	movwi 	fsr1++	// must be set
//store	movwf	____
	moviw		fsr0++
// store	movwi 	fsr1++
	#endasm

	Init();
// test(); //external .as file
/*
Buff2Of3[0].a[0] = 0xef;
Buff2Of3[0].a[1] = 0xee;
Buff2Of3[0].a[2] = 0xed;
Buff2Of3[0].a[3] = 0xec;
Buff2Of3[0].a[4] = 0xeb;
Buff2Of3[0].a[5] = 0xea;
Buff2Of3[0].d 	= 	0x39;	//d
Buff2Of3[0].rx =	1;		//rx
Buff2Of3[1].a[0] = 0xef;
Buff2Of3[1].a[1] = 0xee;	// normal
//Buff2Of3[1].a[1] = 0xe8;	//?? min err
//Buff2Of3[1].a[1] = 0xce;	//big err
Buff2Of3[1].a[2] = 0xed;
Buff2Of3[1].a[3] = 0xec;
Buff2Of3[1].a[4] = 0xeb;
Buff2Of3[1].a[5] = 0xea;
Buff2Of3[1].d 	= 	0x39;	//d
Buff2Of3[1].rx =	1;		//rx
Buff2Of3[2].a[0] = 0xef;
Buff2Of3[2].a[1] = 0xee;
//Buff2Of3[2].a[1] = 0xfe;	//big err
Buff2Of3[2].a[2] = 0xed;
Buff2Of3[2].a[3] = 0xec;
Buff2Of3[2].a[4] = 0xeb;
Buff2Of3[2].a[5] = 0xea;
Buff2Of3[2].d 	= 	0x39;	//d
Buff2Of3[2].rx =	1;		//rx
Buff2Of3[3].a[0] = 0xef;
Buff2Of3[3].a[1] = 0xee;
//Buff2Of3[3].a[1] = 0xfe;	//big err
Buff2Of3[3].a[2] = 0xed;
Buff2Of3[3].a[3] = 0xec;
Buff2Of3[3].a[4] = 0xeb;
Buff2Of3[3].a[5] = 0xea;
Buff2Of3[3].d 	= 	0x39;	//d
Buff2Of3[3].rx =	1;		//rx
*/
/*
//RC2=BuffNew->d & 0x04?1:0;
_buff_TMR1[1] = 0x0200;
_buff_TMR1[2] = 0x0300;	//d  1
_buff_TMR1[3] = 0x0200;
_buff_TMR1[4] = 0x0180;	//d   0
_buff_TMR1[5] = 0x0300;
_buff_TMR1[6] = 0x0180;	//d    0
_buff_TMR1[7] = 0x0280;
_buff_TMR1[8] = 0x0180;	//d   0
_buff_TMR1[9] = 0x02c0;
_buff_TMR1[10] = 0x0300;	//d    1
_buff_TMR1[11] = 0x0300;
_buff_TMR1[12] = 0x0300;	//d    1
//_buff_TMR1[1] >>=1;


/*
ToOut = &Buff2Of3[1];


Buff2Of3[0].d=Buff2Of3[1].d=Buff2Of3[2].d=0;
BuffIn = &Buff2Of3[3];

ToOut =NextOut23(BuffIn);
*/

#ifdef test
	RC5 =1;
	TMR1 = CCPR1 = 0;
	TestStart(0x0180);
	TestStart(0x05C0);		//SI
#endif

	do{
#ifdef test
		TestStart(0x02A1);		//A0		0x51
		TestStart(0x02D2);		//d0     1
		TestStart(0x03A3);		//A1		0xd2
		TestStart(0x02D4);		//d1     1
		TestStart(0x03A5);		//A2		0xd3
		TestStart(0x0300);		//d2     1
		TestStart(0x03A7);		//A3		0xd4
		TestStart(0x0188);		//d3     0
		TestStart(0x02A9);		//A4		0x55
		TestStart(0x018a);		//d4     0
		TestStart(0x03Ab);		//A5		0xd6
		TestStart(0x02fc);		//d5     1   = 0x27 => !0x27 = 0x18
		TestStart(0x05C0);		//SI
#endif
		NOP();
		NOP();
	}while(1);
}
А ето и сам код. Рабочии!. Все еще не законченнъй - да и вряд ли закончу. Там и описание есть.

Как ребенку должен писать, чтоб дошло до Вас. За ручку и повести там где надо. А прочитать, что пишут другие - не судьба.

Схему соединения заводской серво (PPM) тебе нарисовать или сам справишся?
Лом - ето город в Болгарии, а не инструмент юстировки електроники.
roman.com
Друг Кота
Сообщения: 9157
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Re: Радиоуправлениe на модулях nRF24L01+

Сообщение roman.com »

botchin писал(а):На предъдущей странице есть файл Algol.png. Да и сама идея настолько простая, что мне стъдно обсуждать ее.
Видали... дальше что? Ну если всё настролько просто, то взял бы и сделал ... Накидай по быстрому программку под мегу и данный модуль. Какие проблемы? )) Ты лучше ответь.. ты делать будешь или опять пришёл от нечего делать просто языком почесать?))
botchin писал(а):botchin читает и делать не будеть. Причин две:
1. Использование nRF24L01+ и
2. Использование Мега8
Ну тогда не понятно что мы тут вообще тогда обсуждаем... в теме "Радиоуправлениe на модулях nRF24L01+"...
Опять одни разговоры... бла-бла-бла... Короче как всегда))
sashamelja писал(а):я все соберу и протестирую на практеке у меня все есть в наличие
Вот тут чувак (кстате с этого сайта, радиокот) предложил свою идею)) Даже видео снял))
https://www.youtube.com/watch?v=gSVa0IuFyFw
Всё просто и ясно)) Только идеальных импульсов таким образом не получим... Да и можно сделать проще...
А вообще, если одна серва то чего париться... Есть аппаратный ШИМ)) Короче.. берём схему MASIK и переделываем.. ))
Аватара пользователя
botchin
Поставщик валерьянки для Кота
Сообщения: 2029
Зарегистрирован: Чт дек 27, 2012 20:46:09
Откуда: Болгария, г. Лом

Re: Радиоуправлениe на модулях nRF24L01+

Сообщение botchin »

roman.com писал(а):дальше что? Ну если всё настролько просто, то взял бы и сделал
Так сделай.
Вот тебе такой же алгоритм в реализации на ASM.
Спойлер

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

	 list      p=PIC16F873A
     #include  P16F873A.inc ;	; 16.000 MHz
	__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON& _HS_OSC  &_LVP_OFF &_CPD_OFF
	errorlevel -302
#define	sin_ok		Modes,0	;ако сме определили синхро импулс
#define	sin_fal		Modes,1	;ако е инало синхрониация и е пропаднала
#define  ready_in	Modes,2	;ако е минал цял цикъл приемане и
			; е запазена и синхронизацията => прехвърля buf_in в buf_r
 
#define stmacro_
st macro v
#ifdef 	stmacro
	CBLOCK	0x79
	mtot:2			;за 	stmacro
	endc

	movlw 	v & H'FF'        ;Mask to get LSB
	addwf	mtot+1,f
	btfsc	STATUS,C
	incf	mtot,f
	movlw   v >>D'08' & H'FF'
	addwf	mtot,f
 	call	delay_200iS
	movf	mtot,w
	movwf	TMR1H 
	movwf	CCPR1H
	movf  mtot+1,w
	movwf	TMR1L
	movwf	CCPR1L
	bsf	PIR1,CCP1IF
#else
	nop
	nop	
#endif
	endm
; --------------------------------------------------
	CBLOCK	0x7B
	W_TEMP		;storage for WREG during interrupt
	STATUS_TEMP		;storage for STATUS during interrupt
	PCLATH_TEMP		;storage for PCLATH during interrupt
	FSR_TEMP		;storage for FSR during interrupt
	Modes	
	endc		;0x7F

	CBLOCK 	0x20
	CCP1_Mode	;съхраняваме режима на работа на CCP1
	DigVal		;цифрови изходи
	buf_r:.30	;СИ + СП + 6  аналогови + 6 цифрови + СИ
 	CCP1_buf:.2	;буфер за съхранение на CCP1
	CCP1_prev:2	;буфер за съхранение на предишната стойнист на TMR1(CCP1)
	CCP1_Ti:2	;буфер за изчислената продължителност на импулса

	in_pass		;брояч на миналите приемания на информацията
	CCP1_Tmp	;временна променлива за работа в CCP1	
	
	buf_CCP2:12	;тук ще се съхранява информацията за стойностите за машинките
	Calc_CCP2:2	;изчисленото CCP2  - къде трябва да спре машинката
	CCP2_pass	;за цикъла за обработка на стойностите
	CCP2_tmp:2	;временна променлива
	dig_tmp		;временна промелива за цифровите сигнали
	pass_ix		;брояч за указване коя машинка пускаме
	PPM_ix		;указател за пуснатата машинка
	TMR1HH	;натрупване на сработването на препълването на TMR1
	eed		;променлива за работа с EEPROM

	d1	;ЗА ЗАКЪСНЕНИЕТО
	d2

 	endc

	org 0x0000
start 
	nop 
	goto main
	nop
	nop

	org 0x0004
	goto	interrupt


main 
	bsf	    	STATUS, RP0		;bank 1
	movlw   	b'00000111'
    	movwf   	CMCON        ; компараторите - изключени
	movlw		0x06
	movwf		ADCON1
	movlw		b'11000000'	;6 изхода за дискретни команди
	movwf		TRISA
	movlw		b'11000000'	;6 изхода за аналогови команди
	movwf		TRISB
	movlw		b'11111111'	;всички входове
	movwf		TRISC

	bsf		PIE1,CCP1IE	;enable interrupt CCP1
	bsf		PIE2,CCP2IE	;enable interrupt CCP2	
					;ще се пусне за първи път след приемане на пълен пакет данни
	bcf		PIE2,EEIE	;disable interrupt EEPROM
	bcf		PIE1,TMR1IE		;disable interrupt TMR1
	bsf		PIE1,TMR2IE		;enable interrupt TMR2
					;ще се пусне за първи път след приемане на пълен пакет данни
	movlw		.118
	movwf		PR2		; Fosc/(4*16*(118+1)*7) = 0.0033 S
	movlw		b'01000111'		; вкл притягащите резистори, 
	movwf		OPTION_REG		; TMR0 с предделител 256
	bcf	    	STATUS, RP0		;bank 0

	bcf		INTCON,TMR0IE	;disable interrupt TMR0
 	movlw   	b'00110001'
   	movwf   	T1CON        ; TMR1 - Fosc/4, prescale 8,TMR1 включено
	movlw   	b'00110010'
    	movwf   	T2CON        ; TMR2 - Fosc/4, prescale 16*(118+1)*7,TMR2 изключено
				;очаква се да предизвиква прекъсване на 3.3 mS
	clrf		ADCON0	;ADC изключено


	movlw   	b'00000100'	;
	movwf		CCP1_Mode	;запазваме си режима на работа на CCP1
    	clrf	   	CCP1CON        ;спираме CCP1
	clrf		CCP2CON	;спираме CCP2

	bsf		INTCON,PEIE	;enable interrupt's
	bsf		INTCON,GIE	;enable interrupt's

	clrf		PORTA
	clrf		PORTB
	clrf		TMR1HH
;  goto	end_test_start
test_start

 
end_test_start
	
	movlw		1
	movwf		PPM_ix		;подготвяме за пускане първата машинка
	bcf		sin_ok		;
	clrf		DigVal
	clrf		in_pass	
	clrf		Modes
	clrf		pass_ix

	movf		CCP1_Mode,w	;запазваме си режима на работа на CCP1
	movwf	   	CCP1CON        ; Capture mode, every rising
; clrf	TMR1L
; clrf	TMR1H
main_loop

 st	 0x0a03		;1
	nop
 st	 0x0b03		;1
	nop
 st	 0x0a03		;1
	nop
 st	 0xab03		;1
	nop

main_2loop
 st	 0x09c0		;2
 	nop
 st	 0x07c0		;3
	nop
 st	 0x0581		;4
	nop
 st	 0x0300		;5
	nop
 st	 0x0382		;6
	nop
 st	 0x0180		;7
	nop
 st	 0x0683		;8
	nop
 st	 0x0180		;9
	nop
 st	 0x0584		;10
	nop
 st	 0x0180		;11
	nop
 st	 0x0485		;12
	nop
 st	 0x0180		;13
	nop
 st	 0x06a6		;14
	nop
 st	 0x0300		;15
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	goto main_2loop


interrupt
	bcf		INTCON, PEIE		; turn off interupts
	movwf		W_TEMP
	swapf		STATUS,w
	movwf		STATUS_TEMP
	clrf		STATUS
	movf 		PCLATH,w	;save PCLath
	movwf 		PCLATH_TEMP	
	clrf 		PCLATH	;assume that this ISR is in page 0
	movf 		FSR,w
	movwf 		FSR_TEMP

interrupt_TMR1
	btfss		PIR1,TMR1IF
	goto		interrupt_CCP2
;	goto	interrupt_TMR2	; не е от TMR1
	bcf		PIR1,TMR1IF
	incf		TMR1HH,f
	btfsc		TMR1HH,2	;дали имаме 4 препълвания 0.13s*4 = 0.52s
	goto		Stop_PPM
	goto		interrupt_done
Stop_PPM
	bcf		T2CON,TMR2ON	;TMR2 OFF - с което си спиране и машинките	
	bcf		ready_in	;данните са невалидни
	goto		interrupt_done

interrupt_CCP2
	btfss		PIR2,CCP2IF
	goto		interrupt_TMR2
	bcf		PIR2,CCP2IF
	clrf		PORTB		;свършило е времето за работа на машинката	
	clrf		CCP2CON	;и спираме CCP2
;	incf	eed,f
	goto		interrupt_done


interrupt_TMR2
	btfss		PIR1,TMR2IF
	goto		interrupt_CCP1	; не е от TMR2
	bcf		PIR1,TMR2IF
	
;	btfss		T2CON,TMR2ON	;имаме ли разрешение за работа на машинките
;	goto		interrupt_done
	
	movlw		buf_CCP2+1
	movwf		FSR
	bcf		STATUS,C
	rlf		pass_ix,w
	addwf		FSR,f
	incf		FSR,f
	movf		INDF,w
	addwf		TMR1L,w
	movwf		CCPR2L
	decf		FSR,f
	movf		INDF,w
	btfsc		STATUS,C
	incf		INDF,w
	addwf		TMR1H,w
	movwf		CCPR2H
	clrf		CCP2CON
	nop
	nop
; incf	eed,f
	movlw		0x0A
	movwf		CCP2CON	; пускаме CCP2
;следващ индекс
	
	incf		pass_ix,f
	movf		pass_ix,w
	sublw		6
	btfsc		STATUS,Z
	clrf		pass_ix
	movf		PPM_ix,w
	movwf		PORTB
	bcf		STATUS,C
	rlf		PPM_ix,f
	movlw		0x41
	btfsc		PPM_ix,6
	xorwf		PPM_ix,f	;нулираме старшия бит и установяваме младшия
	
	goto		interrupt_done

interrupt_CCP1		;приемане на информацията и предварителна обработка
	btfss		PIR1,CCP1IF
	goto		interrupt_done
	bcf		PIR1,CCP1IF
	clrf		CCP1CON	;изключваме CCP1
	
;обръщаме фронта на сработване на CCP1
	movlw		1
	xorwf		CCP1_Mode,w
	movwf		CCP1_Mode
;	movwf		CCP1CON

;запазваме сработилото CCP1
	movf		CCPR1H,w	;запазваме CCPR1H:L  във временна променлива CCP1_prev
	movwf		CCP1_buf
;	btfsc		STATUS,Z	;ако е 0  имаме лъжливо сработване
;	goto	get_tmr1
	movf		CCPR1L,w
	movwf		CCP1_buf+1
;	goto		CCP1_valid_data		
;get_tmr1
;	movf		TMR1L,w
;	movwf		CCP1_buf+1
;	movf		TMR1H,w
;	movwf		CCP1_buf
CCP1_valid_data		
	movf		in_pass,w
	btfss		STATUS,Z	;ако in_pass <> 0
	goto		CCP1_next
in_pass_add	
	goto		pass_inc	; in_pass == 0
;продължаваме с обработката	- in_pass е по голямо или равно на 1
CCP1_next
;да си определим продължителността на импулса
	movf		CCP1_prev+1,w
	subwf		CCP1_buf+1,w
	movwf		CCP1_Ti+1	;младша част
	btfss		STATUS,C
	decf		CCP1_buf,f
	movf		CCP1_prev,w
	subwf		CCP1_buf,w
	movwf		CCP1_Ti	;старша част
; определили сме продължителността на импулса в Ti
; сега ще си го обработим	
;1 дали е по малко от 0x100
	movf		CCP1_Ti,w
	btfsc		STATUS,Z
	goto		pass_0		; ще отидем да нулираме in_pass
	movlw		0x0A
	subwf		CCP1_Ti,w
	btfsc		STATUS,C	
	goto		pass_0		; ще отидем да нулираме in_pass
;импулса е над 0x100 и под 	0xA00
;записваме го
	movlw		buf_r-2
	movwf		FSR
	bcf		STATUS,C
	rlf		in_pass,w
	addwf		FSR,f
	incf		FSR,f
	movf		CCP1_Ti+1,w
	movwf		INDF		;младша част
	decf		FSR,f
	movf		CCP1_Ti,w
	movwf		INDF		;старша част
;дали 	in_pass ==1
	movlw		.1	
	subwf		in_pass,w
	btfsc		STATUS,Z
	goto		check_SI
	movlw		.15	
	subwf		in_pass,w
	btfss		STATUS,Z
	goto		pass_inc

check_SI	;ако in_pass==1 или in_pass==15 ще проверяваме за СИ
;ще определяме дали е равно на СИ 0x9C0
;	decf		FSR,F	;вече сме го изчислили и знаем къде е	
	movlw		0x09
	subwf		INDF,w
	btfss		STATUS,Z
	goto		do_not_si
	incf		FSR,f
	movf		INDF,w
	andlw	0x80
	xorlw	0x80
	btfss	STATUS,Z	;младшата част на приетото 0x80 ли е?
	goto	do_not_si
;определили  сме СИ 
;	movlw		0
;	btfsc		sin_ok	;дали сме имали предишен СИ
;	movlw		0x0a
;	movwf		CCP2CON	;ако сме имали предишен СИ пускаме CCP2
	movf		in_pass,w
	btfsc		sin_ok	;дали сме имали предишен СИ
	movlw		1
	movwf		in_pass	;ако сме имали СИ и пак го получаваме in_pass==1
	movlw		0
	btfss		sin_ok	;ако сме имали предишен СИ
	goto		set_si
	movf		INDF,w
	movwf		buf_r+1
	decf		FSR,f
	movf		INDF,w
	movwf		buf_r
;тук ще обработим информацията за предаване на изходите
	movlw		6
	movwf		CCP2_pass	;имаме 6 машинки
CCP2_Calc_Loop
	;вземаме информацията от buf_r + CCP2_pass*4
	movlw		buf_r
	movwf		FSR
	movf		CCP2_pass,w
	movwf		CCP2_tmp
	bcf		STATUS,C
	rlf		CCP2_tmp,f
	rlf		CCP2_tmp,w
	addwf		FSR,f
	decf		INDF,w		;изваждаме 0х100
	movwf		CCP2_tmp	;съхраняваме в междинна променлива
	incf		FSR,f
	movf		INDF,w
	movwf		CCP2_tmp+1
	; подготвяме 	buf_CCP2+CCP2_pass*2
	movlw		buf_CCP2
	movwf		FSR
	bcf		STATUS,C
	rlf		CCP2_pass,w
	addwf		FSR,f
	movf		CCP2_tmp+1,w
	movwf		INDF		;и записваме
	decf		FSR,f
	movf		CCP2_tmp,w
	movwf		INDF		;и записваме
	decfsz		CCP2_pass,f
	goto		CCP2_Calc_Loop
; и цифровите команди
	movlw		6
	movwf		CCP2_pass	;имаме 6 машинки
	clrf		dig_tmp
	movlw		buf_r+8
	movwf		FSR
	movf		CCP2_pass,w
	movwf		CCP2_tmp
	bcf		STATUS,C
	rlf		CCP2_tmp,f
	rlf		CCP2_tmp,w
	addwf		FSR,f
	decf		FSR,f
	decf		FSR,f
dig_Calc_Loop
	movlw		4
	subwf		FSR,f
	decf		INDF,w
	bcf		STATUS,C
	btfss		STATUS,Z
	bsf		STATUS,C
	rlf		dig_tmp,f
	decfsz		CCP2_pass,f
	goto		dig_Calc_Loop
	movf		dig_tmp,w
	movwf		DigVal		;прехвърляме стойността в реалния буфер
	movwf		PORTA		;и на 	PORTA
	bsf	    	STATUS, RP0		;bank 1
	bsf		PIE1,TMR1IE		;enable interrupt TMR1
	bcf	    	STATUS, RP0		;bank 0
	clrf		TMR1HH	;изчистване на променливата за натрупване на прекъсванията

 	btfsc		ready_in
	goto		set_si		;избягваме повторно предизвикване на прекъсване
	bsf		ready_in	;минал е цял цикъл приемане и е запазена синхронизацията
	bsf		T2CON,TMR2ON	;TMR2 On	
;	bsf		PIR1,TMR2IF		;и предизвикваме прекъсване по TMR
; call WriteEE
set_si
	bsf		sin_ok
	goto		pass_inc
do_not_si
pass_0
;	clrf		CCP2CON	;спираме CCP2
	clrf		in_pass
	bcf		sin_ok		;нямаме минал СИ
	bcf		ready_in	;нямаме валидна информация
pass_inc
	incf		in_pass,f	
	movf		CCPR1H,w	;запазваме CCPR1H:L  във временна променлива CCP1_prev
	movwf		CCP1_prev
	movf		CCPR1L,w
	movwf		CCP1_prev+1
	movf		CCP1_Mode,w
	movwf		CCP1CON
;	goto	interrupt_done

interrupt_done
	movf 		FSR_TEMP,w
	movwf 		FSR
	movf 		PCLATH_TEMP,w
	movwf		 PCLATH
	swapf		STATUS_TEMP,w
	movwf		STATUS
	swapf		W_TEMP,f
	swapf		W_TEMP,w
	bsf		INTCON,PEIE		;enable interrupt's
	retfie

#ifdef 	stmacro		;само ако се използва st 
delay_200iS
			;798 cycles
	movlw	0x9F
	movwf	d1
	movlw	0x01
	movwf	d2
Delay_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	Delay_0

			;2 cycles
	goto	$+1
	return
#endif

Delay_19k			;19968 cycles
			;19968 cycles
	movlw	0x99
	movwf	d1
	movlw	0x10
	movwf	d2
Delay_19k_loop
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	Delay_19k_loop

	return

WriteEE	;зациклено е
; bsf 	PORTA,0
	movlw	.51
	movlw	0x33

	movwf	eed
	btfsc	Modes,3
	goto	Write_exit
	movlw	0x20
; movlw	wcb
	movwf	FSR		;source
	bsf	STATUS,RP1	;bank 2
	movlw	0x00		;0x2100
	movwf	EEADR
	bsf	STATUS,RP0		;bank 3
	bcf	EECON1, EEPGD	; ще записваме в EEPROM  
	bcf	INTCON,GIE		;малко да спрем прекъсванията
	bsf	EECON1,WREN	;разрешаваме записа
	bcf	STATUS,RP0		;bank 2

write_loop
	movf	INDF,w
	movwf	EEDATA
	bsf	STATUS,RP0	;bank 3
;	btfsc	EECON1,WR
;	goto	$-1
;задължителния код
	movlw	0x55
	movwf	EECON2
	movlw	0xAA
	movwf	EECON2
	bsf	EECON1,WR	;write
;край задължителния код
	btfsc	EECON1,WR
	goto	$-1
	nop
;	bcf	EECON1,WREN	;разрешаваме записа
	bcf	STATUS,RP0	;bank 2
	incf	FSR,f
	incf	EEADR,f
	decfsz	eed,f
	goto	write_loop
	bsf	STATUS,RP0	;bank 3
	bcf	EECON1,WREN	;разрешаваме записа
	bcf	STATUS,RP0		;bank 0
	bcf	STATUS,RP1		;bank 0
	bcf	PIR2,EEIF
	bsf	INTCON,GIE		;малко да пуснем прекъсванията
	bsf	Modes,3


 bcf	INTCON,PEIE		;disable interrupt's

 nop
 nop
 goto $-2
Write_exit
	return

	
;EEPROM данни
	ORG 0X2100
AN_Cor de 0x00,0x01,0x02,0x03

	end
/*
Примите под внимание наличе макроса stmacro. Он сделан для подстройки программъ в тестовом режиме. 
Имейте в виду, что с WriteEE въхода нет. Она замкнута на себе. Тоже для тестовъх режимов - просмотр изменение длинъ даннъх при реальнъх работ.

Давни делал. Ета версия кажется с 2013г. 
*/
Только, понимаеш, здесь не линейнъй алгоритм. Но явно тебе слово алгоритм ничего не говорит.
roman.com писал(а):ты делать будешь
По етой методике у меня 3 или 4 варианта. Включая и последнего (с пред. поста) которъй еще не работал в "жизни" - да и вряд ли заработает. Так, я-то делал и если все будет хорошо и буду делать, а вот тебе кроме линейнъх алгоритмов видно ничего другое не подвластно.
roman.com писал(а):"Радиоуправлениe на модулях nRF24L01+"...
Дополни имя темъ и только про меги. С императивнъм тоном. Можно "и только про roman.com". :)))

Если еще не понял, то есть переносимость идей меж разнъх МК. Только идея важна, а реализация - ето так. Дело техники. Вот я тебе идею дал, а тъ сделать ее явно не сможеш. Жаль.
Лом - ето город в Болгарии, а не инструмент юстировки електроники.
Аватара пользователя
sashamelja
Говорящий с текстолитом
Сообщения: 1565
Зарегистрирован: Пт янв 20, 2012 16:25:02

Re: Радиоуправлениe на модулях nRF24L01+

Сообщение sashamelja »

Товарищи форумчани не сорьтесь
Мне нужно
1 ATmega8 TQFP
2 стабильная рабора радио связи(без потери соединения)
3 одна серва на руль,
3.1 управление мотором как у масика шим+реверс,
4 четыри кнопки (виезд лотка,заезд лотка,свет,ехолот)
5 индикацыя проблем(потоп,перегрев,уровень сьвязі,батарея корабля+пульта)
Я не щитаю что ето просто,а кто щитает что єто просто пусть напишет
И тогда мы увидем кто есть кто
Я такого проекта на ATmega8 TQFP не встечал в нете кроме http://cxem.net/uprav/uprav93.php но там очень много глюков(масик повторил)
И опыт сын ошибок трудных и гений парадоксов друг
roman.com
Друг Кота
Сообщения: 9157
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Re: Радиоуправлениe на модулях nRF24L01+

Сообщение roman.com »

sashamelja писал(а): 1 ATmega8 TQFP
2 стабильная рабора радио связи(без потери соединения)
3 одна серва на руль,
3.1 управление мотором как у масика шим+реверс,
4 четыри кнопки (виезд лотка,заезд лотка,свет,ехолот)
5 индикацыя проблем(потоп,перегрев,уровень сьвязі,батарея корабля+пульта)
ясно)) Тогда рисуем схему... Бедем тестить)) А паять на чём и как ?
Аватара пользователя
sashamelja
Говорящий с текстолитом
Сообщения: 1565
Зарегистрирован: Пт янв 20, 2012 16:25:02

Re: Радиоуправлениe на модулях nRF24L01+

Сообщение sashamelja »

Вот схема поменяй пины(и номера ножек) как будет лутще для конструкцыи(для програмы)
как только утвердим схему я зделаю точнее переделаю печатку с иного проекта
И переделай индикацыю,я незнаю как это зделать по пинам лутше
Я хотел чтоби било всево 5 светодиодов
1 ак пульта когда заряд ниже норми
2 ак корабля ниже норми
3 потеря пакетов
4 температура 60гр
5 наличие води
Вложения
1.7z
(203.68 КБ) 224 скачивания
И опыт сын ошибок трудных и гений парадоксов друг
roman.com
Друг Кота
Сообщения: 9157
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Re: Радиоуправлениe на модулях nRF24L01+

Сообщение roman.com »

sashamelja писал(а):переделай индикацыю,я незнаю как это зделать по пинам лутше
можно... Только показания индикатора будет не точными.. Хотя можно сделать разную частоту мигания диодов))

Вообщем.. первым делом надо нарисовать нормальную схему, чтобы было понятно что куда... Например вот (пульт):
пульт-ATmega8L.rar
(9.15 КБ) 213 скачиваний
Дальше рисуем нормальную схему модели...

P.S. )) Как работает цифровой датчик температуры, я не знаю... пока не знаю))
Аватара пользователя
sashamelja
Говорящий с текстолитом
Сообщения: 1565
Зарегистрирован: Пт янв 20, 2012 16:25:02

Re: Радиоуправлениe на модулях nRF24L01+

Сообщение sashamelja »

Схема понятная сегодня вечером зделаю печатку

Добавлено after 9 hours 19 minutes 59 seconds:
Травить буду в суботу,завтра на свежую голову проверю
Вложения
пульт-ATmega8L(Печатка+схема).7z
(130 байт) 242 скачивания
И опыт сын ошибок трудных и гений парадоксов друг
roman.com
Друг Кота
Сообщения: 9157
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Re: Радиоуправлениe на модулях nRF24L01+

Сообщение roman.com »

Напиши название сервы, хочу глянуть даташит... (на видео не вижу названия) https://www.youtube.com/watch?v=WeZfOw78zCw

Вообщем схема модели будет такая.
пульт-модель.rar
(187.84 КБ) 205 скачиваний
Датчик температуры ... я не знаю)) Нарисовал два - цифровой и аналоговый, какой-нибудь поставим)) Но это потом. Оставь для них место)) Для начала надо нстроить связь и запустить механику... Драйвер двигателя лучше делать на отдельной плате...
Дальше... пишем программку.. :tea:
Аватара пользователя
sashamelja
Говорящий с текстолитом
Сообщения: 1565
Зарегистрирован: Пт янв 20, 2012 16:25:02

Re: Радиоуправлениe на модулях nRF24L01+

Сообщение sashamelja »

https://ru.aliexpress.com/item/High-Qul ... 18796.html
Так и зделаим масик мне скидал печатку драйвера, приемник завта нарисуем ,я думаю что за неделю я соберу в железе,пару деталек прикуплю и вперед
И опыт сын ошибок трудных и гений парадоксов друг
MASIK
Грызет канифоль
Сообщения: 291
Зарегистрирован: Пн авг 12, 2013 21:24:55

Re: Радиоуправлениe на модулях nRF24L01+

Сообщение MASIK »

Приветствую Всех участников форума. Хотя мой паяльник и холодный потому что не включен и дорабатываю напильником кораблик что бы не вышел паровоз :? . Да и версия не моя. Все равно форум почитать нахожу время что бы не пропустить самое интересное. Сейчас мокну лапу в миску со сметаной и как обычно пойдут дебаты. В данной конструкции не нравятся светодиоды по одному, как то не серьезно. Понимаю что есть аварийная сигнализация (теч воды и перегрев двигателя ) значить пора крутить винтом к берегу, а как же с предупредительной сигнализацией (уровень заряда батарей и потеря пакетов) на какой процент настроена на 50%, 40%, 10% или 1%, а может пора качать лодку или снимать сапоги да готовиться к заплыву :) , потому что уже не кто ни куда не плывёт, просто приплыли. roman.com может все же прикрутим какой не будь мониторчик от телефончика для полного фен шуя, выбор конечно за Вами. Думаю пора переходить на новый уровень дизайна. Время еще есть, и я соберу четвертый комплект радио управления. sashamelja с печаткой поможет, у меня много работы последнее время, буду долго рисовать. roman.com что скажите.
Аватара пользователя
sashamelja
Говорящий с текстолитом
Сообщения: 1565
Зарегистрирован: Пт янв 20, 2012 16:25:02

Re: Радиоуправлениe на модулях nRF24L01+

Сообщение sashamelja »

Я про индикацыю думал по разному
с экраном много проблем,5 индекацый по 5 светодиодов уже герлянеда а ето все садит акум
а так 5 светодиодов ошибок (норма не горим легкая проблема мигаем и так до полного свечения
я щитаю идеальний вариант и по денюгах супер(все просто и понятно)мигает плыви на берег,светитса снимай штаны :lol:
И опыт сын ошибок трудных и гений парадоксов друг
roman.com
Друг Кота
Сообщения: 9157
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Re: Радиоуправлениe на модулях nRF24L01+

Сообщение roman.com »

MASIK... так мы и не увидили видео работы твоего кораблика)) Ну если хочешь, то можно попробовать другой индикатор)) В железе не проверял, только в протеусе, но если сильно хочется, то можешь взять какой есть под рукой... проверим как работает в реале))
1.JPG
(79.02 КБ) 517 скачиваний
LCD индикаторы глючные... особенно от мобил. Стабильной работы от них пока не добился... Потом может поковыряю подробно))

Вот тестовая прошивка для проверки работы механики... сервы и двигателя...
тест.rar
(287.05 КБ) 217 скачиваний
Далее.. надо определиться с индикатором. как он должен работать?

А вообще индикаторов существует целая куча))

LCD https://yandex.ru/images/search?text=lc ... source=wiz

Я считаю что самые надёжные - LED https://yandex.ru/images/search?text=le ... source=wiz

Если много диодом, то можно взять готовую матрицу... https://yandex.ru/images/search?text=%D ... source=wiz

И т.д. и т.п. Короче... индикатор - не проблема. Весь вопрос в сложности, стоимости, надёжности...

Короче.. сейчас 5 диодов. Можно их заставить мигать...
1- горит - 100%
2- редко мигает - 75%
3- мигает/горит - 50%
4- редко горит - 25 %
5- не горит - 0%.

И т.д. и т.п.))) Это всё не проблема)) Только все диоды часто будут мигать... будет мигающий пульт))) не знаю... это не очень приятно... для глаз... ))
Ответить

Вернуться в «Радиотехника: приемники, передатчики, антенны»