OSD на ATmega1281

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 стремится к нулю. Во всех алгоритмах, которые я смотрел, это только проблема конечной интерпретации.

varvar
msv:

Те. проц можно сконфигурировать, что-бы дернув ножкой можно аппаратно запустить таймер, который в свою очередь аппаратно запустит DMA?

Об этом я и пытаюсь сказать. Делалось вообще-то абсолютно другая вещь, но вот как-то вылезло, что и видео можно сформировать. Конверсионный продукт 😃 Сегодня подключил к реальному телевизору - понял, что слегка все не так красиво. PLL плавает - нужно все-таки кварц ставить 😦 , а не 32 кгц умножать до 24 мгц. Но в интернете ни разу не встречал, чтобы кто-то OSD делал на MSP. Разве что пинг-понг доисторический в старых аппликухах лежит.

Vlado

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

С этим разберемся I hope so.
Как с последними прошивками и фичами?

msv
Vlado:

Как с последними прошивками и фичами?

Модулятор вперед… 😃

Vlado
msv:

Модулятор вперед… 😃

Всмысле.
Ах да да да конечно
ближе к выходным посмотрим модулятор. Цветовая поднесущая 4.43, плюс полоса
цветоразностного сигнала, полагаю в районе 1-1.5МГц.