martedì 27 febbraio 2024

Standard 7090: Display TFT 320x240

Come abbiamo visto nei precedenti post, stiamo adottando uno standard proprietario per il riutilizzo di moduli e blocchi funzionali per il nostro laboratorio.

Oggi aggiungiamo un Display grafico a colori da 2,8 pollici, montato su una scheda millefori 70x90 che ha anche funzione di backplane ovvero ci fornirà le connessioni per il Bus 7090.

Il display prescelto è un componente compatibile con lo standard Arduino R3 e verrà ospitato proprio da una scheda Arduino UNO R3. Entrambi i componenti vengono forniti da Elegoo e sono facilmente reperibili in commercio e completi di librerie firmware scaricabili o fornite a corredo su CDROM.

Poiché la scheda Elegoo Arduino UNO R3 compatibile provvederà a gestire tutti i segnali del bus parallelo del display, basato su controller ILI9341, non resteranno altri pin se non RX e TX da assegnare al programma di bordo.

In questa applicazione useremo l'assieme come Monitor "intelligente" con un semplice protocollo seriale per configurare il monitor (...qualcosa che ricorda un po' gli home computer anni '80 su cui ho iniziato a programmare).


Display TFT 320x240

Bene, il display funziona e ha caratteristiche piuttosto interessanti se pensiamo che viene pilotato da un microcontrollore a 8 bit quale l'ATMEGA328 con risorse piuttosto limitate.
Adesso vediamo il codice C++

/*


READ THIS BEFORE USE:

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”

AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,

THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.

IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,

INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,

PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;

OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,

STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE

OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


*/


//TFT_Terminal for SYSTEM-24

//v.1.0 last update 26/02/2024

//Use Arduino UNO R3, Elegoo shield 2.8 inch, Serial port

//String format = "$ABCDEF\r\n"


#include <Elegoo_GFX.h>    // Core graphics library

#include <Elegoo_TFTLCD.h> // Hardware-specific library


// The control pins for the LCD can be assigned to any digital or

// analog pins...but we'll use the analog pins as this allows us to

// double up the pins with the touch screen (see the TFT paint example).

#define LCD_CS A3 // Chip Select goes to Analog 3

#define LCD_CD A2 // Command/Data goes to Analog 2

#define LCD_WR A1 // LCD Write goes to Analog 1

#define LCD_RD A0 // LCD Read goes to Analog 0


#define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin


// Assign human-readable names to some common 16-bit color values:

#define BLACK   0x0000

#define BLUE    0x001F

#define RED     0xF800

#define GREEN   0x07E0

#define CYAN    0x07FF

#define MAGENTA 0xF81F

#define YELLOW  0xFFE0

#define WHITE   0xFFFF


Elegoo_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);

String message = ""; //message received from UART


void setup(void) {

  

  Serial.begin(9600);

  Serial.println(F("TFT Terminal for System-24"));

  Serial.print("TFT size is ");

  Serial.print(tft.height());

  Serial.print("x");

  Serial.println(tft.width());


  tft.reset();


   uint16_t identifier = tft.readID();

   if(identifier == 0x9325) {

    Serial.println(F("Found ILI9325 LCD driver"));

  } else if(identifier == 0x9328) {

    Serial.println(F("Found ILI9328 LCD driver"));

  } else if(identifier == 0x4535) {

    Serial.println(F("Found LGDP4535 LCD driver"));

  }else if(identifier == 0x7575) {

    Serial.println(F("Found HX8347G LCD driver"));

  } else if(identifier == 0x9341) {

    Serial.println(F("Found ILI9341 LCD driver"));

  } else if(identifier == 0x8357) {

    Serial.println(F("Found HX8357D LCD driver"));

  } else if(identifier==0x0101)

  {     

      identifier=0x9341;

      Serial.println(F("Found 0x9341 LCD driver"));

  }

  else if(identifier==0x1111)

  {     

      identifier=0x9328;

      Serial.println(F("Found 0x9328 LCD driver"));

  }

  else {

    Serial.print(F("Unknown LCD driver chip: "));

    Serial.println(identifier, HEX);

    Serial.println(F("If using the Elegoo 2.8\" TFT Arduino shield, the line:"));

    Serial.println(F("  #define USE_Elegoo_SHIELD_PINOUT"));

    Serial.println(F("should appear in the library header (Elegoo_TFT.h)."));

    Serial.println(F("If using the breakout board, it should NOT be #defined!"));

    Serial.println(F("Also if using the breakout, double-check that all wiring"));

    Serial.println(F("matches the tutorial."));

    identifier=0x9328;

  

  }


  tft.begin(identifier);

  tft.setRotation(1); //0,2=vertical 1,3=Horizontal

  tft.setTextColor(RED, BLACK);

  tft.setTextSize(3); //17 char per line

  tft.fillScreen(BLACK);

  tft.println();

  tft.println("    SYSTEM-24    ");

  delay(3000);


  tft.setTextColor(WHITE, BLACK);

  tft.setTextSize(2); //26 char per line

  tft.fillScreen(BLACK);

  tft.setCursor(0, 0);


}


void loop(void) {


  rx_message(); //blocking call


  if(message.startsWith("%CLEAR%")) { 

    Serial.println("Clear display"); //debug

    tft.fillScreen(BLACK);

    tft.setCursor(0, 0);

  } else if(message.startsWith("%HOME%")) {

    Serial.println("Home display"); //debug

    tft.setCursor(0, 0);

  } else if(message.startsWith("%BLACK%")) {

    tft.setTextColor(BLACK, 0);

  } else if(message.startsWith("%BLUE%")) {

    tft.setTextColor(BLUE, 0);

  } else if(message.startsWith("%RED%")) {

    tft.setTextColor(RED, 0);

  } else if(message.startsWith("%GREEN%")) {

    tft.setTextColor(GREEN, 0);

  } else if(message.startsWith("%CYAN%")) {

    tft.setTextColor(CYAN, 0);

  } else if(message.startsWith("%MAGENTA%")) {

    tft.setTextColor(MAGENTA, 0);

  } else if(message.startsWith("%YELLOW%")) {

    tft.setTextColor(YELLOW, 0);

  } else if(message.startsWith("%WHITE%")) {

    tft.setTextColor(WHITE, 0);

  } else if(message.startsWith("%SMALL%")) {

    tft.setTextSize(1);

  } else if(message.startsWith("%MEDIUM%")) {

    tft.setTextSize(2);

  } else if(message.startsWith("%LARGE%")) {

    tft.setTextSize(3);

  } else {

    tft.print(message); //debug

  }

    

}


//read serial port

void rx_message(void) {


  int rx_state = 0;

  char c = 0;

 

  // Read formatted message

  while (rx_state <2) {

    switch (rx_state) {

      case 0:

        //whait sync

        if (Serial.available()) {

          c = Serial.read(); //serial read

          if (c == '$') rx_state = 1;

          message = "";

        }

      break;


      case 1:

       //read message

        if (Serial.available()) {

          c = Serial.read();

          message += c;

          if (c == '\n') rx_state = 2;

        }

      break;

    }

  }

  

  return;

}


Nota: per utilizzare il codice copiarlo in uno progetto Arduino IDE, scaricare le librerie incluse e compilare. Il firmware è stato testato con IDE 1.8.19 o successiva.

Sostanzialmente si tratta di un ricevitore su porta seriale di stringhe formattate ($ABCD\r\n) che verranno depurate dai caratteri di sincronismo ("$", "\r") e visualizzate sullo schermo.

Facciamo un esempio:

    $Test message<CR><LF>

Visualizzerà con font di default la scritta "Test message".

Per cambiare font è possibile inviare delle stringhe di controllo.

    $%SMALL%<CR><LF>

Selezionerà il font più piccolo disponibile

Per cambiare il colore delle scritte, usare invece

    $%GREEN%<CR><LF>

Ora tutte le prossime stringhe appariranno di colore verde.

I font disponibili sono tre: SMALL, MEDIUM, LARGE.

I colori disponibili sono otto. Da nero a bianco (vedere codice c++).

Completano le istruzioni due comandi per ripulire il display e per resettare il cursore:

    $%CLEAR%<CR><LF>

    $%HOME%<CR><LF>

CLEAR cancella lo schermo e riporta il cursore su 0,0, mentre HOME resetta solo il cursore senza cancellare il contenuto del monitor.

* - * - * - *

Così anche questo modulo è pronto e potremo riutilizzarlo in molteplici occasioni per visualizzare i risultati dei nostri esperimenti con lo Standard 7090 che saranno presentati un futuro su questo blog.

Un anticipazione?

Si! Realizzeremo un sistema modulare multi-cpu. In particolare popoleremo le nostre schede 7090 con Arduino Nano, Arduino Nano 33 IoT, Arduino Nano 33 BLE Sense, STM32F103, ESP8266, ESP32, Raspberry PI Zero W, Onion Omega-2, e forse anche altre CPU.

Aggiungeremo anche molti sensori ed attuatori, ma restate connessi per non perdevi nulla.


...piccola anticipazione...


Buona sperimentazione e a presto :)



domenica 25 febbraio 2024

Standard 7090: Alimentatore 5 Volt e 3.3 Volt

Come descritto nel precedente post, per realizzare dei moduli riutilizzabili è opportuno adottare uno standard personale o ufficialmente riconosciuto da enti normatori o dal mercato.
In questo post Vi presento la soluzione che ho adottato, per creare un alimentatore Switch Mode semplice ed economico, realizzato per moduli (Schema a blocchi in Fig. 1), che utilizzerò per tutte le successive sperimentazioni o prototipi.

Come visibile dalla foto in Figura 2, ho utilizzato dei moduli commerciali, installati su una scheda prototipale 70x90. In particolare la tensione di ingresso afferisce ad un modulo MB102 che provvede a distribuirla ad un voltmetro digitale a tre cifre e a due moduli LM2596, regolati con precisione alle rispettive tensioni di 5,0 Volt e 3,3 Volt. Una volta effettuata la taratura il nostro alimentatore sarà pronto per alimentare gran parte delle schede a microcontrollore che successivamente verranno presentate su questo Blog. Le tensioni di uscita saranno quindi disponibili sui Pin descritti in Figura 3

Buona sperimentazione e a presto.

venerdì 23 febbraio 2024

Alla ricerca di uno Standard (?)

Noi progettisti di una certa epoca eravamo soliti riferirci ai bus standard DIN41612, IEC297 ed altri, ma oggi il mondo elettronico è particolarmente dinamico. Alcuni standard tuttavia emergono nell'ambito della prototipazione rapida: Arduino, ESP8266, ESP32, STM32, Raspberry PI, ecc. Tutti con formati differenti e spesso scarsamente compatibili tra loro, sia nella disposizione dei Pin sia come livelli elettrici dei segnali.


Cortesia Schroff nVent


Se non volete ogni volta ricominciare da zero i vostri progetti e, magari, lavorare per blocchi funzionali, allora adottate uno standard e progettate per moduli sia hardware sia firmware.

Un aspetto fondamentale nella prototipazione rapida è la possibilità di reperire componenti hardware in tempi brevi e a costi accettabili, pertanto bisogna adattarsi all'offerta più facilmente reperibile.

Per trarre profitto dagli innumerevoli esperimenti che si effettuano per scopi professionali o per semplice hobby, ho deciso di adottare alcuni standard personali, al solo scopo di poter riutilizzare i moduli sviluppati nel mio lavoro. In tal caso preferisco adottare uno standard 7090 con schede millefori a singola o doppia faccia.

Su questo tipo di scheda è possibile montare un ampia varietà di moduli, tra cui Arduino R3, Arduino Nano, ESP8266, ESP32, STM32F103, Raspberry PI Zero, ecc.

Per garantire una semplice modularità e quindi interscambiabilità tra i blocchi funzionali, ho provveduto a definire una serie di segnali preferenziali da assegnare ad uno dei due lati di connessione, definendo una tabella di base. Per ciascun progetto sarà necessario compilare il nome della scheda è il campo note:

Pinout preferenziele del Bus

Nei prossimi post Vi presenterò in modo dettagliato alcune applicazioni pratiche, corredate da schemi elettrici, firmware di test e note di montaggio.

Le applicazioni sono praticamente ...infinite :)

Buon lavoro e a presto.


Leopardi in "L'infinito": così tra questa immensità s'annega il mio pensiero.