Телеметрия (часть 1)
Почитал про сложную обработку данных по высоте у smalltim и других создателей телеметрий, почитал про “плавающие окна”, про хитрые форумлы и т.п. Не понял ни слова 😦
У меня такой вопрос - к чему такие сложности? В своих экспериментах я тупо опрашивал АЦП 20 раз, суммировал результат и делил на 20, после чего выводил на экран 😃 После устранения нескольких багов в коде, альтиметр с разрешением 1 метр показывает высоту четко, без шумов вообще. Вариометр с разрешением 0.5 м/c вел себя так же
Почитал про сложную обработку данных по высоте у smalltim и других создателей телеметрий, почитал про “плавающие окна”, про хитрые форумлы и т.п. Не понял ни слова 😦
У меня такой вопрос - к чему такие сложности? В своих экспериментах я тупо опрашивал АЦП 20 раз, суммировал результат и делил на 20, после чего выводил на экран 😃 После устранения нескольких багов в коде, альтиметр с разрешением 1 метр показывает высоту четко, без шумов вообще. Вариометр с разрешением 0.5 м/c вел себя так же
С плавающим окном ты бы имел то же самое, но получал данные в 20 раз быстрее. то есть не терял бы 20 выборок.
А реализация проста. В цикле забиваешь массив выборками, когда забил - суммируешь. Потом следующую выборку записываешь в нулевой элемент. Суммиирование. Следующая - в первый элемент. Суммирование.
То есть последовательно перезаливаешь массив, с каждым элементом делая новую сумму. Частота получения данных равна частоте выборке АЦП, качество подавления шумов выше чем у простой суммы. Единственное неудобство - надо сначала залить массив и тллько потом получать данные.
Так работают сигиа-жельта АЦП кстати.
Ещё его называют алгоритмом скользящего среднего.
Спасибо, после вашего объяснения все стало понятно!
(это я под другим аккаунтом заходил)
в схеме smalltim’а все нарисовано. Камеру к меге подключать не нужно, нужно всего лишь подцепить “видеовыход” схемы к проводу “камера-видеопередатчик” паралельно
Можно чучуть поподробней. У меня камера KX171 c rangvideo.com www.rangevideo.com/index.php?main_page=product_inf…
на неё идёт 12 вольт и жолтый провод сигнала. Если я правлено понял то мне нужно ноль от схемы кинуть на минус а сигнал на жолтый провод. Ещё вопрос, какое напряжение должно быть на выходе сигнала, тоесть если я тестером замерю, ноль это минус а сигнал плюс. Я понимаю что это аналоговый сигнал, просто осциллографа у меня нет а сровнять каскады как то нужно. Таким способом я померел выход с приёмника от rangevideo там примерно 3 вольта, а у меня 1,5 с платы выходит 😃 . А если на камере мерю, тоесть минус на минус, а плюс на сигнал, то вообще 0 вольт кажет, хотя камера работает нармуль 😵
Вот ещё, поправьте если я неправильно понимаю (просто разобраться охото во всём). Я цепляю сигнал на разъём V-IN чипа LM1881N (как я понял прошивать его не надо он сразу всё умеет). Выходы HSYNC и VSYNC кидаю на ноги Atmega8. Этот LM1881N раскладывает сигнал на вертикальные и горизонтальные составляющие и дёргает эти ноги по достижению переходов по линиям или точкам линии. В программе Atmega8 описываю прерывания этих ног на которые я подал HSYNC и VSYNC. Ввожу переменные строки и точки в строке, отсчитываю нужную мне точку и на некую ножку кидаю 1. Эту ножку на которую выкидываю 1 я соединяю на выход PAL. В итоге вход и выход это один провод, разделяются только сопротивлениями, на вход 510 ом и кодёр на 0,1 микро фарад, на выход 120 ом. В итоге сверху на сигнал накладываю белые пиксели.
2All
Народ, а насколько необходимо отображать в телеметрии потребляемый от акков ток?..
ИМХО вполне достаточно знать напряжения силового и аппаратурного акка (ну либо одного общего).
А то мне тут советуют датчик тока сделать… Но это ж шунт лепить на плату, и всё равно точность ±лапоть, не считая нагрева… 😕 Проводов, опять же, больше. Что скажете?
2All
Народ, а насколько необходимо отображать в телеметрии потребляемый от акков ток?..
ИМХО вполне достаточно знать напряжения силового и аппаратурного акка (ну либо одного общего).
А то мне тут советуют датчик тока сделать… Но это ж шунт лепить на плату, и всё равно точность ±лапоть, не считая нагрева… 😕 Проводов, опять же, больше. Что скажете?
Я не стал связываться, знать ток, конечно, интересно, но индикации напряжения и так достаточно.
maloii:
Ага, всё так, только прерывания от лм1881 - не точки и строки, а моменты перехода к новому кадру/новой строке.
Ох, не выходит чтото каменный цветок. Подскажите гуру, где я неправильно что сделал.
Подключил всё как у smalltim. Диод только свето поставил. Прошиваю, всё ок, пробую, эран немного тускнеет, делаю в строчке заместо 1 на PORTD.7 ставлю 0, экран светлеет обратно и вообще как бы ничего и не происходило. А по сути должна линия белая показаться как я понимаю.
попробовал прошить прошивкой smalltim, но у меня датчики не подключенны к меге, стали белые полоски прыгать по экрану 😵 .
#incl*ude <mega8.h>
#incl*ude <delay.h>
int i=0;
// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
if(i>100 && i<200){
PORTD.7 = 1;
}
i++;
}
// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
i=0;
}
// Declare your global variables here
void main(void)
{
// Declare your local variables here
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;
// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;
// Port D initialization
// Func7=Out Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=1 State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x80;
DDRD=0x80;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Any change
// INT1: On
// INT1 Mode: Any change
GICR|=0xC0;
MCUCR=0x05;
GIFR=0xC0;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// Global enable interrupts
#asm("sei")
while (1)
{
// Place your code here
};
}
А по сути должна линия белая показаться как я понимаю.
Забыли обнуление PORTD.7.
щас стали показываться, но както не супер. всё дёрается и точки явно длинные. Должно получится две малюсьникие полокси, а получается 2 длиноватые полоски и ещё и дёргаются 😵
#incl*ude <mega8.h>
#incl*ude <delay.h>
int i=0;
int t=0;
int start_line=100;
// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
if (i>start_line && i<start_line+2) {
t=30;
while(t--) { #asm("nop"); }
PORTD.7 = 1;
PORTD.7 = 1;
PORTD.7 = 0;
PORTD.7 = 0;
PORTD.7 = 1;
PORTD.7 = 1;
PORTD.7 = 0;
}
i++;
}
// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
i=0;
}
// Declare your global variables here
void main(void)
{
// Declare your local variables here
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;
// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;
// Port D initialization
// Func7=Out Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=1 State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x80;
DDRD=0x80;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Any change
// INT1: On
// INT1 Mode: Any change
GICR|=0xC0;
MCUCR=0x05;
GIFR=0xC0;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// Global enable interrupts
#asm("sei")
}
>щас стали показываться, но както не супер. всё дёрается и точки явно длинные. Должно получится
>две малюсьникие полокси, а получается 2 длиноватые полоски и ещё и дёргаются 😵
А частота процессора какая?
А кто будет отправлять процессор баиньки после обработки прерывания? Меня учили, что без баиньки время реакции на прерывание может раз от раза отличаться на несколько тактов.
щас стали показываться, но както не супер. всё дёрается и точки явно длинные. Должно получится две малюсьникие полокси, а получается 2 длиноватые полоски и ещё и дёргаются 😵
Посмотри ассемблерный листинг, имхо компилер
PORTD.7 = 1;
PORTD.7 = 1;
PORTD.7 = 0;
PORTD.7 = 0;
PORTD.7 = 1;
PORTD.7 = 1;
PORTD.7 = 0;
оптимизирует. Причём только ту часть, которая обнуляется, превращая в одну команду CLR.
#incl*ude <mega8.h>
#incl*ude <delay.h>
А что за инклюды такие?..
И фьюзы менялись? Может, мега от встроенного на 1 МГц молотит?
кварц поставил на 16 мГц. А как проц в баиньки отправлять?
Программирую с помощью ARV Studio программатором AT AVR ISP2 www.chip-dip.ru/product0/751853999.aspx. Могу ли я с помощью него проверить на какой частоте работает проц и на сколько он загружен? Просто может у меня кварц не пашит 😮
фьюзы не менял, а какие нужно ставить?
>А как проц в баиньки отправлять?
asm sleep в бесконечном цикле в главной функции:)
>фьюзы не менял
Понятно. 1 МГц от встроенного генератора. См тему телеметрия на несколько страниц ранее, я прикладывал скриншот с фьюзами.
Чтото уже более осмысленное стало выводится но не до конца. По логике вещей должна вывестись одна линия, но выводится 2, плюс они очень реагируют на внешние факторы, видео прилагаю. sale-music.com/MPEG0002.AVI
#incl*ude <mega8.h>
#incl*ude <delay.h>
int i=0;
int start_line=200; // íà÷èíàåì âûâîä ñ ëèíèè íîìåð 100
// ñàì òåñòîâûé ñèìâîë (íàðèñîâàí 0 åäèíè÷êàìè)
// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
if (i>start_line && i<start_line+90) {
delay_us(20);
PORTD.7 = 1;
PORTD.7 = 1;
PORTD.7 = 1;
PORTD.7 = 1;
PORTD.7 = 0;
}
i++;
}
// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
i=0;
}
// Declare your global variables here
void main(void)
{
// Declare your local variables here
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;
// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;
// Port D initialization
// Func7=Out Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=1 State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x80;
DDRD=0x80;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Any change
// INT1: On
// INT1 Mode: Any change
GICR|=0xC0;
MCUCR=0x05;
GIFR=0xC0;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// Global enable interrupts
#asm("sei")
PORTD.7 = 0;
while (1)
{
#asm("sleep")
};
}
Разобрался, диод на выходе тупой был. там простой светодиод я поставил, щас поставил BAS16 и нармуль стало всё. Только лини всёравно 2 😦
Фух, разобрался, только чтото оптимизация никуда у codeVisoinAVR с C , выводит медленно и печально. smalltim, выложите пожалуйста если можно кусочек кода на ассемблере вывода строк. Я в ассемблере слаб и всю Вашу прошивку не осилил 😦 , так сказать всё от туда выкинуть кроме вывода пару цифорок. Буду очень признателен. 😒
Всё оттуда выкинуть кроме пары циферок не получится.
Общая суть действий такова:
- Кушаем в регистр А 8-битовое значение, которое есть горизонтальное сечение битовой матрицы символа 8х8
- Выводим старший бит регистра в порт D.7
- Сдвигаем регистр А влево
- Идем на шаг 2.
Так выводится одна восьмая часть одного символа.
>выводит медленно и печально
Так заведите ж проц на 16 МГц.
Залейте мою тестовую прошивку, чтоб по тому, что творится на экране, проверить частоту.
Так заведите ж проц на 16 МГц.
Залейте мою тестовую прошивку, чтоб по том, что творится на экране, проверить частоту.
По вашим тестовым прошивкам всё откалибровал. Работает изумительно. буковки и цыфорки маленькие и окуратненькие кажет, а как пишу на С в codeVisionAVR так один бит не очень похож на пиксель, а похож на продолговатую линию. Вот тут читаю, ребята так же парятся electronix.ru/forum/index.php?showtopic=41013&st=0.
// INT0: On
// INT0 Mode: Any change
// INT1: On
// INT1 Mode: Any change
Стоп, а вот это что такое?
У Вас прерывания возникают и по нарастающему и по спадающему фронту сигнала с лм1881, отсюда и 2 полосы, и каждая строка как две считается. Поставьте, чтоб прерывания только по спадающему фронту возникали.
А неустойчивость относительно собственно содержимого видеосигнала у лм1881 может случаться, камеры-то у всех разные. Поставьте на входе видеосигнала в лм1881 подстроечник, поиграйтесь с его сопротивлением.
>попробовал прошить прошивкой smalltim, но у меня датчики не подключенны к меге, стали белые полоски прыгать по экрану
Не, что-то у Вас было не так. Без датчиков высота-скорость-температура будут нули, но всё остальное должно быть как обычно.
Но я так понимаю, сейчас у Вас мои прошивки нормально заработали.
В общем, правильнее всего, как и ожидалось, писать всё на C со вставками ассемблера в критических местах. У меня лицензионной среды с С нету, так что обхожусь ассемблером…
Спасибо, буду разбираться с прерываниями, я ведь только учюсь, а настройки мне codeVisionAVR сгенерила
Про пирометры: я и раньше скептически к ним относился - а ну как поведет себя самолетик если будет пролетать мимо деревьев и домов? Крениться? 😃
А добила меня мысль о том, что в один из пирометров может заглянуть солнышко. Человек, который эту систему пользовал, подтверждает: в таком случае начинаются опаньки.
Про пирометры: я и раньше скептически к ним относился - а ну как поведет себя самолетик если будет пролетать мимо деревьев и домов? Крениться? 😃
Самолет можно будет сбивать зеркальцем, как жители Сиракуз римские корабли.
Тут где-то обсуждается тема про цифровые магнитные компасы. Что если поставить трехосевой датчик, откалибровать его перед запуском, и он будет выяснять положение самолета относительно вектора Магнитного Поля Земли в данный момент полета. А от вектора МПЗ через калибровочные углы переходим к положению относительно горизонта. Ну и выравниваем, чтобы он был горизонтален. А азимутальную составляющую результатов компаса можно выводить на OSD 😃
Что если поставить трехосевой датчик, откалибровать его перед запуском, и он будет выяснять положение самолета относительно вектора Магнитного Поля Земли в данный момент полета.
К сожалению, не получится однозначно определять положение. Представим ситуацию, когда одна ось датчика параллельна вектору магниного поля. Две другие оси будут выдавать нули. При этом получается неопределенность - можно вращать модель вокруг первой оси на 360 градусов, а выходы датчиков будут одинаковыми.
Я даже пытался испытывать такую систему, пока не напоролся на эти очевидные грабли.
Что касается пирометров. Если на них стоят ИК фильтры на 8-14 мкм, то Солнца они не увидят.
maloii, в компиляторе Си нужно поставить оптимизацию по скорости (в cvAVR по умолчанию стоит оптимизация по размеру).
Project -> configure -> c compiler -> optimize for: speed
после этого вывод станет в 2 раза быстрее
Вот тут читаю, ребята так же парятся electronix.ru/forum/index.php?showtopic=41013&st=0.
Это как раз я там и парился 😃 Почитайте ту тему до конца, там все ответы есть, я дошел до вывода нормальных циферок 😇