mercoledì 26 giugno 2013

Arduino Uno + Display Nokia 5110 = Mandelbrot 48x84

In questo post viene descritto come disegnare un insieme di Mandelbrot utilizzando una Arduino Uno ed un display Nokia 5110

Il display, utilizzato per esempio nel telefono Nokia 3310, viene adesso venduto separatamente ed ha una risoluzione di 84x48 pixel monocromatici

Il mio vecchio Nokia 3310

Il modello usato nell'esempio e' stato acquistato per circa 5 euro da DealExtreme ed a differenza del display originale, connesso con un cavo flat, utilizzata una strip per connetterlo facilmente ad una breadboard

Per l'utilizzo si devono inserire le librerie Arduino per il controller 8544 e per la grafica 

Attenzione che rispetto agli esempi riportati su Internet i nomi dei pin sono leggermente differenti e con un ordine differente tra quelli di Adafruit o Sparkfun e quello comprato su DealExtreme...comunque anche senza istruzioni si riesce a venirne a capo semplicemente


Usando una Arduino Uno e' importante inserire le resistenze (come indicato qui)  in quanto la tensione di esercizio del display e' di 3.3 V



Di seguito lo script per la realizzazione di Mandelbrot

--------------------------------
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>

// tempo di esecuzione 
// 1minuto e 15 secondi su Arduino Uno
// aggiornando il display solo alla fine
// 2 minuti ed 11 secondi aggiornando il display ogni pixel


// 48 righe
// 84 colonne
#define SCREEN_WIDTH 84
#define SCREEN_HEIGHT 48

// pin 7 - Serial clock out (SCLK)
// pin 6 - Serial data out (DIN)
// pin 5 - Data/Command select (D/C)
// pin 4 - LCD chip select (CS)
// pin 3 - LCD reset (RST)
Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 4, 3);

float re_min = -2.0;
float im_min = -1.2;

float re_max = 1.0;
float im_max = 1.2;

int iterazioni = 1024;


float a,b;
float x,y,x_new,y_new;

int test;

int k,j,i;



void setup()   {
  display.begin();
  display.setContrast(50);
  display.clearDisplay();   // clears the screen and buffer

  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 == 0) display.drawPixel(j, i, BLACK);
        display.display();       
        break;
        }
       x = x_new;
       y = y_new;
       }
             
      }
    
     }

  //altrimenti se si fa tutto alla fine e' molto piu' veloce
  display.display();
  delay(2000);
}


void loop() {
  
}