VGA library - now with TV output

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:

#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!

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.

duevga4.sch (69.5 KB)

duevga4.brd (42.7 KB)

board.png

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

great library and work many thanks :slight_smile:

Kamil

Well done!

Rossler chaotic attractor

#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 ++;
}

Rossler_VGA.zip (633 Bytes)

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

http://stimmer.github.com/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 :grin:

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

Hi stimmer

Yes all my codes is absolutelly free for anything use :slight_smile:

Many thanks your great works !

Kamil

Thanks JLS1, I added the Rossler demo :slight_smile:

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 :grin: I also added keywords.txt. Download is in the attachments on the first post.

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 :fearful: :fearful: :fearful:

nice one :slight_smile:

please post code - THANKS

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:

// 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)/(zztwo+ztwo+one);

Thanks :slight_smile:

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 :wink:

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.

rdac.png

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 :

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

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 :

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

Make sure you have selected Arduino Due in the Tools/Board menu - that's the main cause of that particular error message.

stimmer:
Make sure you have selected Arduino Due in the Tools/Board menu - that's the main cause of that particular error message.

It works!

Thank you!

Quick preview of the next release: Only minor bugfixes in the library, although one of those bugs was causing a hang when receiving Serial data, so if you use Serial and VGA you should upgrade (the fix is already in github master if you need it now)

The major addition is a new demo, which decodes GPS GPGGA/GPGSV strings and shows a rotated globe and satellite positions. Data can be taken from a real GPS or entered in the serial monitor. You have probably seen smartphone apps which do this, well now you can do it on an Arduino too 8) Watch satellites move across the sky in real time (although only if you are very patient as it takes the satellites 6 hours to get from one side of their orbit to the other!)

Sparkfun has a VGA breakout introduced lately, can this make connections for Due users easier? Papilio VGA Wing - WIG-11569 - SparkFun Electronics

Yes you could use that although it is actually 6 bit, not 8, so in colour mode you would only get 64 colours (you might be able to get all 256 by adding a few extra resistors). Mono mode should be just fine. It would need a bit of work to wire it to the right pins - it wouldn't just be able to plug straight into the Due like it can with a Papilio.