VGA output

Status
Not open for further replies.

fsk

Member
i thought id make myself some king of glitch generator i could use for VJing. so i started today and spent the day trying to get an image (any image). luckily i have a cheap VGA to composite converter, which is really forgiving with the timings, so even with my naive approach i was able to get something. the problem is there is tons of jitter.

i compared this output to signals generated with my computer on my scope. and the timings are not that much off, apart from the jitter. does anyone have any idea how i could get rid of it? :confused:
or what would be the correct approach to get this done...

Code:
#define RED 0
#define GREEN 1
#define BLUE 2
#define HSYNC 3
#define VSYNC 4


IntervalTimer line;
int lineCount=0; //making this volatile causes a periodic glitch


void setup() {
  // put your setup code here, to run once:
  pinMode(RED,OUTPUT);
  pinMode(GREEN,OUTPUT);
  pinMode(BLUE,OUTPUT);
  pinMode(HSYNC,OUTPUT);
  pinMode(VSYNC,OUTPUT);

  line.begin(vgaLine,26.4f);
  //line.beginCycles(vgaLine,1267); //i made this function public in my investigations...
}

void loop() {

}

void vgaLine()
{
  int kaka;
  boolean vBlank;
  
  
  if(lineCount<29)vBlank=true;
  else vBlank=false;
  
   lineCount++;

   
   
   kaka=0;
   while(kaka<130)
   {
     kaka++;
   if(!vBlank)digitalWriteFast(RED,HIGH);
   if(!vBlank)digitalWriteFast(RED,LOW);
   }
   
   while(kaka<160)kaka++;
   
  
   
   if(lineCount>=628)lineCount=0;
   digitalWriteFast(HSYNC,HIGH);
  // kaka=0;
   if(lineCount>1&&lineCount<6)
   {
      digitalWriteFast(VSYNC,HIGH);
   }
   else
   digitalWriteFast(VSYNC,LOW);
   

   kaka=0;
   while(kaka<69)kaka++;

   digitalWriteFast(HSYNC,LOW); 
   kaka=0;
   //while(kaka<20)kaka++;//38
}
 
I think you should move your VSync/HSync code to its own IntervalTimer... Then read the line counters variables in your main loop to know when set the colour pins.

I might buy a VGA converter myself and have a play (wish I hadn't thrown away that old Monitor now) :)
 
i tried using two timers at first but that is even worse. they drift in relation to one another.

it has to be something more basic that I'm missing. even this simplest way of toggling pins has LOTS of jitter. i just don't get it.

Code:
#define HSYNC 3
#define VSYNC 4

volatile int kaka;

void setup() {
  // put your setup code here, to run once:
  pinMode(HSYNC,OUTPUT);
  pinMode(VSYNC,OUTPUT);
 // kaka=0;
}

void loop() {
  // put your main code here, to run repeatedly: 
  while(1)
  {
      for(kaka=0;kaka<48;kaka++);
      
      digitalWriteFast(HSYNC,HIGH);

      for(kaka=0;kaka<48;kaka++);
      
      digitalWriteFast(HSYNC,LOW);
  }
}
 
Ok i think i made a step forward. the thing that helped a lot was put a noInterrupts() at the beginning of the routine and interrupts() at the end. completely forgot about that one:). It helped enough that i even got an image on my LCD.

But even with this there is still some periodic jitter which causes a glitch on the screen and makes the LCD loose sync. When i put noInterrupts() in setup() and do the whole thing in the loop() everything is perfect!. but now i wonder what causes the jitter. is there a way to turn off other interrupts (and what are they) but keep the timer. or is the jitter in the timer itself? i wish its not the timer, that would make other things much more complicated. :/
 
I would have the Vsync interrupt happen only once per frame, and your HSync only once per line. You are running the interrupt far too often for the teensy :) then generate your picture in the main loop :)


-edit- really, your Sync interrupts shouldn't do any more than toggle the correct pin, and advance/reset a counter variable...
 
Last edited:
the system tick clock interrupts 1,000 times a second.

really, as others have said, people that did this video generation in software, on other projects (famously, one used a little AVR), do it with timer interrupts so the timing is based on the CPU's hardware timers, not delay loops in the software. Or, without using timer interrupts for your code, you can use the CPU timers and read the timer values in a loop until you get >= the desired time and thus sync with the hardware. The sys tick interrupts will steal away CPU time, but assuming the sys tick overhead is tolerable, your code can let systick run. If you analyze this, you can decide if you can tolerate the systick overhead. Also, don't use the USB or serial as those have interrupt overhead too, of course.

With more systems programming expertise, you could have your use of CPU timers for video timing take a priority interrupt over systick, to preempt. That's "nested interrupt service" which is tricky.

Kind of a drill, this is, since there are more and more small embedded PCB computers with on-board graphics with video or HDMI out, such as Raspberry Pi, or the new $74 Freescale RiOT
http://www.element14.com/community/community/knode/single-board_computers/riotboard
 
Last edited:
Status
Not open for further replies.
Back
Top