Ardupilot as an OSD - ONCE AGAIN

Hi there,

 

Maybe I has missed something, even after I exhaustively reading the threads on this forum, but why nobody gave atention to Mr Francesco Ferrara blog about using Ardupilot as a text overlay using his code?

 

I'm refering to this blog http://www.diydrones.com/profiles/blogs/ardupilot-as-osd-without

 

And this is the first demo code:

 

// ***********************************************************
// Project:  Ardupilot OSD test demo
// Copyright (C) 2010 by Francesco Ferrara
// ferrara@libero.it
//
// connect 0.3V reference in D7/AIN1
// connect videoIn/out to D6/AIN0
// connect D0/TX to D6 by a 330ohm resistor


#include <avr/delay.h>
#include <avr/sleep.h>

char tileset[]={
  // 48 Zero
  0,
  0b01110000,
  0b10001000,
  0b10011000,
  0b10101000,
  0b11001000,
  0b10001000,
  0b01110000,
  //49 One
  0,
  0b00100000,
  0b01100000,
  0b00100000,
  0b00100000,
  0b00100000,
  0b00100000,
  0b01110000, 
  //50 two
  0,
  0b01110000,
  0b10001000,
  0b00001000,
  0b00010000,
  0b00100000,
  0b01000000,
  0b11111000,
  //51 Three
  0,
  0b11111000,
  0b00010000,
  0b00100000,
  0b00010000,
  0b00001000,
  0b10001000,
  0b01110000,
  //52 Four
  0,
  0b00010000,
  0b00110000,
  0b01010000,
  0b10010000,
  0b11111000,
  0b00010000,
  0b00010000,
  //53 Five
  0,
  0b11111000,
  0b10000000,
  0b11110000,
  0b00001000,
  0b00001000,
  0b10001000,
  0b01110000,
  //54 Six
  0,
  0b01110000,
  0b10000000,
  0b10000000,
  0b11110000,
  0b10001000,
  0b10001000,
  0b01110000,
  //55 Seven
  0,
  0b11111000,
  0b00001000,
  0b00010000,
  0b00100000,
  0b01000000,
  0b10000000,
  0b10000000,
  //56 Eight
  0,
  0b01110000,
  0b10001000,
  0b10001000,
  0b01110000,
  0b10001000,
  0b10001000,
  0b01110000,
  //57 Nine
  0,
  0b01110000,
  0b10001000,
  0b10001000,
  0b01111000,
  0b00001000,
  0b00001000,
  0b01110000,
  // 10
  0,
  0,0,0,0,0,0,0,
  // 11 K/H
  0,
  0b10100000,
  0b10101010,
  0b11001010,
  0b10101110,
  0b10101010,
  0b00001010,
  0,
  // 12 .
  0,
  0b0,
  0b0,
  0b0,
  0b0,
  0b0,
  0b00011000,
  0b00011000,
  // 13 grade
  0,
  0b00011000,
  0b00100100,
  0b00100100,
  0b00011000,
  0b0,
  0b0,
  0b0,
};
// Interrupt handler for ANA_COMP_vect
//
int line=0;
byte state=0;
byte screen[]={
  10,10,11,10,3,6,0,13,10,0,0,0,0,0,10,10,10,0,12,0,1,10,10,10,1,1,6,12,3,11,10,10,10,10,10,10,10,10,10,10,10 };
int startline=50;
int frame=0;
byte buffer[40*8];
byte vcynccount;


ISR(ANALOG_COMP_vect) {
  //int val=;
  _delay_loop_1(1);
  if (ACSR & _BV(ACO))
  {

    if (TCNT1>=15*16)
    {
      vcynccount++;

      if (vcynccount>=5)
      {
        vcynccount=0;
        line=0;
        frame++;
        int temp=frame;
        screen[13]=temp%10;
        temp/=10;
        screen[12]=temp%10;
        temp/=10;
        screen[11]=temp%10;
        temp/=10;
        screen[10]=temp%10;
        temp/=10;
      }

    }
    else if (TCNT1 >= 3*16) {

      line++;
      byte offset=(line-startline)&7;

      if (line>=startline-16 && line<startline-8)
      {

        for(int i=0;i<40;i++)
        {
          buffer[i+offset*40]=tileset[screen[i]*8+offset];
        }
      }
      else if (line>=startline && line<=startline+8)
      {



        UDR0 = buffer[0];
        UCSR0B = _BV(TXEN0); // Start trasmission on D1
        UDR0 = buffer[1];
       
        for (int x=2;x<40;x++)
        {
          while (!(UCSR0A & _BV(UDRE0))) ;
          UDR0 = buffer[x+offset*40] ;

        }
        UCSR0B = 0;


      }
    }
  }
  else
    TCNT1=0;

}

void setup() {
  TCCR1B = _BV(WGM12) | _BV(CS10); // prescaler main freq/1 clear when OCR1 is reached
  OCR1A = 0xffff; // top count

  // D2 is output D6 is AIN0, D7 AIN1
  PORTD=0xff; // all on
  DDRD=0; // all D port input
 
  ADCSRB &= ~(1<<ACME);//disable multiplexer we take external reference no ADC
  ADCSRA&=~(1<<ADEN);//make sure ADC is OFF
  //ADMUX|=(0<<MUX2)|(1<<MUX1)|(1<<MUX0); //select ADC3 as negative AIN
  ACSR=
    (0<<ACD)| //Disable comparatore? no
    (0<<ACBG)| //don't Connect 1.1V reference to AIN0
    (1<<ACIE)| //Comparator Interrupt enable
    (0<<ACIC)| //input capture disabled
    (0<<ACIS1)|(0<<ACIS0) //set interrupt on toggle edge 1->0 0->1
    ;
  MCUCR |= _BV(PUD); // Pull-up disable override so when not used output is disconnected

  TIMSK0=0; // no timer interrupt
  TIMSK1=0;
  TIMSK2=0;

  // USART in MSPIM mode, transmitter enabled
  UCSR0C = _BV(UMSEL01) | _BV(UMSEL00); // MSPIM full control of USART
  // 0 is 8mhz pixel clock
  // 1 is 4mhz
  // 2 is 2.67mhz
  UBRR0 = 0 ; // freq/(2*(UBBR0+1))

  sei();//enable global interrupts
  set_sleep_mode(SLEEP_MODE_IDLE);
  sleep_enable();
}


void loop()
{
  while(1) {     // Infinite loop; interrupts do the rest
    sleep_mode();

    //PORTB^=0xff;
  }
}

#######################################################

 

What are the issues related to this code implementation?

Does Ardupilot has enough resources to deal with this code without lose performance on its main functions?

It's important to mention that this code was made for Ardupilot 2 using ATMega 328 microcontroller.

I really insist on this becouse I can take no more gadgets into my planes, and this code definetly eliminates a big one gadget: the entire OSD and its annoying wires.

 

Let's make it happen?

 

Regards

 

FPVCuritiba

 

You need to be a member of diydrones to add comments!

Join diydrones

Email me when people reply –

Replies

  • 3D Robotics
    It's very cool, but I have no idea how or even if it could be used with the APM code. Given how cheap dedicated OSD boards are, and how complex it would be to try to ingrate this in the current code without messing up timing and interrupts, I can see why people are reluctant to dive in.  The core dev team is working on a different OSD board.
This reply was deleted.

Activity