Go Down

Topic: VGA library - now with TV output (Read 29 times) previous topic - next topic

stimmer

Feb 23, 2013, 09:57 pm Last Edit: May 13, 2013, 03:02 am by stimmer Reason: 1
The Due VGA library lets you connect a Due to a monitor with a VGA input. Resolutions available are up to 800x600 in monochrome and 320x240 in colour. The API is quite simple and straightforward - just VGA.begin(x,y); and off you go! The library has some common drawing functions for pixels, lines, triangles, rectangles, circles, ellipses and text. It also derives the Print library, so it supports the Arduino VGA.print(...) and VGA.println(...) functions. Just 3 resistors needed for mono and 10 resistors for colour.

Github page http://stimmer.github.com/DueVGA/

Download: DueVGA-0.512.zip

Update 12/05/2013 Version 0.512: Fixed interrupt handling so the library now works better with Serial and Audio libraries, and added some longer demos (display of data from GPS, showing animation from an SD card, and a waterfall visualization of an audio input signal)

Update 04/04/2013 Version 0.404: Added PAL/NTSC colour composite modes for TV output. Circuit is 6 resistors and (if needed) one capacitor.

Update 14/03/2013 Version 0.314: Colour mode now uses DMA, making it 4 times faster than before 8) - the Mandelbrot demo used to take about 4 minutes, now it is finished in under 1 minute. Also fixed a bug involving analogWrites to pin 2, and added keywords.txt for source highlighting.

Example code:
Code: [Select]
#include <VGA.h>

// DrawingTest
// test of all drawing functions

void setup() {
 VGA.begin(320,240,VGA_COLOUR);
}

double a=0;

void loop() {
 int x0=random(320),y0=random(240),x1=random(320),y1=random(240),x2=random(320),y2=random(240);
 VGA.fillTri(x0,y0,x1,y1,y2,y2,random(512)-256);
 VGA.drawTri(x0,y0,x1,y1,y2,y2,random(512)-256);

 x0=random(320);y0=random(240);x1=random(320);y1=random(240);
 VGA.fillRect(x0,y0,x1,y1,random(512)-256);
 VGA.drawRect(x0,y0,x1,y1,random(512)-256);
 
 x0=random(320);y0=random(240);x1=random(320);y1=random(240);
 VGA.fillEllipse(x0,y0,x1,y1,random(512)-256);
 VGA.drawEllipse(x0,y0,x1,y1,random(512)-256);
   
 x0=random(320);y0=random(240);int r=random(70);
 VGA.fillCircle(x0,y0,r,random(512)-256);
 VGA.drawCircle(x0,y0,r,random(512)-256);
 
 x0=random(320);y0=random(240);r=random(5)-1;
 VGA.drawText("Hello Arduino!",x0,y0,random(256),random(256),r);
 
 x0=random(320);y0=random(240);r=random(5)-1;
 VGA.drawText("Due VGA Library",x0,y0,random(256),random(256),r);
 
 VGA.scroll(0,0,320,240,8*sin(a),8*cos(a));
 a+=0.05;
}


For monochrome modes the circuit is very simple - just 3 resistors
Connect pin 42 through an 82 ohm resistor to VGA VSync (pin 14 on VGA D-connector)
Connect pin 43 through an 82 ohm resistor to VGA HSync (pin 13 on VGA D-connector)
Connect GND to VGA GND (pins 5,6,7,8,10 on VGA D-connector)
Connect SPI MOSI pin (bottom middle pin on 6-pin SPI connector) through a 100 ohm resistor to VGA Red, Green and Blue pins (pins 1,2 and 3 on D-connector)
You may need to experiment with the values of the resistors for best results.

For colour the circuit needs a few more pins and resistors:
Due pin 34 -> 820R resistor -> VGA pin 3 (blue)
Due pin 35 -> 390R resistor -> VGA pin 3 (blue)
Due pin 36 -> 2k2 resistor -> VGA pin 2 (green)
Due pin 37 -> 1k resistor -> VGA pin 2 (green)
Due pin 38 -> 470R resistor -> VGA pin 2 (green)
Due pin 39 -> 2k2 resistor -> VGA pin 1 (red)
Due pin 40 -> 1k resistor -> VGA pin 1 (red)
Due pin 41 -> 470R resistor -> VGA pin 1(red)
Due pin 42 -> VGA pin 14 (VSync)
Due pin 43 -> VGA pin 13 (HSync)
Due pin GND -> VGA pins 5,6,7,8,10
Again the resistor values probably aren't optimal.

For PAL/NTSC:
Due pin 36 -> 3k3  resistor -> Video In
Due pin 37 -> 1k5  resistor -> Video In
Due pin 38 -> 820R resistor -> Video In
Due pin 39 -> 390R resistor -> Video In
Due pin 40 -> 200R resistor -> Video In
Due pin 41 -> 100R resistor -> Video In
Due pin GND -> Video GND
You may need a 100uF capacitor between the resistors and Video In for DC blocking.

I shall keep this post updated with the latest library release so keep checking back here. Have fun!

stimmer

#1
Feb 23, 2013, 09:57 pm Last Edit: Feb 23, 2013, 10:03 pm by stimmer Reason: 1
This post is a placeholder for the mini-shield design I made for the VGA library. I shall edit this with more details about the shield when I have the time, but for now please find the Eagle files attached below. If you do try to build this, bear in mind that you may need to experiment with the resistor values as I said above.

TheKitty

Awesome work!  You should post the library availability in the Due library thread also.

JLS1

great library and work many thanks :-)

Kamil

robtillaart

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

JLS1

#5
Feb 24, 2013, 03:22 pm Last Edit: Feb 25, 2013, 04:27 pm by JLS1 Reason: 1
Rossler chaotic attractor

Code: [Select]

#undef printf
#include <VGA.h>

  float a = 0.2;
  float b = 0.2;
  float c = 8;

  float x,y,z;

  float xnn = 0;
  float ynn = 0;
  float znn = 0;

  float dt = 0.02;
 
  int cnt = 0;
 
  boolean vis;

void setup() {
 
  VGA.begin(800,600);
  VGA.clear();
  VGA.drawText(" Rossler chaotic attractor ",25,25,0,1);
  VGA.drawText("dx/dt = -y - z",25,50,1);
  VGA.drawText("dy/dt = x + ax",25,60,1);
  VGA.drawText("dz/dt = b + z(x-c)",25,70,1);
  VGA.drawText("a = 0.2",25,90,1);
  VGA.drawText("b = 0.2",25,100,1);
  VGA.drawText("c = 8",25,110,1);
}

void loop() {
 
       xnn = -(y+z);
       ynn = x+a*y;
       znn = b+x*z-c*z;

       x = x+xnn*dt;
       y = y+ynn*dt;
       z = z+znn*dt;
 
       VGA.drawPixel(350+(16*((z/2)-x)), 200+(12*((z/2)-y)), vis);
       
       if (cnt == 1500) {
         vis = !vis;
         cnt =0;
       }
       
       cnt ++;
}

stimmer

Update: The Due VGA Library now has a github page :)

http://stimmer.github.com/DueVGA/
https://github.com/stimmer/DueVGA

I have written some instructions on how to wire up the circuit on a breadboard:
http://stimmer.github.com/DueVGA/breadboard.html


No code updates yet but the next release will have a big improvement in the speed of the colour modes, as I have now worked out how to do them using DMA  :smiley-mr-green:


JLS1: May I include your Rossler code as an example in the next release of the library?

JLS1

Hi stimmer

Yes all my codes is absolutelly free for anything use :-)

Many thanks your great works !

Kamil

stimmer

Thanks JLS1, I added the Rossler demo :)

I've made a new release of the library. The big news is the colour mode now uses DMA resulting in a speed increase of a factor of 4  :smiley-mr-green: I also added keywords.txt. Download is in the attachments on the first post.

stimmer

No new release but I just had to share this: Whilst working on some experimental PAL code with a modified branch of the library I accidentally created the fractal below  :smiley-eek-blue: :smiley-eek-blue: :smiley-eek-blue:

JLS1

nice one :-)

please post code - THANKS

stimmer

I've realised where I went wrong, I made a mistake in the calculus. It was supposed to be a fractal based on Newton's method - here is the correct code:
Code: [Select]

// Newton-Raphson fractal of Z^3+Z^2+Z+1=0

#include <VGA.h>
#include <complex>
using namespace std;

const byte cmap[]={0b00000000,0b11100000,0b11100100,0b11101000,0b11101100,0b11110000,0b11110100,0b11111000,0b11111100,
                   0b11011100,0b10111100,0b10011100,0b01111100,0b01011100,0b00111100,0b00011100,0b00011101,0b00011110,
                   0b00011111,0b00011011,0b00010111,0b00010011,0b00001111,0b00001011,0b00000111,0b00000011,0b00100011,
                   0b01000011,0b01100011,0b10000011,0b10100011,0b11000011,0b11100011,0b11100010,0b11100001,0b11100000,0b00000000};

void setup() {
  VGA.begin(320,240,VGA_COLOUR);
}

void loop(){
  for(int i=0;i<320;i++){
    for(int j=0;j<240;j++){     
      complex<float> c(0,0),z((i-160.0)/80.0,(j-120.0)/60.0),zz,zzz;
      complex<float> one(1.0,0.0),two(2.0,0.0),three(3.0,0.0);
      int n;
      for(n=1;n<sizeof(cmap);n++){       
        zz=z*z; zzz=zz*z;
        c=(zzz+zz+z+one)/(zz*three+z*two+one);
        z-=c;       
        if(norm(c)<0.01)break;
      }
      VGA.drawPixel(i,j,cmap[sizeof(cmap)-n]);
    }
  }
  for(;;);
}


The correct output is attached. To get the bizarre picture above, change the line to:

c=(zzz+zz+z+one)/(zz*two+z*two+one);

JLS1


stimmer

I've merged in the PAL and NTSC branches so the VGA library now does TV output. The circuit uses just 6 resistors and a capacitor. Quality is... err... well if you remember what home computers used to be like in the 80s you will have a fair idea of how low to set your expectations ;)

Resolution is fixed at 320x240 in PAL and 320x200 in NTSC. I've tested it on 5 different TVs and monitors, but my timings are quite a way off spec so I would expect some trouble particularly on old TVs. I'll try and do a proper release tomorrow but the code is already on Github.


Ithos92

First of all, really great work!


I tried the DrawingTestPal example of your library with the Arduino Ide 1.5.2 on my Arduino Due, but it show me this error :

Code: [Select]

In file included from DrawingTestPAL.ino:1:
C:\Users\andrea\Desktop\Andrea\Arduino\arduino-1.5.2\libraries\VGA/VGA.h: In function 'void _v_digitalWriteDirect(int, boolean)':
C:\Users\andrea\Desktop\Andrea\Arduino\arduino-1.5.2\libraries\VGA/VGA.h:49: error: 'g_APinDescription' was not declared in this scope
C:\Users\andrea\Desktop\Andrea\Arduino\arduino-1.5.2\libraries\VGA/VGA.h:50: error: 'g_APinDescription' was not declared in this scope

Go Up