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

 

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:

1 VCC Positivo alimentazione 3.3-5V
2 GND Negativo alimentazione
3 GND Negativo alimentazione
4 NC  
5 NC  
6 NC  
7 CLK Clock della seriale
8 SDA Data della seriale
9 RS Livello 0 command / Livello 1 Data
10 RST Reset
11 CS Abilitazione

 

La piedinatura del secondo connettore è la seguente:

 

1 SD_CS SD card chi selected
2 SD_MOSI SPI data input
3 SD_CLK SPI bus clock
4 SD_MISO SPI 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:

I sorgente utilizza le librerie Adafruit ed è il seguente:

 

 

#include <Arduino.h>

//https://learn.adafruit.com/adafruit-gfx-graphics-library/graphics-primitives
#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);


void setup() {
  Serial.begin(9600);

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

  tft.setTextColor(ST77XX_BLUE);
  tft.setCursor(5,10);
  tft.print("This");
  delay(3000);

  tft.setCursor(90,10);
  tft.print("is");
  delay(3000);

  tft.setTextColor(ST77XX_RED);
  tft.setCursor(5,70);
  tft.print("a test!");
  delay(3000);
}

void loop(){}

 

 Ecco il risultato

Un esempio più divertente è il seguente (un "voltmetro analogico"):

#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