Hola, estoy haciendo un proyecto que necesito activar una pista de Audio cuando un sensor PIR detecta movimiento.
Hasta aquí todo bien, pero al tratar de leer el "BUSY PORT" del DFRPlayer, la idea es que cuando esté ocupado, activar un relé (ahora solo prendo un led por cuestión de probar código), el código se salta la función funcion_altavoz(); y no hace nada.
El busy port está activo cuando está en LOW.
¿Alguien tiene alguna idea?
Gracias,
aquí el código:
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <DFRobotDFPlayerMini.h>
#include <SoftwareSerial.h>
//Inicia a serial por software nos pinos 10 e 11
SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
//Crear el objeto lcd dirección 0x27 y 16 columnas x 2 filas
LiquidCrystal_I2C lcd(0x27,16,2);
const int LEDPin = 5; // pin para el LED
const int PIRPin = 2; // pin de entrada (for PIR sensor)
int busyPin = 8;
int pirState = LOW; // de inicio no hay movimiento
int val = 0; // estado del pin
int tcalibracion=10;
void setup()
{
// Inicializar el LCD
lcd.init();
//Encender la luz de fondo.
lcd.backlight();
//--------------------------zona dfplayer---------------
//Comunicacao serial com o modulo
mySoftwareSerial.begin(9600);
//Inicializa a serial do Arduino
Serial.begin(9600);
//Verifica se o modulo esta respondendo e se o
//cartao SD foi encontrado
Serial.println();
Serial.println(F("DFRobot DFPlayer Mini"));
Serial.println(F("Initializing DFPlayer module ... Wait!"));
if (!myDFPlayer.begin(mySoftwareSerial))
{
Serial.println(F("Not initialized:"));
Serial.println(F("1. Check the DFPlayer Mini connections"));
Serial.println(F("2. Insert an SD card"));
while (true);
}
Serial.println();
Serial.println(F("DFPlayer Mini module initialized!"));
//Definicoes iniciais
myDFPlayer.setTimeOut(500); //Timeout serial 500ms
myDFPlayer.volume(1); //Volume 5
myDFPlayer.EQ(0); //Equalizacao normal
//--------------------------zona dfplayer---------------
//-----calibración sensor PIR------------
//daremos un tiempo de calibración al sensor
Serial.print(" Calibrando sensor ");
for(int i=0; i< tcalibracion; i++){
Serial.print(".");
delay(1000);
}
Serial.println("hecho");
Serial.println("SENSOR ACTIVO");
delay(50);
//-------FIN CALIBRACIÓN-------------------
pinMode(LEDPin, OUTPUT);
pinMode(busyPin, INPUT);
pinMode(PIRPin, INPUT);
Serial.begin(9600);
myDFPlayer.pause();
delay(2000);
}
void loop()
{
val = digitalRead(PIRPin);
if (val == HIGH) //si está activado
{
Serial.println("Sensor activado");
long randomNumber = random(1,5);
myDFPlayer.play(randomNumber);
funcion_altavoz();
myDFPlayer.pause();
Serial.print("gos num:");
Serial.println(randomNumber);
delay(2000);
if (pirState == LOW) //si previamente estaba apagado
{
pirState = HIGH;
}
}
else //si esta desactivado
{
digitalWrite(LEDPin, LOW); // LED OFF
if (pirState == HIGH) //si previamente estaba encendido
{
Serial.println("Sensor parado");
pirState = LOW;
}
}
}
void funcion_altavoz()
{
int voz = digitalRead(busyPin);
if ( voz==LOW)
{
while(voz=LOW)
{
Serial.print("sensor dfplayer activo");
digitalWrite(LEDPin, HIGH); //LED ON
}
}
else
{
digitalWrite(LEDPin, LOW); //LED off
Serial.print("sensor dfplayer parado");
}
}
El pin busy del Dfplayer es muy ruidoso al iniciar un track, dale tiempo a que se estabilice , inicia por ejemplo la funcion_altavoz () con un delay de 500 y ya iras ajustando al valor necesario.
PD. No creo que esa función funcione tal como la tienes. pruébala de esta forma:
void funcion_altavoz() {
delay (500);
int voz = digitalRead(busyPin);
if ( voz == LOW) {
while (digitalRead(busyPin) == LOW) {
Serial.print("sensor dfplayer activo");
digitalWrite(LEDPin, HIGH); //LED ON
}
}
else {
digitalWrite(LEDPin, LOW); //LED off
Serial.print("sensor dfplayer parado");
}
}
@gonpezzi muchas gracias por el TIP. Efectivamente con ese Delay me entra en la función_altavoz(); pero se me mete ahí y se quede en ese while para siempre.
Parace que el DFPlayer de la señal LOW cuando entra en busy pero no reconozca el HIGH del apagado.
@gonpezzi tengo tracks de duración de entre 5 a 10 segundos, con nombres 0001, 0002, 0003 y 0004 y pasados esos segundos en el monitor sèrie el print me da todo el rato el mensaje del while sin salir de ahí... Deduzco que o no estoy leyendo correctamente la señal del busyport o el busyport lanza un Low pero no lanza un high cuando se para el track.
Me pillas en mal momento sin un DFPlayer a mano así que estoy dando palos de ciego. En fin...
Pero.. ¿te sigue reproduciendo los tracks?, ¿el randomizado?, ¿todos continuamente?.
Prueba esto:
void funcion_altavoz() {
delay (500);
int voz = digitalRead(busyPin);
if ( voz == LOW) {
myDFPlayer.disableLoop();
delay(1000);
while (digitalRead(busyPin) == LOW) {
Serial.print("sensor dfplayer activo");
digitalWrite(LEDPin, HIGH); //LED ON
}
}
else {
digitalWrite(LEDPin, LOW); //LED off
Serial.print("sensor dfplayer parado");
}
}
@gonpezzi ey!! mil gracias. Con tu tip me ha venido la idea de meterle la misma función en el else del loop cuando supuestamente el DFPlayer da HIGH y ya me ha funcionado. Ahora ajustando los delay un poco o incluso pasandolos a millis se va a ajustar mejor ese LED encendido para una longitud de pista de audio variable.
Dejo el código por si a alguien le ayuda:
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <DFRobotDFPlayerMini.h>
#include <SoftwareSerial.h>
//Inicia a serial por software nos pinos 10 e 11
SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
//Crear el objeto lcd dirección 0x27 y 16 columnas x 2 filas
LiquidCrystal_I2C lcd(0x27,16,2);
const unsigned long INTERVALO_TEMP = 5000UL; //TIEMPO RELE ON
const int LEDPin = 5; // pin para el LED
const int PIRPin = 2; // pin de entrada (for PIR sensor)
int busyPin = 6;
const int RELE = 3;
int pirState = LOW; // de inicio no hay movimiento
int val = 0; // estado del pin
int tcalibracion=5;
void setup()
{
// Inicializar el LCD
lcd.init();
//Encender la luz de fondo.
lcd.backlight();
//--------------------------zona dfplayer---------------
//Comunicacao serial com o modulo
mySoftwareSerial.begin(9600);
//Inicializa a serial do Arduino
Serial.begin(9600);
//Verifica se o modulo esta respondendo e se o
//cartao SD foi encontrado
Serial.println();
Serial.println(F("DFRobot DFPlayer Mini"));
Serial.println(F("Initializing DFPlayer module ... Wait!"));
if (!myDFPlayer.begin(mySoftwareSerial))
{
Serial.println(F("Not initialized:"));
Serial.println(F("1. Check the DFPlayer Mini connections"));
Serial.println(F("2. Insert an SD card"));
while (true);
}
Serial.println();
Serial.println(F("DFPlayer Mini module initialized!"));
//Definicoes iniciais
myDFPlayer.setTimeOut(500); //Timeout serial 500ms
myDFPlayer.volume(5); //Volume 5
myDFPlayer.EQ(0); //Equalizacao normal
//--------------------------zona dfplayer---------------
//-----calibración sensor PIR------------
//daremos un tiempo de calibración al sensor
Serial.print(" Calibrando sensor ");
for(int i=0; i< tcalibracion; i++){
Serial.print(".");
delay(1000);
}
Serial.println("hecho");
Serial.println("SENSOR ACTIVO");
delay(50);
//-------FIN CALIBRACIÓN-------------------
pinMode(LEDPin, OUTPUT);
pinMode(busyPin, INPUT);
pinMode(PIRPin, INPUT);
Serial.begin(9600);
myDFPlayer.pause();
delay(2000);
}
void loop()
{
unsigned long actual = millis();
val = digitalRead(PIRPin);
if (val == HIGH) //si está activado
{
Serial.println("Sensor PIR activado");
long randomNumber = random(1,5);
myDFPlayer.play(randomNumber);
funcion_altavoz();
myDFPlayer.pause();
Serial.print("gos num:");
Serial.println(randomNumber);
delay(2000);
if (pirState == LOW) //si previamente estaba apagado
{
pirState = HIGH;
}
}
else //si esta desactivado
{
// digitalWrite(LEDPin, LOW); // LED OFF
if (pirState == HIGH) //si previamente estaba encendido
{
Serial.println("Sensor PIR parado");
funcion_altavoz();
pirState = LOW;
}
}
}
void funcion_altavoz()
{
delay (500);
int voz = digitalRead(busyPin);
if ( voz == LOW)
{
myDFPlayer.disableLoop();
delay(500);
while (digitalRead(busyPin) == LOW)
{
Serial.println("sensor dfplayer activo");
delay(500);
digitalWrite(LEDPin, HIGH); //LED ON
}
}
if( voz == HIGH)
{
Serial.print("sensor dfplayer parado");
digitalWrite(LEDPin, LOW); //LED ON
}
}