SingendesBild/vscode/singing_picture_serial/src/main.cpp

339 lines
8.9 KiB
C++

#include <Arduino.h>
#define MV_ONE_IS_PLAYING 3100 //voltage level in mV of the busy signal - if there is one player is playing
#define MS_MAX_PLAYING_LENGTH 60000 //if there is one SD card signaling busy all the time - this is the time out for the play detection
#define MS_TO_WAIT_BEFORE_NEXT_MOVE 120000 //ms to wait before new movement is valid
#define MS_TO_WAIT_BEFORE_VALID_NO_MOVEMEVENT 10000 //ms a no movement phase must be
#define MS_TO_WAIT_BEFORE_NEXT_PRESS 200
const uint8_t vol_poti_pin = 35;
const uint8_t vol_down_out = 17;
const uint8_t button_stop_pin = 18;
const uint8_t button_play_pin = 2;
const uint8_t movesensor_pin = 4;
const uint8_t busyanalog_pin = 36; // to get status of all players
const uint8_t green_led_pin = 5;
const uint8_t red_led_pin = 0;
const uint8_t blue_led_pin = 16;
const uint8_t mp3player_control_pin[] = {15,13,12,14,27,26,25,33,32};
const uint8_t mp3player_nr = sizeof(mp3player_control_pin)/sizeof(mp3player_control_pin[0]);
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
SoftwareSerial mySoftwareSerial(19, 23); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void play_sequence(void);
void check_players_state(void);
void check_button(void);
void check_movement(void);
void set_volume(void);
void set_leds(void);
void setup()
{
Serial.begin(115200);
Serial.println("Setting button,movement sensor pin to input.");
digitalWrite(vol_down_out,HIGH);
pinMode(button_stop_pin, INPUT_PULLUP);
pinMode(button_play_pin, INPUT_PULLUP);
pinMode(movesensor_pin, INPUT_PULLDOWN);
pinMode(green_led_pin, OUTPUT);
pinMode(red_led_pin, OUTPUT);
pinMode(blue_led_pin, OUTPUT);
digitalWrite(red_led_pin, HIGH);
delay(500);
digitalWrite(red_led_pin, LOW);
delay(500);
digitalWrite(blue_led_pin,HIGH);
delay(500);
digitalWrite(blue_led_pin,LOW);
delay(500);
digitalWrite(green_led_pin,HIGH);
delay(500);
digitalWrite(green_led_pin,LOW);
delay(500);
Serial.println("Setting all control pins to outputs and disable playing.");
for(uint8_t ix = 0; ix < mp3player_nr; ix++)
{
pinMode(mp3player_control_pin[ix], OUTPUT);
digitalWrite(mp3player_control_pin[ix],HIGH);
pinMode(mp3player_control_pin[ix], INPUT);
}
mySoftwareSerial.begin(9600);
myDFPlayer.begin(mySoftwareSerial);
if (!myDFPlayer.begin(mySoftwareSerial, false)) { //Use softwareSerial to communicate with mp3.
Serial.println(F("Unable to begin:"));
Serial.println(F("1.Please recheck the connection!"));
Serial.println(F("2.Please insert the SD card!"));
while(true){
digitalWrite(red_led_pin, HIGH);
delay(500);
digitalWrite(red_led_pin, LOW);
delay(500);
}
}
myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); // Setzt SD-Karte als Quelle
set_volume();
myDFPlayer.EQ(DFPLAYER_EQ_NORMAL); // Equalizer auf normal setzen
myDFPlayer.disableDAC();
myDFPlayer.stop(); // Sicherstellen, dass nichts ungewollt abgespielt wird
// myDFPlayer.sleep();
Serial.println(F("DFPlayer Mini online and sleeping."));
}
bool movement = false;
bool there_was_no_movement_in_between = true;
bool is_playing = false; // forced by software - signals that the play sequence is started
bool is_busy = false; // status of all the busy pins coming from the mp3players itself
bool button_play_pressed = false;
bool button_stop_pressed = false;
unsigned long last_move_ms = 0;
unsigned long last_no_move_ms = 0;
bool movement_detected = false;
bool next_playing_possible = false;
void loop()
{
check_players_state();
check_movement();
check_button();
set_leds();
set_volume();
play_sequence();
delay(100);
}
void set_volume(void)
{
static long last_vol = 0;
uint16_t vol_poti = analogRead(vol_poti_pin);
long vol_mp3 = map(vol_poti, 0, 4095, 2 , 30);
if(last_vol != vol_mp3)
{
digitalWrite(green_led_pin,LOW);
Serial.printf("Over all Volume set from %d to %d \n", last_vol, vol_mp3 );
myDFPlayer.volume(vol_mp3); //Set volume value. From 0 to 30
last_vol = vol_mp3;
// myDFPlayer.sleep();
}
}
void check_button(void)
{
static unsigned long last_play_button_ms = 0;
static unsigned long last_stop_button_ms = 0;
unsigned long current_ms = millis();
if( MS_TO_WAIT_BEFORE_NEXT_PRESS < current_ms - last_play_button_ms)
{
if(false == button_play_pressed && LOW == digitalRead(button_play_pin))
{
Serial.println("Play button pressed ...");
last_play_button_ms = current_ms;
button_play_pressed = true;
}
}
if( MS_TO_WAIT_BEFORE_NEXT_PRESS < current_ms - last_stop_button_ms)
{
if(false == button_stop_pressed && LOW == digitalRead(button_stop_pin))
{
Serial.println("Stop button pressed ...");
last_stop_button_ms = current_ms;
button_stop_pressed = true;
}
}
}
void check_movement(void)
{
int act_movement = digitalRead(movesensor_pin);
if(MS_TO_WAIT_BEFORE_NEXT_MOVE < millis()-last_move_ms)
{
if(next_playing_possible == false)
{
Serial.printf("Playing the sounds after next movement is possible now.\n");
}
next_playing_possible = true;
}
else
{
next_playing_possible = false;
}
if(LOW == act_movement )
{
if(movement_detected == true)
{
Serial.printf("Changed to No movement at %dms.\n", millis());
}
movement_detected = false;
if( false == there_was_no_movement_in_between)
{
if(MS_TO_WAIT_BEFORE_VALID_NO_MOVEMEVENT < millis()-last_no_move_ms)
{
there_was_no_movement_in_between = true;
Serial.printf("No movement anymore ...\n");
}
}
}
else
{
if(movement_detected == false)
{
Serial.printf("Changed to Movement at %dms.\n", millis());
}
movement_detected = true;
if( false == is_playing)
{
if(HIGH == act_movement && true == there_was_no_movement_in_between)
{
Serial.printf("Movement detected after a while of no movemwnt (last movement before %dms)...\n", millis()-last_move_ms);
there_was_no_movement_in_between = false;
if(true == next_playing_possible)
// if(MS_TO_WAIT_BEFORE_NEXT_MOVE < millis()-last_move_ms)
{
last_move_ms = millis();
movement = true;
Serial.printf("New movement detected ...\n");
}
}
}
else
{
last_move_ms = millis();
}
last_no_move_ms = millis();
}
}
void check_players_state(void)
{
// 0 ... 0V - 4095 ... 3.3V
uint16_t voltage_dig = analogRead(busyanalog_pin);
uint16_t voltage_mV = map(voltage_dig,0,4095,0,3300);
//Serial.printf("Voltage at busy pins is: dig=%d , ana=%dmV\n", voltage_dig, voltage_mV);
if(voltage_mV < MV_ONE_IS_PLAYING)
{
if(false == is_busy)
{
Serial.println("At least one player is in busy mode (Playing or SD card problem?).");
}
is_busy = true;
}
else
{
if(true == is_busy)
{
Serial.println("All players off now.");
}
is_busy = false;
is_playing = false;
myDFPlayer.stop();
// myDFPlayer.sleep();
}
}
void play_sequence(void)
{
static unsigned long start_playing_ms = 0;
if(true == button_stop_pressed)
{
myDFPlayer.stop();
// myDFPlayer.sleep();
is_playing = false;
last_move_ms = 0;
there_was_no_movement_in_between = true;
Serial.println("All players stopped.");
}
else
{
if(true == is_playing)
{
if(MS_MAX_PLAYING_LENGTH < millis()-start_playing_ms){
is_playing = false;
myDFPlayer.stop();
// myDFPlayer.sleep();
}
}
else
{
//Serial.println("All players still off .");
if(true == button_play_pressed || true == movement )
{
Serial.println("All players starting now.");
myDFPlayer.play();
Serial.println("All players started.");
start_playing_ms = millis();
is_playing = true;
}
}
}
button_play_pressed = false;
button_stop_pressed = false;
movement = false;
}
void set_leds(void)
{
static unsigned long last_update_blue_led = 0;
bool next_play_possible = false;
if(millis() - last_update_blue_led > 1000)
{
next_play_possible = next_playing_possible;
last_update_blue_led = millis();
}
if(is_playing == true)
{
digitalWrite(blue_led_pin, HIGH);
}
else
{
if(next_play_possible == true)
{
digitalWrite(blue_led_pin, HIGH);
}
else
{
digitalWrite(blue_led_pin, LOW);
}
}
if(there_was_no_movement_in_between == false)
{
digitalWrite(red_led_pin, HIGH);
}
else
{
digitalWrite(red_led_pin, LOW);
}
digitalWrite(green_led_pin,HIGH);
}