Video tearing left to right

Store Forums Video Experimenter Bugs/Problems Video tearing left to right

Viewing 6 posts - 1 through 6 (of 6 total)
  • Author
    Posts
  • #709
    dgcaste
    Member

    I bought the shield from you just recently and got it in the mail today. Fine piece of work.

    I tried the VE sketch for the NTSCDemo (within the TVout-VE library) and the text and graphics are tearing left to right like crazy. Then I tried your Video Overlay demo with the randomized up and down graph and the scrolling letters, and it worked fine, as did the Object Tracking code and the edge detection sketch.

    Could it be the Arduino Uno R3 causing issues? Why is this tearing happening in the NTSC Demo that the library comes with, is it just that the demo wasn’t modified with the rest of the library to be optimized for the VE? Is there something in the NTSC demo that can be modified to work well with the VE?

    Here’s the code for the NTSCDemo:


    #include
    #include
    #include "schematic.h"
    #include "TVOlogo.h"

    TVout TV;

    int zOff = 150;
    int xOff = 0;
    int yOff = 0;
    int cSize = 50;
    int view_plane = 64;
    float angle = PI/60;

    float cube3d[8][3] = {
    {xOff - cSize,yOff + cSize,zOff - cSize},
    {xOff + cSize,yOff + cSize,zOff - cSize},
    {xOff - cSize,yOff - cSize,zOff - cSize},
    {xOff + cSize,yOff - cSize,zOff - cSize},
    {xOff - cSize,yOff + cSize,zOff + cSize},
    {xOff + cSize,yOff + cSize,zOff + cSize},
    {xOff - cSize,yOff - cSize,zOff + cSize},
    {xOff + cSize,yOff - cSize,zOff + cSize}
    };
    unsigned char cube2d[8][2];


    void setup() {
    TV.begin(NTSC,120,96);
    TV.select_font(font6x8);
    intro();
    TV.println("I am the TVoutnlibrary running on a freeduinon");
    TV.delay(2500);
    TV.println("I generate a PALnor NTSC composite video usingninterruptsn");
    TV.delay(2500);
    TV.println("My schematic:");
    TV.delay(1500);
    TV.bitmap(0,0,schematic);
    TV.delay(10000);
    TV.clear_screen();
    TV.println("Lets see whatnwhat I can do");
    TV.delay(2000);

    //fonts
    TV.clear_screen();
    TV.println(0,0,"Multiple fonts:");
    TV.select_font(font4x6);
    TV.println("4x6 font FONT");
    TV.select_font(font6x8);
    TV.println("6x8 font FONT");
    TV.select_font(font8x8);
    TV.println("8x8 font FONT");
    TV.select_font(font6x8);
    TV.delay(2000);

    TV.clear_screen();
    TV.print(9,44,"Draw Basic Shapes");
    TV.delay(2000);

    //circles
    TV.clear_screen();
    TV.draw_circle(TV.hres()/2,TV.vres()/2,TV.vres()/3,WHITE);
    TV.delay(500);
    TV.draw_circle(TV.hres()/2,TV.vres()/2,TV.vres()/2,WHITE,INVERT);
    TV.delay(2000);

    //rectangles and lines
    TV.clear_screen();
    TV.draw_rect(20,20,80,56,WHITE);
    TV.delay(500);
    TV.draw_rect(10,10,100,76,WHITE,INVERT);
    TV.delay(500);
    TV.draw_line(60,20,60,76,INVERT);
    TV.draw_line(20,48,100,48,INVERT);
    TV.delay(500);
    TV.draw_line(10,10,110,86,INVERT);
    TV.draw_line(10,86,110,10,INVERT);
    TV.delay(2000);

    //random cube forever.
    TV.clear_screen();
    TV.print(16,40,"Random Cube");
    TV.print(28,48,"Rotation");
    TV.delay(2000);

    randomSeed(analogRead(0));
    }

    void loop() {
    int rsteps = random(10,60);
    switch(random(6)) {
    case 0:
    for (int i = 0; i < rsteps; i++) {
    zrotate(angle);
    printcube();
    }
    break;
    case 1:
    for (int i = 0; i < rsteps; i++) {
    zrotate(2*PI - angle);
    printcube();
    }
    break;
    case 2:
    for (int i = 0; i < rsteps; i++) {
    xrotate(angle);
    printcube();
    }
    break;
    case 3:
    for (int i = 0; i < rsteps; i++) {
    xrotate(2*PI - angle);
    printcube();
    }
    break;
    case 4:
    for (int i = 0; i < rsteps; i++) {
    yrotate(angle);
    printcube();
    }
    break;
    case 5:
    for (int i = 0; i < rsteps; i++) {
    yrotate(2*PI - angle);
    printcube();
    }
    break;
    }
    }

    void intro() {
    unsigned char w,l,wb;
    int index;
    w = pgm_read_byte(TVOlogo);
    l = pgm_read_byte(TVOlogo+1);
    if (w&7)
    wb = w/8 + 1;
    else
    wb = w/8;
    index = wb*(l-1) + 2;
    for ( unsigned char i = 1; i < l; i++ ) {
    TV.bitmap((TV.hres() - w)/2,0,TVOlogo,index,w,i);
    index-= wb;
    TV.delay(50);
    }
    for (unsigned char i = 0; i < (TV.vres() - l)/2; i++) {
    TV.bitmap((TV.hres() - w)/2,i,TVOlogo);
    TV.delay(50);
    }
    TV.delay(3000);
    TV.clear_screen();
    }

    void printcube() {
    //calculate 2d points
    for(byte i = 0; i < 8; i++) {
    cube2d[0] = (unsigned char)((cube3d[0] * view_plane / cube3d[2]) + (TV.hres()/2));
    cube2d
    [1] = (unsigned char)((cube3d[1] * view_plane / cube3d[2]) + (TV.vres()/2));
    }
    TV.delay_frame(1);
    TV.clear_screen();
    draw_cube();
    }

    void zrotate(float q) {
    float tx,ty,temp;
    for(byte i = 0; i < 8; i++) {
    tx = cube3d
    [0] - xOff;
    ty = cube3d
    [1] - yOff;
    temp = tx * cos(q) - ty * sin(q);
    ty = tx * sin(q) + ty * cos(q);
    tx = temp;
    cube3d
    [0] = tx + xOff;
    cube3d
    [1] = ty + yOff;
    }
    }

    void yrotate(float q) {
    float tx,tz,temp;
    for(byte i = 0; i < 8; i++) {
    tx = cube3d
    [0] - xOff;
    tz = cube3d
    [2] - zOff;
    temp = tz * cos(q) - tx * sin(q);
    tx = tz * sin(q) + tx * cos(q);
    tz = temp;
    cube3d
    [0] = tx + xOff;
    cube3d
    [2] = tz + zOff;
    }
    }

    void xrotate(float q) {
    float ty,tz,temp;
    for(byte i = 0; i < 8; i++) {
    ty = cube3d
    [1] - yOff;
    tz = cube3d
    [2] - zOff;
    temp = ty * cos(q) - tz * sin(q);
    tz = ty * sin(q) + tz * cos(q);
    ty = temp;
    cube3d
    [1] = ty + yOff;
    cube3d
    [2] = tz + zOff;
    }
    }

    void draw_cube() {
    TV.draw_line(cube2d[0][0],cube2d[0][1],cube2d[1][0],cube2d[1][1],WHITE);
    TV.draw_line(cube2d[0][0],cube2d[0][1],cube2d[2][0],cube2d[2][1],WHITE);
    TV.draw_line(cube2d[0][0],cube2d[0][1],cube2d[4][0],cube2d[4][1],WHITE);
    TV.draw_line(cube2d[1][0],cube2d[1][1],cube2d[5][0],cube2d[5][1],WHITE);
    TV.draw_line(cube2d[1][0],cube2d[1][1],cube2d[3][0],cube2d[3][1],WHITE);
    TV.draw_line(cube2d[2][0],cube2d[2][1],cube2d[6][0],cube2d[6][1],WHITE);
    TV.draw_line(cube2d[2][0],cube2d[2][1],cube2d[3][0],cube2d[3][1],WHITE);
    TV.draw_line(cube2d[4][0],cube2d[4][1],cube2d[6][0],cube2d[6][1],WHITE);
    TV.draw_line(cube2d[4][0],cube2d[4][1],cube2d[5][0],cube2d[5][1],WHITE);
    TV.draw_line(cube2d[7][0],cube2d[7][1],cube2d[6][0],cube2d[6][1],WHITE);
    TV.draw_line(cube2d[7][0],cube2d[7][1],cube2d[3][0],cube2d[3][1],WHITE);
    TV.draw_line(cube2d[7][0],cube2d[7][1],cube2d[5][0],cube2d[5][1],WHITE);
    }
    #1983
    Michael
    Keymaster

    You need to set the SYNC SELECT jumper to the D9 position so that the Arduino generates the sync signal.

    #1989
    dgcaste
    Member

    Turns out that adding the initOverlay() and initInputProcessing() function calls to setup() fixed the problem.

    #2016
    Andon
    Member

    I’m having the exact same problem – Using the DemoNTSC, I get wretched amounts of tearing through the display.

    @Michael wrote:

    You need to set the SYNC SELECT jumper to the D9 position so that the Arduino generates the sync signal.

    Tried this… And there was no effect. Still had tearing.

    @dgcaste wrote:

    Turns out that adding the initOverlay() and initInputProcessing() function calls to setup() fixed the problem.

    I’m only beginning to work with arduino, and coding in general. Any chance you could put the code up for me to take a peek at?

    #2017
    Michael
    Keymaster

    the code for initializing the Video Experimenter version of TVout is in all the example programs that the library comes with. The Video Experimenter requires the special version of TVout, and the examples demonstrate how to initialize the library.

    #2018
    dgcaste
    Member

    @Andon wrote:

    I’m only beginning to work with arduino, and coding in general. Any chance you could put the code up for me to take a peek at?

    Sure. In your setup() function, just add these two lines in between the brackets:


    initOverlay();
    initInputProcessing();

    Then outside of the setup() and loop() functions, declare what those two functions you just added are:


    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);
    }

    void initInputProcessing() {
    // Analog Comparator setup
    ADCSRA &= ~_BV(ADEN); // disable ADC
    ADCSRB |= _BV(ACME); // enable ADC multiplexer
    ADMUX &= ~_BV(MUX0); // select A2 for use as AIN1 (negative voltage of comparator)
    ADMUX |= _BV(MUX1);
    ADMUX &= ~_BV(MUX2);
    ACSR &= ~_BV(ACIE); // disable analog comparator interrupts
    ACSR &= ~_BV(ACIC); // disable analog comparator input capture
    }

    Note: it may be unnecessary to declare and call initInputProcessing() depending on your code. If you’re running the NTSC Demo, there is no input processing done, and all this function does is set up the analog comparator in order to compare input voltages to reference voltages. I put both functions up because you would need them for other sketches that use the full capability of the VideoExperimenter board.

    Note2: since you’re learning, what these functions are performing are bit-level operations on the ATMega microprocessor. The funny looking operators are bitwise operators: http://en.wikipedia.org/wiki/Bitwise_operations_in_C

Viewing 6 posts - 1 through 6 (of 6 total)
  • You must be logged in to reply to this topic.