I now have some working code. Download a JPG file using ftp and displaying it on the screen.
Rough code, proof of principle.
/******************************************************************************
FTPClient_DownloadFile.ino
FTP Client for Generic boards using SD, FS, etc.
Based on and modified from
1) esp32_ftpclient Library https://github.com/ldab/ESP32_FTPClient
Built by Khoi Hoang https://github.com/khoih-prog/FTPClient_Generic
******************************************************************************/
// iets met JPG : https://github.com/lvgl/lv_lib_split_jpg
// esp32-cam PIXFORMAT_RGB565, // 2BPP/RGB565
// over RGB565 format : https://rgbcolorpicker.com/565#:~:text=RGB565%20(also%20known%20as%2016,bits%20for%20the%20blue%20channel.
#include "Arduino.h"
#include <TJpg_Decoder.h>
#include "panda.h"
#include "SPI.h"
//#include "Arduino_H7_Video.h"
//#include "lvgl.h"
//Arduino_H7_Video Display(800, 480, GigaDisplayShield);
//#include "defines.h"
#include "WiFi.h"
#include <FTPClient_Generic.h>
#include "Arduino_GigaDisplay_GFX.h"
GigaDisplay_GFX tft;
#define GC9A01A_CYAN 0x07FF
#define GC9A01A_RED 0xf800
#define GC9A01A_BLUE 0x001F
#define GC9A01A_GREEN 0x07E0
#define GC9A01A_MAGENTA 0xF81F
#define GC9A01A_WHITE 0xffff
#define GC9A01A_BLACK 0x0000
#define GC9A01A_YELLOW 0xFFE0
#define WHITE 0xffff
#define BLACK 0x0000
#define WIFI_SSID ""
#define WIFI_PASS ""
const int max_File_size=32000;
uint8_t file_buffer[max_File_size]; // moet dit niet 16 bit zijn ? maar panda is ook uint8_t
int Nr_Bytes_Read;
// To use `true` with the following PASV mode asnswer from server, such as `VSFTP`
// 227 Entering Passive Mode (192,168,2,112,157,218)
// Using `false` with old style PASV answer, such as `FTP_Server_Teensy41` library
// 227 Entering Passive Mode (4043483328, port 55600)
#define USING_VSFTP_SERVER true
// Change according to your FTP server
char ftp_server[] = ""; // port 21 ?
char ftp_user[] = "";
char ftp_pass[] = "";
char dirName[] = ""; //"/home/ftp_test";
char newDirName[] = "/Test1"; //"/home/ftp_test/NewDir";
// FTPClient_Generic(char* _serverAdress, char* _userName, char* _passWord, uint16_t _timeout = 10000);
FTPClient_Generic ftp (ftp_server, ftp_user, ftp_pass, 60000);
char fileName[] = "helloworld.txt";
// This next function will be called during decoding of the jpeg file to
// render each block to the TFT. If you use a different TFT library
// you will need to adapt this function to suit.
bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t* bitmap)
{
// Stop further decoding as image is running off bottom of screen
if ( y >= tft.height() ) return 0;
// This function will clip the image block rendering automatically at the TFT boundaries
//tft.pushImage(x, y, w, h, bitmap);
//tft.drawRGBBitmap(pDraw->x, pDraw->y, pDraw->pPixels, pDraw->iWidth, pDraw->iHeight);
tft.drawRGBBitmap(x, y, bitmap,w, h);
// This might work instead if you adapt the sketch to use the Adafruit_GFX library
// tft.drawRGBBitmap(x, y, bitmap, w, h);
// Return 1 to decode next block
return 1;
}
void setup()
{
Serial.begin(115200);
tft.begin();
tft.setTextColor(0xFFFF, 0x0000);
tft.fillScreen(GC9A01A_GREEN);
WiFi.begin( WIFI_SSID, WIFI_PASS );
Serial.println("Connecting WiFi, SSID = ");
Serial.println(WIFI_SSID);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.print("\nIP address: ");
Serial.println(WiFi.localIP());
Serial.println("Downloading file");
ftp.OpenConnection();
ftp.ChangeWorkDir(dirName);
ftp.InitFile(COMMAND_XFER_TYPE_BINARY);
ftp.DownloadFile("WiFi.jpg", file_buffer, max_File_size, false);
Serial.println("Download ready");
// check the content of the file
int Cnt=0;
Nr_Bytes_Read=0;
while (Nr_Bytes_Read<max_File_size)
{
Serial.print(file_buffer[Nr_Bytes_Read],HEX);
Serial.print(" ");
Nr_Bytes_Read++;
Cnt++;
if (Cnt>=16) {Serial.println();Cnt=0;}
}
Serial.println();
Serial.println("Gettin filesize");
uint8_t index_1=0xFF;
uint8_t index_2=0xD9;
// Now trying to find 0xFF 0xD9 so that you know the length of the file
bool NietKlaar;
Nr_Bytes_Read=0;
NietKlaar=true;
while (Nr_Bytes_Read<max_File_size-2 and NietKlaar)
{
if (file_buffer[Nr_Bytes_Read]==index_1)
{
if (file_buffer[Nr_Bytes_Read+1]==index_2) {NietKlaar=false; break;}
}
Nr_Bytes_Read++;
}
Serial.print("File size : ");
Serial.println(Nr_Bytes_Read);
Serial.println("CloseConnection");
ftp.CloseConnection();
// The jpeg image can be scaled by a factor of 1, 2, 4, or 8
TJpgDec.setJpgScale(1);
// The byte order can be swapped (set true for TFT_eSPI)
TJpgDec.setSwapBytes(false);
// The decoder must be given the exact name of the rendering function above
TJpgDec.setCallback(tft_output);
}
void loop()
{
tft.fillScreen(GC9A01A_MAGENTA);
// Time recorded for test purposes
uint32_t t = millis();
// Get the width and height in pixels of the jpeg if you wish
uint16_t w = 0, h = 0;
// TJpgDec.getJpgSize(&w, &h, file_buffer, sizeof(file_buffer)); // volgens mij moet je dit handmatig doen
w=240;
h=300;
Serial.print("Width = "); Serial.print(w); Serial.print(", height = "); Serial.println(h);
// Draw the image, top left at 0,0
TJpgDec.drawJpg(100, 100, file_buffer, sizeof(file_buffer));
// How much time did rendering take (ESP8266 80MHz 262ms, 160MHz 149ms, ESP32 SPI 111ms, 8bit parallel 90ms
t = millis() - t;
Serial.print(t); Serial.println(" ms");
// Wait before drawing again
while(1) {delay(300);}
delay(2000);
}
unsigned long testFillScreen() {
unsigned long start = micros();
tft.fillScreen(BLACK);
yield();
Serial.println("1");
delay(10000);
tft.fillScreen(WHITE);
yield();
Serial.println("2");
delay(10000);
tft.fillScreen(BLACK);
yield();
Serial.println("3");
delay(10000);
tft.fillScreen(WHITE);
yield();
Serial.println("4");
delay(10000);
tft.fillScreen(BLACK);
yield();
Serial.println("5");
delay(10000);
return micros() - start;
}