Hi I have been trying to solve this issue all night and finally figured I would see if any of you folk know what might be the issue. I am trying to build a battery powered data logger that uses the HC-SR04 ultrasonic sensor to measure the water level and then log it to an SD card.
Having got the HC-SR04 measuring well and logging to the SD card connected to an Uno powered via USB from my laptop I migrated it all over on to a bare bones arduino on a breadboard which again worked as intended when the circuit was powered via the 5v and GND pins of the Uno board.
My issue has come about since I switched my power supply from the 5v/GND pins from the Uno board to being powered from a 18650 Lithium Battery boosted through a TPS63020 buck/boost converter board like this.
The SD card continues to log values absolutely fine however these values are all "0.00" rather that the readings that should be coming from the sensor hence I don't think the sensor is returning values correctly for some reason.
I initially thought it might be noise from the boost converter however I tried connecting a USB cable 5v and GND wires from my laptop to the input of the voltage converter and it worked fine. I then thought it might be that with the USB input the the voltage converter being the same as the output it may reduce the noise so I took another buck converter set to an output of ~3.3v and connected the USB power supply to the inputs of that and the outputs to the boost converter and it also worked fine. I have also tried other boost modules using different IC's and circuit architectures non of which have worked with the battery but all of which have worked with the USB power supply.
Notes:
Battery I am using is this AB3-S 18650 2300mAh battery with PCB protected (though I have tried a range of other batteries).
Battery voltage is currently around 4.09v and does not drop by more than 0.02v when load is applied.
I have tried adding a couple of 1000uF electrolytic capacitors as in the past when I have had issues where modules draw short bursts of higher current, this has resolved the issue.
Essentially I am at a loss as to what is the issue and would really appreciate some advice. I have included the circuit setup (with the battery) and the code I am using below. Hopefully it all makes sense but feel free to ask questions if not.
#include <LowPower.h>
#include <SD.h>
// HC-SR04 sensor pins
const int trigPin = 9; // Trigger pin for HC-SR04
const int echoPin = 8; // Echo pin for HC-SR04 (moved from pin 10)
// SD card module chip select pin
// Arduino connections for SD card module:
// - VCC to 5V
// - GND to GND
// - MOSI to pin 11
// - MISO to pin 12
// - SCK to pin 13
// - CS to pin 4 (you can change this if needed)
const int chipSelect = 4;
void setup() {
// Start serial communication for debugging/logging
Serial.begin(9600);
// Set sensor pins
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
// Initialize the SD card
if (!SD.begin(chipSelect)) {
Serial.println("SD card initialization failed!");
// If SD card fails, halt execution.
while (1);
}
Serial.println("SD card initialized.");
}
void loop() {
const int numReadings = 30;
float distances[numReadings];
// Collect 30 sensor readings
for (int i = 0; i < numReadings; i++) {
// Ensure the trigger pin is LOW
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Trigger the sensor with a 10µs HIGH pulse
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Read the echo pulse (timeout set to 30000 microseconds)
long duration = pulseIn(echoPin, HIGH, 30000);
// Convert duration (microseconds) to distance (in millimeters).
// Calculation: distance = duration * (0.343 mm/us / 2) = duration * 0.1715.
float distance = duration * 0.1715;
distances[i] = distance;
delay(50); // Short delay between readings
}
// Sort the array using bubble sort to compute the median.
for (int i = 0; i < numReadings - 1; i++) {
for (int j = 0; j < numReadings - i - 1; j++) {
if (distances[j] > distances[j + 1]) {
float temp = distances[j];
distances[j] = distances[j + 1];
distances[j + 1] = temp;
}
}
}
// Calculate the median.
float median;
if (numReadings % 2 == 0) {
median = (distances[numReadings / 2 - 1] + distances[numReadings / 2]) / 2.0;
} else {
median = distances[numReadings / 2];
}
// Print the median distance to the Serial Monitor.
Serial.print("Median Distance: ");
Serial.print(median);
Serial.println(" mm");
// Log the median result to the SD card BEFORE the delay.
logData(median);
// Added delay so the serial monitor can finish printing before sleeping.
delay(50);
// Enter low power mode for approximately 30 seconds.
// Three cycles of 8 seconds (24 sec) + one cycle of 4 seconds (4 sec) + one cycle of 2 seconds (2 sec) = 30 seconds.
for (int i = 0; i < 1; i++) {
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
}
LowPower.powerDown(SLEEP_4S, ADC_OFF, BOD_OFF);
//LowPower.powerDown(SLEEP_2S, ADC_OFF, BOD_OFF);
}
void logData(float medianValue) {
// Open the file in append mode. It will be created if it doesn't exist.
File dataFile = SD.open("datalog.txt", FILE_WRITE);
if (dataFile) {
// Log the median distance to the file.
dataFile.print("Median Distance: ");
dataFile.print(medianValue);
dataFile.println(" mm");
dataFile.close(); // Ensure data is written by closing the file.
Serial.println("Data logged to SD card.");
} else {
Serial.println("Error opening datalog.txt");
}
}