The On-board Display (TFT carrier)
The 800x480 LCD on the TFT carrier, the TRANSPORT_LCD mode, and drawing on the hardware overlay layer.
The TFT carrier, which mounts the OV5640, has an 800x480 LCD driven by the STM32N6 LTDC controller over a 16-bit RGB565 interface. The LTDC blends two input layers, supports resolutions up to XGA, and accepts predefined and flexible ARGB pixel formats, which is how the ARGB4444 overlay is possible. No VD66GY module has a display. The camera image is written to the panel continuously by hardware. A second layer above it, the overlay, receives the post-processors' boxes and masks and any graphics drawn by the sketch. No host is required.
Minimum configuration
#include <OV5640_Arduino.h>
#include <PostProcess.h>
#pragma neuron6 model="yolov8n_256_quant_pc_ii_seg_coco-st.tflite" name=yolov8_iseg
OV5640 camera(CARRIER_TFT);
NEURON6_DECLARE_MODEL(yolov8_iseg);
void setup() {
VisionConfig cfg;
cfg.camera = CAMERA_WVGA; // 800x480 fills the panel
cfg.fps = FPS_30;
cfg.transport = TRANSPORT_LCD;
Vision.begin(&NN_Instance_yolov8_iseg, PostProcess_YOLOv8_ISEG(0.4f, 0.5f), cfg);
}
void loop() {
Vision.run();
}Three conditions apply. The camera object names CARRIER_TFT, the only carrier with a panel. The transport is TRANSPORT_LCD. The mode is WVGA or VGA, because the display pipe has no downscaler; larger modes disable the panel with a warning while the sketch continues. VGA is shown centred with 80 pixel bars either side.
TRANSPORT_LCD behaviour
The JPEG encoder and the USB video stream are not started, which reduces power and PSRAM bandwidth. The serial console remains available.
The camera layer is double buffered: the camera writes one buffer while the panel scans the other, and the buffers are exchanged at vertical blank. The camera image does not tear.
cfg.fps sets the panel refresh as well as the camera rate, clamped to 30 to 60 Hz.
Display with a host transport
With the transport set to USB or WiFi and cfg.lcd = true, the panel shows the image and overlay while JPEG and metadata stream to the host. The encoder and the panel then share the PSRAM bus and the panel may tear under load; a lower frame rate reduces this. The WiFi access point example uses this configuration at 15 fps.
Overlay drawing
The overlay is a hardware layer in ARGB4444 format above the camera image. Pixels not drawn are transparent. Drawing follows a fixed sequence: obtain the back buffer, bind it, draw, commit.
#include <PostProcess.h>
#include <ohmlab_lcd_draw.h>
void drawHud() {
uint16_t *ovl = OVL_GetBackBuffer();
if (ovl == nullptr) return;
ohm_lcd_bind_argb4444(ovl, 800, 480, 800);
ohm_lcd_clear_transparent();
ohm_lcd_set_font(&Font16);
ohm_lcd_set_color(255, 40, 40);
ohm_lcd_rect_thick(60, 180, 260, 110, 3);
ohm_lcd_text(70, 300, "UNKNOWN");
ohm_lcd_set_color_alpha(8, 0, 0, 0); // half transparent black
ohm_lcd_fillrect(0, 0, 800, 40); // tints the camera image
OVL_Commit();
}Primitives are putpixel, hline, vline, rect, fillrect, rect_thick, char and text. rect_thick(x, y, w, h, t) draws its border inward, so the drawn box does not extend beyond the given rectangle. Fonts range from Font8 to Font24.
Colour is 4 bits per channel: sixteen levels each of red, green, blue and alpha. Saturated colours are exact and gradients band. Because the LTDC blends the layer, a partly transparent fill tints the camera image rather than obscuring it.
The _white variants (ohm_lcd_rect_white and others) always draw white regardless of the current colour. The bundled post-processors use them, so a sketch that sets a colour cannot recolour a post-processor's output drawn later in the same frame. ohm_lcd_get_color() and ohm_lcd_set_color_packed() save and restore the current colour.
LCD_Overlay_SetBanner("text") draws a caption along the top of the panel on every frame.
Overlay ownership with a model
In a sketch that runs a model, Vision.run() clears the overlay, draws the post-processor's output and commits. A sketch that also clears and commits from loop() conflicts with it. Two approaches avoid the conflict: drawing from a custom post-processor's draw_lcd callback, or running the model with OVL_CLEAR (clear and draw without committing), drawing into the same back buffer, then calling OVL_Commit(). The overlay modes are described in Running Several Models.
Camera buffer access
Under TRANSPORT_LCD, LCD_GetCameraBuffer() returns the buffer currently displayed. For CPU vision, NN_capture_snapshot() is normally preferred because it returns a scaled RGB888 crop.
Refresh rate and tearing
When a host transport is also active the panel refreshes at about 30 Hz, half its capability, to halve the LTDC's continuous reads of the overlay in PSRAM and leave bandwidth for the encoder. Under TRANSPORT_LCD alone it follows cfg.fps up to 60 Hz. Both the camera layer and the overlay are double buffered. Horizontal stripes in the Neuro Studio view while the panel is active indicate bus contention; a lower frame rate reduces it.
Bench sketches
DisplayBenchmark runs TRANSPORT_LCD with no model and a static overlay, and is the reference configuration for diagnosing tearing. DisplayTouchBringUp draws colour swatches, an alpha blended bar and a touch button. Both are in extras/bench.
Touch
The TFT carrier's touch controller is described in Touch Input.