Gas Fireplace Crackling Wood Sound System

I am a beginner when it comes to coding. I have worked with systems where I need to teach myself enough to get by and generally, I devote time to a self-teaching effort before I ask for help. In this case I have several hours invested and so hopefully someone knowledgeable will feel that I have suffered enough in silence and may be willing to help. :wink:

I built the Arduino nano/DFRobotDFPlayer mini centered "fireplace sound project" described here and it works as expected:

Brief description of my variation for the project . . .

I intend to have the fireplace sound system play when the gas valve opens and stop playing when the gas valve shuts down. The gas valve is energized when 1.6 VDC is applied and the "trigger voltage quickly drops to 0.3 VDC to hold the valve open. When the voltage drops to "0" the valve closes and the flame goes out.

I built the system with the intention to use the gas valve voltage change to turn the sound system on or off. My thought is that a series 10K Ohm resistor to Pin A0 set as analog input will be the interface point.

I have run into two issues:

I've been able to monitor the input to the A0 pin and it floats high when unterminated and so it will need to be pulled down. This is a lesser concern at the moment.

I have experimented with the code and I have used AI programming tools available online to attempt to generate code that I could try and then analyze, as well as searched here and elsewhere and so far . . . no joy.

Here is the latest code:

#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

SoftwareSerial mySoftwareSerial(10, 11);  // RX, TX
DFRobotDFPlayerMini myDFPlayer;

// Define the analog input pin
#define ANALOG_PIN A0

float voltage;

// Define the threshold voltage
float threshold = 0.3;

void setup() {
  
mySoftwareSerial.begin(9600);
// Initialize serial communication
Serial.begin(9600);

Serial.println();
Serial.println(F("Initializing ..."));

if (!myDFPlayer.begin(mySoftwareSerial)) {
Serial.println(F("Unable to begin: recheck the connection or insert an SD card "));
while (true);
}
Serial.println(F("DFPlayer Mini online."));

delay (1000);

// Set the volume to maximum
myDFPlayer.volume(30);

// Print a message to indicate setup is complete
Serial.println("Setup complete.");

myDFPlayer.enableLoopAll();

}

void loop() {

// Read the analog input
float analogValue = analogRead(ANALOG_PIN);
 
// Convert the sensor value to voltage
float voltage = analogValue * (5.0 / 1023.0);

//Print the voltage to serial monitor
Serial.println(voltage);

// Delay for 1000 milliseconds
delay(1000);

// Check if the voltage is greater than the threshold
if (voltage > threshold) {

//Play all continuously
myDFPlayer.play();

}else{
//Stop playing
myDFPlayer.stop();
}
}

It took me a while to realize that the "delay" in the loop equally affected the voltage monitoring and the play function. Originally it was set for 100 msec and there was no sound at all regardless of A0 input state.

Once I began to play with delay time, increasing it, I discovered that I would get no sound when A0 was low, but sound would play in snippets when A0 was high. 1 second, 10 seconds or any other delay setting provided a screen print of the polled voltage rate on A0 but also determined the maximum play time.

I.E. when delay was set to 5 seconds, voltage measurements would occur or pole every five seconds and snippets of audio would play for a duration of 5 seconds, stopping and restarting at the next pole/or voltage measurement, so long as A0 was > 0.3 VDC which was nearly continuously.

I went down the rabbit hole of trying two sequential loops after learning that Arduino nano does not support multiple loops only to discover that any delay statement effects all sub-loops and I was back to "square one."

I have exhausted a number of approaches.

Assistance will be gratefully appreciated.

Thanks in advance for any help I may receive.

Putting aside your project issues, have you sought advice regarding the implications of tapping into the gas valve control signal?

1 Like

Rest assured there is much more to the system than you report. There has to be some gas ignition system and some system to verify the gas did light or else turn off the gas. You do not want to interfere with any of those systems.

1 Like

Total nonsense! Of course it does, just like any other Arduino or any other computer.

Hi Mark,

My experience with various fora over the years is that, before joining a community, one should spend some time reading in it. One should start from a place of humility and get to know the culture of the place before diving in . . . and about the last thing one should want to do is to show laziness as in:

"Help me! I don't know anything and I'm lazy, but please solve my problems for me!"

Such folks usually don't even say "thank you," whether they are castigated or not.

I'd like to get some help with my project and I certainly know that I won't get any if I offend anyone, but especially "the regulars." Apart from that, I am not naturally rude. :wink:

So yes, Mark, I do actually know what I am doing as far as the fireplace goes.

I'll say a bit more in response to Paul, KD7HB. I am also an amateur radio operator first licensed in 1960 at the age of 11 as WV2PMC and these days I am an inactive KC2MC.

Might I suggest a non-invasive source of control will be to detect the heat from your fireplace, not the valve control.

Hello Paul_KD7HB . . .

Once upon a time we could tell which state a radio amateur radio operator hailed from by the call sign, zone 7 being Arizona, New Mexico or Nevada, if I remember correctly. :wink:

It's been a minute.

From the reading I have done in here, people are requested to keep their posts as compact or efficient as possible without putting in extraneous information. So while I do know how the fireplace works - and I have set it up myself, I did not expect that I would have to demonstrate my complete system understanding to get some help with the code for my project.

I assure you that it is perfectly safe to make a high-impedance non-blocking connection to the gas valve, made even safer by adding a 10K resister in series.

This project does not require messing about with gas. Even if an inexperienced person were to load down the supply voltage to the stepper solenoid, the worst thing that can happen is that the valve would not open an and the fireplace would not light.

By the way, there was a product sold as a DIY item once upon a time by a company called "Redfire" and the product was called "Firesong." The product was very well made and predated the Arduino. It probably used a PIC processor. The guy who made them is no longer among us. I own two of those which I installed.

May we get back on track?

Thanks,

Joe

Then you might get better response by moving the thread to programming.

PaulRB,

I actually tried to get two sequential loops to do the job, but it the result behaved similarly to the single loop approach. I then read somewhere (and please correct me if I am wrong) that any timer put in one sub-loop will also affect any other sub-loop. This seemed to be true from the testing I did as the timer in the "vmeasure" loop only allowed the audio to play in the "trigaudio" loop for the duration of the timer setting.

If an experienced person were to examine the code I used and try and help me troubleshoot where I went wrong, believe me, I will be very grateful.

I belong to several other forums from horology to British car rebuilding. We all start off as n00bs or tyros and if all goes well, we end up being the kind of people who help others one day.

Paul_KD7HB . . .

Is it possible to move this thread into the programming forum or do I just cut and paste the first post here over into the programming forum?

I do not wish to annoy anyone by going about things the wrong way.

~ Joe

I can't say why that happened because you didn't share that code.

Maybe, maybe not. It all depends on exactly what you mean by "sub-loop" and "timer".

Those "loops" (whatever you meant by that) don't appear in the code you shared, so I can't help you understand exactly what was going on there.

I think the problem with your code is that each time loop() executes, it either executes either .play() or .stop(). And .play() doesn't continue playing a track, it starts over. So change your code so that .play() and .stop() only get executed when the input signal changes from being below the threshold to above it, or vice versa.

Take a look at the "state change" code from the example menu in the IDE. You may not immediately understand the relevance of it as an example because it's about a pushbutton. Think about the principle the example is trying to illustrate.

1 Like

Moderators don't read every topic, and won't see this request. If you want them to take some action, you need to flag the post using the flag icon.

In this case, I can move the topic for you.

Starting a new topic on the same subject would be considered "cross-posting" and is against forum rules.

UPDATE: Done. The topic is now in the "programming" section. I don't think moving it will make any difference, by the way. Neither the original section or this section are inappropriate for your topic.

1 Like

That was going to be my suggestion, but I looked into it a bit and to accommodate the key difference to the instructables functionality (start and stop) you can base it off this sketch, which chatGPT wrote after I asked about 'xactly what play() does.

I'm going to @Terrypin who has learned more than there is to know about this stuff the hard way.

chatGPT code. Plausible, not tested:

#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>

SoftwareSerial mySerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;

void setup() {
  mySerial.begin(9600);
  Serial.begin(115200);

  if (!myDFPlayer.begin(mySerial)) {
    Serial.println("Unable to begin DFPlayer Mini");
    while(true);
  }

  myDFPlayer.volume(20); // Set volume (0-30)
  myDFPlayer.play(1);    // Start playing track 1
}

void loop() {
  // Just an example of how you might pause/resume
  if (someConditionToPause()) {
    myDFPlayer.pause(); // Pauses current playback
  }

  if (someConditionToResume()) {
    myDFPlayer.start(); // Resumes from where it was paused
  }
}

I don't see why your analog read shouldn't work. With pause() and start() you should not need any large delay in the loop.

chatGPT also kindly says the same as @PaulRB, only half-baked:

bool isPaused = false;

void pausePlayback() {
  myDFPlayer.pause();
  isPaused = true;
}

void resumePlayback() {
  if (isPaused) {
    myDFPlayer.start();
    isPaused = false;
  }
}

A test of isPaused could be added to pausePlayback() to fully bake it.

HTH

a7

PaulRB and A7 thank you.

I will try to execute on your suggestions and come back here with a result.

To others who posted here, I believe your heart(s) were in the right place :wink:

I was all set to put a scaled down and less chatty thread in the programming sub-forum without reference to the name of the device providing the input range to A0 as either low (0) or > 0.3VDC.

I probably should have done so in the first place, but I mistakenly thought some folks would find the entire project interesting and it never occurred to me that anyone would worry whether I blew my house up or burned it down. :wink:

A lot of people have gas fireplaces these days with bluetooth or even WiFi control and these Cracklebox products one can buy sound like toys.

I shall return.

Further edit: If I still can't make it work following the suggestions offered, I'll come back with the sequential loop code I used.

It looks like a cool project!

And it's certainly feasible.

I looked quickly at the example project and I didn't see where he got the MP3 file. I would think it should be at-least several minutes long so you don't notice the repetition. That shouldn't be a problem.

...If it was me I'd probably try to make something that generates random "snap", "crackle" and "pop", rather than playing a file. But you'd need a DAC which isn't built-into the Nano. (Of course the DFPlayer does have a DAC but it only plays from files on the SD card.)

A million years I wrote a program for my Commodore computer to generate random ocean wave sounds. The Commodore had a sound generator chip that couldn't play WAV or MP3 files but generating simple sound was easier than on a modern computer with a soundcard.

1 Like

Doug,

For testing purposes I have been using Lindsey Buckingham's "Never Going Back Again," but I am beginning to tire of it! :slight_smile:

There are some really good long crackling fire wav and mp3 files on the net and the one I have runs 11:54.

File name: aachen_burning-fireplace-crackling-fire-soundswav-14561.mp3

Here is the link:

https://pixabay.com/sound-effects/search/crackling%20fire/

Third one down.

Now I'm really going off-topic but also a million years ago (before the Commodore) I worked at a place that repaired car stereos. We only had a couple of 8-Track "test tapes" and I got sick of The Four Seasons Greatest Hits.

Doug,

Good thing you didn't change your handle to EightTrackDoug or you'd never have been able to get any pick-up lines to work!

These days STREAMINGDoug would be a good choice!!

By the way . . .

Using Pause and Play worked perfectly.

I just need to pull down A0 when no source voltage is present as the line is floating high when unterminated, but the code change works a treat.

When I have an opportunity, I'll put up some photos of the finished project in this thread if such a thing is allowable here.

Thanks again,

~ Joe

Yes.

Do you mean pause and start?

Post the code for what you have settled on when it is settled.

TIA

a7

Sorry for being imprecise. Yes, pause and start

#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

SoftwareSerial mySoftwareSerial(10, 11);  // RX, TX
DFRobotDFPlayerMini myDFPlayer;

// Define the analog input pin
#define ANALOG_PIN A0

float voltage;

// Define the threshold voltage
float threshold = 0.3;

void setup() {

  mySoftwareSerial.begin(9600);
  // Initialize serial communication
  Serial.begin(9600);

  Serial.println();
  Serial.println(F("Initializing ..."));

  if (!myDFPlayer.begin(mySoftwareSerial)) {
    Serial.println(F("Unable to begin: recheck the connection or insert an SD card "));
    while (true)
      ;
  }
  Serial.println(F("DFPlayer Mini online."));

  delay(1000);

  // Set the volume to maximum
  myDFPlayer.volume(30);

  // Print a message to indicate setup is complete
  Serial.println("Setup complete.");

  myDFPlayer.enableLoopAll();
}

void loop() {

  // Read the analog input
  float analogValue = analogRead(ANALOG_PIN);

  // Convert the sensor value to voltage
  float voltage = analogValue * (5.0 / 1023.0);

  //Print the voltage to serial monitor
  Serial.println(voltage);

  // Delay for 100 milliseconds
  delay(100);

  // Check if the voltage is greater than the threshold
  if (voltage < threshold) {

    //Pause Play if voltage < threshold
    myDFPlayer.pause();

  } else {
    //Start
    myDFPlayer.start();
  }
}


Thanks again,

~ Joe

Edit: Used Autoformat per suggestion of docdoc