Generating Composite Video

I've been trying to generate some composite video signals based on the following website
http://www.rickard.gunee.com/projects/video/pic/howto.php

Basically each horizontal scan the electron gun shoots corresponds to a 64uS waveform. The first 4uS are the sync pulsem the next 8uS prime the electon gun, and the last 52uS correspond to the asctual image you see( .3V is black and 1V is white)

I'm using the same Digital to Analog converter shown on the website

to generate 0V, .33V, .67V, and 1V based on pin 2(D0) and pin 3(D1). I tested the different voltage to make sure I haven't wired anything wrong, and the hardware seems to be fine.
My code should just continously display lines white, but I'm getting moving white and black lines.
http://www.datablue.net/random/badVid.AVI

/* Composite Video Generation
 * ------------
 *
 * uses a 2-bit D-A converter to generate
 * voltages for composite video to RCA. This
 * code should generate continous white horizontal 
 * lines to create a fullly white TV
 *
 * Created 18 December 2006
 * copyleft 2006 Kyle Granat <http://www.datablue.net>
 * http://arduino.cc
 *
 * based on Rickard Gunée's pic work
 * http://www.rickard.gunee.com/projects/video/pic/howto.php
 */

int d0 = 2;                 
int d1 = 3;  

void setup()
{
  pinMode(d0, OUTPUT);      // sets the digital pin as output
  pinMode(d1, OUTPUT);      // sets the digital pin as output
}

void loop()
{
    digitalWrite(d0, LOW);  //sets out to 0V for sync pulse for 4 uS
    digitalWrite(d1, LOW); 
    delayMicroseconds(4);
    digitalWrite(d0, HIGH);   //sets out to .33V  for beam ready pulse for older tvs
    digitalWrite(d1, LOW); 
    delayMicroseconds(8);
    digitalWrite(d0, HIGH);   //sets out to 1V(White)
    digitalWrite(d1, HIGH); 
    delayMicroseconds(52);    

}

I've tried some other waveforms( another site said the wave form should be a 2uS black pulse, a 4us sync pulse, another 4uS black pulse, and a 54uS image data) but still didn't get proper results.
I've also read that it should be 63.5uS not 64uS.

I beleive it's a timing problem with my sync pulse (possibly becuase the digitalWrite() function is taking a few microseconds or beacuse the delayMicroseconds() isn't accurate enough?)

Has anyone tried this or have any ideas/tips?

Hi

great, really complex question. Composite video is an amazing pain in the ..um...
I used to build video edit suites, with miles of precisely cut cable and ten thousand dollar little boxes (time-base correctors) whose sole purpose was to correct the timing of the sync signals coming from VTR's. All that was so that you could get this thing called a "dissolve". A lot of executives at Sony bought a lot of hot tubs and fancy cars from that technology.

I am not sure you can really do what you want to do do anything else useful at the same time with the Arduino, as generating video has to be done constantly and very accurately, or the screen loses sync and the image disppears rolls, tears, etc etc. That's probably why most designs use an outboard video chip that is devoted to that job.

Anyway. I don't remember everything, but you are sort of on the right track. You have described the horizontal blanking interval, which is the time the beam is between drawing lines. In the HBI you've got the horizontal sync, and then some quiet time, and then the colour burst. There's something called the "breezeway" and the "back porch" in there too. (In fact, if you look closely, you can almost see abunch of old TV engineers in white lab coats sitting around in front of miles of tall grey rack mount gear, with their coffee cups perched on their Tektronix roll-around oscilloscopes.)

This standard has been around for a long time, and they have all kinds of cool names for each part of it. I'm assuming you will ignore the colour burst, as I doubt you could generate it in the Arduino (the colour is phase encoded onto a 3.58Mhz signal, which gets sent at the right end of the HBI for about 2.5 microseconds. Most Tv's will just default to B/W if the colour burst is there or minimally there, as this was the work-around, in NTSC at least, to make colour TV's receive stations that were transmitting B/W back when colour was introduced. Yes this stuff is that old.

There are two things you haven't mentioned: the colour standard and the vertical blanking interval. You need to find the specs for the standard waveform for wherever you are: NTSC (aka 'never twice same colour'), SECAM or PAL? The blanking intervals are different for each. Diferent countries use different standards.. it's all very political.

Next, you've got to have some code for the Vertical blanking interval, which includes the vertical sync. (This is probably why your code doesn't work-- you don't have a vertical blanking interval.) Vertical sync, If I remember correctly, is easy. They used to derive it by half-wave rectifying the power line frequency... so in Canada it's 60hz/2= 30hz, and in Europe it's 50hz/2= 25 hz. ( there are some finicky exceptions to this rule, as later on they started deriving the sync signal from the colour burst crystal at 3.58Mhz, and the closest they could get to 30 was 29.94, which led to a whhole industry in machines to convert between those rates in production houses) Anyway, the vertical sync has to be in the middle of the vertical blanking signal.

So, in NTSC for example, you have this happening thirty times per second:

  • vertical blanking interval, with vertical sync moves beam to top
  • horizontal blanking interval, with H sync, moves beam to left of screen
  • phase of the colour burst signal locks the colour decoded in the TV
  • line gets drawn
  • repeat sync, burst and horizontal line for odd lines
  • another vertical interval, with vertical sync,
  • repeat sync, burst and horizontal line for even lines
  • Voila, you have a frame!

The even lines and odd lines get drawn separately, since if they were drawn consecutively, the phosphor on the top part of the screen would fade before the linews were all drawn.

Last but not least, all this stuff has to be really precise! A little "jitter" in the signal, and it doesn't work.

The good news is that this is an extensively documented standard: hundreds of millions of tv's and video cameras have been made for NTSC, and they all use the same signal standard. Here's one excellent document on the video signal:

But hey.. there are lots of chips around that are designed to do this for you, why not use one of those?

Example of a really old video chip: Motorola 6847 - Wikipedia
Example of recent one that can insert 'arbitrary graphics' into 8 video sources...
Mixed-signal and digital signal processing ICs | Analog Devices
The MC1377 is another old old old chip.. it takes RGB analog values and the chip adds the required sync.

Example of a video generator module: serial in, video out: http://www.smarthome.com/78553.html
There's also the classic 'Bob' video module...

There are lots of others, so have a look around.

Wow this was a long post, and I am sad to know that I have stored so much irrelevant information in my head for this long.
I will try to forget it now.

Disclaimer: I think most of what I remember above is right, but there's probably something not right in there. :slight_smile: It was a while ago.

PS: if you are really into the pain and suffering of generating your own video, then the smart thing to do seems like:
code a dedicated Atmega8 to generate the video, and have it look for the information on what it should display during the (relatively) long vertical blanking interval. Even so, you'll need a lot of ram (a full frame of digital video uncompressed is something like 4MB) to store the screen data for even the simplest of images. The Atmega serial port isn't really known for its capacity to process that kind of throughput.

The logical deigner-type thing to do is: surrender! Then, order an external video generator chip, drink coffee and alcohol, eat turkey, open presents, enjoy Christmas! ;D

D

Hej,

there was an AVR awarded design that was making full teletext (thus 40x25 char screens) on composite b&w using only the atmega8. I cannot find the link, but the whole thing was open source.

BTW I am also interested in this project, keep us posted with your experiments, I will try to look for those files in my old hard-drive.

/David

web page ECE 4760

source code ECE 4760

Here is a video overlay project using the ATmega8. It's meant to overlay text on top of an incoming video stream. The code is gcc-avr C, but it might work with the Arduino without too much effort.

http://www.knology.net/~gdion/videoverlay.html

-j

hej,

the arduino is also having some timing issues, the delayMircoseconds don't work so well for delay between 2-10 uS, but the delay for 1 uS is working perfekt. So for a delay with 4 us you should write 4x delayMircoseconds(1), the same for the 8 us delay, the 52uS delay should work on the normal way.
One the other hand you should use the c code for writing the pins. Just copy it from the arduino library, this will save some time.
You can also have a look in the DMX512 code example on the arduino wiki (not on the arduino website, the one on the website is not working!) For DMX you also have to use 4uS delays.

looking forward to your results
tomek

Thanks for all of the ideas. I realize how critical it is to get the timing just right. At the moment I'm still having issues witht the video syncing up so I'm really not sure what to do. I've tried using the delayMicroseconds(1) but I'm having similar difficulties as before.

I haven't even begun to play around with the vertical blanking interval since right now I'm just trying to get it to display solid lines down, so I know I have the horizontal timing right.

I'm not giving up yet, but I'm kinda stuck :confused:

One of my goals is to have a small protable text generator to use in some other projects. If i can I'd like to make some basic atari-like games as well.

hey

composite video won't display anything correctly without a vertical refresh twice per frame, or 60 tims per second, so try that. It's the same idea as the horizontal sync, but for the vertical retrace. Without a vertical sync signal, you would get exactly what you're describing: rolling lines.

D

I actually want rolling, solid lines (at the moment) right now I'm just getting this


http://www.datablue.net/random/badVid.avi

Shouldn't I be getting somthing like

?

hey you are getting close!

But you need the vertical sync signal, that's why it's rolling. You can't jump ahead and work on the image part until you have the sync signals right... video won't display any kind of image correctly until you give it nice stable vertical horizontal sync signals! That establishes the 'canvas' to which you can write your images. Using one sync without without the other is like trying to walk on one foot only.

D

Hello, this is my first post after reading some months, please ignore any mistakes.

I just got this out of my arduino:

and no, i did not write the code myself, i only ported it to my arduino wich was not very hard, got the code from this website:

http://mitglied.lycos.de/polyxos/video.htm

I followed the (german) instructions and burned the resulting hex file into my board with my (eprom)programmer, had to use other fuse settings as the arduino uses a x-tal unlike the schematic on the site.

Now i would like to disassemble his code to make some mods, anyone know how to do this? is there a disasm with the arduino?

Maybe this is useful?

Oscilloscope using a microcontroller and a TV
http://www.nbb.cornell.edu/neurobio/land/PROJECTS/VideoScope/

Wow, lots of interesting links! I'm definitely gonna have a go at making a pong system when i get my arduino through! (after I get my darn university project finished too...)

http://mitglied.lycos.de/polyxos/video.htm

Since Germany uses the PAL TV standard it might not work on NTSC equipment.

http://mitglied.lycos.de/polyxos/video.htm

Since Germany uses the PAL TV standard it might not work on NTSC equipment.

as this is black&white (and there is no burst involved, PAL=4.43Mhz, NTSC=3.38Mhz) it might work on some Tv's because 50Hz * 625 lines = 31250 lines in PAL and 60Hz * 525 lines = 31500 lines so there is only difference of 250 lines/sec, it all depends on the vertical sync of the TV.

if we can get to the asm source I think it would be easy to change the 50Hz into 60Hz and the 625 lines to 525 lines.

Erik

I think possibly the problem might be that the DigitalWrite command takes a few microseconds to work... maybe you could try using port registers to switch the outputs?

http://www.arduino.cc/playground/Code/BitMath#registers

You might need to add up the cycles that you're using to make sure you get exact timing...

Sorry if all of what I've said is total rubbish... this is just my guess at a possible solution

I think possibly the problem might be that the DigitalWrite command takes a few microseconds to work... maybe you could try using port registers to switch the outputs?

Arduino Playground - BitMath

You might need to add up the cycles that you're using to make sure you get exact timing...

Sorry if all of what I've said is total rubbish... this is just my guess at a possible solution

I've actually had a feeling that that's where my problem is and I've been trying to figure out just how to figure out how long digitalWrites take. This page might help out though, I'll try it later tonight.
Thanks!

Yeah, the guy who did the pic pong counted each clock cycle- I'm hoping that the arduino's delay functions are accurate enough for this... does anyone know of a way to delay a specific amount of cycles in code? If a specific amount can be delayed, and one knows how many cycles each instruction uses, you could get perfect timing this way I should have thought...

The arduino does seem to have quite a bit more processing power than the pic he used, so i'm hoping you could get some better game logic in there...

Keep us updated with your progress though, this is one of the things i want to try when i get my arduino! Roll on a wave of arduino based games I say!

O.K. so after reading some about using the registers and applying it to some code I ended up with this


http://datablue.net/random/better_vid.AVI

Not perfect, but alot better than before!
This code still doesn't incorporate the vertical sync because I can't get the timing right. I think It might have something to do with the loop I'm using.

/* Composite Video Generation
 * ------------
 *
 * uses a 2-bit D-A converter to generate
 * voltages for composite video to RCA. This
 * code should generate continous white horizontal 
 * lines to create a fullly white TV
 *
 * Created 18 December 2006
 * copyleft 2006 Kyle Granat <http://www.datablue.net>
 * http://arduino.cc
 *
 * based on Rickard Gunée's pic work
 * http://www.rickard.gunee.com/projects/video/pic/howto.php
 * 
 * Register code from Cosine Kitty
 * http://www.arduino.cc/playground/Code/BitMath#registers 
 */


void setup()
{
        // set pins 0 (serial transmit) and 2 and 3 as output,
        // but leave pin 1 (serial receive) as input
        // (otherwise serial port will stop working!) ...
        DDRD = B00001101;  // digital pins 7,6,5,4,3,2,1,0
        // Turn off digital output pins 2 and 3
        PORTD &= B00000011;   // turns off 2..7, but leaves pins 0 and 1 alone

}

void loop()
{
  
  
    PORTD = B00000000;    // sets out to 0V for sync pulse for 4 uS 
    delayMicroseconds(1);
    delayMicroseconds(1);
    delayMicroseconds(1);
    delayMicroseconds(1);

    PORTD = B00000100;//sets out to .33V  for 'porch'
    delayMicroseconds(1);
    delayMicroseconds(1);
    delayMicroseconds(1);
    delayMicroseconds(1);
    delayMicroseconds(1);
    delayMicroseconds(1);
    delayMicroseconds(1);
    delayMicroseconds(1);

    PORTD = B00001100;   //sets out to 1V(White)
    delayMicroseconds(52);   


}