Hallo Tonuino,
vor etwa 3 Jahren habe ich meinem Sohn eine TonieBox mit Arduino, DFPlayer mini und PN532 nachgebaut.
Diese Version hatte eine Relais Selbsthaltung, die den gnd abschaltete. Alles war mit Drähten angelötet und mit Heißkleber fixiert.
Der Code beinhaltete die UIDs der einzelnen möglichen Karten und die jeweilige Funktion dazu. Wenn ich also eine neue Karte hinzufügen wollte, musste ich den Code anpassen und alles neu hochladen.
Einen Ordner abzuspielen habe ich gleich garnicht geschafft.
Wie man liest, habe ich da eine Menge Mist gebaut.
Im Arduinoforum habe ich um Hilfe gebeten und etwas neues konstruiert…
- eine Selbsthaltung mit Transistor,
- eine erstelle Platine,
- ein Code der ein neues Anlernen per NFC Handy ermöglicht.
Code hängt unten. Leider funktioniert er nicht.
Ich weiß nicht, wie blind ich gewesen sein muss, nicht auf dem Tonuino gestoßen zu sein.Fast all meine Wünsche wurden hier schon übertroffen.
Nur die Einbindung von WS2812 habe ich im Nachbarthread schon gesehen und werde mich mit befassen.
Die Möglichkeit eines Startsounds habe ich noch nicht gefunden, aber auch dies denke ich zu schaffen. Am Ende des Setups kann ich einfach ein myDFPlayer.Play einfügen, oder?
Nun aber zu meiner Hardwarefrage.
Natürlich möchte ich meine Platine weiterhin nutzen, die Versorgung des Readers muss ich von 5V auf 3,3V umlöten, keine Frage.
Aber ich habe die Knöpfe auf den digitalen Pins.
Kann ich diese im Code einfach umbenennen oder schimpft er wenn ich ihm die analogen wegnehme?
Falls ihr die Platinen hier nochmal ändert, ich habe vor dem Player eine Diode eingeplant, die die Knatterprobleme verhindert, hilft super.
Die Schaltung für meine Selbsthaltung könnt ihr auch gerne haben.
Liebe Grüße
#include <SPI.h>
#include <EEPROM.h>
#include <Adafruit_PN532.h>
#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
#include <FastLED.h>
#define NUM_LEDS 1
#define DATA_PIN 4
CRGB leds[NUM_LEDS];
// define the pins for SPI communication.
#define PN532_SCK (13)
#define PN532_MOSI (12)
#define PN532_SS (10)
#define PN532_MISO (11)
Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);
SoftwareSerial mySoftwareSerial(3, 2); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);
bool musikLaeuft = LOW; //um StandbyAbschaltung zu verhindern
bool aus = LOW; //SelbstmordBefehl
bool pauseGedrueckt = HIGH;
long standby = 1;
long ruhezeit = 60000; //Abschaltung nach ms
uint16_t Befehl;
uint16_t Parameter1;
uint16_t Parameter2;
uint16_t BefehlAlt;
uint16_t Parameter1Alt;
uint16_t Parameter2Alt;
uint16_t aktuellesLied;
uint16_t letztesLied;
unsigned long currentMillis;
unsigned long startMillisLesen;
const unsigned long periodeLesen = 1000;
unsigned long startMillisStatus;
const unsigned long periodeStatus = 500;
//uint8_t AnzahlLieder = 1;
void setup() {
FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);
FastLED.setBrightness(50);
leds[0] = CRGB::Yellow;
FastLED.show();
pinMode(5, INPUT); //DfPlayer
digitalWrite(6, HIGH);
pinMode(6, INPUT); //frei
digitalWrite(6, HIGH);
pinMode(7, INPUT); //Lauter
digitalWrite(7, HIGH);
pinMode(8, INPUT); //Leiser
digitalWrite(8, HIGH);
pinMode(9, OUTPUT); //Selbstmord
digitalWrite(9, HIGH);
standby = ruhezeit;
Serial.begin(115200); // Serielle Kommunikation mit dem PC initialisieren
while (!Serial) delay(10); // für Leonardo/Micro/Zero
mySoftwareSerial.begin(9600); //Kommunikation mit DFPlayer
Serial.println();
Serial.println(F("PhonieBox startet"));
Serial.println(F("Initialisiere DFPlayer ... (dauert 3 - 5 Sekunden)"));
if (!myDFPlayer.begin(mySoftwareSerial)) { //Software Serial als Kommunikation zum dfPlayer
Serial.println(F("Start nicht möglich:"));
Serial.println(F("1.Die Verbindung nochmals prüfen"));
Serial.println(F("2.Bitte SD- Karte einlegen"));
leds[0] = CRGB::Red;
FastLED.show();
while (true) {
delay(0); // Code to compatible with ESP8266 watch dog.
}
}
Serial.println(F("DFPlayer Mini ist startbereit."));
myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); //SD Karte als Quelle
if (EEPROM.read(0) != 0 ) myDFPlayer.volume(EEPROM.read(0)); //Start-Lautstärke aus dem EEPOROM, wenn nicht 0
Serial.println("PN532 starten");
nfc.begin();
uint32_t versiondata = nfc.getFirmwareVersion();
if (! versiondata) {
leds[0] = CRGB::Blue;
FastLED.show();
Serial.print("PN5... Board nicht gefunden");
while (1); // Abbruch
}
// Alles in Ordnung
Serial.print("PN5... gefunden"); Serial.println((versiondata >> 24) & 0xFF, HEX);
Serial.print("Firmware ver. "); Serial.print((versiondata >> 16) & 0xFF, DEC);
Serial.print('.'); Serial.println((versiondata >> 8) & 0xFF, DEC);
// configure board to read RFID tags
nfc.SAMConfig();
leds[0] = CRGB::Green;
FastLED.show();
Serial.println("Warte auf einen ISO14443A Tag ...");
}
void loop() {
uint8_t success;
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
currentMillis = millis(); //get the current time
if (currentMillis - startMillisStatus >= periodeStatus)
{
startMillisStatus = currentMillis;
if (!digitalRead(5)) { //läuft der DF Player?
musikLaeuft = HIGH;
pauseGedrueckt = LOW;
}
else {
musikLaeuft = LOW;
if (!pauseGedrueckt) { //Kontrolle ob das Lied vorbei ist oder einer Pause gedrückt hat
if (aktuellesLied <=100000) aktuellesLied = aktuellesLied + 1;
if (aktuellesLied <= letztesLied) myDFPlayer.play(aktuellesLied); //ist ein Lied vorbei, spiele das Nächste bis du alle durch hast
}
}
if (currentMillis - startMillisLesen >= periodeLesen)
{
startMillisLesen = currentMillis;
leds[0] = CRGB::Green;
FastLED.show();
delay(200);
leds[0] = CRGB::Black;
FastLED.show();
success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 100);
if (success) { //Wenn er einen neuen Tag erkannt hat
leds[0] = CRGB::Blue;
FastLED.show();
delay(200);
leds[0] = CRGB::Black;
FastLED.show();
uint8_t data[32];
success = nfc.ntag2xx_ReadPage(7, data); //lese den Block 7
if (success)
{
Befehl = data[2] * 100 + data[3]; // hole dir aus Block 7 die Daten zur Berechnung des Befehls
Serial.print("Befehl: ");
Serial.println(Befehl);
}
else
{
Serial.println("Block 7 konnte nicht gelesen werden");
}
success = nfc.ntag2xx_ReadPage(8, data); //lese den Block 8
if (success)
{
Parameter1 = (data[0] - '0') * 100 + (data[1] - '0') * 10 + (data[2] - '0'); //hole dir aus Block 8 die Daten zur Berechnung des Parameter1
Parameter2 = (data[3] - '0') * 100 ; //hole dir aus der letzten Stelle des Block 8 den Hunderter der Parameter2
Serial.print("Parameter1: ");
Serial.println(Parameter1);
}
else
{
Serial.println("Block 8 konnte nicht gelesen werden");
}
success = nfc.ntag2xx_ReadPage(9, data); //lese den Block 9
if (success)
{
Parameter2 = Parameter2 + (data[0] - '0') * 10 + (data[1] - '0') * 1; //hole dir aus Block 9 die restlichen Daten zur Berechnung des Parameter2
Serial.print("Parameter2: ");
Serial.println(Parameter2);
}
else
{
Serial.println("Block 9 konnte nicht gelesen werden");
}
}
if (Befehl == BefehlAlt && Parameter1 == Parameter1Alt && Parameter2 == Parameter2Alt) {
Serial.println("gleicher Befehl");
delay(2000);
}
else
{
Serial.println("Abarbeiten");
switch (Befehl) {
case 6976: //"EL" = EinzelLied
Serial.println("EL erkannt");
myDFPlayer.play(Parameter1); // Bsp: "EL026" spielt Lied 26
aktuellesLied = Parameter1;
letztesLied = Parameter1;
Serial.print("Spiele Einzellied: ");
Serial.println(aktuellesLied);
break;
case 7683: //"LS" = Lautstärke
Serial.println("LS erkannt");
switch (Parameter1) {
case 1: //001 = ein Schritt leiser
myDFPlayer.volumeDown(); // "LS001"
Serial.println("eins leiser");
break;
case 2: //002 = ein Schritt lauter
myDFPlayer.volumeUp(); // "LS002"
Serial.println("eins leiser");
break;
case 100 ... 130: //100-130 = aktuelle Lautstärke auf 0-30 setzen
myDFPlayer.volume(Parameter1 - 100); // Bsp: "LS113" setzt die aktuelle Lautstärke auf 13
Serial.print("Setze Normallautstärke: ");
Serial.println(Parameter1);
break;
case 200 ... 230: //200 = Lautstärke bleibt wie beim ausschalten
EEPROM.write(0, Parameter1 - 200); //201-230 = Startlautstärke auf 1-30 setzen
Serial.print("Setze EEPROM Lautstärke: ");//"LS200" lässt die Lautstärke vom letzten mal
Serial.println(EEPROM.read(0)); // Bsp:"LS215" beginnt nach jedem Neustart mit Lautstärke 15
break;
default:
break;
}
break;
case 7978: //"ON" = Ordner Normal
Serial.println("ON erkannt");
myDFPlayer.play(Parameter1); // Bsp: "ON003006" spielt die Lieder 3 bis 6 hintereinander weg
aktuellesLied = Parameter1;
letztesLied = Parameter2;
Serial.print("Spiele Lieder: ");
Serial.println(Parameter1);
Serial.print(" bis ");
Serial.println(Parameter2);
break;
case 7990: //"OZ" = Ordner im Zufall
Serial.println("OZ erkannt");
myDFPlayer.play(Parameter1); // Bsp: "OZ005" spielz Ordner 5 durcheinander
//random einstellen
Serial.print("Spiele Randomordner: ");
Serial.println(Parameter1);
break;
case 8377: //"SM" = Selbstmord
Serial.println("SM erkannt");
aus == true; //"SM000"
Serial.println("Selbstmord");
break;
case 8779: //"WO" Wiedergabe Optionen
Serial.println("WO erkannt");
switch (Parameter1) {
case 1: //1 = Play
myDFPlayer.start(); // "WO001"
Serial.println("Play");
break;
case 2: //2 = Pause
pauseGedrueckt = pausenFunktion(); // "WO002"
Serial.println("Pause");
break;
case 3: //3 = Wechsel
if (!digitalRead(5)) { //"WO003" war Pause, wird gespielt, wurde gespielt kommt Pause
pauseGedrueckt = pausenFunktion();
}
else {
myDFPlayer.start();
}
Serial.println("Wiedergabewechsel");
break;
case 4: //4 = vorheriges Lied
myDFPlayer.previous(); //"WO004"
Serial.println("vorheriges Lied");
break;
case 5: //5 = nächstes Lied
myDFPlayer.next(); //"WO005"
Serial.println("nächstes Lied");
break;
default:
break;
}
break;
default:
break;
}
BefehlAlt = Befehl;
Parameter1Alt = Parameter1;
Parameter2Alt = Parameter2;
}
}
if (!digitalRead(6)) {
leds[0] = CRGB::Yellow;
FastLED.show();
myDFPlayer.volumeUp();
delay(200);
}
if (!digitalRead(7)) {
leds[0] = CRGB::Red;
FastLED.show();
myDFPlayer.volumeUp();
delay(200);
}
if (!digitalRead(8)) {
leds[0] = CRGB::Green;
FastLED.show();
myDFPlayer.volumeDown();
delay(200);
}
if (musikLaeuft) (standby = millis() + ruhezeit); // Wenn die Musik läuft, kann "Ruhezeit" ausgeschalten werden.
if (millis() >= standby) (aus = HIGH); // Lief die Musik "Ruhezeit" nicht, wird der Strom genommen
if (aus) {
Serial.println("ich schalte nun aus");
myDFPlayer.pause();
delay(200);
digitalWrite(9, LOW);
delay(10000);
standby = millis() + ruhezeit;
aus = LOW;
}
}
}
bool pausenFunktion() {
myDFPlayer.pause();
return HIGH;
}
void playFunktion(uint16_t x) {
myDFPlayer.play(x);
}
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 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;
}
}