OSD на ATmega1281

torex777
sirQWERTY:

я не смог расшифровать

Катушка индуктивности 15мкГн +_10%

msv
Vlado:

есть ли чем поделиться

Работа проделано много, но пока нечего показать что-то интересное. Да и толком полетных испытаний еще не проводил…
За межсезонье:
Полностью переделал наземку. И железо и софт.
Много изменений ( почти все… 😃 ) в софте OSD/АП. Маленько причесал код, повыкидывал то, что не оправдало себя. Серьезно все упростилось, в тч за счет сознательного уменьшения точности. В результате код немного уменьшился в размере и заметно ускорился в основном за счет уменьшения операций с промежуточными long-ами. Т.е. появились резервы по процессорному времени еще что-нибудь влепить. Наконец переделал вывод пикселя за три такта, теперь разрешение экрана 256x160. Ну и конечно поддержка моего LRS.
Облетал новый носитель, в принципе доволен, но еще стоит поучить его летать… Облетывал на своей LRS, наземный тест до 200м- ни одного дропа (дальше поленился идти). В полете (пока только визуально) к РУ вопросов не было. В общем к сезону более-менее подготовился, жду когда подсохнет, а то новой камерой да прям в грязь плюхать… как-то не хочется.

Увлекся темой IMU… Хотя в инете полно видяшек с идеальной работой этих систем на столе, безупречного поведения в полете что-то пока не видно… 😃 Но тема сама по себе интересная, пока копаюсь в даташитах, теориях, рисую вращающиеся прямоугольники, вспоминая основы 3D-программирования (например вчера целый вечер вспоминал, как определить направление обхода многоугольника…😃 ). К сожалению серьезно подскочили цены на сенсоры на sparcfun. Относительно дешевые платки 9dof нашел только на ebay. Может кто даст наводку?..

ЗЫ Игорь, а вы запустили OSD с той прошивкой, которую я высылал?

alexeykozin
msv:

Может кто даст наводку?..

наводка store.diydrones.com/…/kt-arduimu-30.htm
надеюсь в скором времени собрать такую же немного дешевле (в основном за счет что сборка своими руками)
у нее уже все готово. по сериалу выдает ориентацию

Vlado

ЗЫ Игорь, а вы запустили OSD с той прошивкой, которую я высылал?

О спасибки. Собираюсь неспеша это делать, дел невпроворот поэтому интересуюсь по поводу новинок. Тоже камера + поворотный столик все уже намази. Довольно серьезно подготовился с антеннами и тд и тп. Если можно сбросте последнюю прошивку и пжлс фузы для ОСД, чтобы голову не ломать. Как что нибудь существенное нарисуется, покажу.

msv

Если можно сбросте последнюю прошивку и пжлс фузы для ОСД, чтобы голову не ломать. Как что нибудь существенное нарисуется, покажу.

Крайнюю версию можете скачать здесь: narod.ru/disk/…/osd_msv_v2_5.rar.html
Прошивка тщательно проверялась на симуляторе и на земле, но ни одного полета на ней еще не делал.
Фузы со своей платы скачать не могу, прошивки меняю через бутлоадер (им конечно фузы ни прочитать, ни поменять), программатор на работе, а плата на самолете, да и разъем надо паять( я его сделал, зашил фузы, бутлоадер и разобрал). Поэтому так же придется копать даташит. Думаю Вы сами справитесь… 😃

alexeykozin:

надеюсь в скором времени собрать такую же немного дешевле

Спасибо, неплохой вариант, и по нынешним ценам относительно недорогой. Но мечтается раза в три дешевле и можно без проца…
Как вот такое, сильно плохо?

Vlado

Крайнюю версию можете скачать здесь

А ну спасибки, посмотрим. Тогда спрошу если что.

Думаю Вы сами справитесь…

А что еще остается, халява она ведь всегда скользкая.😃

leprud
msv:

Как вот такое, сильно плохо?

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

16 days later
xrenb

Здравствуйте! Основное на плате припаял - прошить не получается 😦 (шью USBASP через winXP )программатор не видит проц .Помогите советом где рыть (монтаж проверил - соплей нет ) 😦

msv

Похоже не те ножки зацепили программатор. См. даташит “30.8.1 Serial Programming Pin Mapping”.

xrenb

Сразу пробывал ничего не читалось 😦 (в смысле с разъёма) Уже стал думать что спалил проц ненароком ,avr910 подключал не читался . Откинул стабилитроны с программатора - прочитался 😆Это уже радует ,теперь фьюзы осталось определить и прошить.

xrenb

Прошил , включил питание .Моргает светодиод на 31 ноге (для чего светодиоды и кнопки ?) на кварце 20 мег есть. В очках или на телеке ничего нет (камеру подключил ). Возможно чёта не так припаял (уважаемый MSV можно посмотреть фото вашей платки ?)

msv

Начнем с аналоговой части… В основе видео-микшера простейший каскад с общим коллектором. Проверьте его работу по постоянному току (цешкой). Видео должно проходить с камеры на передатчик даже при неработающей цифровой части.
(Питание на камеру/передатчик(лучше для начала видео-выход OSD сразу в телек) через соответствующий разъем OSD не забыли подать? 😃 )

xrenb

Хм по ходу я голова, два уха .На работе всё подключил - работает и картинка есть.

msv

Камера PAL? Пока только он поддерживается… Смотрите сигнал кадровой синхронизации с 3-ей ноги LM1881. Должны быть четкие одиночные импульсы 50Гц. Возможно потребуется увеличить резистор на 6-й ноге LM-ки до 1мОма. Или даже уменьшить резистор по ее входу до 470ом… На схеме показаны номиналы из даташита 1881, но жизнь иногда приподносит сюрпризы…
ЗЫ Пока я ответ сочинял все заработало? В чем была проблема?

xrenb

Я резистор на 6 ноге лм1881 не тот поставил ,680 ом вместо 680ком.Поменял и бежать перестало😒

3 months later
msv

Раз подняли тему, мой отчетец…
С уменьшением пиксела до 0.15мкс (три такта CPU) во всей красе вылезли цветные факела из-за того, что спектр OSD стал активно налазить на цветовую поднесущую… Простых идей, без полного вырезания из суммарного видео+OSD цветовой поднесущей и отдельным подмешивания к этому, чисто яркостному сигналу, исходной поднесущей пока нет…
Наконец разжился вертикальной пиропарой, любезно задаренной Сергеем (ubd). Забацал честную 3d-математику:


void GetAngleCurrent(void)
{
s_int a, x, y, z, x1;
s_long l, l1;

// Cur Sensor
x1=gADC_Val[ADC_SENSOR1]- gCalibr.SensorMid[0];
y=gADC_Val[ADC_SENSOR2]- gCalibr.SensorMid[1];
z=gADC_Val[ADC_SENSORZ]- gCalibr.SensorMid[2];
// Rotate
l=x1; l*=gSensor.COS_Matrix; a=(s_int)(l/128); // COS_Matrix=0..128
l=y; l*=gSensor.SIN_Matrix; x=a-(s_int)(l/128); // SIN_Matrix=0..128
l=x1; l*=gSensor.SIN_Matrix; a=(s_int)(l/128);
l=y; l*=gSensor.COS_Matrix; y=a+(s_int)(l/128);
// length vector
l=x; l*=x;
l1=y; l1*=y; l+=l1;
l1=z; l1*=z; l+=l1;
a=lsqrt(l);
// angle
gRollAngle=a_tan2(y, z); // +180..-180
gPitchAngle=a_sin(x, a); // +90..-90
if(gRollAngle>90 || gRollAngle<-90) gPitchAngle=-gPitchAngle;
// Trimm
gRollAngle-=gSensor.RollTrimmer;
if(gRollAngle>180) gRollAngle-=360;
else if(gRollAngle<-180) gRollAngle+=360;
gPitchAngle-=gSensor.PitchTrimmer;
if(gPitchAngle>90) gPitchAngle=180-gPitchAngle;
else if(gPitchAngle<-90) gPitchAngle=-180-gPitchAngle;
}

Конечно все как-то работает… Но после того как вывел в поля отладки значения сенсоров, не удивился, что все работает именно “как-то”… Может и не хуже, чем в других подобных проектах, но до идеала ой как далеко… Возможно проблема, что сами корпуса пиросенсоров в полете по разному нагреваются/охлаждаются от солнца/ветра и от этого сигнал диф. пары весьма сильно плывет…
Вообщем не зря народ поголовно переходит на IMU, наверное и мне пора… 😃

varvar

Недавно решил проверить, можно ли сгенерировать видео на MSP430 и LM1881 - был приятно удивлен - не можно, а, видимо, нужно 😃 Причем процессор и делать почти ничего не должен. Одно прерывание - от Vsync - сбрасываю счетчики. Hsync заведен на вход таймера - при приходе следующий таймер настораживается на время, когда должна пойти развертка своего изображения, ну и считает строки. Дальше процессор просто отдыхает автоматически выбрасывая посылки через SPI контроллером прямого доступа. Первый канал DMA выплевывает первый байт буферной строки по готовности настороженного таймера. Второй канал выплевывает в буфер SPI байты по его готовности, сколько байт закажешь. Все! И никаких разрывов. Нужно только буферную строку приготовить или если вся память используется как видеобуфер, менять адрес для DMA. Программа написана на С++, никаких ассемблерных вставок, и еще операционка успевает крутиться. Если это можно назвать программой - практически только аппаратуру инициализировать и несколько строк в обработчике прерывания. Внешнего кристалла не надо - внутри калиброванный генератор 32 кгц и умножитель - я поставил 24 мгц. При цене процессора 1.5-2 доллара - неплохо.
Никаких ухищрении для того, чтобы изображение не дышало не надо - все делается на железном уровне.
Сделать в двух строках еще один канал для вывода черных каемочек пока не получилось - всего 3 канала DMA, ставить процессор с 7 каналами не хочется - куда мне столько ног?
А на счет IMU - похоже, пора. Гироскоп с акселерометром в одном флаконе с доставкой уже продают дешевле 7 долларов. Можно поставить не нормальный кальман, а два простейших, выдрано из моей проверенной программы, в свою очередь откуда-то скопипасчено (налетят знатоки - по ушам надают за безграмотность и незнание арифметики, а свое решение все равно при себе оставят):

const float Sw[2][2]={0.001, 0.003, 0.003, 0.003};
  const float dT=0.05;
  const float Sz=0.07701688;

float roll_kalman_update(float gyro_rate, float accel_angle)
{
  float s_00;
  float angle_err;
  float K_00;
  float K_10;
  float AP[2][2];
  float APAT[2][2];
  float KCPAT[2][2];

  static float angle=0;
  static float bias=0;

  static float P[2][2];

  angle += dT*gyro_rate - dT*bias;
  angle_err = accel_angle - angle;
  s_00 = P[0][0] + Sz;
  if (s_00 == 0) s_00 = 0.001;

  AP[0][0] = P[0][0] - dT * P[1][0];
  AP[0][1] = P[0][1] - dT * P[1][1];
  AP[1][0] = P[1][0];
  AP[1][1] = P[1][1];

  K_00 = AP[0][0] / s_00;
  K_10 = AP[1][0] / s_00;
  angle += K_00 * angle_err;
  bias  += K_10 * angle_err;

  APAT[0][0] = AP[0][0] - AP[0][1] * dT;
  APAT[0][1] = AP[0][1];
  APAT[1][0] = AP[1][0] - AP[1][1] * dT;
  APAT[1][1] = AP[1][1];

  KCPAT[0][0] = K_00 * P[0][0] - K_00 * P[0][1] * dT;
  KCPAT[0][1] = K_00 * P[0][1];
  KCPAT[1][0] = K_10 * P[0][0] - K_10 * P[0][1] * dT;
  KCPAT[1][1] = K_10 * P[0][1];

  P[0][0] = APAT[0][0] - KCPAT[0][0] + Sw[0][0];
  P[0][1] = APAT[0][1] - KCPAT[0][1] + Sw[0][1];
  P[1][0] = APAT[1][0] - KCPAT[1][0] + Sw[1][0];
  P[1][1] = APAT[1][1] - KCPAT[1][1] + Sw[1][1];

  return angle;
}
msv

Владимир, надеюсь мои сомнения не воспримете как “…по ушам надают за безграмотность и незнание арифметики…”. 😃
DMA- замечательная штука… Но не решает проблемы неопределенностью времени входа в прерывание, которое, имхо, существует практически для всех процов в несколько тактов. Вы, для определения момента времени начала вывода строки, используете последовательно два прерывания, и вроде бы визуально строка должна заметно подергиваться по горизонтали.

По коду, конечно не разобрался с Вашим алгоритмом коррекции дрифта, но показалось, что для определения углов ориентации используете прямое интегрирование значения скорости поворота вокруг одной оси. Тут есть известная засада в том, что углы поворота вокруг осей не определяют ориентацию модели из-за некоммутативности (о, каких слов набрался…) этих поворотов…
Те. поворот на 90 вокруг оси X и поворот на 90 вокруг оси Y могут представлять две абсолютно разные ориентации в зависимости от порядка выполнения.

Я пока для начала хочу попробовать банальный DCM. Забавно, но похоже получиться уместить весь код и по объему и по скорости даже с float на меге8 …

ЗЫ Может у кого есть идеи по модулятору OSD, способному выдавать качественное наложение белого и черного без искажений исходной цветовой поднесущей?

varvar
msv:

DMA- замечательная штука… Но не решает проблемы неопределенностью времени входа в прерывание, которое, имхо, существует практически для всех процов в несколько тактов.

В этом случае решает. Прерывание время не определят - оно определяет, когда слудующий таймер аппаратно запустит DMA. Т.е. никакие критичные по времени операции программно не обрабатываются. Неопределенность исключительно с точностью до разности между Hsync и фронтом 24-мгц генератора.

С фильтром одна гадость есть - он не работает, когда самолет вверх ногами - там точка разрыва. Для стабилизированного полета не очень реальная ситуация, а для индикации - нужно фильтр дофильтровывать 😃 вручную, когда угол близок к 180. При проходе через разрыв фильтр действительно с ума сходит. Но не надолго 😃
Да, и я писал - алгоритм не мой, откуда-то скопированный и немного подправленный в основном для лучшей читаемости. Ответственности я за него не несу 😃, на авторство тем более не претендую.

msv

Те. проц можно сконфигурировать, что-бы дернув ножкой можно аппаратно запустить таймер, который в свою очередь аппаратно запустит DMA? Реально круто (как сказала бы младшая дочь), почти ПЛИС получается…
Мертвые углы это другая проблема… Тангаж всегда определен, поскольку это угол между осью X и горизонтальной плоскостью и имеет значения +90…-90град. А вот крен (+180…-180) при углах тангажа близких к 90град действительно неопределен, в чем даже вики сознается… Это видно и из выражения Roll=atan2(y, z);, где при тангаже близкому к ±90град Z стремится к нулю. Во всех алгоритмах, которые я смотрел, это только проблема конечной интерпретации.