At the scouting Pakaweversgroep Neede we are doing A game called Labyrinth for some time now. We use A camera high in A tree and A monitor with A labyrinth sheet over it. 1 of the players sits behind the monitor and gives directions over A PMR porto to the other player.
Be-course I want to be able to transmit the video on Amateur television I had to figure out A way to overlay the labyrinth on my video signal.
I’ve been using the Arduino for sometime and found there was A video overlay shield called the video experimenter shield.
It was an opensource shield and the schematics where available at the. Nootropic Design website.
I used the same chip together with an Arduino UNO rom chip and made A pcb on experiment circuit board.
The schematic of the board:Note. the lm1881 is not in the Eagle lib so I used A op-amp picture instead, the numbers 1 til 8 are right but the picture isn’t.
I build everything together in A nice little box and its ready to use for the next Jota event.
Off course I had to write some software for the arduino. I used A programming interface but you can also program the chip in your arduino and then put it in your own pcb. The arduino code I used uses the tv out library and has 4 options which I can switch with the button on the front of the box. (this way I don’t have to reprogram the device every time I want to do something els) :
- labyrinth 1
- labyrinth 2
- my callsign
- my callsign with frequency
The code is included at the end of this page.
Some pictures of my TV screen with my amateur TV camera in the background and the osd over it:
The arduino code:
#include <TVout.h>
#include <fontALL.h>
TVout TV; //unsigned char x,y;
int zOff = 150;
int xOff = 0;
int yOff = 0;
int cSize = 50;
int view_plane = 64;
float angle = PI/60;
const int buttonPin = 11; // the pin that the pushbutton is attached to
int buttonPushCounter = 0; // counter for the number of button presses
int buttonState = 1; // current state of the button
int lastButtonState = 0; // previous state of the button
void setup()
{ TV.begin(PAL, 136,96);
initOverlay();
TV.select_font(font6x8);
TV.fill(0);
pinMode(buttonPin, INPUT);
Serial.begin(9600); }
void initOverlay() { TCCR1A = 0; // Enable timer1. ICES0 is set to 0 for falling edge detection on input capture pin.
TCCR1B = _BV(CS10); // Enable input capture interrupt
TIMSK1 |= _BV(ICIE1); // Enable external interrupt INT0 on pin 2 with falling edge.
EIMSK = _BV(INT0); EICRA = _BV(ISC11); } // Required to reset the scan line when the vertical sync occurs
ISR(INT0_vect) { display.scanLine = 0;
}
void loop() { buttonState = digitalRead(buttonPin);
if (buttonState != lastButtonState) {
if (buttonState == HIGH) { buttonPushCounter++;
Serial.print("number of button pushes: ");
Serial.println(buttonPushCounter, DEC); }
}
lastButtonState = buttonState;
if (buttonPushCounter == 4) { buttonPushCounter = 0; }
if (buttonPushCounter == 0) { TV.print(0, 87, " PE1BR"); }
if (buttonPushCounter == 1) { TV.print(0, 87, "144.700Mhz PE1BR"); }
if (buttonPushCounter == 2)
{ TV.draw_line(0,0,0,95,WHITE); //links boven links onder
TV.draw_line(13.6,0,134,0,WHITE); //links boven recht boven
TV.draw_line(134,0,134,95,WHITE); //rechts boven rechts onder
TV.draw_line(0,95,27.2,95,WHITE); //links onder rechts onder
TV.draw_line(0,13.6,27.2,13.6,WHITE);
TV.draw_line(40.8,13.6,134,13.6,WHITE);
TV.draw_line(40.8,0,40.8,13.6,WHITE);
TV.draw_line(13.6,27.2,120.4,27.2,WHITE);
TV.draw_line(120.4,40.8,120.4,27.2,WHITE);
TV.draw_line(106.8,40.8,120.4,40.8,WHITE);
TV.draw_line(0,40.8,93.2,40.8,WHITE);
TV.draw_line(93.2,27.2,93.2,40.8,WHITE);
TV.draw_line(13.6,54.4,120.4,54.4,WHITE);
TV.draw_line(13.6,54.4,13.6,81.6,WHITE);
TV.draw_line(27.2,68,120.4,68,WHITE);
TV.draw_line(120.4,68,120.4,81.6,WHITE);
TV.draw_line(120.4,81.6,134,81.6,WHITE);
TV.draw_line(27.2,81.6,27.2,95,WHITE);
TV.draw_line(0,81.6,106.8,81.6,WHITE);
TV.draw_line(40.8,95,134,95,WHITE); }
if (buttonPushCounter == 3)
{ TV.draw_line(0,0,0,95,WHITE); //links boven links onder
TV.draw_line(13.6,0,134,0,WHITE); //links boven recht boven
TV.draw_line(134,0,134,95,WHITE); //rechts boven rechts onder
TV.draw_line(0,95,27.2,95,WHITE); //links onder rechts onder
TV.draw_line(0,13.6,27.2,13.6,WHITE);
TV.draw_line(40.8,13.6,134,13.6,WHITE);
TV.draw_line(40.8,0,40.8,13.6,WHITE);
TV.draw_line(13.6,27.2,120.4,27.2,WHITE);
TV.draw_line(120.4,40.8,120.4,27.2,WHITE);
TV.draw_line(106.8,40.8,120.4,40.8,WHITE);
TV.draw_line(0,40.8,79.6,40.8,WHITE);
TV.draw_line(93.2,27.2,93.2,54.4,WHITE);
TV.draw_line(13.6,54.4,134,54.4,WHITE);
TV.draw_line(13.6,54.4,13.6,81.6,WHITE);
TV.draw_line(27.2,68,120.4,68,WHITE);
TV.draw_line(120.4,68,120.4,81.6,WHITE);
TV.draw_line(27.2,81.6,120.4,81.6,WHITE);
TV.draw_line(27.2,81.6,27.2,95,WHITE);
TV.draw_line(40.8,95,134,95,WHITE); }
delay (100);
TV.clear_screen();
}
Copyrights:
All software is distributed under the GNU/GPL licence.
All hardware and designs are distributed under a Creative Commons license Attribution-ShareAlike 2.5.