Pages

AVR based monochrome signal generation for a PAL TV


Introduction:
       I have learned some thing about TV in one of my B.tech semester but I forgot most of them. Now I refreshed a few basics and tried to implement a monochrome PAL TV signal generator using an AVR micrcontroller. I was using PIC earlier but later I jumped to AVR because I loves the USBASP programmer, the free avr-gcc compiler and the user friendly architecture of AVR microcontroller .Also at any time, if I feel little bit lazy, they I can try arduino also..;-)


At first, my aim was to display few A B C D letters on my tv screen. But it is not possible for a beginner to do it directly(at least in my case) without doing any hello world stuff on TV. The first and the basic hello world pattern which one could display very easily on his tv is a vertical line of desired thickness and position. This is very easy because we don't need to provide any vertical synchronization to lock the picture scrolling on vertical axis, what we need to provide is a horizontal synchronization only.

Synchronization:
  We need to display a picture exactly on it's position relative to the coordinates of the tv display. ie we need to lock a picture frame on the screen and it should not vibrate or move up and down or it should not disturb the scanning rules. For this along with the analog picture data (.3 to 1v), we send few digital data of 0 - 0.3 v levels which do the synchronization process. There are two synchronizations , the horizontal synchronization and the vertical synchronization. 
   Horizontal synchronization pulse in the signal makes it synchronized with the horizontal scanning. Similarly vertical synchronization pulses(a stream) makes it synchronized in the vertical direction , this ensures that the picture always starts from the top on each field(each interlacing fields) and locks the picture on the screen on it's exact position. Vertical synchronization is a long compared to horizontal synchronization.

TV screen and timings:
  A pal TV screen consist of 625 horizontal lines on which few lines are not visible and those are used in vertical synchronization and some other purposes. About 576 lines actually display the images for viewers. A horizontal scannig time period is exactly 64us in which the actual picture information lies on the later 51.95us. The first 4.7 us should be horizontal synchronization pulse (zero) and the next 5.7 should be black (.3v). Also, in most tv sets, it will work with 4 us h.sync and 8 us black and then 52us analog data. Now it is better to illustrate the timings using figures. There is a very good explanation about the working of TV at this link. Below picture is taken from the above link and this timing diagram is enough for some one to make his own monochrome tv signal (doesn't mean the tv should be monochrome)... Here I am following the second figure , the fake progressive monochrome pal and there the vertical lines will be virtually 312. If I need a high resolution in vertical direction, then I must use the real interlacing but any way I now I stick with the fake one in which two lines are combined to show as a single line....


 full interlaced pal monochrome signal timing..


One field of 'fake progressive' monochrome PAL video


"Hello world" monochrome PAL signal generation using atmega16/32:
R1 = 6.2k, R2=2.2K, R3=470 ohm

Creating a vertical line  on screen with '1us thinkness':(1/52 of length of tv)

C code:
#include<avr/io.h>
#define F_CPU 16450000
#include <util/delay.h>
#define ZERO PORTC=0
#define BLACK PORTC=1 //v out = .3v (black color)
#define WHITE PORTC=2 //v out = .8v (just white color)

void main()
{
    DDRC = 1<<PC0|1<<PC1;
    while(1) {
        ZERO;_delay_us(4);BLACK;_delay_us(8);//horizontal synchronization
        _delay_us(10);
        WHITE;
        _delay_us(1);
        BLACK;
        _delay_us(41);
    }
}

In the above code, the first line after while(1) is the horizontal synchronization code. For the first 4us it generates 0v at o/p and then for the next 8us .3v. Now for the next 51.95us we can provide analog value between .3 to 1v. So here I am adding a WHITE (but any way .8v is not the brightest one). Then making a delay of 1us so that it could be visible for 1us time of a single horizontal scan. After that it is made black for remaining 41us and then again the horizontal sync pulse is applied and this continues.... So the white line grows from up to down and then again and again and thus we see a white stripe of 1/52 of the length of the TV screen. The white strip will be moving or vibrating on the vertical axis because we didn't provided vertical sync. But due to the symmetry of the white stripe, we couldn't feel it...

Now I will show another exmple:
#include<avr/io.h>
#define F_CPU 16450000
#include <util/delay.h>
#define ZERO PORTC=0
#define BLACK PORTC=1
#define WHITE PORTC=2

void main()
{
    DDRC = 1<<PC0|1<<PC1;
    while(1) {
        //////////////////////////////////////
        ZERO;_delay_us(4);BLACK;_delay_us(8);
        _delay_us(10);
        WHITE;                   //WHITE COLOR
        _delay_us(1);
        BLACK;
        _delay_us(41);
        //////////////////////////////////////
        ZERO;_delay_us(4);BLACK;_delay_us(8);
        BLACK;                         //BLACK
        _delay_us(52);
        //////////////////////////////////////
        ZERO;_delay_us(4);BLACK;_delay_us(8);
        BLACK;                         //BLACK
        _delay_us(52);
        //////////////////////////////////////
        ZERO;_delay_us(4);BLACK;_delay_us(8);
        BLACK;                         //BLACK
        _delay_us(52);
        //////////////////////////////////////
    }
} 
 
If we run the above code, we could see the white line is having many cuts. So we could easily observe that it is not stable in vertical axis. This will become more important if the picture is interlaced.

One more example:
#include<avr/io.h>
#define F_CPU 16450000
#include <util/delay.h>
#define ZERO PORTC=0
#define BLACK PORTC=1
#define WHITE PORTC=2

void main()
{
    DDRC = 1<<PC0|1<<PC1;
    unsigned int i;
    while(1) {
        /*--VERTICAL SYNCHRONIZATION (uncomment the below line and try-------------------------------------------*/
        //_delay_us(28);BLACK;_delay_us(4);ZERO;_delay_us(28);BLACK;_delay_us(4);
        //try with and without above line and see the difference
        
        ////////////first few lines are black/////////////////////////////
        for(i=0;i<150;i++) {
            ZERO;_delay_us(4);BLACK;_delay_us(8);
            BLACK;
            _delay_us(52);
            asm("nop");
        }
        ////////////then 50 lines are white, a white strip////////////////
        for(i=150;i<200;i++) {
            ZERO;_delay_us(4);BLACK;_delay_us(8);
            _delay_us(10);
            WHITE;                   //WHITE COLOR
            _delay_us(1);
            BLACK;
            _delay_us(41);
        }
        
        for(i=200;i<312;i++) {
            ZERO;_delay_us(4);BLACK;_delay_us(8);
            BLACK;
            _delay_us(52);
        }
    }
}



In the above code, if we remove the '//' from the 14th line, it will activate the vertical synchronization. Then we could see a small rectangle as seen in the picture above(right). Otherwise we could see some thing is scrolling in vertical direction and will be difficult to identify the exact thing(left).. My vertical synchronization code is not exactly according to the rules because it actually needs 8 lines but I just cut short it to a single line and tested in on my tv and it is working fine. So I hope it will work in modern TV sets....
I also tried the full interlacing but not posting it here because the procedure for that is almost same, we need to provide first vertical sync and then display first field at and then the second field's sync pulses followed by the second field data..

Now for drawing geometric figures on TV, see my next post

8 comments:

  1. Can this signal be generated with at89s52 microcontroller?

    ReplyDelete
  2. Hi i try to make this but on a lcd tv and it doesn't work can you help me ?

    ReplyDelete
  3. Hi! Thanks for this article, I'm gonna try this next week with my AtMega8 and 16, but there's one snag... There's only 41,6us for operations other than generating signal? That is not too much... When Your code will work for my TV, I'm gonna try to rewrite it using TCNT timer, so that will give much more time for other operations. Cheers!

    ReplyDelete
  4. My wife manages the home much efficiently, and she hardly bothers me for repairing of gadets and accessories. A few days ago, we had to face some hindrance in watching TV because something went wrong with the satellite receiver. I was surprised to know that mechanics reached our home within minutes, and my wife told me that they are from PE DSTV, and she has called them for troubleshooting. While we prepared some coffee, they restored the connection, and everything was done so quickly that I felt deeply impressed with their technical expertise.

    ReplyDelete
  5. please tell me how to generate this signal using a AT89S52

    ReplyDelete
  6. This comment has been removed by the author.

    ReplyDelete