Moderators: Dave Moll, Andrew Davie, Steve Anderson
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 NBTV.org 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.
// Nextion UI - File Selection Dialog
// program by Andrew Davie (andrew@taswegian.com)
// 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.
// LIBRARIES...
// For use on Arduino Mirco, do the following...
// Uses the Nextion Library at https://github.com/itead/ITEADLIB_Arduino_Nextion
// 1: see: http://support.iteadstudio.com/support/discussions/topics/11000012238
// --> 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.
#define REFRESH_TOP_LINE 0
#define REFRESH_BOTTOM_LINE 7
#define REFRESH_ALL_LINES 8
#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[] = {
&trackSlider,
&t0,
&t1,
&t2,
&t3,
&t4,
&t5,
&t6,
&t7,
NULL
};
// 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.",
0
};
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("Base=");
Serial.print(base);
Serial.print(" Update=");
Serial.println(updateReq);
// 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.
Serial.println("----------");
switch (updateReq) {
case REFRESH_TOP_LINE:
case REFRESH_BOTTOM_LINE: {
char *p = 0;
if (base + updateReq < menuSize) // strictly speaking, should never be false - can be removed
p = menuItems[base + updateReq];
Serial.println(p);
textLine[updateReq]->setText(p);
}
break;
case REFRESH_ALL_LINES:
default:
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];
Serial.println(p);
textLine[i]->setText(p);
}
break;
}
Serial.println("----------");
}
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("#");
Serial.print(selection);
Serial.print(" = ");
Serial.println(menuItems[selection]);
uint32_t val;
if (va1.getValue(&val)){
Serial2.print("t0.txt=");
Serial2.write(0x22);
Serial2.print(menuItems[selection]);
Serial2.write(0x22);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
}
} 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:
nex_download.upload();
Serial.begin(9600);
while (!Serial) {}
Serial.println(F("Nextion File Dialog Demo"));
nexInit();
//SD.begin(BUILTIN_SDCARD);
Serial.print("Initializing SD card...");
if (SD.begin(chipSelect)) {
Serial.println("initialization failed!");
//return;
}
Serial.println("initialization done.");
root = SD.open("/");
printDirectory(root, 0);
Serial.println("done!");
//////////////////////////////////////////////////////////////////////////////////////////
// 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...
delay(1000);
//////////////////////////////////////////////////////////////////////////////////////////
// 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])
menuSize++;
Serial.print("Menu items: ");
Serial.println(menuSize);
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() {
nexLoop(nex_listen_list);
}
void printDirectory(File dir, int numTabs) {
while(true) {
File entry = dir.openNextFile();
if (! entry) {
// no more files
//Serial.println("**nomorefiles**");
break;
}
for (uint8_t i=0; i<numTabs; i++) {
Serial.print('\t');
}
Serial.print(entry.name());
if (entry.isDirectory()) {
Serial.println("/");
printDirectory(entry, numTabs+1);
} else {
// files have sizes, directories do not
Serial.print("\t\t");
Serial.println(entry.size(), DEC);
}
//entry.close();
}
}
// EOF
Return to Andrew Davie's Arduino Televisor
Users browsing this forum: No registered users and 10 guests