element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
RoadTests & Reviews
  • Products
  • More
RoadTests & Reviews
Review Blogs Arduino GIGA R1 - Display Images from a USB Memory Device with Touch Control
  • Blogs
  • RoadTest Forum
  • Documents
  • RoadTests
  • Reviews
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join RoadTests & Reviews to participate - click to join for free!
  • Share
  • More
  • Cancel
  • Author Author: dougw
  • Date Created: 20 Oct 2025 12:46 AM Date Created
  • Views 21 views
  • Likes 7 likes
  • Comments 0 comments
Related
Recommended
  • dougw
  • touch screen
  • USB memory device
  • arduino giga r1

Arduino GIGA R1 - Display Images from a USB Memory Device with Touch Control

dougw
dougw
20 Oct 2025

image

Intro

This is the second installment of material that will contribute to a road test of the Arduino GIGA R1 and its LCD.

The Arduino web site has an example of how to display an image stored on a USB memory stick, but it needs the IDE serial monitor to work. I wanted to operate stand-alone using the touch screen to step to the next image.

Here is a short video showing the result:

Giga Touch USB Image Demo

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

The images stored on the USB memory need to be 800 x 480 in RGB565 format (binary). These images end up being 768 kbytes each so it is useful to store them on an external USB memory device.

Here is the firmware program:

Firmware

// Arduino GIGA R1 program to display images stored on a USB memory device
// by Doug Wong 2025
// Touching the screen displays the next image
// The image will roll over to thr first image after the last image
// Image format should be 800 x 480 in RGB565 format - binary

#include <Arduino_USBHostMbed5.h>
#include <DigitalOut.h>
#include <FATFileSystem.h>
#include <Arduino_H7_Video.h>
#include <ArduinoGraphics.h>
#include "Arduino_GigaDisplayTouch.h"

Arduino_GigaDisplayTouch touchDetector;

USBHostMSD msd;
mbed::FATFileSystem usb("usb");

const int USB_HOST_ENABLE_PIN = PA_15;
const int MAX_FILES = 50;
const int MAX_NAME_LEN = 128;
char fileNames[MAX_FILES][MAX_NAME_LEN];
int fileCount = 0;
const int MAX_CONNECTION_ATTEMPTS = 10;
int filenum = 0;                        // file number selected

Arduino_H7_Video Display(800, 480, GigaDisplayShield);
const int IMG_WIDTH = 800;
const int IMG_HEIGHT = 480;
const uint32_t EXPECTED_FILE_SIZE = IMG_WIDTH * IMG_HEIGHT * 2;

uint8_t rowBuffer[IMG_WIDTH * 2]; // Static buffer

void setup() {
    Serial.begin(115200);
    touchDetector.begin();
    pinMode(USB_HOST_ENABLE_PIN, OUTPUT);
    digitalWrite(USB_HOST_ENABLE_PIN, HIGH);
    while (!Serial) {}
    delay(1500);

    Serial.println("=== USB File List ===");
    Display.begin();
    forceScreenClear();

    if (!initUSBHost() || !mountUSB()) return;
    listRootDirectory();
    if (fileCount == 0) return;

    printFileList();
    Serial.println("Select a file # to open as 800x480 .bin, or type 'clear' to reset the screen:");
}

void loop() {
    if (fileCount > 0) handleUserInput();
    uint8_t contacts;
    GDTpoint_t points[5];
    
    contacts = touchDetector.getTouchPoints(points);  //capture touches on touchscreen
    if (contacts > 0) {                               //Check for screen touch
        filenum++;                                    //increment filenumber
        if (filenum > fileCount)  filenum = 1;        //handle rollover when filenum exceeds filecount
        displayRawRowByRow(fileNames[filenum-1]);     //call image disply of file number
    }
    contacts = touchDetector.getTouchPoints(points);  //check screen for touches - should br none at this time
    contacts = 0;                                     //clear any touch count anyway
    delay (20);
}

bool initUSBHost() {
    for (int i = 0; i < MAX_CONNECTION_ATTEMPTS; i++) {
        if (msd.connect()) {
            Serial.println("USB mass storage device connected!");
            return true;
        }
        Serial.println("USB device not detected, retrying...");
        delay(1000);
    }
    return false;
}

bool mountUSB() {
    Serial.print("Mounting USB device... ");
    if (usb.mount(&msd)) {
        Serial.println("Failed to mount USB.");
        return false;
    }
    Serial.println("done.");
    return true;
}

void listRootDirectory() {
    fileCount = 0;
    DIR* dir = opendir("/usb/");
    if (!dir) return;
    while (fileCount < MAX_FILES) {
        struct dirent* entry = readdir(dir);
        if (!entry) break;
        strncpy(fileNames[fileCount], entry->d_name, MAX_NAME_LEN - 1);
        fileNames[fileCount][MAX_NAME_LEN - 1] = '\0';
        fileCount++;
    }
    closedir(dir);
}

void printFileList() {
    Serial.print("Found "); Serial.print(fileCount); Serial.println(" file(s) in /usb/:");
    for (int i = 0; i < fileCount; i++) {
        Serial.print(i + 1); Serial.print(") "); Serial.println(fileNames[i]);
    }
}

void handleUserInput() {
    if (Serial.available() > 0) {
        String input = Serial.readStringUntil('\n');
        input.trim();

        if (input.equalsIgnoreCase("clear")) {
            forceScreenClear();
            return;
        }

        int sel = input.toInt();
        if (sel < 1 || sel > fileCount) return;

        Serial.print("Displaying: /usb/");
        Serial.println(fileNames[sel - 1]);

        displayRawRowByRow(fileNames[sel - 1]);
    }
}

bool displayRawRowByRow(const char* fileName) {
    String path = "/usb/" + String(fileName);
    FILE* f = fopen(path.c_str(), "rb");
    if (!f) return false;

    forceScreenClear();
    Display.beginDraw();

    for (int y = 0; y < IMG_HEIGHT; y++) {
        if (fread(rowBuffer, 1, IMG_WIDTH * 2, f) != IMG_WIDTH * 2) break;
        Image rowImage(ENCODING_RGB16, rowBuffer, IMG_WIDTH, 1);
        Display.image(rowImage, 0, y);
    }

    Display.endDraw();
    fclose(f);
    Serial.println("Image displayed successfully!");
    return true;
}

void forceScreenClear() {
    Display.beginDraw();
    Display.fill(0x0000);
    Display.endDraw();
}

Discussion

The Arduino GIGA R1 has many individual features that can be combined to produce really impressive functionality. In the road test I want to go a bit beyond what is available in the already extensive set of demo examples. This demo uses the LCD, the touch screen, and the USB host interface to create a touch controlled slide show of images stored on an external USB memory device. I am blown away at how simple it is to create a demonstration with this level of complexity. I just needed to integrate a couple of demo programs and of course generate some nice images to display. Initially I had some extra touch events that caused images to flash by, but eventually I figured out how to obtain decent control. There are lots more features to explore....

Links:

Unboxing and display demo

Touch Screen and USB memory demo

Giga R1 Road Test page

  • Sign in to reply
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube