Hello everyone.
A bit of backstory before I explain my problem. I am using an Arduino Mega with an SD card and an ADC module. Since both work on SPI protocol I searched around and wrote a code that made sense in my head and it worked. I developed a PCB (which also has a GPS module, a 12-5v power supply module and 12v barrel jack for power). Now here is the problem,
When I power my board with just the usb connector connected to Mega, the code works perfectly. But when i power the board with the 12v supply and connect the usb to read from the serial monitor the sd card does no initialize. I thought i was going mad so checked several times and it still does not work. Any idea whats the problem?
The code i am using is this
//ADS1256 library developed by Curious Scientist
//A very detailed documentation can be found at: https://curiousscientist.tech/ads1256-custom-library
#include <SPI.h>
#include <ADS1256.h>
#include <SD.h>
//#include <FS.h>
#include <TinyGPS++.h>
#include <TimeLib.h>
#include <UnixTime.h>
TinyGPSPlus gps; // create gps object
UnixTime stamp(5);
#define time_offset 18000 // define a clock offset of 18000 seconds (5 hour) ==> UTC + 5
// variable definitions
char Time[] = "00:00:00";
char Date[] = "00-00-2000";
byte last_second, Second, Minute, Hour, Day, Month; //For setting time to local +5hrs
int Year;
uint32_t timeStamp;
unsigned long interval;
String sat;
const char filename[] = "test.txt";
File txtFile;
float buff;
unsigned long lastMillis = 0;
//ADS1256 A(2, 0, 8, 10, 2.500); //DRDY, RESET, SYNC(PDWN), CS, VREF(float). //Arduino Uno
ADS1256 A(2, 0, 46, 53, 2.500); //DRDY, RESET, SYNC(PDWN), CS, VREF(float). //Arduino Mega
//ADS1256 A(44, 0, 47, 10, 2.500); //DRDY, RESET, SYNC(PDWN), CS, VREF(float). //Arduino Due
float rmsValue = 0;
long rawConversion = 0; //24-bit raw value
float voltageValue = 0; //human-readable floating point value
float readings[8];
int singleEndedChannels[8] = {SING_0, SING_1, SING_2, SING_3, SING_4, SING_5, SING_6, SING_7}; //Array to store the single-ended channels
int differentialChannels[4] = {DIFF_0_1, DIFF_2_3, DIFF_4_5, DIFF_6_7}; //Array to store the differential channels
int inputChannel = 0; //Number used to pick the channel from the above two arrays
char inputMode = ' '; //can be 's' and 'd': single-ended and differential
int pgaValues[7] = {PGA_1, PGA_2, PGA_4, PGA_8, PGA_16, PGA_32, PGA_64}; //Array to store the PGA settings
int pgaSelection = 0; //Number used to pick the PGA value from the above array
int drateValues[16] =
{
DRATE_30000SPS,
DRATE_15000SPS,
DRATE_7500SPS,
DRATE_3750SPS,
DRATE_2000SPS,
DRATE_1000SPS,
DRATE_500SPS,
DRATE_100SPS,
DRATE_60SPS,
DRATE_50SPS,
DRATE_30SPS,
DRATE_25SPS,
DRATE_15SPS,
DRATE_10SPS,
DRATE_5SPS,
DRATE_2SPS
}; //Array to store the sampling rates
int drateSelection = 0; //Number used to pick the sampling rate from the above array
String registers[11] =
{
"STATUS",
"MUX",
"ADCON",
"DRATE",
"IO",
"OFC0",
"OFC1",
"OFC2",
"FSC0",
"FSC1",
"FSC2"
};//Array to store the registers
int registerToRead = 0; //Register number to be read
int registerToWrite = 0; //Register number to be written
int registerValueToWrite = 0; //Value to be written in the selected register
//____________________________________________________________________________________________________________________________________________________________________________
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial1.begin(9600); // connect gps sensor
delay(10);
// buff.reserve(1024);
pinMode(53, OUTPUT);
pinMode(4, OUTPUT);
// set LED pin to output, used to blink when writing
// pinMode(LED_BUILTIN, OUTPUT);
Serial.println("Initializing SD");
// digitalWrite(53, 1);
digitalWrite(4, 0);
initSDCard();
digitalWrite(4, 1);
Serial.println("Initializing ADC");
// Serial.println("ADS1256 - Custom Library Demo File by Curious Scientist - 2023-11-10");
digitalWrite(53, 0);
A.InitializeADC(); //See the documentation for every details
//Setting up CS, RESET, SYNC and SPI
//Assigning default values to: STATUS, MUX, ADCON, DRATE
//Performing a SYSCAL
//Below is a demonstration to change the values through the built-on functions of the library
//Set a PGA value
A.setPGA(PGA_1); //0b00000000 - DEC: 0
//--------------------------------------------
//Set input channels
A.setMUX(SING_1); //0b01100111 - DEC: 31
//--------------------------------------------
//Set DRATE
A.setDRATE(DRATE_100SPS); //0b00010011 - DEC: 19
//--------------------------------------------
A.setBuffer(1);
delay(50);
//Read back the above 3 values to check if the writing was succesful
// Serial.print("PGA: ");
// Serial.println(A.readRegister(IO_REG));
// delay(100);
//--
// Serial.print("MUX: ");
// Serial.println(A.readRegister(MUX_REG));
// delay(100);
//--
// Serial.print("DRATE: ");
// Serial.println(A.readRegister(DRATE_REG));
// delay(100);
//--
// Serial.println(A.getPGA());
// delay(100);
A.getBuffer();
delay(100);
//--
//Freeze the display for 3 sec
delay(3000);
interval = millis();
}
//________________________________________________________________________________________________________________________________________________________________________
void loop() {
// put your main code here, to run repeatedly:
// rawConversion = A.readSingle(); // To read multiple channels goto end of code to see example
// A.stopConversion();
// voltageValue = A.convertToVoltage(rawConversion);
getADC();
rmsValue = RMS(readings[0], readings[1], readings[2]);
getTime();
sat = gps.satellites.value();
// Serial.print(Date);
// Serial.print(",");
Serial.print(timeStamp);
Serial.print(",");
Serial.print(readings[0], 6);
Serial.print(",");
Serial.print(readings[1], 6);
Serial.print(",");
Serial.print(readings[2], 6);
Serial.print(",");
Serial.print(rmsValue, 6);
Serial.println(" ");
// Serial.print("\t");
// Serial.print(sat);
// Serial.print("\t");
// Serial.println(gps.hdop.hdop());
if (millis() - interval > 1000)
{
digitalWrite(53, 1);
digitalWrite(4, 0);
writeToSD(Date, Time, readings[0], readings[1], readings[2], rmsValue);
Serial.println("written");
interval = millis();
digitalWrite(4, 1);
digitalWrite(53, 0);
}
}
static void smartDelay(unsigned long ms)
{
unsigned long start = millis();
do
{
while (Serial1.available())
gps.encode(Serial1.read());
} while (millis() - start < ms);
}
void writeToSD(char d[], char t[], float v1, float v2, float v3, float v4)
{
digitalWrite(4, 0);
txtFile = SD.open(filename, FILE_WRITE);
if (!txtFile) {
Serial.print("error opening ");
Serial.println(filename);
// while (1);
}
else
{
txtFile.print(d);
txtFile.print(",");
txtFile.print(t);
txtFile.print(",");
txtFile.print(v1, 6);
txtFile.print("uT,");
txtFile.print(v2, 6);
txtFile.print("uT,");
txtFile.print(v3, 6);
txtFile.print("uT,");
txtFile.print(v4, 6);
txtFile.print("uT");
txtFile.println();
txtFile.close();
}
digitalWrite(4, 1);
}
void getTime()
{
smartDelay(10); //Serial.available, gps encode both are done inside smartDelay function.
if (gps.time.isValid())
{
Minute = gps.time.minute();
Second = gps.time.second();
Hour = gps.time.hour();
// timeStamp = gps.time.hour() + 5;
// timeStamp += ":";
// timeStamp += gps.time.minute();
// timeStamp += ":";
// timeStamp += gps.time.second();
}
if (gps.date.isValid())
{
Day = gps.date.day();
Month = gps.date.month();
Year = gps.date.year();
}
if (last_second != gps.time.second()) // if time has changed
{
last_second = gps.time.second();
// set current UTC time
// setTime(Hour, Minute, Second, Day, Month, Year);
// add the offset to get local time
// adjustTime(time_offset);
// update time array
stamp.setDateTime(Hour, Minute, Second, Day, Month, Year);
timeStamp = stamp.getUnix();
Time[6] = second() / 10 + '0';
Time[7] = second() % 10 + '0';
Time[3] = minute() / 10 + '0';
Time[4] = minute() % 10 + '0';
Time[0] = hour() / 10 + '0';
Time[1] = hour() % 10 + '0';
// update date array
Date[8] = (year() / 10) % 10 + '0';
Date[9] = year() % 10 + '0';
Date[3] = month() / 10 + '0';
Date[4] = month() % 10 + '0';
Date[0] = day() / 10 + '0';
Date[1] = day() % 10 + '0';
}
}
void getADC ()
{
digitalWrite(53, 0);
// rawConversion = A.readSingle(); // To read multiple channels goto end of code to see example
// A.stopConversion();
// voltageValue = A.convertToVoltage(rawConversion);
for (int i = 0; i < 8; i++) // Convert all single channels and store in array
{
readings[i] = A.convertToVoltage(A.cycleSingle());
// Serial.print(A.convertToVoltage(A.cycleSingle()), 4); //print the converted single-ended results with 4 digits
// Serial.print("\t");//tab separator to separate the 4 conversions shown in the same line
readings[i] = mapF(readings[i], -3.7, 3.7, -100, 100);
}
A.stopConversion();
// Serial.print(readings[0], 6); //prints only the desired channels
// Serial.print("\t");
// Serial.print(readings[1], 6);
// Serial.print("\t");
// Serial.print(readings[2], 6);
// Serial.println();
digitalWrite(53, 1);
}
void initSDCard() {
if (!SD.begin(4)) {
Serial.println("Card Mount Failed");
return;
}
else {
Serial.println("Initialized SD card");
}
}
float mapF(float x, float in_min, float in_max, float out_min, float out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
float RMS (float x, float y, float z)
{
return (sqrt((x * x) + (y * y) + (z * z)));
}