lunedì 13 gennaio 2014

Mandelbrot su Arduino con TvOut

Un metodo veloce per visualizzare dati derivanti da una Arduino senza utilizzare display appositi ed impiegando solo due uscite digitali puo' essere quella di ricorrere alla libreria TvOut ed inviando il segnale all'uscita SVideo di un comune televisore


In questo modo, usando un semplice connettore S-Video ed un paio di resistenze, si puo' avere una visualizzazione senza troppi problemi
Lo schema delle resistenza e' il seguente


Alcuni riportano che' obbligatoria una resistenza da 75 Ohm anche sul GND. Per quanto mi riguarda il tutto ha funzionato anche senza (ho avuto difficolta' a trovare questo taglio di resistenza)
Importante: sul sito e' indicato che per la Arduino Uno i pin digitali da collegare sono D7 (Video), D9 (Sync) e GND ma nel mio caso hanno funzionato D8 (Video), D9 (Sync) e GND

La risoluzione di base e' sostanzialmente pessima, un misero 128x98, ma per un sistema cosi' semplice non e' male
Ovviamente non potevo esimermi dal provare a disegnare l'insieme di Mandelbrot




-----------------------------------------------------------------------------
#include <TVout.h>
TVout TV;


int SCREEN_WIDTH = 0;
int SCREEN_HEIGHT = 0;

float re_min = -2.0;
float im_min = -1.2;
float re_max = 1.0;
float im_max = 1.2;
int iterazioni = 60;
float a,b;
float x,y,x_new,y_new;
int test;
int k,j,i;


void setup(void) {
  TV.start_render(_PAL);
  TV.delay_frame(50);

  TV.clear_screen();
  SCREEN_WIDTH = TV.horz_res();
  SCREEN_HEIGHT = TV.vert_res();

  //---------------------------------
  float re_factor = (re_max-re_min);
  float im_factor = (im_max-im_min);
  for (i=0;i<SCREEN_HEIGHT;i++)
     {
     for (j=0;j<SCREEN_WIDTH;j++)
      {
      a = re_min+(j*re_factor/SCREEN_WIDTH); 
      b = im_min+(i*im_factor/SCREEN_HEIGHT);
      x = 0;
      y = 0;
      test = 0;
      for (k=0;k<iterazioni;k++)
       {
       x_new = (x*x)-(y*y)+a;
       y_new = (2*x*y)+b;
       if (((x_new*x_new)+(y_new*y_new))>4)
        {
        test = k;
        if (k%2)
          {
            TV.set_pixel(j,i,1); 
         }     
        break;
        }
       x = x_new;
       y = y_new;
       }
      }
     }
}

void loop(void) {
  while (1) {}
}