Hallo ihr Lieben,
ich bin blind und zudem neu in der Welt der Arduinos.
Ich bastel aktuell zu Lernzwecken an einer sprechenden Uhr für Blinde mit einem Nano, Display, RTC, DFPlayer und mini Lautsprecher.
Der aktuelle Sketch läuft auch soweit. Die Zeitansage läuft noch mit vielen Pausen, aber werde ich ändern, sobald die delays raus sind. Auch wenn einige Modis noch nicht fertig sind, möchte ich gerne wissen, was man am aktuellen Code noch optimieren müsste. Hat jemand eine Idee, wie das eleganter aussehen könnte? Einige Funktionen sehen ja gleich aus. Vielleicht gibts ja Ideen.
Mir fehlt die Metode für einmaliges Abspielen der Ansagen in den entsprechenden Modis und beim Alarm.
Hat jemand vielleicht auch eine Idee, wie man die delays für diesen Sketch ersetzen könnte und wie die Alarmfunktion noch vervollständigt werden kann? z.B. der Alarm soll 5 min. lang klingeln und bei Tastendruck auf Button 2 oder 3 beendet werden können.
Über Ideen, Ratschläge und lesbaren Code freue ich mich sehr.
#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
#include "TM1637Display.h"
#include "DS3231.h"
#include "Wire.h"
//Display PINs
#define Disp_CLK 2
#define Disp_DIO 3
//DFPlayer PINs
#define MF_RX 10
#define MF_TX 11
//Buttons PINs
int bGetMode=4; //Button für Modis
int bSetMin=5; Button 2
int bSetHour=6; Button 3
//Variablen für Programmlogik
byte hour, minute;
int mode = 0; //Verschiedene Modis
byte alarmhour=18, alarmminute=30; //Variablen für Alarm/Wecker
//Serielle Schnittstelle Konfigurieren
SoftwareSerial mySoftwareSerial(MF_RX, MF_TX); // RX, TX für dfplayer
//Anlegen des Objekts myDFPlayer über DFRobotDFPlayerMini Library
DFRobotDFPlayerMini myDFPlayer;
//Anlegen des Objekts display über TM1637 Library
TM1637Display display(Disp_CLK, Disp_DIO);
//Anlegen des Objekts Clock über DS3231 Library
DS3231 Clock;
void setup() {
//------------------------------ init Taster
pinMode(bGetMode, INPUT);
pinMode(bSetMin, INPUT);
pinMode(bSetHour, INPUT);
// Starte die kommunikation mit dem seriellen Monitor mit der Baudrate
Serial.begin(115200);
Serial.println("MyTalkingClock v1.0 is starting..."); //Der Arduino schreibt in den seriellen Monitor
Serial.println("");
//------------------------------ init DFPlayer
mySoftwareSerial.begin(9600);
if (!myDFPlayer.begin(mySoftwareSerial, true, false))
{ //Geräusch beim Starten des DFPlayers verhindern
Serial.println(F("Unable to begin:"));
Serial.println(F("1.Recheck the connection."));
Serial.println(F("2.Insert the SD card."));
while(true)
{
delay(0); // the ESP8266 watchdog likes this.
}
}
myDFPlayer.setTimeOut(500); //Set serial communication time out 500ms
//myDFPlayer.volume(30); //0-30 möglich
myDFPlayer.EQ(DFPLAYER_EQ_NORMAL);
myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); //----Set device we use SD as default
//----------------------------- init Display
display.setBrightness(0x00); //0-15 möglich
//----------------------------- init DS3231
Wire.begin();
}
void loop() {
if(bPressed(bGetMode)){
delay(700);
mode++;
if(mode > 3) mode = 0;
}
switch(mode) {
case 1:
//Modus 1 = Uhrzeit (stunden und minuten) einstellen
//Einmalige Ansage des Modus
//if (millis() % 1000 > 300)
// playSound(31);
setClock();
break;
case 2:
//Modus 2 = Datum (Tag und monat) einstellen
//Einmalige Ansage des Modus
//if (millis() % 1000 > 300)
// playSound(32);
//Funktion für Datum einstellen kommt hier noch...
break;
case 3:
//Modus 3 = Alarm/Wecker (Stunde und Minute) einstellen
//Einmalige Ansage des Modus
//if (millis() % 1000 > 300)
// playSound(33);
getAlarm();
setAlarm();
break;
default:
//Modus 0 = Uhrzeit und Datum ansagen
//Einmalige Ansage des Modus
//if (millis() % 1000 > 998)
// playSound(34);
getTime();
ringAlarm();
//Uhrzeit ansagen auf Tastendruck
if(bPressed(bSetMin)) sayTime();
//Datum ansagen auf Tastendruck
if(bPressed(bSetHour)) sayTime(); //Datumfunktion fehlt, spricht ersatzweise aktuelle Zeit
break;
}//end switch
}
// Zeige Dezimalzahl mit führenden Nullen und Doppelpunkt
void printNum(int num){
display.showNumberDecEx(num, 0b11100000, true, 4, 0);
}
// Hole die Zeit vom DS3231 RTC
void getTime(){
int time;
bool A12h, Apm;
minute=Clock.getMinute();
hour=Clock.getHour(A12h, Apm);
time=hour*100;
time=time+minute;
printNum(time);
}
/*
* ------------------Definition der Dateien, die in dem Ordner liegen
* 1-21 = durchgängig
* 22 = thirty
* 23 = fourty
* 24 = fifty
* 25 = and
* 26 = hours
* 27 = minutes
* 28 = beep
* 29 = beep beep
* 30 = ringtone / alarm
* 31 - 34 = modis
*/
// Spielt die Datei in Ordner 01 ab
void playSound(int track){
myDFPlayer.volume(30);
delay(700);
myDFPlayer.playLargeFolder(1, track);
/*
int playerState = 0;
while(playerState != 512) {
delay(pause); // prevents clicks and static during playback - increase if necessary.
playerState = myDFPlayer.readState();
}
*/
//delay(500);
//myDFPlayer.volume(0);
}
// Angepasste Zahlenansage bis 59, noch in Englisch
// Muss verändert werden wenn die Ansage auf Deutsch erfolgen soll
void sayDecNum(int num){
if(num<21){
playSound(num+1);
if(num>11)delay(700);
}else {
playSound(20+(num/10)-1);
delay(600);
if(num%10!=0) {
delay(500);
playSound((num%10)+1);
delay(600);
}
}
}
// Ansage der Momentanen Zeit
void sayTime(){
int dely=700;
playSound(29);
delay(dely);
playSound(26);
delay(dely);
sayDecNum(hour);
delay(dely);
sayDecNum(minute);
delay(dely);
playSound(27);
delay(dely);
playSound(28);
}
// Reagieren auf Taster für Uhrzeit (Stunde und Minute) einstellen
void setClock(){
//Minuten einstellen
if(bPressed(bSetMin)){
minute++;
if(minute>=60){
hour++;
minute=0;
}
Clock.setMinute(minute);
delay(500);
sayDecNum(minute);
delay(650);
playSound(27);
}
//Stunde einstellen
if(bPressed(bSetHour)){
hour++;
if(hour>=24){
hour=0;
}
Clock.setHour(hour);
delay(500);
sayDecNum(hour);
delay(650);
playSound(26);
}
}
// Abfrage ob eine bestimmte Taste gedrückt UND wieder los gelassen wurde
// Solange die Taste gedrückt wird passiert nichts
bool bPressed(int button){
if(digitalRead(button)==HIGH){
while(digitalRead(button)==HIGH){}
return true;
}
return false;
}
// Reagieren auf Taster für Alarm/Wecker (Stunde und Minute) einstellen
void setAlarm(){
//Minuten einstellen
if(bPressed(bSetMin)){
alarmminute++;
if(alarmminute>=60){
alarmhour++;
alarmminute=0;
}
delay(500);
sayDecNum(alarmminute);
delay(700);
playSound(27);
}
//Stunden einstellen
if(bPressed(bSetHour)){
alarmhour++;
if(alarmhour>=24){
alarmhour=0;
}
delay(500);
sayDecNum(alarmhour);
delay(650);
playSound(26);
}
}
// Hole die Zeit für Alarm
void getAlarm(){
int time;
alarmminute = alarmminute;
alarmhour = alarmhour;
time = alarmhour*100;
time=time+alarmminute;
printNum(time);
}
//Alarmfunktion
void ringAlarm() {
if(hour == alarmhour && minute == alarmminute && mode == 0) {
//einmalige Ansage der aktuellen Uhrzeit
if (millis() % 1000 > 100) {
sayTime();
delay(50);
}
playSound(30);
delay(7000);
}
}
liebe Grüße