Arduino Forum

Forum 2005-2010 (read only) => General => Frequently-Asked Questions => Topic started by: kamon on Dec 21, 2006, 03:15 am

Title: Generating Composite Video
Post by: kamon on Dec 21, 2006, 03:15 am
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
(http://www.rickard.gunee.com/projects/video/pic/vinfo_da00.png)
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

Code: [Select]
/* 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?
Title: Re: Generating Composite Video
Post by: Daniel on Dec 21, 2006, 06:52 am
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 <and> 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:
http://www.maxim-ic.com/appnotes.cfm/appnote_number/734

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: http://en.wikipedia.org/wiki/MC6847
Example of recent one that can insert  'arbitrary graphics' into 8 video sources...
http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3415
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 (http://www.jameco.com/webapp/wcs/stores/servlet/ProductDisplay?langId=-1&storeId=10001&catalogId=10001&productId=283733)' 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. :) It was a while ago.
Title: Re: Generating Composite Video
Post by: Daniel on Dec 21, 2006, 07:23 am
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
Title: Re: Generating Composite Video
Post by: DojoDave on Dec 21, 2006, 10:03 am
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
Title: Re: Generating Composite Video
Post by: admin on Dec 21, 2006, 01:33 pm
web page http://instruct1.cit.cornell.edu/courses/ee476/video/

source code http://instruct1.cit.cornell.edu/courses/ee476/video/Video32v3.c
Title: Re: Generating Composite Video
Post by: kg4wsv on Dec 21, 2006, 01:43 pm
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
Title: Re: Generating Composite Video
Post by: tomek on Dec 21, 2006, 08:57 pm
[font=Sans-Serif]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

[/font]
Title: Re: Generating Composite Video
Post by: kamon on Dec 27, 2006, 03:07 am
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 :/

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.
Title: Re: Generating Composite Video
Post by: Daniel on Dec 27, 2006, 03:49 am
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
Title: Re: Generating Composite Video
Post by: kamon on Dec 27, 2006, 04:08 am
I actually want rolling, solid lines (at the moment) right now I'm just getting this

(http://datablue.net/random/badVid.jpg)
http://www.datablue.net/random/badVid.avi

Shouldn't I be getting somthing like
(http://datablue.net/random/vinfo_first_screen.png)
?
Title: Re: Generating Composite Video
Post by: Daniel on Dec 27, 2006, 04:22 am
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 <and> 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

Title: Re: Generating Composite Video
Post by: Erik on Dec 27, 2006, 01:29 pm
Hello, this is my first post after reading some months, please ignore any mistakes.

I just got this out of my arduino:

(http://mitglied.lycos.de/polyxos/mod6.jpg)

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?

Title: Re: Generating Composite Video
Post by: brainfart on Dec 29, 2006, 09:15 am
Maybe this is useful?

Oscilloscope using a microcontroller and a TV
http://www.nbb.cornell.edu/neurobio/land/PROJECTS/VideoScope/
Title: Re: Generating Composite Video
Post by: Goobers on Jan 01, 2007, 05:24 am
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...)
Title: Re: Generating Composite Video
Post by: brainfart on Jan 01, 2007, 10:00 am
> http://mitglied.lycos.de/polyxos/video.htm

Since Germany uses the PAL TV standard it might not work on NTSC equipment.
Title: Re: Generating Composite Video
Post by: Erik on Jan 01, 2007, 12:25 pm
Quote
> 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
Title: Re: Generating Composite Video
Post by: Goobers on Jan 05, 2007, 02:21 am
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
Title: Re: Generating Composite Video
Post by: kamon on Jan 05, 2007, 02:37 am
Quote
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'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!
Title: Re: Generating Composite Video
Post by: Goobers on Jan 06, 2007, 12:16 am
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!
Title: Progress!
Post by: kamon on Jan 09, 2007, 06:39 pm
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/bettervid.jpg)
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.

Code: [Select]
/* 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);  


}
Title: Re: Generating Composite Video
Post by: CosineKitty on Jan 09, 2007, 07:16 pm
My guess is that you might have some problems because of timer interrupts (or other interrupts?) messing up your timing.  Just as an experiment, try adding this to the end of your setup():

   cli();   // disable interrupts

Of course, this will mess up all kinds of stuff you might want to add later, like serial port I/O, use of timers, delay(), millis(), etc.

I say this because I was surprised when I tried generating radio frequency energy and encountered an unexpected tone modulated on top of what was supposed to be a pure carrier wave.  See here:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1166896036
Title: Re: Generating Composite Video
Post by: kamon on Jan 10, 2007, 12:13 am
Quote
My guess is that you might have some problems because of timer interrupts (or other interrupts?) messing up your timing.  Just as an experiment, try adding this to the end of your setup():

   cli();   // disable interrupts


I disabled the interrupts but nothing noticable has changed. Thanks for the suggestion though.
Title: Re: Generating Composite Video
Post by: superware on Jan 25, 2007, 02:49 am
Quote
I disabled the interrupts but nothing noticable has changed. Thanks for the suggestion though.


Any news?  :)
Title: Re: Generating Composite Video
Post by: superware on Jan 25, 2007, 12:44 pm
Quote
Here is a video overlay project using the ATmega8 [...]

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


Hi, do you understand what's Q1 specifications in that schematic?

Thanks,
Superware
Title: Re: Generating Composite Video
Post by: kamon on Jan 25, 2007, 04:03 pm
Quote


Any news?  :)


Still working on it, though classes seem to be getting in the way :3
I might get a chance this weekend to tinker some more, but no real progress as of late.

Also q1 in the schematic is a pnp transtor. I'd imagine a 2n3906 would work fine.
Title: Re: Generating Composite Video
Post by: Goobers on Mar 12, 2007, 09:55 pm
I'm going to start work on an ASM version of this to get the timing exact.

How would I go about writing a block of ASM code in C? Would you just stick all the lines in an asm() ?
Title: Re: Generating Composite Video
Post by: jds on Mar 19, 2007, 11:33 am
Looking forward to any updates on this. Also, anyone knows if it would be possible to create a video overlay (OSD) with Arduino?
Title: Re: Generating Composite Video
Post by: Erik on Mar 21, 2007, 09:29 am
Quote
Looking forward to any updates on this. Also, anyone knows if it would be possible to create a video overlay (OSD) with Arduino?


http://www.knology.net/~gdion/videoverlay.html
Title: Re: Generating Composite Video
Post by: jds on Mar 21, 2007, 09:39 am
Thank Erik,

That is a very valuable link!

Cheers,

JD
Title: Re: Generating Composite Video
Post by: benoit on Apr 20, 2007, 04:13 pm
hello,

 I had the same idea : http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1176757335.

 Now I'm giong to read your post, I have some timming pbroblems in interruption mode...

Title: Re: Generating Composite Video
Post by: benoit on Apr 20, 2007, 04:22 pm
Hello,

 I've read the post. You have the same problems :) of timing.

 Could we try to resolve them together ? My project is working in the loop() function, everything is ok. I try do it with interupt but I don't have an oscilloscope to fine tuning synchro.
Title: Re: Generating Composite Video
Post by: droolcup on May 10, 2007, 10:49 pm
Hi everyone,

I just stumbled on this thread while looking into something else entirely (curse you stream of consciousness browsing).

Some of us did this a few years ago with a pair of PIC 18f452s in CSS C at 40MHz.  One PIC set up the video environment, and on interrupt we used a second one to read inputs and do our "drawing" routines.  

As I recall, it was a pretty crude effort, but it worked well enough for our purposes.  You can look at the project notes and code here : http://droolcup.com/pictv

~s
Title: Re: Generating Composite Video
Post by: benoit on May 10, 2007, 11:10 pm
Hello droolcup,

 Thank's for your post. I've just seen the video of your project. I have the same result with interrupt, one somme image configuration there some lines are "overshooting", it depends of the white surface on screen...

 I think I'll have to write some parts of the code in asm to be sure of timings.
Title: Re: Generating Composite Video
Post by: Goobers on May 22, 2007, 02:43 am
The best way that I've seen to do this is by using 2 micros- one of them is programmed in ASM and reads the pixel data from a ram chip, which the other micro updates. There would be a sync line between the two to make sure one isn't trying to write while the other is reading. This would eliminate timing problems and also allow for more complex programs to be run.

I'm thinking of giving this approach a try soon- what does everyone think?
Title: Re: Generating Composite Video
Post by: jlulian38 on May 25, 2007, 08:43 am
Maybe this is just crazy talk, but couldn't you try and generate your sync signal with a bi-stable oscillator, you'd want to watch that with the MCU so that you don't keep sending data as your sync goes off, if not using the oscillator directly, you could use it to keep track of were you are in your output (send the sync with the MCU, but use the oscillator to time everything right.

(Please excuse any tyops I've made, it's late, and it's hard for me to keep up with my high standard of typing when I'm tired.)
Title: Re: Generating Composite Video
Post by: benoit on May 25, 2007, 01:04 pm
Hello,

 Yes, I'm thinking about soltions with external components. But, at first I want to do it the best without active components. It's a challenge with Arduino Board  :). I will try with some asm code include in  C code...
Title: Re: Generating Composite Video
Post by: zitron on May 26, 2007, 05:29 am
Hey Benoît ROUSSEAU,

Just want to say good luck! I hope you'll find a way to get it to work eventually, meanwhile I can dream about arduino pong!

-Z-
Title: Videocritter
Post by: XNDR on Jun 13, 2007, 02:01 am
I stumbled upon a site where they sell all kinds of electronic video/audio instruments. There's a lot of interesting information about how these guys managed to get the video output running.. They use a ARM7TDMI Microcontroller in conjunction with an AD725 RGB to PAL/NTSC encoder IC from Analog Devices. They run a crystal at 4 times the video burst frequency to get stable output, it still only handles 256 colors at a 160 x 128 resolution. But it looks like lots of fun to play with, it could also be interfaced with an arduino board. Programming the microcontroller itsself requires C skills and the GNU toolchain, a flash utility and an USB board (i bet the arduino can also be used as an Serial/USB interface to program this board).

http://www.critterandguitari.com/catalog/index.php?main_page=product_info&cPath=1&products_id=13
Title: Re: **Detecting** Composite Video?
Post by: Golan on Jun 17, 2007, 01:16 am
Hi All,

Possibly this should be a new thread, but the "generating video bboard" is pretty close to my question:

Has anyone written code to detect the vertical blanking interval in an incoming NTSC composite video signal (RS-170A)?

I'm creating a project in which I need to switch a circuit on and off, precisely in sync with the video fields from an NTSC video source. In order to do this, I would need to sample the video signal fairly frequently and write an analyzer/detector for the vertical blanking interval, which is used to synchronise the video frames.

Any advice would be greatly appreciated before I bore headlong into the oscilloscope.
Thanks,
Golan


Title: Re: Generating Composite Video
Post by: Daniel on Jun 17, 2007, 04:00 am
hi

you can get a single-chip solution for that: they're called sync separators. The LM1881 (http://www.national.com/pf/LM/LM1881.html) comes to mind. It only needs +5V,  3 capacitors and two resistors. In return, it provides the vertical and horizontal sync, as well as the field (odd/even) and the back porch signal form a composite video signal. It's about $3 US.

D

PS: there is an interesting article at this link (http://www.circuitcellar.com/archives/viewable/Aparicio203/Aparicio-203.pdf), with code and schematics, on using the above chip with an AVR to create a motion detection system.
Title: Re: Generating Composite Video
Post by: Daniel on Jun 27, 2007, 02:00 am
this was just posted via Make Magazine... an AVR based video overlay. Interestingly, it uses the LM1881 to separate sync, and then one pin pulls the video level to generate the overlay.

http://garydion.com/projects/videoverlay/

D
Title: Re: Generating Composite Video
Post by: agent_orange on Jul 15, 2007, 02:47 am
I managed to get the Arduino generating a PAL signal. My TV syncs to this signal without any problems. I followed the specs for a PAL signal as close as possible. It uses asm nops to try and get more precise delay times. Each nop is a 65ns delay (1 instruction at 16 Mhz...it should be 65ns but i don't have a good enough oscilloscope to check). The PAL signal has +- 0.3 microseconds leeway on the sync signals anyway so it works ok.

The code generates a white bar in the middle of the TV. Here is the first half.

Code: [Select]

int pixel = 6;  // Connected to 550ohm resistor (Should be 470ohm)
int sync = 7;   // Connected to 1k ohm resistor
int i;

void setup()
{
 pinMode(pixel,OUTPUT); // Switch to output pin
 pinMode(sync,OUTPUT);  // Switch to output pin
 cli();                // Turn off interupts
}


void loop()
{
 //
 // Generate 5 Narrow Equalization pulses
 //
 PORTD = B10000000; // Make the sync high to start with
 for(i=0;i<5;i++)
 {
    PORTD = B00000000; // Sync pulse goes low and delay 2.3 microseconds
    delayMicroseconds(1);
    delayMicroseconds(1);
    __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
    PORTD = B10000000; // Sync pulse goes high and delay 29.7 microseconds
    delayMicroseconds(29);
    __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
 }
 
 //
 // Generate the 5 Field Sync Pulses
 //
 for(i=0;i<5;i++)
 {
   PORTD = B00000000; // Sync goes low and delay 27.3 microseconds
   delayMicroseconds(27);
   __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
   PORTD = B10000000; // Sync goes high and delay 4.7 microseconds
   delayMicroseconds(1);
   delayMicroseconds(1);
   delayMicroseconds(1);
   delayMicroseconds(1);
   __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
 }
 //
 // Generate 5 Narrow Equalization pulses
 //
 for(i=0;i<5;i++)
 {
    PORTD = B00000000; // Sync pulse goes low and delay 2.3 microseconds
    delayMicroseconds(1);
    delayMicroseconds(1);
    __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
    PORTD = B10000000;
    delayMicroseconds(29); // Sync pulse goes high and delay 29.7 microseconds
    __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
   
 }
 // Generate 18 Blank Frames
 for(i=0;i<18;i++)
 {
   PORTD = B00000000;    // Pull sync pin low -> 0 volts
    delayMicroseconds(4);
   __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
   PORTD = B10000000; // Pull sync pin high
   delayMicroseconds(59);
 }
 //  
 // Generate half the Image
 //
 for(i=0;i<285;i++)
 {
   //
   // Front Porch
   //
   PORTD = B10000000;
   delayMicroseconds(1); // Front Porch: 1.65 microseconds
   __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
   
   //
   // Generate sync pulse
   //
   PORTD = B00000000;    // Sync pulse pulled low: 4.7 microseconds
    delayMicroseconds(4);
   __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
   
   //
   // Back Porch
   //
   PORTD = B10000000;    // This is the back porch: 5.6 microseconds.
   delayMicroseconds(5);
   __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
   
   //
   // Drawing starts here: Total time available is 53 microseconds
   //
   PORTD = B10000000;    // Draw black
   delayMicroseconds(20);
   PORTD = B11000000;    // Draw white
   delayMicroseconds(10);
   PORTD = B10000000;    // Draw black
   delayMicroseconds(22);
   

 }
Title: Re: Generating Composite Video
Post by: agent_orange on Jul 15, 2007, 02:50 am
And the other half....just a copy of the first half  :) Cut and paste both of these into one file and it should be good to go.

Code: [Select]

//
 // Generate 5 Narrow Equalization pulses
 //
 PORTD = B10000000; // Make the sync high to start with
 for(i=0;i<5;i++)
 {
    PORTD = B00000000; // Sync pulse goes low and delay 2.3 microseconds
    delayMicroseconds(1);
    delayMicroseconds(1);
    __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
    PORTD = B10000000; // Sync pulse goes high and delay 29.7 microseconds
    delayMicroseconds(29);
    __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
 }
 
 //
 // Generate the 5 Field Sync Pulses
 //
 for(i=0;i<5;i++)
 {
   PORTD = B00000000; // Sync goes low and delay 27.3 microseconds
   delayMicroseconds(27);
   __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t"); // 0.3 microseconds
   PORTD = B10000000; // Sync goes high and delay 4.7 microseconds
   delayMicroseconds(1);
   delayMicroseconds(1);
   delayMicroseconds(1);
   delayMicroseconds(1);
   __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t"); // 0.7 microseconds
 }
 //
 // Generate 5 Narrow Equalization pulses
 //
 for(i=0;i<5;i++)
 {
    PORTD = B00000000; // Sync pulse goes low and delay 2.3 microseconds
    delayMicroseconds(1);
    delayMicroseconds(1);
    __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t"); // 0.3 microseconds
    PORTD = B10000000;
    delayMicroseconds(29); // Sync pulse goes high and delay 29.7 microseconds
    __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t"); // 0.7 microseconds
   
 }
 
 // Generate 18 Blank Frames
 for(i=0;i<18;i++)
 {
   PORTD = B00000000;    //0 volts
    delayMicroseconds(4);
   __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t"); //0.7 microseconds
   PORTD = B10000000;
   delayMicroseconds(59);
 }
 
   
//  
 // Generate the next half of the Image
 //
 for(i=0;i<285;i++)
 {
   //
   // Front Porch
   //
   PORTD = B10000000;
   delayMicroseconds(1); // Front Porch: 1.65 microseconds
   __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
   
   //
   // Generate sync pulse
   //
   PORTD = B00000000;    // Sync pulse pulled low: 4.7 microseconds
    delayMicroseconds(4);
   __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
   
   //
   // Back Porch
   //
   PORTD = B10000000;    // This is the back porch: 5.6 microseconds.
   delayMicroseconds(5);
   __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
   
   //
   // Drawing starts here: Total time available is 53 microseconds
   //
   PORTD = B10000000;    // Draw black
   delayMicroseconds(20);
   PORTD = B11000000;    // Draw white
   delayMicroseconds(10);
   PORTD = B10000000;    // Draw black
   delayMicroseconds(22);
   
   
 }
}

Title: Re: Generating Composite Video
Post by: Goobers on Jul 15, 2007, 10:30 pm
Nice, I'll have to give this a go in a bit :)
Title: Re: Generating Composite Video
Post by: javg on Jul 23, 2007, 01:59 am
Yet another link, this one is written for Arduino in pure C (not Processing nor assembly)

http://hklab.net/wiki/TV_Video_Signal_Generator_with_Arduino

I'm a fortunate man because I have an oscilloscope and I have seen that

Conclusion: don't use Processing to accomplish a hard real-time task like this. Use C or assembly.

Sorry for my poor english.
Regards,
Javi
Title: Re: Generating Composite Video
Post by: agent_orange on Jul 23, 2007, 09:53 am
Its much more precise using ASM or C but you can generate a valid video signal using arduino. The PAL standard for example allows +-0.3 microseconds for its timing pulses. By using some asm nops you can tune your code to work ok. The main problem people seem to be having is they aren't generating proper signals....not using eq pulses and field sync pulses for example in their code. Also it is important to disable the interrupts. If you get hold of the specifications for TV signals, and follow them, you can generate something that will work ok on most modern tv's.

If you don't have an oscilloscope then you can use a timing trick mentioned in this thread http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1174587934/10#10

to measure timing precisely. I'm gonna get hold of a DSO in a few weeks and I'll write a better video gen example then.
Title: Re: Generating Composite Video
Post by: javg on Jul 24, 2007, 05:27 am
Quote
Its much more precise using ASM or C but you can generate a valid video signal using arduino.


Yes. I agree with you but when I tried Processing transient pulses appeared and they corrupted my tv signal. See this picture in which I show you the transient pulses (in a red circle) due to slowly digitalWrite() calls, the signal timing using delayMicroseconds() is very bad also.

(http://hklab.net/pub/pictures/Arduino_tvpalsignal_transients.jpg)

I don't know yet AVR assembly so I decided to use C

Regads,
Javi
Title: Re: Generating Composite Video
Post by: agent_orange on Jul 24, 2007, 07:41 am
I got the same signal when I first tried it. The solution is don't use digitalwrite, you can only change one pin at a time using that function(so it takes some time to change once and then again so you get step). Just output directly to the port

e.g portb=00000011;

instead of calling digitalwrite() twice. Once I did that I got a clean signal without the steps as shown in your oscilloscope. Also make sure interrupts are disabled. Cheers. Maybe that will help.
Title: Re: Generating Composite Video
Post by: javg on Jul 24, 2007, 12:46 pm
Quote

Just output directly to the port
e.g portb=00000011;
instead of calling digitalwrite() twice.


Good idea!
With this trick, now, there is not a thin white border in the gray bars caused for micro-transient pulses.
Thanks.