Сама идея и код стырен hobby.msdatabase.ru/project-updates/…/modesw, :
передатчик инплантируется Arduino , один из выходов которой , генерирующий ШИМ (0-255) подключается вместо переменного резистора (крутилки) на передатчике, получается этакий импульсный преобразователь . Чем “выше” ШИМ тем больше напряжение подаваемое на вход АЦП передатчика. К Arduino подключаются в свою очередь, кнопки, переключатели, переменные резисторы значения которых и определяют частоту ШИМ на выходе платы.
На принимающей стороне Ardu подключается к соответствующему каналу приемника, задача платы определить ширину входящего импулса и в зависимости от его значения подключить соответсвующую нагрузку, а использовани функции myservo ,
позволяет управлять сервоприводами.
Исходный код, в части измерения длины импульсов, я до конца так и не постиг.
Но переделать автоматы преключения if () {} под свои хотелки получилось.
Кроме этого хотелось получить на принимающей стороне индикацию режимов работы посредством мигающих светодиодов. Чтобы не подвешивать контроллер вместо
delay() были использованы прерывания по совпадению на таймере Т2. Код был как обычно стырен arduino.ru/forum/…/preryvaniya-po-taimeru?page=1
Целью проекта является полной переход на управление моделью по одному каналу, однако для начала я перевел на один канал управление полетными режимами автопилота FY -41rcopen.com/forum/f90/topic316066
На Тх скетч:
#define AnalogOut 3// PWM out, с этого пина снимаем ШИМ 0- //255 т.е напряжение
#define AP_RC_ABM_BUTTON_PIN 7
#define AP_LRP_BUTTON_PIN 6
#define AP_NAV_BUTTON_PIN 5
#define LED_PIN_1 10 //red
#define LED_PIN_2 9 //Blye
#define LED_PIN_3 13 // Green
int SelBtn = 1; // default
int BtnLevels[5]; //обьявляем массив
boolean RCABM;
boolean LRP;
boolean NAV;
volatile int cntr;
volatile int cntr2;
int LEDBLINK;
void setup()
{
cntr=0;
TIMSK2 &= ~(1<<OCIE2A); // запрещение прерывания по совпадению таймера/счетчика Т2
TCCR2B = (1<<CS22)|(1<<CS21)|(0<<CS20); // прескалер на 256
TCCR2A &= ~((1<<WGM22) | (1<<WGM20)); // Режим работы таймера/счетчика устанавливаю в
TCCR2B |= (1<<WGM22); // Режим работы таймера/счетчика
ASSR &= ~(1<<AS2); // Выбор источника синхронизации таймера если
// AS2=0 от системного генератора
OCR2A = 250; // срабатывание таймера 16000000/256/250=250 раз в секунду
TIMSK2 |= (1<<OCIE2A); //Разрешение прерывания по совпадению.
// Serial.begin(9600);
BtnLevels[1] = 0; //RC 1000
BtnLevels[2] = 40; // ABC 1250
BtnLevels[3] = 80;// NAV 1500
BtnLevels[4] = 255;// LRP 1750
*/}
ISR(TIMER2_COMPA_vect)
{
cntr++;
if (cntr >50 ) { // через каждые 125 вызовов прерывания перекидываем состояние светодиода
digitalWrite(LED_PIN_3, !digitalRead(LED_PIN_3)); //&& cntr2<LEDBLINK*2
cntr=0;
cntr2++; }
if (cntr2>LEDBLINK*2) { digitalWrite(LED_PIN_3, LOW); }
if (cntr2>LEDBLINK*2+4) { cntr2=0; }
}
Comments
Целью проекта является полной переход на управление моделью по одному каналу
И всё-же непонятно, вы шим преобразуете в аналоговый сигнал через какие-то внутренние сглаживающие цепочки передатчика, а потом оцифровываете в приёмнике, или же передаёте чистый шим а в приёмнике меряете длину импульсов?
В любом случае ИМХО потеряете в помехоустойчивости и увеличится дискретность в управлении.
Все правильно.
И всё-же непонятно, вы шим преобразуете в аналоговый сигнал через какие-то внутренние сглаживающие цепочки передатчика, а потом оцифровываете в приёмнике, или же передаёте чистый шим а в приёмнике меряете длину импульсов?
В любом случае ИМХО потеряете в помехоустойчивости и увеличится дискретность в управлении.
Все правильно. ШИМ преобразуем в аналог, пульт аналог оцифровывает, причем на сглаживающем фильтре падает напряжение, таким образом сужается диапазон измерений. Передаем мы в любом случае PWM пачку, но нас интересует в данном случае ШИМ на одном из каналов (остальные работают в штатном режиме), на котором мы и измеряем длительность импульсов.
Дискретность однозначно увеличится, но для определенных задач (режимы АП, бано, каналы передатчика, настройка камеры и т.д) это не критично. Для управления ELE, ALE, RU по такому каналу однозначно понадобится автопилот, да и само управление в этом случае6 будет сводиться скорее к триммированию модели и корректировке курса. А вот с помехоустойчивостью, не соглашусь, в первом приближении она конечно снизится в разы, но если принять определенные меры и поменять алгоритм работы Rx и Tx то возможно даже удастся получить увеличение дальности и помехоустойчивости ( за счет увеличения дискретности в конечном счете конечно).
Василий, а такой мини подойдёт, если просто несколько “серв” или светодиодов вместо одной крутилки подключить ? amperka.ru/product/arduino-mini
Да Arduino-Mini конечно подойдет. Единственно , что перепрошивать его придется ISP программатором или вот такой штукой amperka.ru/product/usb-serial-converter. Я на передатчик поставил Nano, чтоб можно было перепрошивать прямо с ПК, а на самоль Mini - места меньше занимает. Главное правило Мега на плате должна быть 386 или 168 ( в противно возможно придется перенастраивать тймер - счетчики), а так хоть Uno поставьте (там тоже 386 мега). Ну и вам в любом случае понадобиться хоть одна плата с USB выходом, чтобы иметь возможность отстроить свой код с использование окна терминала.
Спасибо ! Есть желание По “незанятому” каналу поднимать ножки (серву), включать маячок, щёлкать фотоаппаратом. А на отдельной платке - светАдиодный индикатор режимов полёта - например при возврате домой - красно-синяя мигалка 😁. Надысь как раз в Амперке заказал свой первый набор. Мож разберусь. 😒
Ну во первых почему индикатор полетов на отдельной платке? Под мигания как раз ISR (прерывания) в програмке имеются(чтоб не занимать процессорное время), а ног у меги достаточно под все ваши хотелки. А во вторых индикатор режимов полета я по факту оставил только на передатчике … на самоле мигающие светодиоды пригодились только в процессе настройки, в полете с земли их невидно…
У меня Нова(СХ-20) с ОСД-миним. Так как ноги отвалились ещё на стадии покупки, я собрал отдельное аллюминивое съёмное шасси - для всех экспериментов. Там ОСД сейчас со входом Тх и Рх от квада. Там два ДС-ДС - 8В (для подвеса) и 5В для ОСД . В планах именно в шасси и встроить ответную часть (дешифратор) на управление “вкусняшками” и именно отдельную платку для съёма со входа ОСД (а может САМО ОСД так может ?!) для индикации режимов - пульт-то мож и “отдал”- можно и на нём увидеть, а вот что уже переключилось - должно шасси “отморгать” при переключении и выдать “нужный” цвет. Планов, конечно … Не уверен, поддастся ли мне программирование😵, но попа-робовать-то я могу ! 😒
отдельную платку для съёма со входа ОСД не совсем понятно, что вы хотите со входа ОСД снимать? Если у вас на ОСД выделен отдельный канал для управления режимами работы, тогда да можно на этот канал посадить ардуину и ис нее всем и управлять , в том числе и ОСД.
поддастся ли мне программирование😵, но попа-робовать-то я могу !
Если хотите попробовать программировать, то не ждите посылку с арду, а изучайте язык и среду прогрммирования.
Кстати на амперке есть много хороших материалов и ссылок…
отдельную платку для съёма со входа ОСД не совсем понятно
Т.е. у меня уже стоит платка ОСД-миниМ , которая по ФПВ отдаёт на земной монитор инфу, в том числе и состояние “режима полёта”. Она - на борту. И световую индикацию светодиодами именно режимов полёта (именно на корпусе копа) , наверное, можно именно к ней кака-то подключить, а не городить отдельную платку . Т.е. Контроллер копа (надеюсь) отдаёт на ОСД состояние режимов полета только тогда, когда уже переключился (а не тогда, когда сигнал на переключение пришёл). Значит эт инфа “по факту срабатывания”, что важнее.
Осталось понять, как “раскрасить” эти режимы -
отдельной и специально переделанной (подкл светодиоды и откл питание аналоговой части) платкой , подключённой к Тх параллельно действующей ОСД
или есть возможность “найти концы” в той, которая УЖЕ “отзванивается на землю-монитор”. 😃
Ну контроллер (он же Автопилот как понимаю) связывается с ОСД по какому либо протоколу, скорее всего UART или I2C. Чтобы вытащить из этого потока какую либо инфу вы должны: А-знать кодировку, какая последовательность битов, что обозначает (ну получите вы с выхода пи пи пи и че с этим делат?) и В - уметь пользоваться библиотекой работающей с этими протоколами. Осмелюсь предположить ни того ни другого вы не имеете. Так что про Тх забудте (по крайней мере на ближайшие пол года).
Подключать светодиоды к ОСД тоже думаю не самая удачная идея . Для этого вы должнв взять прошивку (програмку) для ОСД и дописать к ней свой код(не запоганив прогу ОСД), а затем прошить эту свою програмку в ОСД. Даже если предположить, что вы крутой программер и сможете это сделать, то совершенно не факт , что на микркотроллере ОСД есть свободные ресурсы (незадействованные таймер счетчики, порты вывода и свободная память ) для выполнения дополнительных функций по миганию светодиодом.
или есть возможность “найти концы” в той, которая УЖЕ “отзванивается на землю-монитор”. 😃
ОСД не гонит на монитор информацию ( как это ни странно) оно всего лишь накладывает на видеоизображение свою картинку
и из видеопотока вы не выудите никакой информции. Есть конечно системы которые передают по видеотракту доп информацию , но там их тоже надо отфильтровать, расшифровать и т.д.
Так, что самый простой способ убедится, что режим переключился померить ШИМ в управляющем канале, как вариант на приемнике, а залезать в мозги Автопилоту (или ОСД) совершенно не тривиальная задача.
Учите матчасть, читайте мурзилку на амперке, многие вопросы сами отпадут…
Жду - не дождусь, когда “юнный ардуинец” придёт, а то самоучитель без пиа-нино не воспринимается 😁
{"assets_hash":"a8b26fa7f6e768b07a72c8c9aadb9422","page_data":{"users":{"4466c5063df955007778b1a8":{"_id":"4466c5063df955007778b1a8","hid":14087,"name":"RDL_Rider","nick":"RDL_Rider","avatar_id":null,"css":""},"50063c2a3df955007774201c":{"_id":"50063c2a3df955007774201c","hid":122518,"name":"vasia","nick":"vasia","avatar_id":null,"css":""},"53d4a4b63df9550077727045":{"_id":"53d4a4b63df9550077727045","hid":205470,"name":"gosha57","nick":"gosha57","avatar_id":null,"css":""}},"settings":{"blogs_can_create":false,"blogs_mod_can_delete":false,"blogs_mod_can_hard_delete":false,"blogs_mod_can_add_infractions":false,"can_report_abuse":false,"can_vote":false,"can_see_ip":false,"blogs_edit_comments_max_time":30,"blogs_show_ignored":false,"blogs_reply_old_comment_threshold":30,"votes_add_max_time":168},"entry":{"_id":"546985279970730077110fdd","hid":19638,"title":"Управление через один канал несколькими нагрузками (да и вообще самолетом)","html":"<p>Сама идея и код стырен <a href=\"http://hobby.msdatabase.ru/project-updates/theresultsofoursurvey/modesw\" class=\"link link-ext link-auto\" data-nd-link-type=\"autolink\" data-nd-link-orig=\"http://hobby.msdatabase.ru/project-updates/theresultsofoursurvey/modesw\" target=\"_blank\" rel=\"nofollow noopener\">hobby.msdatabase.ru/project-updates/…/modesw</a>, :<br>\nпередатчик инплантируется Arduino , один из выходов которой , генерирующий ШИМ (0-255) подключается вместо переменного резистора (крутилки) на передатчике, получается этакий импульсный преобразователь . Чем “выше” ШИМ тем больше напряжение подаваемое на вход АЦП передатчика. К Arduino подключаются в свою очередь, кнопки, переключатели, переменные резисторы значения которых и определяют частоту ШИМ на выходе платы.<br>\nНа принимающей стороне Ardu подключается к соответствующему каналу приемника, задача платы определить ширину входящего импулса и в зависимости от его значения подключить соответсвующую нагрузку, а использовани функции myservo ,<br>\nпозволяет управлять сервоприводами.<br>\nИсходный код, в части измерения длины импульсов, я до конца так и не постиг.<br>\nНо переделать автоматы преключения if () {} под свои хотелки получилось.<br>\nКроме этого хотелось получить на принимающей стороне индикацию режимов работы посредством мигающих светодиодов. Чтобы не подвешивать контроллер вместо <!--cut</p>-->\n<a href=\"http://arduino.ru/Reference/Delay\" class=\"link link-ext\" data-nd-link-orig=\"http://arduino.ru/Reference/Delay\" target=\"_blank\" rel=\"nofollow noopener\">delay</a>() были использованы прерывания по совпадению на таймере Т2. Код был как обычно стырен <a href=\"http://arduino.ru/forum/programmirovanie/preryvaniya-po-taimeru?page=1\" class=\"link link-ext link-auto\" data-nd-link-type=\"autolink\" data-nd-link-orig=\"http://arduino.ru/forum/programmirovanie/preryvaniya-po-taimeru?page=1\" target=\"_blank\" rel=\"nofollow noopener\">arduino.ru/forum/…/preryvaniya-po-taimeru?page=1</a><br>\nЦелью проекта является полной переход на управление моделью по одному каналу, однако для начала я перевел на один канал управление полетными режимами автопилота FY -41<a href=\"https://rcopen.com/forum/f90/topic316066\" class=\"link link-int link-auto\" data-nd-link-type=\"autolink\" data-nd-link-orig=\"https://rcopen.com/forum/f90/topic316066\">rcopen.com/forum/f90/topic316066</a><br>\nНа Тх скетч:<br>\n#define AnalogOut 3// PWM out, с этого пина снимаем ШИМ 0- //255 т.е напряжение<br>\n#define AP_RC_ABM_BUTTON_PIN 7<br>\n#define AP_LRP_BUTTON_PIN 6<br>\n#define AP_NAV_BUTTON_PIN 5<br>\n#define LED_PIN_1 10 //red<br>\n#define LED_PIN_2 9 //Blye<br>\n#define LED_PIN_3 13 // Green<br>\nint SelBtn = 1; // default<br>\nint BtnLevels[5]; //обьявляем массив<br>\nboolean RCABM;<br>\nboolean LRP;<br>\nboolean NAV;<br>\nvolatile int cntr;<br>\nvolatile int cntr2;<br>\nint LEDBLINK;<br>\nvoid setup()<br>\n{<br>\ncntr=0;<br>\nTIMSK2 &= ~(1<<OCIE2A); // запрещение прерывания по совпадению таймера/счетчика Т2<br>\nTCCR2B = (1<<CS22)|(1<<CS21)|(0<<CS20); // прескалер на 256<br>\nTCCR2A &= ~((1<<WGM22) | (1<<WGM20)); // Режим работы таймера/счетчика устанавливаю в<br>\nTCCR2B |= (1<<WGM22); // Режим работы таймера/счетчика<br>\nASSR &= ~(1<<AS2); // Выбор источника синхронизации таймера если<br>\n// AS2=0 от системного генератора<br>\nOCR2A = 250; // срабатывание таймера 16000000/256/250=250 раз в секунду<br>\nTIMSK2 |= (1<<OCIE2A); //Разрешение прерывания по совпадению.<br>\n// Serial.begin(9600);<br>\nBtnLevels[1] = 0; //RC 1000<br>\nBtnLevels[2] = 40; // ABC 1250<br>\nBtnLevels[3] = 80;// NAV 1500<br>\nBtnLevels[4] = 255;// LRP 1750</p>\n<p>//TCCR1B = 0x01; //force pwm<br>\n//delay(100);</p>\n<p>pinMode(AP_RC_ABM_BUTTON_PIN, INPUT_PULLUP);<br>\npinMode(AP_LRP_BUTTON_PIN, INPUT_PULLUP);<br>\npinMode(AP_NAV_BUTTON_PIN, INPUT_PULLUP);<br>\npinMode (LED_PIN_1, OUTPUT);<br>\ndigitalWrite(LED_PIN_1,LOW);<br>\npinMode (LED_PIN_2, OUTPUT);<br>\ndigitalWrite(LED_PIN_2,LOW);<br>\npinMode (LED_PIN_3, OUTPUT);<br>\ndigitalWrite(LED_PIN_3,LOW);<br>\n}</p>\n<p>void loop()<br>\n{<br>\nRCABM = digitalRead(AP_RC_ABM_BUTTON_PIN);<br>\nLRP = digitalRead(AP_LRP_BUTTON_PIN);<br>\nNAV = digitalRead(AP_NAV_BUTTON_PIN);</p>\n<p>if (!RCABM) { SelBtn=1; digitalWrite(LED_PIN_1,LOW);digitalWrite(LED_PIN_2,LOW);digitalWrite(LED_PIN_3,LOW);}//RC 0 не горит<br>\nif (RCABM && LRP&& NAV ) { SelBtn=2; digitalWrite(LED_PIN_1,LOW);digitalWrite(LED_PIN_2,LOW);digitalWrite(LED_PIN_3,HIGH);}//ABC 80 зеленый<br>\nif (!NAV&& LRP&& RCABM) { SelBtn=3; digitalWrite(LED_PIN_1,LOW);digitalWrite(LED_PIN_2,HIGH);digitalWrite(LED_PIN_3,LOW);}//NAV 160 голубой<br>\nif (!LRP && RCABM) { SelBtn=4; digitalWrite(LED_PIN_1,HIGH);digitalWrite(LED_PIN_2,LOW);digitalWrite(LED_PIN_3,LOW);}//LRP 240 красный</p>\n<p>analogWrite (AnalogOut, BtnLevels[SelBtn]); // то пишется соответ знач массива</p>\n<p>/*<br>\nSerial.print (“RCABM:”);<br>\nSerial.print(RCABM);<br>\nSerial.print (“\\\\LRP:”);<br>\nSerial.print(LRP);<br>\nSerial.print (“\\\\NAV:”);<br>\nSerial.println(NAV);<br>\nSerial.print("BtnLevels[SelBtn]<span class=\"emoji emoji-blush\" data-nd-emoji-src=\":blush:\">😊</span>;<br>\nSerial.println(BtnLevels[SelBtn]);<br>\nSerial.print(“SelBtn:”);<br>\nSerial.println(SelBtn);<br>\n//Serial.print(“ch11:”);<br>\n//Serial.println(ch11);</p>\n<p>delay(3000);</p>\n<p>*/}<br>\nISR(TIMER2_COMPA_vect)<br>\n{<br>\ncntr++;<br>\nif (cntr >50 ) { // через каждые 125 вызовов прерывания перекидываем состояние светодиода<br>\ndigitalWrite(LED_PIN_3, !digitalRead(LED_PIN_3)); //&& cntr2<LEDBLINK*2<br>\ncntr=0;<br>\ncntr2++; }<br>\nif (cntr2>LEDBLINK*2) { digitalWrite(LED_PIN_3, LOW); }<br>\nif (cntr2>LEDBLINK*2+4) { cntr2=0; }</p>\n<p>}</p>\n","user":"50063c2a3df955007774201c","ts":"2014-11-17T05:18:31.000Z","st":1,"cache":{"comment_count":12,"last_comment":"5486fc3d9970730077131364","last_comment_hid":12,"last_ts":"2014-12-09T13:42:21.000Z","last_user":"53d4a4b63df9550077727045"},"views":1829,"bookmarks":0,"votes":0},"subscription":null},"locale":"en-US","user_id":"000000000000000000000000","user_hid":0,"user_name":"","user_nick":"","user_avatar":null,"is_member":false,"settings":{"can_access_acp":false,"can_use_dialogs":false,"hide_heavy_content":false},"unread_dialogs":false,"footer":{"rules":{"to":"common.rules"},"contacts":{"to":"rco-nodeca.contacts"}},"navbar":{"tracker":{"to":"users.tracker","autoselect":false,"priority":10},"forum":{"to":"forum.index"},"blogs":{"to":"blogs.index"},"clubs":{"to":"clubs.index"},"market":{"to":"market.index.buy"}},"recaptcha":{"public_key":"6LcyTs0dAAAAADW_1wxPfl0IHuXxBG7vMSSX26Z4"},"layout":"common.layout"}