Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Exibir Fotos JPEG e Vídeo RGB565 em Display TFT SPI 2.8" com Arduino Nano

Componentes e Materiais

Arduino Nano R3 1
Display TFT SPI 2.8" 320x240 (com touchscreen) 1
Cartão microSD (>1GB) 1
Shield TFT (breakout) para Arduino Nano 1

Sobre o Projeto

Introdução

Olá! Neste artigo, vou mostrar como visualizar fotos no formato *.jpg e reproduzir vídeos no formato RGB565 na tela de um display TFT SPI (320x240, 2.8").

Primeiro, uma pequena demonstração em vídeo:

Hardware

Componentes necessários:

A montagem de todas as peças segue a ordem mostrada no vídeo (ou consulte o artigo anterior: TFT Shield for Arduino Nano - Start).

Software

Preparação do Cartão microSD

O cartão microSD deve ser formatado em FAT32. As imagens podem ser gravadas diretamente no cartão (sem nenhum processamento). É desejável que o tamanho das imagens não exceda 2560x1920 pixels.

Conversão de Vídeo para RGB565

Para reproduzir vídeos no formato RGB565, os arquivos devem ser preparados previamente. Use o ffmpeg (ffmpeg.org) para conversão. Baixe e instale no seu computador. Em seguida, utilize o comando de exemplo abaixo para gerar um vídeo compatível com esta demonstração:

ffmpeg -i video.avi -s 320x240 -pix_fmt rgb565 video.rgb

Bibliotecas e Sketch

Baixe e instale a biblioteca necessária para trabalhar com o shield TFT para Arduino Nano: YATFT.

Carregue o seguinte sketch no Arduino Nano:

/****************************************************************************** 
 * SOFTWARE E DOCUMENTAÇÃO FORNECIDOS "COMO ESTÃO" SEM GARANTIA DE QUALQUER 
 * TIPO, EXPRESSA OU IMPLÍCITA, INCLUINDO, SEM LIMITAÇÃO, QUALQUER GARANTIA 
 * DE COMERCIALIZAÇÃO, TÍTULO, NÃO VIOLAÇÃO E ADEQUAÇÃO PARA UM FIM 
 * ESPECÍFICO. EM NENHUM CASO O AUTOR OU SEUS LICENCIADORES SERÃO RESPONSÁVEIS 
 * OU OBRIGADOS SOB CONTRATO, NEGLIGÊNCIA, RESPONSABILIDADE ESTRITA, 
 * CONTRIBUIÇÃO, VIOLAÇÃO DE GARANTIA, OU OUTRA TEORIA JURÍDICA EQUITATIVA 
 * POR QUAISQUER DANOS DIRETOS OU INDIRETOS OU DESPESAS, INCLUINDO, MAS NÃO 
 * LIMITADO A QUAISQUER DANOS INCIDENTAIS, ESPECIAIS, INDIRETOS, PUNITIVOS 
 * OU CONSEQUENCIAIS, LUCROS PERDIDOS OU DADOS PERDIDOS, CUSTO DE AQUISIÇÃO 
 * DE BENS, TECNOLOGIA, SERVIÇOS SUBSTITUTOS, OU QUAISQUER REIVINDICAÇÕES 
 * DE TERCEIROS (INCLUINDO, MAS NÃO LIMITADO A QUALQUER DEFESA DELES), OU 
 * OUTROS CUSTOS SEMELHANTES. 
 *******************************************************************************/
#include <YATFT2.h>        // Biblioteca específica do hardware
#include <SPI.h>
#include <XPT2046_Touchscreen.h>
#include <util/yasdc.h>

YATFT tft(0);
SDC sdc;

#define CS_PIN A0  // MOSI=11, MISO=12, SCK=13
XPT2046_Touchscreen ts(CS_PIN);

/* Se estiver usando o shield, todas as linhas de controle e dados são fixas,
   e uma declaração mais simples pode ser usada opcionalmente: */

uint16_t frame = 0;
uint32_t total_time = 0;
bool f_first = true;
uint8_t mode = 0;

/*************************************************************************************************/
void setup(void) {
  Serial.begin(115200);
  Serial.println(F("Exemplo Photo And Video Play!"));
  
  tft.begin(0x4391, -8);  // Inicializa o display
  tft.SetColor(BLACK);
  tft.ClearDevice();      // Limpa a tela
  
  ts.begin();             // Inicializa Touchscreen
  SPI.end();
  
  Serial.print(F("FS Init... "));
  uint8_t state = sdc.FSInit();
  if (state == 0) Serial.println(F("falhou."));
  else Serial.println(F("sucesso."));
  
  sdc.currentFileType = DEMO_FILE_TYPE_RGB;
  total_time = millis() + 500;
}

void loop(void) {
  if (total_time < millis()) {
    total_time = millis() + 2000;
    
    if (f_first == true) {
      if (-1 != sdc.FindFirst("*.*", ATTR_ARCHIVE, &sdc.nextFile))
        f_first = false;  // Limpa flag
      else
        total_time = 0;
    } else {
      // Processamento de arquivos JPEG
      if (sdc.GetFileType(sdc.nextFile.filename) == DEMO_FILE_TYPE_JPEG) {
        if (sdc.currentFileType != DEMO_FILE_TYPE_JPEG) {
          // Define modo YUV para exibir JPEG
          tft.SetColor(0x007F);  // Preto em YUV
          tft.ClearDevice();
          tft.SetYUV();          // Troca mostra leve piscar verde
          sdc.currentFileType = DEMO_FILE_TYPE_JPEG;
        }
        
        Serial.print(" JPEGPutImage:");
        Serial.println(sdc.nextFile.filename);
        
        FSFILE * jpeg_file;
        JPEG_DECODE jpeg_decode;
        jpeg_file = sdc.FSfopen(sdc.nextFile.filename, "r");
        
        if (!jpeg_file) {
          Serial.println(F("Falha ao abrir!"));
          return (FALSE);
        }
        
        jpeg_decode.stream = (void *)jpeg_file;
        sdc.JPEGReadFromSD(&jpeg_decode, 0, 0, GetMaxX()+1, GetMaxY()+1);
        
        uint8_t err = sdc.FSfclose(jpeg_file);
        if (err) {
          Serial.println(F("Falha ao fechar!"));
          return err;
        }
        
        frame++;
        frame &= 0xF;
        total_time = millis() + 2000;
      }
      // Processamento de arquivos RGB (vídeo)
      else if (sdc.GetFileType(sdc.nextFile.filename) == DEMO_FILE_TYPE_RGB) {
        if (sdc.currentFileType != DEMO_FILE_TYPE_RGB) {
          // Define modo RGB
          tft.SetColor(BLACK);   // Preto em RGB é verde escuro em YUV
          tft.ClearDevice();
          tft.SetRGB();          // Troca mostra leve piscar verde
          sdc.currentFileType = DEMO_FILE_TYPE_RGB;
        }
        
        Serial.print(F("Reproduzindo vídeo RGB: "));
        Serial.println(sdc.nextFile.filename);
        
        FSFILE * pFile = sdc.FSfopen(sdc.nextFile.filename, "rb");
        if (!pFile) {
          Serial.println(F("Falha ao abrir!"));
          return (FALSE);
        }
        
        tft.SetColor(BLACK);
        tft.ClearDevice();
        sdc.RGBReadFromSD(pFile, &ScanTouch);
        mode = 0;
        tft.SetColor(BLACK);
        tft.ClearDevice();
        sdc.FSfclose(pFile);
        total_time = millis() + 1000;
      }
      
      if (-1 == sdc.FindNext(&sdc.nextFile)) {
        f_first = true;  // Define flag
      }
    }
  }
}

uint8_t ScanTouch(void) {
  uint16_t x, y;
  
  // Touch
  // Quando o pino SS é definido como OUTPUT, pode ser usado como
  // porta de saída de propósito geral (não influencia operações SPI).
  SPI.begin();
  
  if (ts.touched()) {
    TS_Point p = ts.getPoint();
    delay(3);  // Delay para filtragem
    SPI.end();
    
    // Calcula coordenadas x, y a partir do código ADC
    if (p.x < 450) p.x = 450;
    if (p.y < 500) p.y = 500;
    
    x = (uint16_t)(320L - ((uint32_t)p.x - 450L) * 10L / 106L);
    y = (uint16_t)(240L - ((uint32_t)p.y - 500L) * 10L / 140L);
    
    // Botão Stop
    if (x < 130 && y > 100 && y < 140) {
      mode = 1;
      Serial.println(F("mode = 1"));
    }
    // Botão Pause
    else if (x > 140 && x < 180 && y > 100 && y < 140) {
      mode = 2;
      // Desenha botões
      tft.SetColor(BRIGHTRED);
      tft.DrawFillCirc(GetMaxX()/4, GetMaxY()/2, 50);
      tft.SetColor(BRIGHTYELLOW);
      tft.DrawFillRect(GetMaxX()/4-30, GetMaxY()/2-30, GetMaxX()/4+30, GetMaxY()/2+30);
      tft.SetColor(BRIGHTRED);
      tft.DrawFillCirc(GetMaxX()/4*3, GetMaxY()/2, 50);
      tft.SetColor(BRIGHTYELLOW);
      for (uint8_t i = 0; i < 60; i++) {
        tft.DrawLine(210+i, 90+i/2, 210+i, 150-i/2);
      }
      Serial.println(F("mode = 2"));
    }
    // Botão Play
    else if (x > 190 && y > 100 && y < 140) {
      mode = 0;
      Serial.println(F("mode = 0"));
    }
    
    return mode;
  }
  
  SPI.end();
  return mode;
}

Tentei fazer um artigo curto e descrever os pontos principais. Não há nada difícil neste projeto. Mas se tiver dúvidas, pergunte à vontade! ;-) Tentarei adicionar mais artigos.

Obrigado pela atenção!

Continua...

Artigos Anteriores:

  1. Unique TFT Shield for Arduino Uno - Start
  2. Unique TFT Shield for Arduino Uno - OV7670 Cam Live View
  3. Unique TFT Shield for Arduino Uno - Arduino Bluetooth Camera (ABC)
  4. TFT Shield for Arduino Nano - Start

Atualização 01.04.2021:

Olá novamente! Há uma biblioteca atualizada para uma série de telas, que atualmente consiste em dois shields e duas breakout boards. O sketch é compilado dependendo da versão selecionada (de 1 a 4) e do tipo de microcontrolador (MegaAVR ou ESP-32). Foram adicionadas fotos e exemplos. Mais informações podem ser encontradas em https://github.com/Ekaburg/EkaTFT.

Código

PhotoAndVideoPlay.ino

O código completo está disponível no repositório GitHub da biblioteca YATFT.

Esquemáticos

Biblioteca TFT Shield para Arduino Nano

https://github.com/YATFT/YATFT

Processo de manufatura

  1. Transformando Manufatura com Mobilidade: Soluções de Dados, Voz, Vídeo e Localização
  2. Novo Conversor HDMI‑APIX3 Capacita Testes de Vídeo Automotivo e ADAS
  3. DATA MODUL Lança Display TFT Ultra-Slim 23,1" com Controle Smart Wi-Fi
  4. Leitura de Sensores Analógicos com Raspberry Pi e Zabbix: Guia Passo a Passo
  5. Como Instalar Display TFT 3.5″ Kuman no RetroPie – Guia Passo a Passo
  6. K 2019 Apresenta Máquinas de Reciclagem de Ponta e Inovações em Embalagens Sustentáveis
  7. Entendendo Designações DN e PN em Flanges: Guia Completo
  8. Display 3D Holográfico de Campo de Luz: Visão Clara e sem Distorção para Realidade Aumentada
  9. Guia Profissional de Animação de Bitmap no Shield TFT Touchscreen ILI9341 2,4″ com Arduino
  10. Dominando Acabamentos de Injeção: Normas SPI e VDI Explicadas