I've run through the great tutorials on here but am still struggling to get my code to work. I'm basically trying to use an LDR as an on off switch effectively so that when it reads over 800 on the serial monitor, it triggers an LED and plays the full length of an MP3 I have loaded on the DFmini player module.
I currently do trigger the LED and sound but it runs in one continuous loop from reset and im not sure why.
I'm not sure currently how to set an amount of time to allow the mp3 to play without using delay, i need to to play for roughly 3 seconds.
#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
float b;
const int ledPin = 3;
const int ledpingreen = 5;
const int switchpin = 6;
const int LDR = A5;
int LDRValue = 0; // variable to store the value coming from the sensor
int prev_LDRValue = 0; // variable to store the previous state of the sensor
long startOnLDR = 0; // The Last time that input was recieved
//mp3 stuff
SoftwareSerial mySoftwareSerial(10, 11); // RX, TX //
DFRobotDFPlayerMini myDFPlayer; //
void printDetail(uint8_t type, int value); //
void setup()
{
mySoftwareSerial.begin(9600); //
Serial.begin(115200); //
Serial.println(); //
Serial.println(F("DFRobot DFPlayer Mini Demo"));
Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)")); //
if (!myDFPlayer.begin(mySoftwareSerial)) { //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); //
}
{
// put your setup code here, to run once:
Serial.begin(9600);
pinMode (ledPin, OUTPUT); //red LED
pinMode (ledpingreen, OUTPUT); //green LED
}
Serial.println(F("DFPlayer Mini online."));
myDFPlayer.setTimeOut(8000); //Set serial communictaion time out 500ms
//----Set volume----
myDFPlayer.volume(20); //Set volume value (0~30).
//----Set different EQ----
myDFPlayer.EQ(DFPLAYER_EQ_NORMAL);
myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD);
//----Read imformation----
Serial.println(myDFPlayer.readState()); //read mp3 state
Serial.println(myDFPlayer.readVolume()); //read current volume
Serial.println(myDFPlayer.readEQ()); //read EQ setting
Serial.println(myDFPlayer.readFileCounts()); //read all file counts in SD card
Serial.println(myDFPlayer.readCurrentFileNumber()); //read current play file number
Serial.println(myDFPlayer.readFileCountsInFolder(3)); //read file counts in folder SD:/03
}
void loop(){
LDRValue = analogRead(LDR); // read the value from the sensor
Serial.println(LDRValue); //prints the values coming from the sensor on the screen
if (prev_LDRValue<=800 && LDRValue>800){// New Code to start Timing
startOnLDR=millis();// Start the Timer
prev_LDRValue=LDRValue;
}
if (millis()>=800){
digitalWrite(5,HIGH);
myDFPlayer.play (3);
}else{
digitalWrite (5 , LOW);
}
}
any help would be greatly appreciated. Just a nudge in the right direction would be top.
if (!myDFPlayer.begin(mySoftwareSerial))
{ //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); //
}
{
// put your setup code here, to run once:
Serial.begin(9600);
pinMode (ledPin, OUTPUT); //red LED
pinMode (ledpingreen, OUTPUT); //green LED
}
if (!myDFPlayer.begin(mySoftwareSerial))
{ //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); //
}
I think the whole idea of this piece of code is to prevent further execution until communication with DFPlayer is established.
Anyhow, back to your timing issue, you start the timer by setting startOnLDR=millis(); and then never test it against the elapsing time. If you want to run for three seconds (=3000ms) then test
if((mills() - startOnLDR) >= 3000)
and implement code to stop whatever you were doing. The test will repeatedly fail until 3000ms (or more) has elapsed.
DKWatson:
Anyhow, back to your timing issue, you start the timer by setting startOnLDR=millis(); and then never test it against the elapsing time. If you want to run for three seconds (=3000ms) then test
if((mills() - startOnLDR) >= 3000)
and implement code to stop whatever you were doing. The test will repeatedly fail until 3000ms (or more) has elapsed.
ok cool, i understand that i think. I need to only trigger this in relation to the analogue read im gathering from the LDR, do I just put that in as something like this...
Sort of except analogRead returns an integer and your comparing floats, try
b = analogRead(A5);
float c = (float)b * 5 / 1023;
if((c >= 2.0) && (c <= 2.3));
It's important to cast at least one R value as a float in the calculation. When the compiler performs its math it will use register(s) or stack sufficient enough only to accommodate the largest type on the right hand side of the equation. If you simply went float c = b * 5 / 1023, everything on the right hand side is still an integer so the result will be an integer, regardless of the type of the L value.
It's important to cast at least one R value as a float in the calculation. When the compiler performs its math it will use register(s) or stack sufficient enough only to accommodate the largest type on the right hand side of the equation. If you simply went float c = b * 5 / 1023, everything on the right hand side is still an integer so the result will be an integer, regardless of the type of the L value.
Why bother scaling the output of the analogRead() into a range of float values just to test if it's within some limits? Instead, just scale the limits of your comparison to work with the (0-1023) range produced by analogRead(). That's a static operation that can be done once at compile-time, much better than a run-time operation that's computed for EVERY comparison.
gfvalvo:
Why bother scaling the output of the analogRead() into a range of float values just to test if it's within some limits? Instead, just scale the limits of your comparison to work with the (0-1023) range produced by analogRead(). That's a static operation that can be done once at compile-time, much better than a run-time operation that's computed for EVERY comparison.
That IS its purpose, but it would be far better to include a comment in the code that says that.
if(!myDFPlayer.begin(mySyupidNameForASoftwareSerialInstance))
{
// Useless comments on the ends of these line removed. Some people...
Serial.println(F("Unable to begin:"));
Serial.println(F("1.Please recheck the connection!"));
Serial.println(F("2.Please insert the SD card!"));
// Do nothing until the wiring problem is fixed or an SD card is inserted
while(true);
}
so... Im still struggling with this. really struggling to understand how to use millis to get an mp3 file to play once and then wait for further input, such as the LDR picking up a change in light, to carry on and carry out another procedure. How do you get something to rely on one thing finishing to start another???
#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
float b;
const int ledPin = 3;
const int ledpingreen = 5;
const int switchpin = 6;
const int LDR = A5;
int LDRValue = 0; // variable to store the value coming from the sensor
int prev_LDRValue = 0; // variable to store the previous state of the sensor
long startOnLDR = 0; // The Last time that input was recieved
unsigned long currentMillis = 0; // stores the value of millis() in each iteration of loop()
const long interval = 1000;
//mp3 stuff
SoftwareSerial mySoftwareSerial(10, 11); // RX, TX //
DFRobotDFPlayerMini myDFPlayer; //
void printDetail(uint8_t type, int value); //
void setup()
{
mySoftwareSerial.begin(9600); //
Serial.begin(115200); //
Serial.println(); //
Serial.println(F("DFRobot DFPlayer Mini Demo"));
Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)")); //
if (!myDFPlayer.begin(mySoftwareSerial)) { //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); //
}
{
// put your setup code here, to run once:
Serial.begin(9600);
pinMode (ledPin, OUTPUT); //red LED
pinMode (ledpingreen, OUTPUT); //green LED
}
Serial.println(F("DFPlayer Mini online."));
myDFPlayer.setTimeOut(8000); //Set serial communictaion time out 500ms
//----Set volume----
myDFPlayer.volume(20); //Set volume value (0~30).
//----Set different EQ----
myDFPlayer.EQ(DFPLAYER_EQ_NORMAL);
myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD);
//----Read imformation----
Serial.println(myDFPlayer.readState()); //read mp3 state
Serial.println(myDFPlayer.readVolume()); //read current volume
Serial.println(myDFPlayer.readEQ()); //read EQ setting
Serial.println(myDFPlayer.readFileCounts()); //read all file counts in SD card
Serial.println(myDFPlayer.readCurrentFileNumber()); //read current play file number
Serial.println(myDFPlayer.readFileCountsInFolder(3)); //read file counts in folder SD:/03
}
void loop(){
currentMillis = millis();
b=analogRead(A5);
b=b*5/1023;
Serial.println(b); //prints the values coming from the sensor on the screen
if(b>=4.0&&b<=5.00)
{digitalWrite(5,HIGH);
myDFPlayer.play (1);
delay (500);
}
else{
digitalWrite (5 , LOW);
digitalWrite (3, HIGH);
}
while(digitalRead(3) == HIGH)
{ myDFPlayer.play (3);
delay (100); }
}
currently the mp3's just play in a loop. I want to trigger a second mp3 to play once when the LDR is uncovered and then when then wait for the LDR to be covered again to reset. Any help would be greatly appreciated
I want to trigger a second mp3 to play once when the LDR is uncovered and then when then wait for the LDR to be covered again to reset.
You need to look at the state change detection example. While that specifically refers to digital state changes associated with switches (from pressed to released or from released to pressed), it doesn't take much imagination to extend it to analog values - the value is above the threshold this time but was not last time or the value is below the threshold this time but was not the last time or the value.
You want to trigger the player ONLY when the state changes. As it is now, you are trigger the player when the value IS above the threshold or IS below the threshold, rather than when the values GOES ABOVE or GOES BELOW the threshold.
PaulS:
You need to look at the state change detection example. While that specifically refers to digital state changes associated with switches (from pressed to released or from released to pressed), it doesn't take much imagination to extend it to analog values - the value is above the threshold this time but was not last time or the value is below the threshold this time but was not the last time or the value.
You want to trigger the player ONLY when the state changes. As it is now, you are trigger the player when the value IS above the threshold or IS below the threshold, rather than when the values GOES ABOVE or GOES BELOW the threshold.
thanks paul thats a really good insight, ill have a look at that now and try and wrap my skull around it