Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
f019cbd
271: First skeleton of a 'test' type for running a factory test
TheBakedPotato Oct 31, 2025
583c59d
271: Started laying out the 'loop back' test more
TheBakedPotato Nov 1, 2025
b81ea60
FactoryTest_Krake01, Factory test files collage.
nk25719 Nov 23, 2025
e77c815
FactoryTest with Menu first draft.
Dec 4, 2025
a8d23e1
Merge pull request #304 from nk25719/271-firmware-factory-test-bring-up
nk25719 Dec 6, 2025
c9661eb
Merge branch '271-firmware-factory-test-bring-up' into 271-single-fir…
nk25719 Dec 21, 2025
d6094b6
Fix Serial prompt input (line-based),abort prompts via menu keys,and …
nk25719 Dec 27, 2025
c28031b
At v0.4.0 bugs fixed.
nk25719 Dec 27, 2025
7b777a6
FactoryTest_wMenu.ino, Add date and time of build to Serial Splash (b…
ForrestErickson Dec 28, 2025
4faa8da
debugging and cleaning the factory test for the dfplayer sdcard and s…
nk25719 Dec 28, 2025
4acac73
bump[ing the firmware version to indicate updates.
nk25719 Dec 29, 2025
66b385c
FactoryTest_wMenu, UART1 and SPI factory test loopback working.
nk25719 Jan 1, 2026
c98eb14
SPI Backloop working, updated dfplayer, sd card and speaker tests.
nk25719 Jan 1, 2026
93a6b09
dfplayer code cleanup.
nk25719 Jan 2, 2026
a314b97
spi typo fix.
nk25719 Jan 2, 2026
ac4b0f6
fixed SPI typpo.
nk25719 Jan 2, 2026
5e28ff2
fixed SPi, version v 0.4.2.2
nk25719 Jan 2, 2026
5dcb8b6
FactoryTest_wMenu.ino, Make the test menu into two colums for better …
ForrestErickson Jan 5, 2026
ed0c91f
FactoryTest_wMenu.ino, Make results menu more compact.
ForrestErickson Jan 6, 2026
5c220b8
FactoryTest_wMenu.ino, Trying to make DFPlayer command 4 more verbose…
ForrestErickson Jan 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Firmware/GPAD_API/GPAD_API.ino
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ const int LED_COUNT = sizeof(LED_PINS) / sizeof(LED_PINS[0]);
// const char* password = "$Suve07$$";

// Austin network
const char* ssid = "readfamilynetwork";
const char* password = "magicalsparrow96";
// const char* ssid = "readfamilynetwork";
// const char* password = "magicalsparrow96";


// MQTT Broker
Expand Down
280 changes: 280 additions & 0 deletions Firmware/factoryTest/FactoryTest_Krake01/DFPlayerTD5580ATest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,280 @@
#include "DFPlayerTD5580ATest.h"
#define COMPANY_NAME "pubinv.org "
#define PROG_NAME "DFPlayerTD5580ATest "
#define VERSION "V0.7 "
#define DEVICE_UNDER_TEST "Krake: DFPlayer and OTA" //A PMD model number
#define LICENSE "GNU Affero General Public License, version 3 "
#define ORIGIN "USA"

/*
File: DFPlayerTD5580ATest
Author: Forrest Lee Erickson
Date: 20240929
Date: 20250414 V0.2, added functionality from :https://github.com/DFRobot/DFRobotDFPlayerMini/blob/master/examples/FullFunction/FullFunction.ino

*/

#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ElegantOTA.h>

// const char* ssid = "VRX";
// const char* password = "textinsert";

// const char* ssid = "Hometplink";
// const char* password = "adt@1963#";

//Houstin network
// const char* ssid = "DOS_WIFI";
// const char* password = "$Suve07$$";

// Austin network
const char* ssid = "readfamilynetwork";
const char* password = "magicalsparrow96";


AsyncWebServer server(80);

#define BAUDRATE 115200 // For UART0 the DEBUG Serial Monitor

#define BAUD_DFPLAYER 9600 //for UART2 to the DFPlayer
#define TXD2 17
#define RXD2 16

#include <DFRobotDFPlayerMini.h>
DFRobotDFPlayerMini dfPlayer;

HardwareSerial mySerial1(2); // Use UART2

const int LED_PIN = 13; // Krake
//const int LED_PIN = 2; // ESP32 LED

const int nDFPlayer_BUSY = 4; //not Busy from DFPLayer
bool isDFPlayerDetected = false;
int volumeDFPlayer = 20; // Set volume initial volume. Range is [0 to 30]
int numberFilesDF = 0; // Number of the audio files found.

//Functions
void setupDFPlayer() {
// Setup UART for DFPlayer
Serial.println("UART2 Begin");
mySerial1.begin(BAUD_DFPLAYER, SERIAL_8N1, RXD2, TXD2);
while (!mySerial1) {
Serial.println("UART2 inot initilaized.");
delay(100);
; // wait for DFPlayer serial port to connect.
}
Serial.println("Begin DFPlayer: isACK true, doReset false.");
if (!dfPlayer.begin(mySerial1, true, false)) {
Serial.println("DFPlayer Mini not detected or not working.");
Serial.println("Check for missing SD Card.");
isDFPlayerDetected = false;
} else {
isDFPlayerDetected = true;
Serial.println("DFPlayer Mini detected!");
}

dfPlayer.volume(volumeDFPlayer); // Set initial volume
dfPlayer.setTimeOut(500); // Set serial communictaion time out 500ms
// delay(100);

dfPlayer.start(); //Todo, ?? necessary for DFPlayer processing
delay(1000);
// dfPlayer.play(11); //DFPlayer Splash
dfPlayer.play(9);
delay(100);
dfPlayer.stop();
delay(1000);
dfPlayer.previous();
delay(1500);
dfPlayer.play(); //DFPlayer Splash

displayDFPlayerStats();

} //setupDFPLayer

void displayDFPlayerStats() {
Serial.print("=================");
Serial.print("dfPlayer State: ");
Serial.println(dfPlayer.readState()); //read mp3 state
Serial.print("dfPlayer Volume: ");
Serial.println(dfPlayer.readVolume()); //read current volume
Serial.print("dfPlayer EQ: ");
Serial.println(dfPlayer.readEQ()); //read EQ setting
Serial.print("SD Card FileCounts: ");
Serial.println(dfPlayer.readFileCounts()); //read all file counts in SD card
Serial.print("Current File Number: ");
numberFilesDF = dfPlayer.readCurrentFileNumber();
Serial.println(numberFilesDF); //Display the read current play file number
Serial.print("File Counts In Folder: ");
Serial.println(dfPlayer.readFileCountsInFolder(3)); //read file counts in folder SD:/03
// dfPlayer.EQ(0); // Normal equalization //Causes program lock up
Serial.print("=================");
}
void printDetail(uint8_t type, int value) {
switch (type) {
case TimeOut:
Serial.println(F("Time Out!"));
break;
case WrongStack:
Serial.println(F("Stack Wrong!"));
break;
case DFPlayerCardInserted:
Serial.println(F("Card Inserted!"));
break;
case DFPlayerCardRemoved:
Serial.println(F("Card Removed!"));
break;
case DFPlayerCardOnline:
Serial.println(F("Card Online!"));
break;
case DFPlayerUSBInserted:
Serial.println("USB Inserted!");
break;
case DFPlayerUSBRemoved:
Serial.println("USB Removed!");
break;
case DFPlayerPlayFinished:
Serial.print(F("Number:"));
Serial.print(value);
Serial.println(F(" Play Finished!"));
break;
case DFPlayerError:
Serial.print(F("DFPlayerError:"));
switch (value) {
case Busy:
Serial.println(F("Card not found"));
break;
case Sleeping:
Serial.println(F("Sleeping"));
break;
case SerialWrongStack:
Serial.println(F("Get Wrong Stack"));
break;
case CheckSumNotMatch:
Serial.println(F("Check Sum Not Match"));
break;
case FileIndexOut:
Serial.println(F("File Index Out of Bound"));
break;
case FileMismatch:
Serial.println(F("Cannot Find File"));
break;
case Advertise:
Serial.println(F("In Advertise"));
break;
default:
break;
}
break;
default:
break;
}
} //end printDetail for DFPlayer


void dfPlayerUpdate(void) {
unsigned long timePlay = 3000; //Plays 3 seconds of all files.
static unsigned long timer = millis();
if (millis() - timer > timePlay) {
// if (millis() - timer > 10000) {
timer = millis();
dfPlayer.next(); //Play next mp3 every 3 second.
}
if (dfPlayer.available()) {
printDetail(dfPlayer.readType(), dfPlayer.read()); //Print the detail message from DFPlayer to handle different errors and states.
}
} // end




// Functions to learn DFPlayer behavior
void playNotBusy() {
//Plays all files succsivly.
Serial.println("PlayNotBusy");
if (HIGH == digitalRead(nDFPlayer_BUSY)) {
//mp3_next ();
dfPlayer.next();
}
if (dfPlayer.available()) {
printDetail(dfPlayer.readType(), dfPlayer.read()); //Print the detail message from DFPlayer to handle different errors and states.
}
delay(1000); //This should be removed from code. We set a time for the next allowed message.
// Or better yet use interupt to find the end of BUSY and set time for the next allowed DFPlayer message
} // end playNotBusy



// Play a track but not if the DFPlayer is busy
bool playAlarmLevel(int alarmNumberToPlay) {
static unsigned long timer = millis();

const unsigned long delayPlayLevel = 20;
// const int MAX_ALARM_NUMBER = 6;
int tracNumber = alarmNumberToPlay;

if (millis() - timer > delayPlayLevel) {
// if (millis() - timer > 10000) {
timer = millis();

//If not busy play the alarm message
if ((0 > tracNumber < 0) || (numberFilesDF < tracNumber)) {
return false;
} else //Valid track number
if (HIGH == digitalRead(nDFPlayer_BUSY)) { // Should the test for busy be at the start of this function???
//mp3_next ();
dfPlayer.play(tracNumber);
} else {
Serial.println("Not done playing previous file");
}
if (dfPlayer.available()) {
printDetail(dfPlayer.readType(), dfPlayer.read()); //Print the detail message from DFPlayer to handle different errors and states.
}
return true;
} else {
return false;
}
} // end of playAlarmLevel


void DFPlayerTD5580ATest_setup() {
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);
pinMode(nDFPlayer_BUSY, INPUT_PULLUP);

// Start serial communication
Serial.begin(BAUDRATE);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB
}

//delay(500);
serialSplash();

//DFPlayer Splash
setupDFPlayer();
// dfPlayer.play(9); //DFPlayer Splash

setupOTA();
Serial.print("OTA setup done.");

while (LOW == digitalRead(nDFPlayer_BUSY)) {
; //Hold still till splash file plays
}

Serial.println("End of setup");
digitalWrite(LED_PIN, LOW);
} // end of setup()

void DFPlayerTD5580ATest_loop() {
ElegantOTA.loop();
//dfPlayerUpdate(); //Play all but for only a constant time.
// playNotBusy(); // Play all but only when not busy.
//playAlarmLevel(3);
digitalWrite(LED_PIN, !digitalRead(nDFPlayer_BUSY)); //Polarity of the LED must be inverted relative to the BUSY.

checkSerial();
} // end of loop()
17 changes: 17 additions & 0 deletions Firmware/factoryTest/FactoryTest_Krake01/DFPlayerTD5580ATest.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef DFPLAYERTD5580ATEST_H
#define DFPLAYERTD5580ATEST_H

#include <Arduino.h>

#ifdef __cplusplus
extern "C" {
#endif

void DFPlayerTD5580ATest_setup();
void DFPlayerTD5580ATest_loop();

#ifdef __cplusplus
}
#endif

#endif // DFPLAYERTD5580ATEST_H
70 changes: 70 additions & 0 deletions Firmware/factoryTest/FactoryTest_Krake01/FactoryTest_Krake01.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* main.cpp selector
* Define one of the USE_<MODULE> macros (e.g., -DUSE_Krake_MQTT)
* to build/run that converted module's setup/loop.
*/
#include <Arduino.h>

#include "DFPlayerTD5580ATest.h"
#include "Krake_MQTT.h"
#include "LCD_Test_2.h"
#include "LCD_nI2C_scanner.h"
#include "OTA.h"
#include "RotaryEncoderTest.h"
#include "Serial.h"
#include "WiFiAccessPointWithMAC.h"
void setup() {

#ifdef USE_DFPlayerTD5580ATest
DFPlayerTD5580ATest_setup();
#endif
#ifdef USE_Krake_MQTT
Krake_MQTT_setup();
#endif
#ifdef USE_LCD_Test_2
LCD_Test_2_setup();
#endif
#ifdef USE_LCD_nI2C_scanner
LCD_nI2C_scanner_setup();
#endif
#ifdef USE_OTA
OTA_setup();
#endif
#ifdef USE_RotaryEncoderTest
RotaryEncoderTest_setup();
#endif
#ifdef USE_Serial
Serial_setup();
#endif
#ifdef USE_WiFiAccessPointWithMAC
WiFiAccessPointWithMAC_setup();
#endif
}

void loop() {
#ifdef USE_DFPlayerTD5580ATest
DFPlayerTD5580ATest_loop();
#endif
#ifdef USE_Krake_MQTT
Krake_MQTT_loop();
#endif
#ifdef USE_LCD_Test_2
LCD_Test_2_loop();
#endif
#ifdef USE_LCD_nI2C_scanner
LCD_nI2C_scanner_loop();
#endif
#ifdef USE_OTA
OTA_loop();
#endif
#ifdef USE_RotaryEncoderTest
RotaryEncoderTest_loop();
#endif
#ifdef USE_Serial
Serial_loop();
#endif
#ifdef USE_WiFiAccessPointWithMAC
WiFiAccessPointWithMAC_loop();
#endif
delay(1);
}
Loading