Hello Arduino Community
I am collecting data and attempting to log it on to a Deek Robot SD shield via a Mega.
I have the data in a dataString which I can Serial.print to the monitor but would like to log it to an SD card instead. When I run the the Datalogger example sketch from the SD library I can see the data and access the datalog file from the SD card (as per point of the example) but when I try to cross-pollinate the example with mySketch the debugging message
error opening datalog.txt
is all I get.
I've uploaded the sketch, apologies it is pretty long, there's some adc stuff going on, the call for the data file open and write etc starts on line 200 and ends on 212.
I've tried positioning the datafile functions in different places in the code, using other libraries, reading forum posts but I am getting nowhere. if anyone could point out what I'm doing wrong I would be eternally grateful.
Cheers, Michael
//!!!change this to name of sketch!!!!
#define SKETCH_VERSION "SD for loop array test"
//include relevant libraries
#include <EnableInterrupt.h>
#include <SPI.h>
#include <SD.h>
//globally define pins
#define BUSY 3 //purple*
#define RD 4 //yellow* RD+CS tied together
#define RESET 5 //grey*
#define CONVST 6 //green* CONVSTA+CONVSTB soldered together on the board
#define RANGE 7 //blue* *not permanent - double check!!!*
#define DB0 38
#define DB1 39
#define DB2 40
#define DB3 41
#define DB4 42
#define DB5 43
#define DB6 44
#define DB7 45
#define DB8 46
#define DB9 47
#define DB10 48
#define DB11 49
#define DB12 50
#define DB13 51
#define DB14 52
#define DB15 53
byte statusLed = 13;
byte sensorPin1 = 10;
byte sensorPin2 = 11;
byte sensorPin3 = 12;
int sensorValue[8];
int rawData[16];
//change the size of these arrays to match the amount of channels being read by the ADC
int adcChannel[5];
int adcData[5];
int channelCount=5;
volatile byte pulseCount1;
volatile byte pulseCount2;
volatile byte pulseCount3;
int pulses[3];
// cs pin for sd-shield *NB 53 for Mega
const int chipSelect = 53;
unsigned long oldTime;
void setup() { //set up the hardware
Serial.begin(9600);
//sd card.....
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Initializing SD card...");
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
while (1);
}
Serial.println("card initialized.");
enableInterrupt(BUSY, bitBang, FALLING);
oldTime = 0;
pinMode(DB0, INPUT_PULLUP);
pinMode(DB1, INPUT_PULLUP);
pinMode(DB2, INPUT_PULLUP);
pinMode(DB3, INPUT_PULLUP);
pinMode(DB4, INPUT_PULLUP);
pinMode(DB5, INPUT_PULLUP);
pinMode(DB6, INPUT_PULLUP);
pinMode(DB7, INPUT_PULLUP);
pinMode(DB8, INPUT_PULLUP);
pinMode(DB9, INPUT_PULLUP);
pinMode(DB10, INPUT_PULLUP);
pinMode(DB11, INPUT_PULLUP);
pinMode(DB12, INPUT_PULLUP);
pinMode(DB13, INPUT_PULLUP);
pinMode(DB14, INPUT_PULLUP);
pinMode(DB15, INPUT_PULLUP);
pinMode(RESET, OUTPUT);
pinMode(CONVST, OUTPUT);
pinMode(RD, OUTPUT);
pinMode(RANGE, OUTPUT);
pinMode(BUSY, INPUT);
//reset ADC to begin conversion
digitalWrite(RESET, HIGH);
delayMicroseconds(10);
digitalWrite(RESET, LOW);
digitalWrite(CONVST, LOW);
digitalWrite(RD, HIGH);
digitalWrite(RANGE, LOW);
digitalWrite(BUSY, LOW);
delayMicroseconds(100);
// Set up the status LED line as an output
pinMode(statusLed, OUTPUT);
digitalWrite(statusLed, HIGH); // We have an active-low LED attached
pinMode(sensorPin1, INPUT);
digitalWrite(sensorPin1, HIGH);
pinMode(sensorPin2, INPUT_PULLUP);
digitalWrite(sensorPin2, HIGH);
pinMode(sensorPin3, INPUT_PULLUP);
digitalWrite(sensorPin3, HIGH);
pulseCount1 = 0;
pulseCount2 = 0;
pulseCount3 = 0;
oldTime = 0;
// the hall effect sensors are configured to trigger on a FALLING state change
// (transition from HIGH state to LOW state)
enableInterrupt(sensorPin1, pulseCounter1, FALLING);
enableInterrupt(sensorPin2, pulseCounter2, FALLING);
enableInterrupt(sensorPin3, pulseCounter3, FALLING);
//this prints the name of the sketch !!!read line 1!!!
Serial.print("sketch version: ");
Serial.println(SKETCH_VERSION);
}
void loop() {
//Serial.print("hello");
//change this value to preferred sampling rate
if ((millis() - oldTime) == 1000) {
oldTime = millis();
//Serial.print(millis());
//Serial.print("\t");
//tell ADC to start read (converting analogue input to digital output)
delayMicroseconds(10);
digitalWrite(CONVST, LOW);
delayMicroseconds(10);
digitalWrite(CONVST, HIGH);
//when read-conversion is complete ADC sends the BUSY pin low triggering the bitBang ISR
//print ADC data from array within the bitBang ISR to a string
String adcString = "";
for(int thisChannel=0; thisChannel<channelCount; thisChannel++){
adcString += String(adcData[thisChannel]);
adcString += ",";
}
//disable interrupt to access current pulse count
disableInterrupt(sensorPin1);
disableInterrupt(sensorPin2);
disableInterrupt(sensorPin3);
//grab current pulse count and store in a variable
pulses[0] = pulseCount1;
pulses[1] = pulseCount2;
pulses[2] = pulseCount3;
//reset pulse count
pulseCount1 = 0;
pulseCount2 = 0;
pulseCount3 = 0;
//enable interrupt and start incrementing pulse count again
enableInterrupt(sensorPin1, pulseCounter1, FALLING);
enableInterrupt(sensorPin2, pulseCounter2, FALLING);
enableInterrupt(sensorPin3, pulseCounter3, FALLING);
String pulseString = "";
for(int i=0; i<3; i++){
pulseString += String(pulses[i]);
if (i<2) {
pulseString += ",";
}
}
String dataString = String(adcString + pulseString);
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dataFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
// print to the serial port too:
Serial.println(dataString);
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.txt");
}
//Serial.println(dataString);
}
//start again
}
//grabbing ADC data ISR (for n channel)
void bitBang () {
//a for loop to bitbang the values fom the analogue (ADC) channels (maximum 8) sequentially storing them in a variable array (equal to the channels of the ADC)
for(int thisChannel=0; thisChannel<channelCount; thisChannel++){
//send ADC read pin low to bitbang the first channel
digitalWrite(RD, LOW);
//read the state of the 16 pins and store in a variable
rawData[0] = digitalRead(DB15);
rawData[1] = digitalRead(DB14);
rawData[2] = digitalRead(DB13);
rawData[3] = digitalRead(DB12);
rawData[4] = digitalRead(DB11);
rawData[5] = digitalRead(DB10);
rawData[6] = digitalRead(DB9);
rawData[7] = digitalRead(DB8);
rawData[8] = digitalRead(DB7);
rawData[9] = digitalRead(DB6);
rawData[10] = digitalRead(DB5);
rawData[11] = digitalRead(DB4);
rawData[12] = digitalRead(DB3);
rawData[13] = digitalRead(DB2);
rawData[14] = digitalRead(DB1);
rawData[15] = digitalRead(DB0);
//convert into 16bit 2s compliment and store in a variable array
adcData[thisChannel] = rawData[0] | (rawData[1] << 1) | (rawData[2] << 2) | (rawData[3] << 3) | (rawData[4] << 4) | (rawData[5] << 5) | (rawData[6] << 6) | (rawData[7] << 7) | (rawData[8] << 8) | (rawData[9] << 9) | (rawData[10] << 10) | (rawData[11] << 11) | (rawData[12] << 12) | (rawData[13] << 13) | (rawData[14] << 14) | (rawData[15] << 15);
//send ADC pin high to say we have read the first channel
digitalWrite(RD, HIGH);
//repeat for n channels
}
}
//counting pulses ISRs
void pulseCounter1(){
// Increment the pulse counter
pulseCount1++;
}
void pulseCounter2(){
// Increment the pulse counter
pulseCount2++;
}
void pulseCounter3(){
// Increment the pulse counter
pulseCount3++;
}