Page 1 of 1

File Selection UI

PostPosted: Tue Apr 25, 2017 1:02 am
by Andrew Davie
I started work on the file selection UI. The idea is that I can put multiple NBTV-format videos on the Micro SD card, and the file selection UI allows the user to choose which to play. This will allow any SD card to be inserted with valid content, and the televisor will play. OK, so this is a mockup - I just wanted to see what the UI might look like in action. The mock file names are being sent continually to the LCD so it refreshes mid-scroll - but the whole point of this was to start the ball rolling, so as I said - it's a complete mockup. It looks like the Nextion might be capable of doing what I want, so the next step will probably be to read a list of files from the SD card and get them onto the Nextion and scrolling properly, with selection.

Edit: Yes I know I spelled "Betty" incorrectly :) Mockup.

Re: File Selection UI

PostPosted: Tue Apr 25, 2017 11:05 pm
by Andrew Davie
Still at mockup stage, but the UI is looking much cleaner now I'm starting to understand how best to drive the Nextion LCD display. It's a fantastic little thing, but it's primitive in what it offers on-board. No fonts, so you have to convert and import (they provide a tool) but it doesn't know anything about anti-aliasing, or sub-pixel rendering, or even spacing - all fonts are monospaced and monochrome. It has scrollbars, but nothing attached to them, so to build a file dialog I have to create 6 text boxes, and then manually shift/populate the contents and attributes when the scrollbar changes. It's really basic - kind of like writing your own windows system if you want to do the sort of things I'm doing. Anyway, it's coming along nicely. As I said, still (mostly) mockup, although the brightness/contrast/volume work, and now I'm populating the selection window with the actual contents of the SD card.

Re: File Selection UI

PostPosted: Tue Apr 25, 2017 11:33 pm
by Harry Dalek
Excellent choice of videos i have noticed you are using most of the time Andrew being a fan my self of the good Doctor is this one i am not sure but your controlling of the video is great ! i am jealous again way beyond me ...pretty much sci fi :shock: :wink: you have a amazing televisor there !

Re: File Selection UI

PostPosted: Fri Apr 28, 2017 2:01 am
by Andrew Davie
I've done some more work on the UI on the Nextion. I've added a "frame shift" control and am now populating the "file dialog" with the filenames from the SD card. I still need to load the selected file, and get the scrolling on that selection dialog working. But I'm happy with the general "look and feel" of the UI, and with what's operational at the moment. Biding my time, really, until I get the components I need to build the smaller integrated board, and once that's done then I'll have to start thinking about my replacement LED matrix (to run off 12V).

Edit: The LEDs flash during upload from my computer so that's the garbage image at the start. The Arduino starts up when you see "Boo's Mechanical Televisor" on the screen; before that is the Nextion LCD doing it's own thing. So after the appearance of "Boo's Mechanical Televisor", note the super-fast frame lock! Something under a second, I reckon. Disc was already spinning so this is a warm-start. Nonetheless, pretty impressive!

Re: File Selection UI

PostPosted: Wed May 03, 2017 12:11 am
by Andrew Davie
I finally got the selection UI working. The Nextion is a bit primitive in that it doesn't offer this sort of capability, just text fields, scrollbars and variables. I kludged up a file-selection dialog and now have it updating in "real time" with filenames from the SD card. Won't be long until I'm actually playing selected files. I think the visuals are OK - but of course I would think that, wouldn't I.

Re: File Selection UI

PostPosted: Wed May 03, 2017 7:04 am
by Klaas Robers
Andrew, I saw in your "directory" an item "MUTR television". I hope that you know that the whole MUTR CD contents is on the website. It is there as .wav-files, as well in positive as in negative polarity. There are about 15 different files, but of course in 2 x 16 bits, 14.4 kHz sample frequency. You may convert them. They are already DC restored with black is 00 00.

Re: File Selection UI

PostPosted: Wed May 03, 2017 4:57 pm
by Andrew Davie
Klaas Robers wrote:Andrew, I saw in your "directory" an item "MUTR television". I hope that you know that the whole MUTR CD contents is on the website. It is there as .wav-files, as well in positive as in negative polarity. There are about 15 different files, but of course in 2 x 16 bits, 14.4 kHz sample frequency. You may convert them. They are already DC restored with black is 00 00.

Thanks Klaas - yes I grabbed all of those, I think, but maybe not from the site. Not sure about the quality - some of them look like they've been saved as MP3 and then converted back to WAV. In any case, I can produce my own videos from any source material now and the list of files in the video was just a random sample of the files I have on my computer. I have yet to figure out AC->DC restoration but I'm thinking I can just ignore this and just play videos that I've done myself or are already DC coupled.

Re: File Selection UI

PostPosted: Sat May 06, 2017 10:06 pm
by Andrew Davie
I spent some time making a stand-alone version of the selection dialog for the Nextion ITEAD people - hopefully it gets placed in their "how to" section. It was a good diversion as I improved the methods I'm using to communicate with the display.

I just got the "select and play" working - so this video is showing selection of a video from the menu, and that video being played. I don't quite have the code working which STOPS a video and lets you select another, so I'm re-uploading the code between videos here. But in principle you can see how it's working - and this is the first time I've been able to select files to play without having to manually change the filename in the source code.

The new UI code I wrote is also much more responsive. In particular, where I used to poll each control in a A... B... C fashion, one per main loop... now I just have callback functions which effectively let me handle any control without polling - the control tells ME when it's pressed instead of having to be asked. This dramatically decreases the traffic over the serial comms to the Nextion LCD. So it's come out pretty well.

I'll continue to clean up the UI - brightness contrast and volume are working but I want to get them working in real time, rather than when you release. That should be straightforward. I need to get the gamma control working, and also the "frame shift" dialog. Finally, the track seek and the time display and I think the UI will just about be wrapped up. Then it will be a complete working televisor and I'll move on to the cosmetics (which will include a rebuild onto a small board).

Re: File Selection UI

PostPosted: Thu May 11, 2017 2:20 am
by Andrew Davie
Still sick with a lingering cold. It's been really hard to motivate to do anything, and I've spent a few days off work just coughing and spluttering and feeling sorry for myself. Today I just tinkered and came up with a title screen I like and a name for the beast - "Dr. Boo's astounding ArduinoVisor". So, there we go. Here's a short video of the UI with new title screen and a few other bits I'm working on...

Tip: If you see a YouTube video you like and want a copy of, put "ss" before the youtube bit, and you'll be taken to a website that gives you a download button for the video. e.g.,<whatever was here >

Re: File Selection UI

PostPosted: Thu May 11, 2017 11:41 pm
by Andrew Davie
I started to work on the multi-file selection issues. That is, when one video is playing then allow it to be stopped and another video to be loaded from the selection menu, and play that. I have lots of problems here. The frame lock has gone - it still locks vertcially but it's getting the horizontal wrong - a bit odd! But the biggest worry is that I start to see glitching on the image (indicative that the SD card read is going slower than expected) and eventually SD card reading fails altogether. I wonder/suspect if the SD library has some bugs in it. I hope not; I would hate to have to debug it. Anyway, it's a work in progress and I just thought I'd throw up the video. It's effectively a mechanical video jukebox at this stage.

Edit: I have 30 *Bytes* of ROM left, so I'm going to have to start removing diagnostic output from now on to fit in any more code.

Re: File Selection UI

PostPosted: Fri May 12, 2017 3:44 pm
by Andrew Davie
I seem to have bypassed/fixed the majority of the problems with the glitching and timing, and now it seems to be synching very nicely indeed. Here's a run-through with some files being selected/stopped/played. The synch is quite impressive. The one file that doesn't look like it's frame-synched correctly (horizontally offset) is actully an error in the file itself, not with the televisor/synch.

Re: File Selection UI

PostPosted: Fri May 12, 2017 10:49 pm
by Andrew Davie
I've finished the code that handles "end of video" and that's working fine. I also added the "repeat" button to the UI and confirmed that's working. Now I can start the televisor and leave it actively playing/repeating a video for demo purposes. The only UI component left to do on the main control page is the "seek" slider - allowing manual positioning by dragging the seek bar, but I'm not entirely sure I want/need this. The other thing that's not functional is the "frame shift" code - not quite sure how I'm going to tackle/fix that at the moment, as my first version wasn't very cooperative.

Re: File Selection UI

PostPosted: Sat Jun 17, 2017 12:24 am
by Andrew Davie
I have modified the codebase so that the nextion is completely optional. If you do not include the nextion code (i.e., comment out the NEXTION definition at the top), then none of the Nextion/UI code is included. Instead, the code will play all of the files on the SD card, one by one - and then repeat. Thus, Nextion and UI is now an optional part of the televisor build. If you want to modify brightness/contrast/volume, though, it has to be done in the code and recompile.

Re: File Selection UI

PostPosted: Tue Dec 19, 2017 10:46 am
by JDMDyno
Hi Andrew

I am new to this forum as I have just found your video on youtube with the nextion dialog demo 8)

I have downloaded it from the nextion forum and modified it to work on my 7" display running a teensy 3.5 with built in SD card the demo runs ok with some tweaks to for my application,
But I can't get it to list the file list from the SD card, I have it listing them with the serial monitor with Serial.print(; so it is reading the SD card but I can't find a way to get it to list the files and use them in the nextion

I'm probably missing something simple

would you be able to give me a sample of how to get the SD list to list on the nextion like it does with the demo static char's
As i'm using a teensy with built in SD card some of the commands are diferent to you have in the source code for this TV project you are doing I have had a look but still can't figure it out

this is test code I have so far that does not have any errors when compiling and runs and prints SD card file list to serial monitor
Code: Select all
// Nextion UI - File Selection Dialog
// program by Andrew Davie (
// released to public domain; drop me an email if you use it, and pay it forward

// This short program interfaces with the Nextion LCD touch display to implement
// a scrollable "text selection dialog". In fact, it's a generic text scroller,
// but can be used as a selection dialog if you wish. Click on any line and it
// flashes - the actual selection code is not implemented here, but basically
// You'd implement a listener on each of the 8 text lines and handle the result
// here on the MC side.

// BUGS:
// OK, there's a problem when the system first starts up, and the error messages
// logged to serial include
//    Warning: Could not read update requirement - defaulting to ALL
//    Error reading base
// These can safely be ignored, because the system defaults to work without this
// particular part of the code working the first time through. For some reason, reading
// these variables from the Nextion just doesn't work. First time only.  However, after
// the first time.. all OK.  I would love to know what stuipd thing I have done that is
// causing this :(  C'est la vie.


// For use on Arduino Mirco, do the following...
// Uses the Nextion Library at
// 1: see:
//    --> Delete NexUpload.h and NexUpload.cpp from Nextion library folder to save RAM
// 2. Disable DEBUG_SERIAL_ENABLE in NexConfig.h
// 3. set   #define nexSerial Serial1 in NexConfig.h
// If you're using another MC of course you will need to do things suitable for your platform.


#include "Nextion.h"          // You may need angle brackets...
#include "NexUpload.h"
#include <SD.h>
#include <SPI.h>
NexUpload nex_download("nex.tft",BUILTIN_SDCARD,115200);
File root;

// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
// Teensy audio board: pin 10
// Teensy 3.5 & 3.6 on-board: BUILTIN_SDCARD
// Wiz820+SD board: pin 4
// Teensy 2.0: pin 0
// Teensy++ 2.0: pin 20
const int chipSelect = BUILTIN_SDCARD;

// Nextion UI - The file selection dialog - consists of 8 "buttons" showing the menu
// and each of these has a listener so that we know when there's a selection

NexButton t0 = NexButton(2, 1, "f0");
NexButton t1 = NexButton(2, 2, "f1");
NexButton t2 = NexButton(2, 3, "f2");
NexButton t3 = NexButton(2, 4, "f3");
NexButton t4 = NexButton(2, 5, "f4");
NexButton t5 = NexButton(2, 6, "f5");
NexButton t6 = NexButton(2, 9, "f6");
NexButton t7 = NexButton(2, 10, "f7");

NexButton *textLine[] = { &t0, &t1, &t2, &t3, &t4, &t5, &t6, &t7 };

NexVariable baseVar = NexVariable(2, 11, "basex");
NexVariable selectedTrack = NexVariable(2, 8, "va0");
NexSlider trackSlider = NexSlider(2, 15, "h0");
NexVariable requiredUpdate = NexVariable(2, 12, "canUpdate");
NexVariable va1 = NexVariable(2, 19, "va1");
// We "listen" to the slider for the position change of the first line
// and we listen to the text buttons for a selection

NexTouch *nex_listen_list[] = {

// For this demo, the menu items are given as a list of "strings".  For a
// file selection dialog, you would want to read filenames from a SD card (for
// example).  In that case, you don't want to have them all in memory at the
// same time, so you would implement a "getFileN()" method, and perhaps others
// too - but for seeing how menus can work, this staic array is sufficient.

// Note that on the Arduino, the below is a TERRIBLE way to define strings,
// because they are placed in the very precious RAM.  For a demo, this is
// forgiveable  :)

 char *menuItems[] = {
  (char*)"00 There's a black crow ",
  (char*)"01 sitting across from",
  (char*)"02 me. His wiry legs are",
  (char*)"03 crossed. He is dangling",
  (char*)"04 my keys, he even fakes",
  (char*)"05 a toss. Whatever could",
  (char*)"06 it be that has brought",
  (char*)"07 me to this loss?",
  (char*)"08 On your back with your",
  (char*)"09 racks as the stacks are",
  (char*)"10 your load. In the back",
  (char*)"11 and the racks and the",
  (char*)"12 stacks of your load",
  (char*)"13 In the back with your",
  (char*)"14 racks and you're",
  (char*)"15 un-stacking your load.",
  (char*)"16 This is not the sound",
  (char*)"17 of a new man or crispy",
  (char*)"18 realization. It's the",
  (char*)"19 sound of the unlocking",
  (char*)"20 and the lift away.",
  //(char*)"21 Your love will be",
  //(char*)"22 Safe with me.",

uint32_t menuSize;

// The callback "happens" when there is a change in the scroll position of the dialog.  This
// means that we need to update one or all of the 8 text lines with new contents. When the up
// or down arrows are pressed, the Nextion automatically does the scrolling up/down for the
// lines that are visible on the screen already, and we only need to update the top (0 for up)
// or the bottom (7 for down) line.  However, if the slider was used, we have to update all
// of the lines (8) - so this is somewhat slower in updating.  Not too bad though.

void writeMenuStrings(void * = NULL) {

  // Ask the Nextion which line(s) require updating.  See the REFRESH_ equates at top of file.
  uint32_t updateReq;
  if (!requiredUpdate.getValue(&updateReq)) {
    Serial.println("Warning: Could not read update requirement - defaulting to ALL");
    updateReq = REFRESH_ALL_LINES;                       // do all as a fallback 
  // Get the "base" from the Nextion. This is the index, or starting file # of the first line
  // in the selection dialog. As we scroll up, this decreases to 0. As we scroll down, it
  // increases to the maximum file # (held in the slider's max value).
  uint32_t base;
  if (!baseVar.getValue(&base)) {
    Serial.println("Error reading base");
    base = 0;

  Serial.print(" Update=");

  // Based on 'requiredUpdate' from the Nextion we either update only the top line (when up arrow pressed),
  // only the bottom line (when down arrow pressed), or we update ALL of the lines (slider dragged). The
  // latter is kind of slow, but that doesn't really matter.  Could switch the serial speed to 115200 bps to
  // make this super-quick, but it works just fine at default 9600 bps.

  switch (updateReq) {
        char *p = 0;
        if (base + updateReq < menuSize)        // strictly speaking, should never be false - can be removed
          p = menuItems[base + updateReq];

      for (int i=0; i<8; i++) {
        char *p = 0;
        if (base + i < menuSize)              // strictly speaking, should never be false - can be removed
        p = menuItems[base + i];

void trackSelectCallback(void *) {

  // When a menu item is selected, we read the selected item absolute number from the Nextion
  // and use that to lookup the menu string itself, and display both of them on the serial.

  uint32_t base;
  if (baseVar.getValue(&base)) {
    uint32_t selection;
    if (selectedTrack.getValue(&selection)) {
      Serial.print(" = ");

 uint32_t val;
      if (va1.getValue(&val)){
    } else
      Serial.println("error retrieving selection");
  } else
    Serial.println("error retrieving base");

// Arduino starts here...

void setup(){
  // put your setup code here, to run once:

  while (!Serial) {}
  Serial.println(F("Nextion File Dialog Demo"));

  Serial.print("Initializing SD card...");

  if (SD.begin(chipSelect)) {
    Serial.println("initialization failed!");
  Serial.println("initialization done.");

  root ="/");
  printDirectory(root, 0);

  // BUG:  I have no idea why the delay below is needed, but the communication with Nextion
  // fails if it's not there - specifically, the trackSlider.setMaxValue(...) fails.  This code
  // has generic communication problems with the Nextion but seemingly ONLY ON STARTUP -
  // once the scrolling system is going, everything seems hunky dory.  So, somewhere there's
  // a mistake by yours truly...

  // Attach callbacks - one for the slider, and one each for the selectable lines
  trackSlider.attachPop(writeMenuStrings, &trackSlider);
  for (int i=0; i<8; i++)
    textLine[i]->attachPop(trackSelectCallback, textLine[i]);

  // Count the number of menu items and then set the maximum range for the slider
  // We subtract 8 from the count because there are 8 lines already visible in the window

  menuSize = 0;
  while (menuItems[menuSize])
  Serial.print("Menu items: ");
  if (!trackSlider.setMaxval(menuSize > 8 ? menuSize - 8 : 0))
    Serial.println("Error setting slider maximum!");

  writeMenuStrings();           // defaults to REFRESH_ALL_LINES, so screen is populated

// Arduino calls this whenever it gets a chance...

void loop() {
void printDirectory(File dir, int numTabs) {
   while(true) {
     File entry =  dir.openNextFile();
     if (! entry) {
       // no more files
     for (uint8_t i=0; i<numTabs; i++) {
     if (entry.isDirectory()) {
       printDirectory(entry, numTabs+1);
     } else {
       // files have sizes, directories do not
       Serial.println(entry.size(), DEC);

// EOF

any help would be really appreciated

the Teensy has lots of space on it so I am using the NexUpload and have fixed a bug in the library that would block the code from running if the SD card was present but no .TFT file on it, now it will load the .TFT file if present or if no .TFT file it will run the normal code without blocking, I am going to try and modify it to delete the .TFT file once it has been loaded to the screen so next time you power it up it doesn't try to load the file again if you haven't removed it, but not got round to it yet yet.