Why do I need to physically reset this before it works normally

This is a simple Nano project that compares the weights of two load cells. Based on the difference, it lights up an LED and plays audio using the DFPlayer. The schematic works, but only if I manually reset it after a power cycle. Why is this manual reset needed?

RexGame-revC.pdf (156.8 KB)

Maybe posting your code too would help?

@electrophile

Why is this manual reset needed?

It may take a few seconds for those two 100uF capacitors to fully discharge.
How long is your "power cycle"?

Fit a capacitor, say 100nF, between the Nano reset pin and GND.
This will hold the reset pin low at power on, until the capacitor charges up through R2 plus the resistor in the Nano.

When I power the project through a 5V DC adapter, the code plays a small chime through the DFPlayer before moving to the endless loop. This takes about 4-5 seconds. I added the two 100uF caps to 'stabilise' the DC adapter source. I can remove them if they are not needed.

Will try this. Thanks.

You can keep them but how long is this "power cycle" you mention?

About 5 seconds.

If the 5V power does not drop close to zero, the 328 internal reset circuit won't reset.
Does it work OK if you wait 15 seconds?

I have not tried this but the weight measurements are glitchy until I manually reset it.

That sounds like a completely different problem and may also be software related.
I see nothing in your schematic relating to weighing devices.

Thats because they are connected to an HX711 breakout boards via the SCKx and DATAx pins. Also the volume on the DFPlayer on startup is really loud, as if the initial startup volume of 10 is never really read. Once I manually reset it, the volume is at the level of what I need it to be.

Well, your software may be trying to communicate with all the things connected to the Nano before they are ready or powered up.
Do you first reset everything and check to see if they are ready?

Yes.

Then it seems very odd.
However since you did not list your code, I don't think I can be of any further help.

Thank you for trying to debug this with me.

Your are welcome.
If you want further help you will need to post your code.
In the IDE click on File, then on Copy for Forum. Then come back here and just do a paste.

Here is the code:

#include "HX711.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

// #define SERIAL_BAUD 9600
#define SOFTWARE_SERIAL_BAUD 9600
#define MIN_WT 70
#define MAX_WT 130
#define BUSY LOW

// pin definitions
const uint8_t dataPin1 = 3;
const uint8_t clockPin1 = 2;
const uint8_t dataPin2 = 11;
const uint8_t clockPin2 = 10;

const uint8_t green2 = A0;
const uint8_t blue2 = A1;
const uint8_t red2 = A2;
const uint8_t green1 = A3;
const uint8_t blue1 = A4;
const uint8_t red1 = A5;
const uint8_t volumePin = A6;

const uint8_t busyPin = 9;

const uint8_t softSerialRX = 13;
const uint8_t softSerialTX = 12;

// variables.
bool measureComplete;

int wt1;
int wt2;
int prev_wt1 = 0;
int prev_wt2 = 0;

// Define colors as hex values
const uint32_t red = 0xFF0000;
const uint32_t green = 0x00FF00;
const uint32_t blue = 0x0000FF;
const uint32_t cyan = 0x00FFFF;       //Green and Blue at full brightness
const uint32_t magenta = 0xFF00FF;    //Red and Blue at full brightness
const uint32_t lightBlue = 0x4CCCFF;  //Red at around 30 percent of brightness, green up high at 80 percent, and blue at full brightness
const uint32_t purple = 0xFF99FF;     //Red and blue are all the way up, with green at 60 percent
const uint32_t white = 0xFFFFFF;      //All colors at full brightness
const uint32_t off = 0x000000;

// scale constants.
const float calibrationCell1 = 432.997039;
const float calibrationCell2 = 421.606750;
const long offsetCell1 = 4294948297;
const long offsetCell2 = 4294445015;

// instance definitions.
HX711 scale1;
HX711 scale2;
SoftwareSerial mySoftwareSerial(softSerialRX, softSerialTX);
DFRobotDFPlayerMini myDFPlayer;

// Function to set the color of the RGB LED
void setColor(uint32_t color) {
  // splitting the 32-bit value into individual 8-bit values using bit-shifting.
  uint8_t redValue = (color >> 16) & 0xFF;
  uint8_t greenValue = (color >> 8) & 0xFF;
  uint8_t blueValue = color & 0xFF;

  // turning on the LEDs with the appropriate colors.
  analogWrite(red1, redValue);
  analogWrite(red2, redValue);
  analogWrite(green1, greenValue);
  analogWrite(green2, greenValue);
  analogWrite(blue1, blueValue);
  analogWrite(blue2, blueValue);
}

// Play DFR audio
void playAudio(uint8_t fileNumber) {
  // play from the MP3 folder as the root sometimes has hidden files with the same numbers and in a weird format.
  myDFPlayer.playMp3Folder(fileNumber);
  // the following two loops eliminate the use of a delay.
  while (digitalRead(busyPin) != BUSY) {
    ;  // // This loop waits for the DFR player to get BUSY.
  }
  while (digitalRead(busyPin) == BUSY) {
    ;  // This loop executes while the DFR BUSY pin is LOW indicating playback in progress.
  }
}

void setup() {
  // begin software serial.
  mySoftwareSerial.begin(SOFTWARE_SERIAL_BAUD);

  // init pin modes
  pinMode(red1, OUTPUT);
  pinMode(green1, OUTPUT);
  pinMode(blue1, OUTPUT);
  pinMode(red2, OUTPUT);
  pinMode(green2, OUTPUT);
  pinMode(blue2, OUTPUT);

  // set the busyPin that monitors the DFPlayer as an input.
  pinMode(busyPin, INPUT);

  // init the scales.
  scale1.begin(dataPin1, clockPin1);
  scale2.begin(dataPin2, clockPin2);

  // set scale offsets and calibration constants.
  scale1.set_offset(offsetCell1);
  scale1.set_scale(calibrationCell1);
  scale2.set_offset(offsetCell2);
  scale2.set_scale(calibrationCell2);

  // reset the scale to zero = 0
  scale1.tare(20);
  scale2.tare(20);

  // Initialize the DFPlayer Mini
  if (!myDFPlayer.begin(mySoftwareSerial)) {
    while (true) {
      ;
    }
  }
  // set volume to 20. max is 30.
  myDFPlayer.volume(20);
  // small delay to let the volume function complete properly.
  delay(250);
  // set the eyes to light blue.
  setColor(lightBlue);
  // play a small startup chime to indicate init complete.
  playAudio(1);
}

void loop() {
  // set the standby color to blue
  setColor(lightBlue);
  // check if the scales are ready for measurement
  if (scale1.is_ready() && scale2.is_ready()) {
    // get the values and convert them to positive values.
    // values are type-casted to int values.
    wt1 = int(scale1.get_units(10));
    wt1 = abs(wt1);
    wt2 = int(scale2.get_units(10));
    wt2 = abs(wt2);

    // if the weights are less or more than the min and max weights, make them zero.
    // this eliminates the weird measurements that the scale shows when there are no weights present.
    if ((wt1 > MAX_WT) || (wt1 < MIN_WT)) {
      wt1 = 0;
    }

    if ((wt2 > MAX_WT) || (wt2 < MIN_WT)) {
      wt2 = 0;
    }

    // the scale takes a little while to completely measure the values, but the arduino is
    // faster than the scale ADC and hence it sometimes misses the true values.
    // by using another var called prev_wtx we can determine when the measurement is complete.
    int wt1_curr_prev_diff = wt1 - prev_wt1;
    int wt2_curr_prev_diff = wt2 - prev_wt2;

    // when the difference between the current and previous values is zero,
    // then measurement is complete.
    if (wt1_curr_prev_diff == 0 && wt2_curr_prev_diff == 0) {
      measureComplete = true;
    } else {
      measureComplete = false;
    }

    if (measureComplete) {
      // calculate the weight difference and convert to a positive value.
      int wt_diff = wt2 - wt1;
      wt_diff = abs(wt_diff);
      // if the weights are within bounds, and between zero and the set maximum weight difference,
      // then turn the leds to a set color and play audio.
      if ((wt1 > 0) && (wt2 > 0) && (wt_diff > 3) && (wt_diff < 10)) {
        setColor(green);
        playAudio(2);
      } else if ((wt1 > 0) && (wt2 > 0) && (wt_diff > 10) && (wt_diff < 15)) {
        setColor(blue);
        playAudio(3);
      } else if ((wt1 > 0) && (wt2 > 0) && (wt_diff > 15) && (wt_diff < 21)) {
        setColor(purple);
        playAudio(4);
      } else if ((wt1 > 0) && (wt2 > 0) && (wt_diff > 21) && (wt_diff < 27)) {
        setColor(magenta);
        playAudio(5);
      }
    }
  }
  prev_wt1 = wt1;
  prev_wt2 = wt2;
}

// -- END OF FILE --

If you tried @JohnLincoln suggestion and you still have problems, all I can suggest at this point is to add a delay at the beginning of setup to give things time to power-up.

Thanks. It was not a problem per se since everything worked ok after the manual reset, but if I'd forget to do that reset then it slowly fell apart.