Pilotare un display TFT con Arduino Nano

Incuriosito dal basso prezzo (circa 7 euro) ho acquistato un display TFT da 1.8 pollici certo che prima o poi mi sarebbe stato utile.

Incuriosito dal basso prezzo (circa 7 euro) ho acquistato un display TFT da 1.8 pollici certo che prima o poi mi sarebbe stato utile.

L'occasione si è presentata durante una delle giornate che dedichiamo alla sperimentazione.

L'obiettivo prefissato era far muovere il braccio di un cartonato seguendo il braccio della persona (reale) di fronte al Kinect.

L'indispensabile (no, non lo era, ma è stata l'occasione per usarlo) display ha l'arduo compito di visualizzare l'angolo tra il braccio e l'asse del corpo.

Parlerò in seguito dell'intero progetto e ora voglio focalizzarmi sul display poichè in rete ho trovato tantissime guide, librerie e cablaggi per i più disparati modelli, ma davvero poco su questo modello.

Il display TFT in oggetto è di 1.8 pollici e misura 128x160 pixel:

Display front

Display retro

Può funzionare a 3.3v oppure a 5, il driver è ST7735s e il display supporta 65K colori.

L'interfacciamento con Arduino avverrà tramite la SPI

La piedinatura del primo connettore è la seguente:


1VCCPositivo alimentazione 3.3-5V
2GNDNegativo alimentazione
3GNDNegativo alimentazione
4NC
5NC
6NC
7CLKClock della seriale
8SDAData della seriale
9RSLivello 0 command / Livello 1 Data
10RSTReset
11CSAbilitazione

La piedinatura del secondo connettore è la seguente:

1SD_CSSD card chi selected
2SD_MOSISPI data input
3SD_CLKSPI bus clock
4SD_MISOSPI Bus data output


E' possibile collegare il display in due modalità: "veloce" e "lento".

Non prenderò in esame la modalità "lenta" perchè è davvero lenta!

Circa 5 volte più lenta dell'altra modalità.

Il cablaggio "veloce" è il seguente:

Arduino Display TFT breadboard


I sorgente utilizza le librerie Adafruit ed è il seguente:

#include <Arduino.h>

#include "Adafruit_GFX.h"    // Core graphics library
#include "Adafruit_ST7735.h" // Hardware-specific library for ST7735

#include "SPI.h"


#define TFT_SCLK 13 //clk
#define TFT_MOSI 11 //sda

#define TFT_CS   10
#define TFT_DC   9
#define TFT_RST 8

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
const int inputPin = A0;
  int x0 = 78;
  int y0 = 70;

  float oldValue=0;
  int oldValueX=0;
  int oldValueY=0;
  
void setup() {
  Serial.begin(9600);

  tft.initR(INITR_BLACKTAB);
  tft.setRotation( 1 );     
  tft.fillScreen(ST77XX_WHITE);
  tft.setTextSize(1);

  tft.setTextColor(ST77XX_RED);
  DrawScale();
  tft.setTextSize(3);
}
const int MAX_VALUE =5;

void DrawValue(float value){
    Serial.print(oldValue);
    Serial.print("      ");
    Serial.print(value);

    Serial.println();
  if(abs(value - oldValue)<0.01){
    Serial.print(" NO DRAW");
    Serial.println();
    return;
  }else{
    Serial.print(" DRAW");
    Serial.println();
    }
   

  int rv=49;
  int xv;
  int yv;
  
  float angleV=180+ ((180/MAX_VALUE) * value);
   
  xv = rv * cos(angleV * PI / 180);
  yv = rv * sin(angleV * PI / 180);

  tft.drawLine(x0, y0, oldValueX, oldValueY, ST77XX_WHITE);
  tft.drawLine(x0, y0, x0+xv, y0+yv, ST77XX_RED);


  
  tft.setCursor(x0 - 30 ,y0 + 20 );
  tft.setTextColor(ST77XX_WHITE);
  tft.print(oldValue);

  tft.setTextColor(ST77XX_BLACK);
  tft.setCursor(x0 - 30,y0 + 20); 
  tft.print(value);
  
  oldValue=value;
  oldValueX=x0+xv;
  oldValueY=y0+yv;
}
void DrawScale(){
  int r1=60;
  int r2=50;
  int rf=70;
  
  int angle; 
  int x1;
  int y1;
  int x2;
  int y2;
  int xf;
  int yf;

  for (int i=0;i<=MAX_VALUE;i++){
    angle=(180/MAX_VALUE) * (i+MAX_VALUE) ;
    x1 = r1 * cos(angle * PI / 180);
    y1 = r1 * sin(angle * PI / 180);

    x2 = r2 * cos(angle * PI / 180);
    y2 = r2 * sin(angle * PI / 180);

    xf = rf * cos(angle * PI / 180);
    yf = rf * sin(angle * PI / 180);
    
    tft.drawPixel(x0+x1,y0+y1, ST77XX_ORANGE);
    tft.drawPixel(x0+x2,y0+y2, ST77XX_ORANGE);

    tft.drawLine(x0+x1, y0+y1, x0+x2, y0+y2, ST77XX_BLACK);
    tft.setCursor(x0+xf,y0+yf); 

    int label=(i);
    tft.print(label);
  }
}


void loop(){
  float rVal = analogRead(inputPin);   
  float val = (5.0 / 1024.0)  * rVal;
  DrawValue(val);
  
  delay(200);
  }

Il piedino A0 è configurato come analog input e applicando una tensione (massimo di 5 volt) sul display verrà mostrato il suo valore.

Ecco un breve video della misurazione di una batteria (quasi scarica).

NOTA: per evitare che disturbi sul piedino A0 causino rilevazioni del tutto casuali dovrei applicare una resistenza da 10k tra il piedino e il negativo di alimentazione

Guarda i video su YouTube