Радиоуправлениe на модулях nRF24L01+
- sashamelja
- Говорящий с текстолитом
- Сообщения: 1565
- Зарегистрирован: Пт янв 20, 2012 16:25:02
Re: Радиоуправлениe на модулях nRF24L01+
Доброго времени суток у меня такое предложение к roman.com
сделай пожалуста изменение в прошивке чтоби PD4(вив6) управлял завоцкой китайской сервой (а PD5 будет про запас)
С остальним всем согласен,теске MASIK Привет БУДЕМ ПОВТОРЯТЬ
сделай пожалуста изменение в прошивке чтоби PD4(вив6) управлял завоцкой китайской сервой (а PD5 будет про запас)
С остальним всем согласен,теске MASIK Привет БУДЕМ ПОВТОРЯТЬ
И опыт сын ошибок трудных и гений парадоксов друг
- Реклама
Re: Радиоуправлениe на модулях nRF24L01+
Эта схема для MASIK, заточена под самодельную серву. Если делать по нормальному, то надо перекинуть модуль nRF24L01+ и сделать нормальную ШИМ (можно с двуми сервами).. А вообще есть и другие варианты))sashamelja писал(а):чтоби PD4(вив6) управлял завоцкой китайской сервой
- sashamelja
- Говорящий с текстолитом
- Сообщения: 1565
- Зарегистрирован: Пт янв 20, 2012 16:25:02
Re: Радиоуправлениe на модулях nRF24L01+
ATmega8 TQFP можна ли зделать так
- Вложения
-
- 1.7z
- (204.89 КБ) 257 скачиваний
И опыт сын ошибок трудных и гений парадоксов друг
Re: Радиоуправлениe на модулях nRF24L01+
Схемки пошли))
Теоретически можно всё)) Основная проблема - китайские сервы. Не знаю, на сколько ты хорошо зазбираешся в МК... Но "на пальцах" примерно так: схемка разработана по заказу MASIK..)) У него самодельная серва от принтера. Примерно такая: Самодельная серва - два вывода на двигатель и отдельно резистор обратной связи. Поэтому MASIKу всё равно на какие выводы МК подключать свою серву)) И сколько подключать самодельных серв - MASIKу тоже всё равно)) Сколько выводов в МК, столько можно подключить самодельных серв))
Вот ещё пример самодельной сервы)) Китайская серва работает чуть иначе... там всё внутри... Управление у китайской сервы по одному выводу с помощью импульсов ШИМ. https://ru.wikipedia.org/wiki/Сервомашинка
Так вот, сложность получить эти самые импульсы заданной точности. Если просто подключить 4 сервы к выводам например PC0, PC1, PC2, PC3 (или любым другим), то сложно обеспечить точно длительность этих самых управляющих импульсов. Т.к. придётся делать программный ШИМ и задействовать процессор МК, который будет включать/отключать последовательно выводы PC0, PC1, PC2, PC3...
Процессор МК не может абсолютно точно выдержать длительности всех импульсов для 4-х серв, да ещё одновременно... Поэтому добиться идеальной точности сервы не получится. И ещё есть опасность, что сервы будут "дрожать"... Хотя попытаться можно, но результат не гарантируется))) Когда делали машинку, мы использовали аппаратный ШИМ, который работает от кварца и не зависит от работы процессора МК.
В МК ATmega8 есть два специальных вывода для этих целей:
выводы 15 и 16 - для двух китайских серв.
вывод 17 - для двигателя.
В этом случае гаратнируются импульсы практически идеальной длительности и стабильная работа сервы. Вот))
Сейчас к выводам 15, 16, 17 подключен радиомодуль, который можно перекинуть (т.е. подключить к любым другим свободным выводам МК).
Радиомодуль менее требовательный к импульсам))) Может работать и на программном SPI. Только скорость передачи в ~10 раз меньше, но это не критично))
Проблема в том, что тогда к ATmega8 можно подключить только две сервы... жаль...
Какие есть варианты? Целая куча...)))
1- поставить ATmega8 - две штуки )) Расточительно))
2- взять другой МК, у которого много ШИМ выводов. Дорого и ... всё переделывать под другую платформу...
3- оптимизировать программу и добиться работы сервы близкой к идеальному... (до идеала ещё не пробовали).
4- другие варианты...)))
датчик температуры цифровой с шиной 1-Wire. С таким ещё не работали, но думаю разобраться можно))
Остальное ..мелочи))

Теоретически можно всё)) Основная проблема - китайские сервы. Не знаю, на сколько ты хорошо зазбираешся в МК... Но "на пальцах" примерно так: схемка разработана по заказу MASIK..)) У него самодельная серва от принтера. Примерно такая: Самодельная серва - два вывода на двигатель и отдельно резистор обратной связи. Поэтому MASIKу всё равно на какие выводы МК подключать свою серву)) И сколько подключать самодельных серв - MASIKу тоже всё равно)) Сколько выводов в МК, столько можно подключить самодельных серв))
Вот ещё пример самодельной сервы)) Китайская серва работает чуть иначе... там всё внутри... Управление у китайской сервы по одному выводу с помощью импульсов ШИМ. https://ru.wikipedia.org/wiki/Сервомашинка
Так вот, сложность получить эти самые импульсы заданной точности. Если просто подключить 4 сервы к выводам например PC0, PC1, PC2, PC3 (или любым другим), то сложно обеспечить точно длительность этих самых управляющих импульсов. Т.к. придётся делать программный ШИМ и задействовать процессор МК, который будет включать/отключать последовательно выводы PC0, PC1, PC2, PC3...
Процессор МК не может абсолютно точно выдержать длительности всех импульсов для 4-х серв, да ещё одновременно... Поэтому добиться идеальной точности сервы не получится. И ещё есть опасность, что сервы будут "дрожать"... Хотя попытаться можно, но результат не гарантируется))) Когда делали машинку, мы использовали аппаратный ШИМ, который работает от кварца и не зависит от работы процессора МК.
В МК ATmega8 есть два специальных вывода для этих целей:
выводы 15 и 16 - для двух китайских серв.
вывод 17 - для двигателя.
В этом случае гаратнируются импульсы практически идеальной длительности и стабильная работа сервы. Вот))
Радиомодуль менее требовательный к импульсам))) Может работать и на программном SPI. Только скорость передачи в ~10 раз меньше, но это не критично))
Проблема в том, что тогда к ATmega8 можно подключить только две сервы... жаль...
Какие есть варианты? Целая куча...)))
1- поставить ATmega8 - две штуки )) Расточительно))
2- взять другой МК, у которого много ШИМ выводов. Дорого и ... всё переделывать под другую платформу...
3- оптимизировать программу и добиться работы сервы близкой к идеальному... (до идеала ещё не пробовали).
4- другие варианты...)))
датчик температуры цифровой с шиной 1-Wire. С таким ещё не работали, но думаю разобраться можно))
Остальное ..мелочи))
- botchin
- Поставщик валерьянки для Кота
- Сообщения: 2029
- Зарегистрирован: Чт дек 27, 2012 20:46:09
- Откуда: Болгария, г. Лом
Re: Радиоуправлениe на модулях nRF24L01+
Я на одном аппаратном модуле ССР (Capture/Compare/PWM) делаю 6 въхода PPM. Так что - возможно. Код (C) вълагал здесь - правда на PIC-e.roman.com писал(а): к ATmega8 можно подключить только две сервы... жаль... Какие есть варианты? Целая куча...)))
Лом - ето город в Болгарии, а не инструмент юстировки електроники.
- Реклама
- sashamelja
- Говорящий с текстолитом
- Сообщения: 1565
- Зарегистрирован: Пт янв 20, 2012 16:25:02
Re: Радиоуправлениe на модулях nRF24L01+
Когда делали машинку, мы использовали аппаратный ШИМ, который работает от кварца и не зависит от работы процессора МК.
В МК ATmega8 есть два специальных вывода для этих целей:
выводы 15 и 16 - для двух китайских серв.
вывод 17 - для двигателя.
В этом случае гаратнируются импульсы практически идеальной длительности и стабильная работа сервы. Вот))
Не подходит усложняет конструкцыю катера,нада одна серва чтоби при включению занимала нулевое положение,на передатчике будем использовать джойсік от ардуино там резистор на 10К,дрожание не критично,главное чтоби связь не терялась а управление мотором такое как в Маsika
1- поставить ATmega8 - две штуки )) Расточительно))
2- взять другой МК, у которого много ШИМ выводов. Дорого и ... всё переделывать под другую платформу...
3- оптимизировать программу и добиться работы сервы близкой к идеальному... (до идеала ещё не пробовали).
4- другие варианты...)))
я за третий вариант,если ти согласен написать програму я все соберу и протестирую на практеке у меня все есть в наличие
Что ненужно виброси что надо добавь,что хочеш поменяй
Вот начем я буду тестить https://www.youtube.com/watch?v=WeZfOw78zCw
В МК ATmega8 есть два специальных вывода для этих целей:
выводы 15 и 16 - для двух китайских серв.
вывод 17 - для двигателя.
В этом случае гаратнируются импульсы практически идеальной длительности и стабильная работа сервы. Вот))
Не подходит усложняет конструкцыю катера,нада одна серва чтоби при включению занимала нулевое положение,на передатчике будем использовать джойсік от ардуино там резистор на 10К,дрожание не критично,главное чтоби связь не терялась а управление мотором такое как в Маsika
1- поставить ATmega8 - две штуки )) Расточительно))
2- взять другой МК, у которого много ШИМ выводов. Дорого и ... всё переделывать под другую платформу...
3- оптимизировать программу и добиться работы сервы близкой к идеальному... (до идеала ещё не пробовали).
4- другие варианты...)))
я за третий вариант,если ти согласен написать програму я все соберу и протестирую на практеке у меня все есть в наличие
Что ненужно виброси что надо добавь,что хочеш поменяй
Вот начем я буду тестить https://www.youtube.com/watch?v=WeZfOw78zCw
- Вложения
-
- 2.7z
- (70.43 КБ) 250 скачиваний
И опыт сын ошибок трудных и гений парадоксов друг
Re: Радиоуправлениe на модулях nRF24L01+
Такие комментарии нам очень помогают... )))botchin писал(а):Я на одном аппаратном модуле ССР (Capture/Compare/PWM) делаю 6 въхода PPM. Так что - возможно. Код (C) вълагал здесь - правда на PIC-e.
Мы можем подключить к одному МК и 20 серв... вопрос какой ценой ))
Не понял... ты насхеме нарисовал 4 сервы... теперь одна? Ты определись... от этого зависит схема ипрограмма...sashamelja писал(а):нада одна серва
Дрожание критично. Может перегреваться серва и самое с главное - повышенный разряд аккумулятора... Оно тебе надо? ))sashamelja писал(а):дрожание не критично,главное чтоби связь не терялась а управление мотором такое как в Маsika
3- оптимизировать программу и добиться работы сервы близкой к идеальному... (до идеала ещё не пробовали).
4- другие варианты...)))
Третий вариант - это для 4 сервы (и больше)... программный ШИМ. Для одной сервы - идеально аппаратный ШИМ.sashamelja писал(а):я за третий вариант,если ти согласен написать програму я все соберу и протестирую на практеке у меня все есть в наличие
Так ты определись что ты хочешь... А то я сейчас всё повыкидываю... Потом тебе не понравится))sashamelja писал(а):Что ненужно виброси что надо добавь,что хочеш поменяй
Твой катер? Для начала нормальненько))sashamelja писал(а):Вот начем я буду тестить https://www.youtube.com/watch?v=WeZfOw78zCw
Тебе нужна нормальная, стабильная схема или "китайская" поделка)) ? Можно накидать всё "на скорую руку" б тогда всё будет работать чёрти как... Если делать по нормальному то надо все детальки собрать в кучку (что у нас есть), нарисовать нормальную схемку, затем написать к этой схемке программку))
Сейчас упёрлись в серву. Если одна серва - то лучше сделать по одной схеме. Если много серв, то лучше по другой схеме.
После того как соберём схемку, что-то менять будет сложно.. Поэтому надо сразу задавать все параметры (на стадии разработки), а потом рисовать и делать...
разрабатывать схемы и писать программы - это не пять минут работы)) Наберись терпения)) Щас подумаем...
- botchin
- Поставщик валерьянки для Кота
- Сообщения: 2029
- Зарегистрирован: Чт дек 27, 2012 20:46:09
- Откуда: Болгария, г. Лом
Re: Радиоуправлениe на модулях nRF24L01+
Как всегда!!!!?roman.com писал(а):Такие комментарии нам очень помогают... ))) опять... ни схемы, ни алгоритма, ни описания...
На предъдущей странице есть файл 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) тебе нарисовать или сам справишся?
Лом - ето город в Болгарии, а не инструмент юстировки електроники.
Re: Радиоуправлениe на модулях nRF24L01+
Видали... дальше что? Ну если всё настролько просто, то взял бы и сделал ... Накидай по быстрому программку под мегу и данный модуль. Какие проблемы? )) Ты лучше ответь.. ты делать будешь или опять пришёл от нечего делать просто языком почесать?))botchin писал(а):На предъдущей странице есть файл Algol.png. Да и сама идея настолько простая, что мне стъдно обсуждать ее.
Ну тогда не понятно что мы тут вообще тогда обсуждаем... в теме "Радиоуправлениe на модулях nRF24L01+"...botchin писал(а):botchin читает и делать не будеть. Причин две:
1. Использование nRF24L01+ и
2. Использование Мега8
Опять одни разговоры... бла-бла-бла... Короче как всегда))
Вот тут чувак (кстате с этого сайта, радиокот) предложил свою идею)) Даже видео снял))sashamelja писал(а):я все соберу и протестирую на практеке у меня все есть в наличие
https://www.youtube.com/watch?v=gSVa0IuFyFw
Всё просто и ясно)) Только идеальных импульсов таким образом не получим... Да и можно сделать проще...
А вообще, если одна серва то чего париться... Есть аппаратный ШИМ)) Короче.. берём схему MASIK и переделываем.. ))
- botchin
- Поставщик валерьянки для Кота
- Сообщения: 2029
- Зарегистрирован: Чт дек 27, 2012 20:46:09
- Откуда: Болгария, г. Лом
Re: Радиоуправлениe на модулях nRF24L01+
Так сделай.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г.
*/
По етой методике у меня 3 или 4 варианта. Включая и последнего (с пред. поста) которъй еще не работал в "жизни" - да и вряд ли заработает. Так, я-то делал и если все будет хорошо и буду делать, а вот тебе кроме линейнъх алгоритмов видно ничего другое не подвластно.roman.com писал(а):ты делать будешь
Дополни имя темъ и только про меги. С императивнъм тоном. Можно "и только про roman.com".roman.com писал(а):"Радиоуправлениe на модулях nRF24L01+"...
Если еще не понял, то есть переносимость идей меж разнъх МК. Только идея важна, а реализация - ето так. Дело техники. Вот я тебе идею дал, а тъ сделать ее явно не сможеш. Жаль.
Лом - ето город в Болгарии, а не инструмент юстировки електроники.
- sashamelja
- Говорящий с текстолитом
- Сообщения: 1565
- Зарегистрирован: Пт янв 20, 2012 16:25:02
Re: Радиоуправлениe на модулях nRF24L01+
Товарищи форумчани не сорьтесь
Мне нужно
1 ATmega8 TQFP
2 стабильная рабора радио связи(без потери соединения)
3 одна серва на руль,
3.1 управление мотором как у масика шим+реверс,
4 четыри кнопки (виезд лотка,заезд лотка,свет,ехолот)
5 индикацыя проблем(потоп,перегрев,уровень сьвязі,батарея корабля+пульта)
Я не щитаю что ето просто,а кто щитает что єто просто пусть напишет
И тогда мы увидем кто есть кто
Я такого проекта на ATmega8 TQFP не встечал в нете кроме http://cxem.net/uprav/uprav93.php но там очень много глюков(масик повторил)
Мне нужно
1 ATmega8 TQFP
2 стабильная рабора радио связи(без потери соединения)
3 одна серва на руль,
3.1 управление мотором как у масика шим+реверс,
4 четыри кнопки (виезд лотка,заезд лотка,свет,ехолот)
5 индикацыя проблем(потоп,перегрев,уровень сьвязі,батарея корабля+пульта)
Я не щитаю что ето просто,а кто щитает что єто просто пусть напишет
И тогда мы увидем кто есть кто
Я такого проекта на ATmega8 TQFP не встечал в нете кроме http://cxem.net/uprav/uprav93.php но там очень много глюков(масик повторил)
И опыт сын ошибок трудных и гений парадоксов друг
Re: Радиоуправлениe на модулях nRF24L01+
ясно)) Тогда рисуем схему... Бедем тестить)) А паять на чём и как ?sashamelja писал(а): 1 ATmega8 TQFP
2 стабильная рабора радио связи(без потери соединения)
3 одна серва на руль,
3.1 управление мотором как у масика шим+реверс,
4 четыри кнопки (виезд лотка,заезд лотка,свет,ехолот)
5 индикацыя проблем(потоп,перегрев,уровень сьвязі,батарея корабля+пульта)
- sashamelja
- Говорящий с текстолитом
- Сообщения: 1565
- Зарегистрирован: Пт янв 20, 2012 16:25:02
Re: Радиоуправлениe на модулях nRF24L01+
Вот схема поменяй пины(и номера ножек) как будет лутще для конструкцыи(для програмы)
как только утвердим схему я зделаю точнее переделаю печатку с иного проекта
И переделай индикацыю,я незнаю как это зделать по пинам лутше
Я хотел чтоби било всево 5 светодиодов
1 ак пульта когда заряд ниже норми
2 ак корабля ниже норми
3 потеря пакетов
4 температура 60гр
5 наличие води
как только утвердим схему я зделаю точнее переделаю печатку с иного проекта
И переделай индикацыю,я незнаю как это зделать по пинам лутше
Я хотел чтоби било всево 5 светодиодов
1 ак пульта когда заряд ниже норми
2 ак корабля ниже норми
3 потеря пакетов
4 температура 60гр
5 наличие води
- Вложения
-
- 1.7z
- (203.68 КБ) 224 скачивания
И опыт сын ошибок трудных и гений парадоксов друг
Re: Радиоуправлениe на модулях nRF24L01+
можно... Только показания индикатора будет не точными.. Хотя можно сделать разную частоту мигания диодов))sashamelja писал(а):переделай индикацыю,я незнаю как это зделать по пинам лутше
Вообщем.. первым делом надо нарисовать нормальную схему, чтобы было понятно что куда... Например вот (пульт): Дальше рисуем нормальную схему модели...
P.S. )) Как работает цифровой датчик температуры, я не знаю... пока не знаю))
- sashamelja
- Говорящий с текстолитом
- Сообщения: 1565
- Зарегистрирован: Пт янв 20, 2012 16:25:02
Re: Радиоуправлениe на модулях nRF24L01+
Схема понятная сегодня вечером зделаю печатку
Добавлено after 9 hours 19 minutes 59 seconds:
Травить буду в суботу,завтра на свежую голову проверю
Добавлено after 9 hours 19 minutes 59 seconds:
Травить буду в суботу,завтра на свежую голову проверю
- Вложения
-
- пульт-ATmega8L(Печатка+схема).7z
- (130 байт) 242 скачивания
И опыт сын ошибок трудных и гений парадоксов друг
Re: Радиоуправлениe на модулях nRF24L01+
Напиши название сервы, хочу глянуть даташит... (на видео не вижу названия) https://www.youtube.com/watch?v=WeZfOw78zCw
Вообщем схема модели будет такая. Датчик температуры ... я не знаю)) Нарисовал два - цифровой и аналоговый, какой-нибудь поставим)) Но это потом. Оставь для них место)) Для начала надо нстроить связь и запустить механику... Драйвер двигателя лучше делать на отдельной плате...
Дальше... пишем программку..
Вообщем схема модели будет такая. Датчик температуры ... я не знаю)) Нарисовал два - цифровой и аналоговый, какой-нибудь поставим)) Но это потом. Оставь для них место)) Для начала надо нстроить связь и запустить механику... Драйвер двигателя лучше делать на отдельной плате...
Дальше... пишем программку..
- sashamelja
- Говорящий с текстолитом
- Сообщения: 1565
- Зарегистрирован: Пт янв 20, 2012 16:25:02
Re: Радиоуправлениe на модулях nRF24L01+
https://ru.aliexpress.com/item/High-Qul ... 18796.html
Так и зделаим масик мне скидал печатку драйвера, приемник завта нарисуем ,я думаю что за неделю я соберу в железе,пару деталек прикуплю и вперед
Так и зделаим масик мне скидал печатку драйвера, приемник завта нарисуем ,я думаю что за неделю я соберу в железе,пару деталек прикуплю и вперед
И опыт сын ошибок трудных и гений парадоксов друг
Re: Радиоуправлениe на модулях nRF24L01+
Приветствую Всех участников форума. Хотя мой паяльник и холодный потому что не включен и дорабатываю напильником кораблик что бы не вышел паровоз
. Да и версия не моя. Все равно форум почитать нахожу время что бы не пропустить самое интересное. Сейчас мокну лапу в миску со сметаной и как обычно пойдут дебаты. В данной конструкции не нравятся светодиоды по одному, как то не серьезно. Понимаю что есть аварийная сигнализация (теч воды и перегрев двигателя ) значить пора крутить винтом к берегу, а как же с предупредительной сигнализацией (уровень заряда батарей и потеря пакетов) на какой процент настроена на 50%, 40%, 10% или 1%, а может пора качать лодку или снимать сапоги да готовиться к заплыву
, потому что уже не кто ни куда не плывёт, просто приплыли. roman.com может все же прикрутим какой не будь мониторчик от телефончика для полного фен шуя, выбор конечно за Вами. Думаю пора переходить на новый уровень дизайна. Время еще есть, и я соберу четвертый комплект радио управления. sashamelja с печаткой поможет, у меня много работы последнее время, буду долго рисовать. roman.com что скажите.
- sashamelja
- Говорящий с текстолитом
- Сообщения: 1565
- Зарегистрирован: Пт янв 20, 2012 16:25:02
Re: Радиоуправлениe на модулях nRF24L01+
Я про индикацыю думал по разному
с экраном много проблем,5 индекацый по 5 светодиодов уже герлянеда а ето все садит акум
а так 5 светодиодов ошибок (норма не горим легкая проблема мигаем и так до полного свечения
я щитаю идеальний вариант и по денюгах супер(все просто и понятно)мигает плыви на берег,светитса снимай штаны
с экраном много проблем,5 индекацый по 5 светодиодов уже герлянеда а ето все садит акум
а так 5 светодиодов ошибок (норма не горим легкая проблема мигаем и так до полного свечения
я щитаю идеальний вариант и по денюгах супер(все просто и понятно)мигает плыви на берег,светитса снимай штаны
И опыт сын ошибок трудных и гений парадоксов друг
Re: Радиоуправлениe на модулях nRF24L01+
MASIK... так мы и не увидили видео работы твоего кораблика)) Ну если хочешь, то можно попробовать другой индикатор)) В железе не проверял, только в протеусе, но если сильно хочется, то можешь взять какой есть под рукой... проверим как работает в реале))
LCD индикаторы глючные... особенно от мобил. Стабильной работы от них пока не добился... Потом может поковыряю подробно))
Вот тестовая прошивка для проверки работы механики... сервы и двигателя... Далее.. надо определиться с индикатором. как он должен работать?
А вообще индикаторов существует целая куча))
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%.
И т.д. и т.п.))) Это всё не проблема)) Только все диоды часто будут мигать... будет мигающий пульт))) не знаю... это не очень приятно... для глаз... ))
Вот тестовая прошивка для проверки работы механики... сервы и двигателя... Далее.. надо определиться с индикатором. как он должен работать?
А вообще индикаторов существует целая куча))
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%.
И т.д. и т.п.))) Это всё не проблема)) Только все диоды часто будут мигать... будет мигающий пульт))) не знаю... это не очень приятно... для глаз... ))


