Embedded device with Hardware issues consisting atmega 328p, RFM96 and ADXL345

I have a device that works on 3V battery (2 D size cells) now I want to debug it so that all the devices work correctly. My device consist of atmega 328p, running on 08 MHz Crystal which gets readings from ADXL345 for 2 seconds and then store it in 25Q64FVSIG flash memory and then RFM96 checks if server is available if yes then send the current timestamp, the data stored in flash and current battery otherwise goes to deep sleep mode. There are two 22 pF, one 100uF25V and one 104 pF (to power up radio) capacitors and 10k resistor. This device is enclose in a hard plastic box and then water packed so that not even air goes in or out of that box.

Now the main issue is that most of devices lose battery faster and die after a week or two ,but then one or two keeps on going for 2 to 3 months, yet same code is uploaded in all of them. I'm attaching reference picture of my device circuit and let me know if you need anything else.

I have tried to debug through checking the voltage and current drop across various components yet got the same values for every device as compare to the perfect one. I have not checked the capacitance of capacitors let me know if that can be crucial as well.

// Cow Health Monitoring Node
// Author: Muhammad Umar
// Date: 16th September 2019
// Version 1.0

#include <Arduino.h>
#include <LowPower.h>
#include <SPI.h>
#include <TimeLib.h>
#include <RHReliableDatagram.h>
#include <RH_RF95.h>
#include <Wire.h>
#include <ADXL345.h>
#include <SPIFlash.h>
#include <EEPROM.h>

#define DEBUGGING false
#define SLEEP false

#define FLASH_CS 8

#define SERVER_ADDRESS 1
#define SAFE_RSSI_VALUE -85
#define RADIO_PWR 14

#define CLIENT_ADDRESS 102
#define X_OFFSET 0
#define Y_OFFSET 0
#define Z_OFFSET 0
#define DATA_RATE 12.5
#define ACCEL_RANGE 2

ADXL345 adxl;
SPIFlash flash(FLASH_CS);
RH_RF95 driver;
RHReliableDatagram manager(driver, CLIENT_ADDRESS);

const int gatherValuesDuration = 2;  // 4 collections @ 12.5 Hz - 1 run = 2 second values
const int sleepingStateDuration = 30; // sleep for 32 seconds 8*8
// const int sleepingStateDuration = 1;
// const int sleepingStateDuration = 2;
const long InternalReferenceVoltage = 1062;

// bool firstBoot = true;
int initialSleepDuration = 0;
bool getValues = true;
bool getTime = true;
bool sendValues;
bool radioAvailable = false;
int timesValuesCollected = 0;
long currentFlashLoc = 0;
long dumpCounter = 0;
int noOfReadingsInTransmission = 0;

/**
 * On board devices setup
 * Radio
 * Flash
 * Accelerometer
 * **/

void radioSetup()
{
  if (!manager.init())
  {
#if DEBUGGING
    Serial.println("Radio init failed");
#endif
  }
  // 13 for ubmilk farm
  driver.setTxPower(RADIO_PWR, false);
  manager.setRetries(2);
  driver.sleep();
#if DEBUGGING
  Serial.println("Radio Setup Complete");
#endif
}

void adxlSetup()
{
  adxl.powerOn();

  // look of activity movement on this axes - 1 == on; 0 == off
  adxl.setActivityX(1);
  adxl.setActivityY(1);
  adxl.setActivityZ(1);

  // setting all interrupts to take place on int pin 1
  // I had issues with int pin 2, was unable to reset it
  adxl.setInterruptMapping(ADXL345_INT_DATA_READY_BIT, ADXL345_INT1_PIN);
  adxl.setInterruptMapping(ADXL345_INT_SINGLE_TAP_BIT, ADXL345_INT1_PIN);
  adxl.setInterruptMapping(ADXL345_INT_DOUBLE_TAP_BIT, ADXL345_INT1_PIN);
  adxl.setInterruptMapping(ADXL345_INT_FREE_FALL_BIT, ADXL345_INT1_PIN);
  adxl.setInterruptMapping(ADXL345_INT_ACTIVITY_BIT, ADXL345_INT1_PIN);
  adxl.setInterruptMapping(ADXL345_INT_INACTIVITY_BIT, ADXL345_INT1_PIN);
  adxl.setInterruptMapping(ADXL345_INT_WATERMARK_BIT, ADXL345_INT1_PIN);

  // register interrupt actions - 1 == on; 0 == off
  adxl.setInterrupt(ADXL345_INT_DATA_READY_BIT, 1);
  adxl.setInterrupt(ADXL345_INT_SINGLE_TAP_BIT, 0);
  adxl.setInterrupt(ADXL345_INT_DOUBLE_TAP_BIT, 0);
  adxl.setInterrupt(ADXL345_INT_FREE_FALL_BIT, 0);
  adxl.setInterrupt(ADXL345_INT_ACTIVITY_BIT, 0);
  adxl.setInterrupt(ADXL345_INT_INACTIVITY_BIT, 0);
  adxl.setInterrupt(ADXL345_INT_WATERMARK_BIT, 1);

  // setting lowest sampling rate
  adxl.setAxisOffset(X_OFFSET, Y_OFFSET, Z_OFFSET);
  adxl.setRangeSetting(ACCEL_RANGE);
  adxl.setRate(DATA_RATE);
  // setting device into FIFO mode
  adxl.setMode(ADXL345_MODE_FIFO);
  // set watermark for Watermark interrupt
  adxl.setWatermark(25);
  adxl.setLowPower(0);
#if DEBUGGING

  Serial.println("ADXL Setup Complete");
#endif
}

void flashSetup()
{
  if (flash.initialize())
  {
    flash.chipErase();
    while (!flash.busy())
    {
      // wait for flash to fully erase
    }
  }
  else
  {
#if DEBUGGING
    Serial.println("Flash Setup Failed");
#endif
  }
#if DEBUGGING
  Serial.println("Flash Setup Complete");
#endif
}

// results are Vcc * 100
// So for example, 5V would be 500.
int getBandgap()
{
  // REFS0 : Selects AVcc external reference
  // MUX3 MUX2 MUX1 : Selects 1.1V (VBG)
  ADMUX = bit(REFS0) | bit(MUX3) | bit(MUX2) | bit(MUX1);
  ADCSRA |= bit(ADSC); // start conversion
  while (ADCSRA & bit(ADSC))
  {
  } // wait for conversion to complete
  int results = (((InternalReferenceVoltage * 1024) / ADC) + 5) / 10;
  return results;
} // end of getBandgap

void updateTime()
{
  uint8_t buf[11];
  uint8_t len = sizeof(buf);
  uint8_t from;
  char target[10];
  if (manager.recvfromAckTimeout(buf, &len, 2000, &from))
  {
    strncpy(target, (char *)buf, 10);
    target[10] = '\0';
#if DEBUGGING
    Serial.print("Time Received: ");
    Serial.println(target);
#endif
    setTime(atol(target));
    driver.sleep();
  }
  delay(50);
}

void updateTimeWithTimePacket()
{
  // updating time from the server
  char timePacket[8];
  sprintf(timePacket, "%d,time\n", CLIENT_ADDRESS);
#if DEBUGGING
  Serial.print("Requesting Time: ");
  for (int i = 0; i < 7; i++)
  {
    Serial.print(timePacket[i]);
  }
  Serial.println();
#endif
  manager.sendtoWait((uint8_t *)timePacket, strlen(timePacket), SERVER_ADDRESS);
  updateTime();
  getTime = false;
}

void sendData()
{
  Serial.println("Yo Boy send the data");
  int packetsCount = 0;
  int noOfLines = 0;
  char packetBuff[120] = "";
  int charNo = strlen(packetBuff) - 1;
  while (dumpCounter < currentFlashLoc)
  {
    char value = (char)flash.readByte(dumpCounter++);
    charNo++;
    packetBuff[charNo] = value;
    if (value == '/')
    {
      noOfLines++;
      if (noOfLines == 7)
      {
        packetsCount++;
        packetBuff[charNo + 1] = '\n';
#ifdef DEBUGGING
        Serial.print("Send Packet: ");
        Serial.print(packetBuff);
#endif
        manager.sendtoWait((uint8_t *)packetBuff, strlen(packetBuff), SERVER_ADDRESS);
        memset(packetBuff, 0, sizeof(packetBuff));
        int count = (packetsCount == 0) ? 1 : (log10(packetsCount) + 1);
        sprintf(packetBuff, "%d?", packetsCount);
        noOfLines = 0;
        charNo = count;
        while ((currentFlashLoc - dumpCounter) < 54)
        {
          // we are nearing the end of transmission
          // handle the last packet
          char value = (char)flash.readByte(dumpCounter++);
          charNo++;
          packetBuff[charNo] = value;
          if ((dumpCounter - currentFlashLoc) == 0)
          {
            packetsCount++;
            packetBuff[charNo + 1] = '\n';
#if DEBUGGING
            Serial.print("LastPacket: ");
            Serial.println(packetBuff);
#endif
            manager.sendtoWait((uint8_t *)packetBuff, strlen(packetBuff), SERVER_ADDRESS);
            memset(packetBuff, 0, sizeof(packetBuff)); // empty packetBuff
            break;
          }
        }
      }
    }
  }
  char timeInfo[10] = "";
  ultoa(now(), timeInfo, 10);
  char eotPacket[21];
  //  sprintf(eotPacket, "eot %d\n", packetsCount);
  //  sprintf(eotPacket, "%d:eot %d\n", CLIENT_ADDRESS, packetsCount);
  int batteryVoltage = getBandgap();
#if DEBUGGING
  Serial.print("Battery Voltage: ");
  Serial.println(batteryVoltage);
  Serial.print("Current Flash Loc: ");
  Serial.println(currentFlashLoc);
#endif
  sprintf(eotPacket, "eot:%s packs:%d vals:%d batt:%d flash:%li\n", timeInfo, packetsCount, noOfReadingsInTransmission, batteryVoltage, currentFlashLoc);
#if DEBUGGING
  Serial.print(eotPacket);
#endif
  manager.sendtoWait((uint8_t *)eotPacket, strlen(eotPacket), SERVER_ADDRESS);
  memset(eotPacket, '\0', sizeof(eotPacket));
  noOfReadingsInTransmission = 0;
  updateTime();
}

int lenHelper(unsigned x)
{
  if (x >= 100)
    return 3;
  if (x >= 10)
    return 2;
  return 1;
}

int readingLen(int x)
{
  return x < 0 ? lenHelper(-x) + 1 : lenHelper(x);
}

void getAccelValues()
{
  int x[25], y[25], z[25];
  byte fifoentries, intEvent;
  fifoentries = adxl.getFifoEntries();
  intEvent = adxl.getInterruptSource();            // reading interrupt status flags
  if (adxl.triggered(intEvent, ADXL345_WATERMARK)) // if watermark interrupt occured
  {
#if DEBUGGING
    Serial.println("Watermark interrupt triggered. Fetching data now.");
#endif
    if (fifoentries != 0)
    {
      // burst read will cause the fifo to empty
      adxl.burstReadXYZ(&x[0], &y[0], &z[0], fifoentries);
#if DEBUGGING
      Serial.print("FIFO Entries: ");
      Serial.println(fifoentries);
#endif
      for (int i = 0; i < 25; i++)
      {
        char buf[16] = "";
        sprintf(buf, "%d,%d,%d/", x[i],y[i],z[i]);
#if DEBUGGING

        Serial.print("Writing to Flash: ");
        Serial.println(buf);
#endif
        flash.writeBytes(currentFlashLoc, buf, strlen(buf));
        currentFlashLoc += strlen(buf);
        noOfReadingsInTransmission++;
      }
    }
  }
}

int checkRSSI()
{
  int availableServer = 1;
  char freePacket[6] = "";
  sprintf(freePacket, "free\n");
#if DEBUGGING
  Serial.println("Checking RSSI");
#endif
  manager.sendtoWait((uint8_t *)freePacket, strlen(freePacket), SERVER_ADDRESS);
  uint8_t buf[5];
  uint8_t len = sizeof(buf);
  uint8_t from;
  char target[3] = "";
  if (manager.recvfromAckTimeout(buf, &len, 2000, &from))
  {
#if DEBUGGING
    Serial.println((char *)buf);
#endif
    strncpy(target, (char *)buf, 3);
    target[3] = '\0';
    if (strcmp(target, "yes") == 0)
    {
#if DEBUGGING
      Serial.println("You have permission to transmit");
#endif
      radioAvailable = true;
    }
  }
  delay(50);
  return availableServer;
}

void sendDataRoutine()
{
  checkRSSI();

  if (radioAvailable)
  {
    sendData();
  }
  else{
      #if DEBUGGING
  Serial.println("no radio access bro");
#endif
  }
  radioAvailable = false;
  sendValues = false;
  driver.sleep();
}

void accelerometerRoutine()
{
  /***
     1. wake up the accelerometer
     2. start running the fifo and taking measurements
     3. put arduino to sleep for 2s following points will be carried out by getAccelValues()
     4. burst read the fifo after watermark interrupt
     5. save the readings in flash
  */
#if DEBUGGING
  Serial.println("Run Accelerometer Routine");
#endif
  adxl.setMode(ADXL345_MODE_BYPASS);
  delay(80);
  adxl.setMode(ADXL345_MODE_FIFO);
  LowPower.powerDown(SLEEP_2S, ADC_ON, BOD_ON);
  LowPower.powerDown(SLEEP_15MS, ADC_ON, BOD_ON);
  // adjustTime(2.5);
  adjustTime(2.15);
  getAccelValues();
  timesValuesCollected++;
}

void writeTime()
{
  char timeInfo[11] = "";
  ultoa(now(), timeInfo, 10);
#if DEBUGGING
  Serial.print("Current Time: ");
  Serial.println(timeInfo);
#endif
  int writtenBytes = 0;
  for (int i = 0; timeInfo[i] != '\0'; i++)
  {
    writtenBytes++;
  }
  flash.writeBytes(currentFlashLoc, timeInfo, writtenBytes);
  currentFlashLoc += writtenBytes;
  flash.writeByte(currentFlashLoc, '/');
  currentFlashLoc += 1;
}

void setup()
{
  // put your setup code here, to run once:
#if DEBUGGING
  Serial.begin(115200);
  Serial.println("Initializing...");
#endif

#if SLEEP
  Serial.println("Going to Sleep Forever");
  delay(1000);
  LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
#endif

  // turn off everything except the radio
  // and get time from the rpi server
  // maybe store this value in the flash?
  // e.g. on the last 10 bytes of the flash
  radioSetup();
  flashSetup();
  adxlSetup();

  // getTime = true;
  //  setTime(1576412345);
}

void loop()
{
  int eprom_value = EEPROM.read(0);
  if (eprom_value == 1)
  {
    for (int i = 0; i < initialSleepDuration; i++)
    {
      #if DEBUGGING
  Serial.println("Im in long sleep boi");
#endif
      LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
      if (i == initialSleepDuration - 1)
      {
        EEPROM.write(0, 0);
      }
    }
  }

  if (currentFlashLoc > 7000000)
  {
    flash.chipErase();
    while (!flash.busy())
    {
      // wait for flash to fully erase
    }
    currentFlashLoc = 0;
    dumpCounter = 0;
  }

  if (getTime)
  {
    updateTimeWithTimePacket();
    return;
  }

  if (getValues && timesValuesCollected != gatherValuesDuration)
  {
    //    Serial.print("Run Accelerometer Routine");
    if (timesValuesCollected == 0)
    {
      writeTime();
      //      adxl.measurementMode(1);
    }
    accelerometerRoutine();
    return;
  }
  else if (timesValuesCollected == gatherValuesDuration)
  {
    getValues = false;
    adxl.setStandbyMode(0);
    sendValues = true;
  }

  if (sendValues)
  {
#if DEBUGGING
    Serial.println("Send Values");
#endif
    sendDataRoutine();
    for (int i = 0; i < sleepingStateDuration; i++)
    {
      #if DEBUGGING
  Serial.println("Im sleeping for short time boi");
#endif
      LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
      if (i % 2 == 0)
      {
        adjustTime(9);
      }
      else
      {
        adjustTime(8);
      }
    }
    getValues = true;
    adxl.setStandbyMode(1);
    timesValuesCollected = 0;
  }
}

I have not heard of DIY SPACE (PVT) LTD, sounds like some of their boards are faulty, have you contacted them ?

Could be a code problem, but without seeing it, the forum wont be able to help.

DIY SPACE (PVT) LTD, just designed the PCB and gave me the Gerber file. Then I ordered these pcb's from JLC PCB and then components were soldered by local person.
Secondly like i said in the post same code was uploaded on all devices yet 1 or 2 works fine so what could be the chances that code is faulty?

The exact probability of the code being faulty, no idea.

But if you want help, just post the code, if the code is reasonable, then its worth looking at other issues.

Thanks for the advice uploaded the code as well let me know if anything else needed