Go Down

Topic: triggering sound and led in response to LDR (Read 274 times) previous topic - next topic

pranghead

Hey guys, so this is a millis question.

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.

Code: [Select]
#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.

DKWatson

while(true);
You'll never get past this!
Live as if you were to die tomorrow. Learn as if you were to live forever. - Mahatma Gandhi

DKWatson

This whole block is confusing
Code: [Select]
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
}
Live as if you were to die tomorrow. Learn as if you were to live forever. - Mahatma Gandhi

pranghead

while(true);
You'll never get past this!
what do you mean? Sorry Im a bit confused with what your referring too.

That is just the inbuilt code for the mp3 module i'm using, it came with the library so not directly involved with the main body of the code.

florinc

#4
Nov 07, 2018, 06:10 pm Last Edit: Nov 07, 2018, 06:10 pm by florinc
Code: [Select]
if (millis() >= 800)
{
  digitalWrite(5,HIGH);
  myDFPlayer.play (3);
}
else
{
 digitalWrite (5 , LOW); 
}


millis() will be always greater than 800 after 800 milli seconds you powered your arduino.

DKWatson

'true' is a defined boolean equal (numerically) to one. while(true); is an infinite loop. Normally when used, it would be like this;
Code: [Select]
bool a = true;
while(a == true)
{
  do something here
  make a test here - if(something else) a = false;
}

The way that code is written, once you enter the if (!myDFPlayer.begin(mySoftwareSerial)) test, you'll never get out without a hard reset.
Live as if you were to die tomorrow. Learn as if you were to live forever. - Mahatma Gandhi

bidouilleelec

what do you mean? Sorry Im a bit confused with what your referring too.

That is just the inbuilt code for the mp3 module i'm using, it came with the library so not directly involved with the main body of the code.
while(true); is an infinte loop.

florinc

#7
Nov 07, 2018, 06:21 pm Last Edit: Nov 07, 2018, 06:22 pm by florinc
Code: [Select]
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.

pranghead

'true' is a defined boolean equal (numerically) to one. while(true); is an infinite loop. Normally when used, it would be like this;
Code: [Select]
bool a = true;
while(a == true)
{
  do something here
  make a test here - if(something else) a = false;
}

The way that code is written, once you enter the if (!myDFPlayer.begin(mySoftwareSerial)) test, you'll never get out without a hard reset.
This bit of code has worked in previous projects so I dont think its the issue

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
Code: [Select]
if((mills() - startOnLDR) >= 3000)
and implement code to stop whatever you were doing. The test will repeatedly fail until 3000ms (or more) has elapsed.
Live as if you were to die tomorrow. Learn as if you were to live forever. - Mahatma Gandhi

DKWatson

This bit of code has worked in previous projects so I dont think its the issue
Likely not as it would only be an issue if the SD card was not inserted/connected. Still, it's bad code unless that is its purpose.
Live as if you were to die tomorrow. Learn as if you were to live forever. - Mahatma Gandhi

pranghead

#11
Nov 07, 2018, 06:34 pm Last Edit: Nov 07, 2018, 06:35 pm by pranghead
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
Code: [Select]
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...

Code: [Select]
b=analogRead(A5);
b=b*5/1023;

if(b>=2.0&&b<=2.3)[code]


outsider

The purpose of that code block is:
If "myDFPlayer.begin" fails, then stop the whole show.

DKWatson

Sort of except analogRead returns an integer and your comparing floats, try
Code: [Select]
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.
Live as if you were to die tomorrow. Learn as if you were to live forever. - Mahatma Gandhi

gfvalvo

#14
Nov 07, 2018, 08:58 pm Last Edit: Nov 07, 2018, 09:05 pm by gfvalvo
Sort of except analogRead returns an integer and your comparing floats, try
Code: [Select]
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.
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.

Go Up