Stazione Meteo con Arduino – il display grafico

Il progetto della Stazione Meteo con Arduino è stato abbondantemente introdotto anche in maniera dettagliata ai seguenti link:

Quello di cui parleremo in questo articolo è come utilizzare un display grafico 128×64 per la nostra stazione meteo. Ci servirà per visualizzare i dati dei sensori, gli stati del sistema anche con la possibilità di visualizzare più pagine.

Il display si presenta come in foto:

display 128x64 stazione meteo micheleardito.info

Si tratta di un display grafico 128×64 pixel retroilluminato blu con pixel bianchi.

Si tratta di un display gestito da un ptocessore ST7920.

Qui un esempio del display accesso e connesso alla mia stazione meteo:

stazione display meteo micheleardito.info

La connessione ad Arduino (vi ricordo che stiamo utilizzando un Arduino Mega 2560) avviene attraverso delle linee parallele secondo il seguente schema:

PIN Display       PIN ARDUINO
 1 VSS            GND
 2 VDD            +5V
 3 V0             NC 
 4 RS             30
 5 R/W            31
 6 E              32
 7 DB0            22
 8 DB1            23
 9 DB2            24
10 DB3            25
11 DB4            26
12 DB5            27
13 DB6            28
14 DB7            29
15 PSB            NC
16 NC             NC
17 RST            NC
18 VOUT           NC
19 A              +5V
20 K              GND
----------------------------------------------------------------
BackLight         33

Sul PIN 33 di Arduino ho inserito un transistor 2N2222 per controllare l’accensione e lo spegnimento della retroilluminazione a tempo.

A questo punto la prima cosa di cui dovremo preoccuparci è scaricare la libreria per controllare il display.

A questo link troverete quello che ci serve: https://github.com/olikraus/u8glib/ – mentre qui: https://github.com/olikraus/u8glib/wiki/device troverete documentazione sulla stessa e sui display interfacciabili.

Una volta scaricata ed installata nell’ambiente di sviluppo di Arduino (IDE) sarà pronta per essere utilizzata nel nostro sketch.

Nelle dichiarazioni iniziali andremo a scrivere:

#define LCDBACKLIGHT     33
#include "U8glib.h"
U8GLIB_ST7920_128X64_1X u8g(22, 23, 24, 25, 26, 27, 28, 29, 32, 30, 31);

In questo modo avremo istanziato la nostra libreria utilizzando l’oggetto U8GLIB_ST7920_128X64_1X che si occuperà di “parlare” con il processore ST7920. In realtà la libreria U8gLib è in grado di interfacciarsi con diversi processori display, quindi è molto versatile. Tra parentesi seguiranno i PIN di Arduino che abbiamo collegato al display.

Come di consueto adesso, nella routine SETUP andremo a definire la prima chiamata alla libreria per fare in modo di avviare la prima pagine del display stabilendo di fatto la comunicazione tra Arduino e display:

void setup() {
  // inizializzazione LCD BACKLIGHT
  pinMode(LCDBACKLIGHT, OUTPUT);
  digitalWrite(LCDBACKLIGHT, HIGH); // accende la retroilluminazione
  // chiamata alla libreria U8g
  u8g.firstPage();  
  do {
    draw();
  } while( u8g.nextPage() );
}

Ripeteremo questa chiamata anche nel ciclo LOOP pari pari.

void loop() {
  u8g.firstPage();  
  do {
    draw();
  } while( u8g.nextPage() );
}

La funzione draw() si occupa di disegnare i contenuti sul display.

All’interno della funzione ci preoccuperemo di sistemare i dati nei punti giusti del display.

Iniziamo con scrivere l’intera funzione:

void draw(void) {
  int x;
  int y;
  int r, r1, r2;
  int angle = sensorWindDirectionValueDegrees - 90;
      // preparazione ambiente
      u8g.setDefaultForegroundColor();
      y = 10;
      // linea superiore
      u8g.drawLine(15, y, 128, y);
      // tensione batteria
      x = 86; y = 0;
      u8g.setPrintPos(x + 9, y); u8g.print(String(battery_Voltage));
      // temperatura quadro
      x = 52; y = 0;
      u8g.setPrintPos(x + 9, y); u8g.print(String(sensorBaroTemperatura));
      // disegno indicatore vento e valori
      u8g.setFont(u8g_font_6x12);  u8g.setFontRefHeightExtendedText();  u8g.setFontPosTop();
      r = 19; 
      r1 = r - 2; 
      r2 = r - 8;
      x = u8g.getWidth() - r - 1;
      y = r + 10;
      u8g.drawCircle(x, y, r);
      u8g.drawTriangle(cos((angle*71.0)/4068.0) * r1 + x, sin((angle*71.0)/4068.0) * r1 + y, 
                       cos(((angle-145.0)*71.0)/4068.0) * r2 + x, sin(((angle-145.0)*71.0)/4068.0) * r2 + y, 
                       cos(((angle+145.0)*71.0)/4068.0) * r2 + x, sin(((angle+145.0)*71.0)/4068.0) * r2 + y);
      u8g.setPrintPos(x - 21, r*2 +  9); u8g.print(String(sensorWindDirectionValueDegrees) + (char)176 + sensorWindDirectionDescription);
      u8g.setPrintPos(x - 39, r*2 + 17); u8g.print(String(windSpeed1) + "km/h");
      // calendario data e ora 
      u8g.setPrintPos(0,47); u8g.print(RTCDate);
      u8g.setPrintPos(0,55); u8g.print(RTCClock);
      // visualizzazione temperatura interna
      // simbolo HOME IN
      x = 0; y = 10;
      u8g.setFont(u8g_font_6x13);        u8g.setFontRefHeightExtendedText();  u8g.setFontPosTop();
      u8g.setPrintPos(x, y);             u8g.print(String(sensorTemperaturaK));
      u8g.setPrintPos(x + 40, y);        u8g.print(String(sensorUmiditaK));
      u8g.setFont(u8g_font_6x12);        u8g.setFontRefHeightExtendedText();  u8g.setFontPosTop();
      u8g.setPrintPos(x + 24, y + 1);    u8g.print(String(((char)176)) + "C");
      u8g.setPrintPos(x + 64, y + 1);    u8g.print("%IN");
      // visualizzazione temperatura esterna
      // simbolo HOME OUT
      x = 0; y = 20;
      u8g.setFont(u8g_font_6x12);          u8g.setFontRefHeightExtendedText();  u8g.setFontPosTop();
      u8g.setPrintPos(x, y);               u8g.print(String(sensorTemperaturaK2) + String(((char)176)) + "C");
      u8g.setPrintPos(x + 40, y);          u8g.print(String(sensorUmiditaK2) + "%OUT");
      u8g.setFont(u8g_font_6x12);          u8g.setFontRefHeightExtendedText();  u8g.setFontPosTop();
      y = 30;
      u8g.drawLine(0, y, 87, y);
      // pressione
      x = 0; y = 31;
      u8g.setPrintPos(x + 9, y);  u8g.print(String(sensorBaroPressione));
      // lux
      x = 0; y = 39;
      u8g.setPrintPos(x + 9, y);  u8g.print(String(sensorLightLux));
}

Le variabili contenute nella funzione draw() sono prese dal resto del programma della stazione meteo che potete trovare nell’articolo: Stazione Meteo con Arduino – i dettagli.