Store › Forums › Video Experimenter › Bugs/Problems › Video tearing left to right
- This topic has 5 replies, 3 voices, and was last updated 10 years, 3 months ago by dgcaste.
-
AuthorPosts
-
August 16, 2014 at 5:07 am #709dgcasteMember
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);
}
August 16, 2014 at 6:43 pm #1983MichaelKeymasterYou need to set the SYNC SELECT jumper to the D9 position so that the Arduino generates the sync signal.
August 17, 2014 at 3:01 am #1989dgcasteMemberTurns out that adding the initOverlay() and initInputProcessing() function calls to setup() fixed the problem.
September 3, 2014 at 8:39 pm #2016AndonMemberI’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?
September 4, 2014 at 1:09 pm #2017MichaelKeymasterthe 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.
September 4, 2014 at 4:55 pm #2018dgcasteMember@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
-
AuthorPosts
- You must be logged in to reply to this topic.