Search code examples
arduinoarduino-unoarduino-ide

Arduino photoresistor (GY-30) stop reading after reach the specific value


I am trying to make a box that will play a song after opening it, using a photoresistor and a DFPlayer Mini MP3 Player. I assume that the mp3 player will play the song after the photoresistor reads the value larger or equal to 15 and stop when it's lower than 15. The problem is when it outputs the value four times (without delay), it stops reading any value, and the player will keep playing the song without any stop when the light change.

Here is my code after some changing:

#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
#include <Wire.h>
#include <BH1750.h>

SoftwareSerial mySoftwareSerial(12, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);

BH1750 lightMeter;

# define ACTIVATED LOW

void setup () {
  Serial.begin(115200);
  mySoftwareSerial.begin(9600);
  delay(300);

  Wire.begin();
  lightMeter.begin();

  Serial.println("Entry...");
  
  Serial.println();
  Serial.println(F("Initializing Player "));
  
  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);
  }
  Serial.println(F("MP3 Player online."));
  Serial.println(F("BH1750 Test"));
  
  myDFPlayer.setTimeOut(500); //Set serial communictaion time out 500ms
  
  myDFPlayer.setTimeOut(500); //Set serial communictaion time out 500ms
  
  myDFPlayer.volume(5);  //Set volume value (0~30).
  myDFPlayer.EQ(DFPLAYER_EQ_NORMAL);
  
}

void loop () { 
  float lux = lightMeter.readLightLevel();
  Serial.print("Light: ");
  Serial.print(lux);
  Serial.println(" lx");
  if (lux < 15) {
    myDFPlayer.pause();
  }
  else if (lux >= 15) {
    myDFPlayer.start();
  }
}

And here is my output:

20:28:55.589 -> Entry...
20:28:55.589 -> 
20:28:55.589 -> Initializing Player 
20:28:56.361 -> MP3 Player online.
20:28:56.361 -> BH1750 Test
20:28:56.892 -> Light: 85.83 lx
20:28:56.892 -> Light: 85.83 lx
20:28:56.924 -> Light: 85.83 lx
20:28:56.970 -> Light: 85.00 lx

It just stop outputing (I guess also stop reading). I have already open autoscroll, so it shouldn't be a problem.

I have tried changing the photoresistor to the module one and also tried using the GY-30 till now. I found that both the photoresistor and the GY-30 are working when they are used alone, but they just stop working after reading some values that are larger than 15 (they will keep reading if the values haven't reached 15). Thx for helping


Solution

  • The root cause of the problem is how you're deciding when to send a serial message to the DFPlayer. You have your code below:

    if (lux < 15) {
      myDFPlayer.pause();
    }
    else if (lux >= 15) {
      myDFPlayer.start();
    } 
    

    Which sends a message to your DFPlayer on every loop. If the lux for example is always less than 15, it will tell it to pause over and over again, even though it is already in a paused state. You're overloading the DFPlayer with messages that it can't handle.

    The exact failure mode I'm not entirely certain, but likely do to with the timeouts on the player, and the fact that you're using software serial. Or maybe the player just cannot handle that many messages without crashing.

    Regardless, the appropriate way to send the commands is to do it on a state change.

    void setup() {
      ... 
      state = 'paused'
      ...
    }
    void loop() {
      if (lux < 15) {
        new_state = 'paused'
      }
      else if (lux >= 15) {
        new_state = 'started' 
      }
      if (state == 'paused' && new_state =='started) {
        myDFPlayer.start();
      }
      else if (state == 'started' && new_state =='paused) {
        myDFPlayer.pause();
      }
      state = new_state
    }