Reading and using data from SD?

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Reading and using data from SD?

Postby rob drizzle » Sun Apr 29, 2012 8:40 pm

I have been working on a data logging project where I want to be able to set a write interval easily. I thought that having a file on the SD card where the interval would be the only number in the file would be easy.

I tried modifying the code from Adafruit's SD example but can't get it to read right... Can someone shed a bit of light on how to do this?

notouch.txt had "300" on the first line, then I tried "3" and added a multipier in the code but it still doesn't work.

Code: Select all
      // re-open the file for reading:
  myFile = SD.open("notouch.txt");
   
    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      interval = myFile.read();
    }
      SYNC_INTERVAL = interval * 10000;
//       Serial.write(myFile.read());
   
    // close the file:
    myFile.close();
rob drizzle
 
Posts: 101
Joined: Wed May 04, 2011 5:14 pm

Re: Reading and using data from SD?

Postby pylon » Mon Apr 30, 2012 4:21 am

Just a wild guess (you posted just a snippet not full code):

Your file probably contains more than just the digits. Most editors add at least a line feed at the end of the file. You have a while loop reading until there are no more characters, so you may get the reading of a invisible character. Also you don't check for the file being really read or opened. If the digits are really read, you don't correct for the ASCII index. Character "3" does not have a byte value of 3. You have to subtract the ASCII value of '0' from it:

Code: Select all
interval = myFile.read() - '0';


To get better support, post full sketch including variable definition and initialization.
pylon
 
Posts: 14
Joined: Tue Apr 24, 2012 10:27 am

Re: Reading and using data from SD?

Postby rob drizzle » Mon Apr 30, 2012 8:46 pm

pylon wrote:Just a wild guess (you posted just a snippet not full code):


Sorry about that. That is the only time that I recall information from that file from the SD card so I didn't think of pasting the whole code.

Code: Select all
/*
Base only code...
*/

#include <serialGLCDlib.h>
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
#include "DHT.h"
#include <Wire.h>
#include "RTClib.h"
#include <SD.h>

#define DHTPIN 2 // DHT Pin
#define DHTTYPE DHT22   // DHT 22
DHT dht(DHTPIN, DHTTYPE);
RTC_DS1307 RTC;

RF24 radio(8,9); //Radio pins 3(to8),4(to9)
RF24Network network(radio);

// Our node address
uint16_t this_node;

// The message that we send is just an unsigned int, containing a sensor reading.
struct message_t
{
int temp_reading;
int humid_reading;
int voltage_reading;
int reset_reading;
  message_t(void): temp_reading(0), humid_reading(0), voltage_reading(0), reset_reading(0) {}//ADD VOLTAGE READING!!!!
};

int lcdCount = 0;
int tempf = 0;
int humidrh = 0;
int voltage = 0;
int dp = 0;
int dewP1 = 0;
int dewP2 = 0;
int dewP3 = 0;
int dewP4 = 0;
int reset = 0;
long sync = 0;
long interval = 0;

char nodereset[10] = "RS";
char nodetemp1[10] = "ND";
char humid1[10] = "ND";
char voltage1[10] = "ND";
char dp1[10] = "ND";
char nodetemp2[10] = "ND";
char humid2[10] = "ND";
char voltage2[10] = "ND";
char dp2[10] = "ND";
char nodetemp3[10] = "ND";
char humid3[10] = "ND";
char voltage3[10] = "ND";
char dp3[10] = "ND";
int nodetemp4 = 0;
int humid4 = 0;
char voltage4[10] = "ND";
char dp4[10] = "ND";
char batstat1[14] = "Odr Bat Low!";
char batstat2[14] = "Idr Bat Low!";
char batstat3[14] = "Atc Bat Low!";
char sysStat[13] = "Sys Stus:";
char sysStatc[14] = "All Ok      ";
char sysStatSD[14] = "Wrtng to SD ";

//------------------------------ SD --------------------------------------------

File myFile;

long SYNC_INTERVAL = 300000; // mills between calls to flush() - to write data to the card
uint32_t syncTime = 0; // time of last sync()

#define ECHO_TO_SERIAL 1 // echo data to serial port
#define WAIT_TO_START 0 // Wait for serial input in setup()

const int chipSelect = 10;

// the logging file
File logfile;

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);
 
  // red LED indicates error
//  digitalWrite(redLEDpin, HIGH);

  while(1);
}

//-------------------------------------------------------------------------------

void setup(void)
{
  Serial.begin(115200);
  delay(5000);
 
    pinMode(53, OUTPUT);

  this_node = 0;

  //
  //DHT sensor, wire and clock
  // 

  dht.begin();
  Wire.begin();
  RTC.begin();
 
  //
  // Bring up the RF network
  //

  SPI.begin();
  radio.begin();
  network.begin(/*channel*/ 92, /*node address*/ this_node);
 
//--------------------------------- SD ---------------------------------------------

  // initialize the SD card
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
 
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    error("Card failed, or not present");
  }
  Serial.println("card initialized.");
 
  delay(3000);
 
      // re-open the file for reading:
  myFile = SD.open("notouch.txt");
   
    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      interval = myFile.read();
    }
      SYNC_INTERVAL = interval * 10000;
       Serial.write(myFile.read());
   
    // close the file:
    myFile.close();
 
 
  // create a new file
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE);
      break; // leave the loop!
    }
  }
 
  if (! logfile) {
    error("couldnt create file");
  }
  Serial.println(" ");
  Serial.println("Logging to:");
  Serial.println(filename);
 
  delay(3000);
 
  Serial.println(" ");
  Serial.println("Sync Time");
  sync = SYNC_INTERVAL / 1000;
  Serial.print(sync);
  Serial.print(" Seconds");
 
  delay(3000);
 
  logfile.println("datetime,Base Temp,Base Humid,Base DP,Indoor Temp,Indoor Humid,Indoor DP,Attic Temp,Attic Humid,Attic DP,Outdoor Temp,Outdoor Humid,Outdoor DP");
 
}

serialGLCD lcd; // initialisation

//------------------------------------------------------------------------------------

void loop(void)
{
//  lcd.reverseColor();
if ( lcdCount == 0 ){
  lcd.clearLCD();
 
    DateTime now = RTC.now();
   
lcd.gotoLine(8);
Serial.print("                     ");
delay(10);
lcd.gotoLine(8);
Serial.print(now.month(), DEC);
Serial.print("/");
delay(10);
Serial.print(now.day(), DEC);
Serial.print("/");
delay(10);
Serial.print(now.year(), DEC);
Serial.print(" ");
delay(10);
printDigits(now.hour());
Serial.print(":");
delay(10);
printDigits(now.minute());
Serial.print(" Start");
delay(10);
   
// Print title information
lcd.gotoLine(1);
Serial.print("Locl Temp RH% Dew Bat");

lcd.gotoLine(4);
Serial.print("      BOOTING UP   ");

lcdCount = 1;
}
 
humid4 = dht.readHumidity();
int t = dht.readTemperature();
nodetemp4 = (t * 1.8 + 32);
 
  // Pump the network regularly
  network.update();

  // If we are the base, is there anything ready for us?
  while ( network.available() )
  {
    // If so, grab it and print it out
    RF24NetworkHeader header;
    message_t message;
    network.read(header,&message,sizeof(message));

//------------------- Converting and Storing radio data ---------------------------------

tempf = (message.temp_reading * 1.8 + 32);
humidrh = (message.humid_reading);
voltage = (message.voltage_reading);
reset = (message.reset_reading);
// Dew point for base--
dp = dewPoint(message.temp_reading, message.humid_reading);
dewP4 = dewPoint4(dht.readTemperature(),dht.readHumidity()) * 1.8 + 32;

//--------------------Storing Node Number for sorting use -----------------------------------

int nodedump = header.from_node;

//------------------------- Sorting received information from radio ---------------------------

switch(nodedump) // If node dump reads "1" through blah is node. Need to assign Attic, Outdoor, etc.
{
case 1: // no "0" because we will hard code it in.
itoa(tempf, nodetemp1,10); //converting tempf to nodetemp3 for display and storage
itoa(humidrh, humid1, 10); //converting humidrh to humid3 for display and storage
itoa(voltage, voltage1, 10);
break;
case 2:
humidrh = humidrh - 2; //calibration indoor sensor humid is +2
itoa(tempf, nodetemp2, 10);
itoa(humidrh, humid2, 10);
itoa(voltage, voltage2, 10);
break;
case 3:
humidrh = humidrh - 5; //calibration attic sensor humid is +5
itoa(tempf, nodetemp3, 10);
itoa(humidrh, humid3, 10);
itoa(voltage, voltage3, 10);
break;
default :
break;
}

//----------------- Dew Point Calc -----------------

switch(nodedump)
{
case 1:
dewP1 = dp * 1.8 + 32;
break;
case 2:
dewP2 = dp * 1.8 + 32;
break;
case 3:
dewP3 = dp * 1.8 + 32;
break;
default :
break;
}

//------------------------- Battery Warning -------------------------------

if (voltage < 25){
switch(nodedump)
{
case 1:
if (voltage < 25){
lcd.gotoLine(6);
Serial.print("                     ");
delay(10);
lcd.gotoLine(6);
Serial.print(sysStat);
delay(10);
Serial.print(batstat1);
delay(10);
}
break;
case 2:
if (voltage < 25){
lcd.gotoLine(6);
Serial.print("                     ");
delay(10);
lcd.gotoLine(6);
Serial.print(sysStat);
delay(10);
Serial.print(batstat2);
delay(10);
}
break;
case 3:
if (voltage < 25){
lcd.gotoLine(6);
Serial.print("                     ");
delay(10);
lcd.gotoLine(6);
Serial.print(sysStat);
delay(10);
Serial.print(batstat3);
delay(10);
}
break;
default :
break;
}
}
else
{
lcd.gotoLine(6);
Serial.print("                     ");
delay(10);
lcd.gotoLine(6);
Serial.print(sysStat);
delay(10);
Serial.print(sysStatc);
delay(10);
}
//------------------------- Reset -------------------------------

switch(nodedump)
{
case 1:
if(reset == 1){
strcpy(nodetemp1, nodereset);
strcpy(humid1, nodereset);
sdWrite();
}
break;
case 2:
if(reset == 1){
strcpy(nodetemp2, nodereset);
strcpy(humid2, nodereset);
sdWrite();
}
break;
case 3:
if(reset == 1){
strcpy(nodetemp3, nodereset);
strcpy(humid3, nodereset);
sdWrite();
}
break;
default :
break;
}

//--------------------------------SD--------------------------------------
  // Now we write data to disk! Don't sync too often - requires 2048 bytes of I/O to SD card
  // which uses a bunch of power and takes time
  if ((millis() - syncTime) > SYNC_INTERVAL){
    sdWrite();
   lcd.gotoLine(6);
Serial.print("                     ");
delay(10);
lcd.gotoLine(6);
Serial.print(sysStat);
delay(10);
Serial.print(sysStatSD);
delay(1000);
lcd.gotoLine(6);
Serial.print("                     ");
delay(10);
lcd.gotoLine(6);
Serial.print(sysStat);
delay(10);
Serial.print(sysStatc);
delay(10);

//  DateTime now;
//  now = RTC.now();

DateTime now = RTC.now();

  logfile.print(now.year(), DEC);
  logfile.print("/");
  logfile.print(now.month(), DEC);
  logfile.print("/");
  logfile.print(now.day(), DEC);
  logfile.print(" ");
  logfile.print(now.hour(), DEC);
  logfile.print(":");
  logfile.print(now.minute(), DEC);
  logfile.print(":");
  logfile.print(now.second(), DEC);
  logfile.print('"'); 
 
  logfile.print(", ");
  logfile.print(nodetemp4);
  logfile.print(", ");
  logfile.print(humid4);
  logfile.print(", ");
  logfile.print(dewP4);
  logfile.print(", ");
  logfile.print(nodetemp2);
  logfile.print(", ");
  logfile.print(humid2);
  logfile.print(", ");
  logfile.print(dewP2);
  logfile.print(", ");
  logfile.print(nodetemp3);
  logfile.print(", ");
  logfile.print(humid3);
  logfile.print(", ");
  logfile.print(dewP3);
  logfile.print(", ");
  logfile.print(nodetemp1);
  logfile.print(", ");
  logfile.print(humid1);
  logfile.print(", ");
  logfile.print(dewP1);
 
  logfile.println();
 
  }
//----------------------- time banned -------------------------------------------

DateTime now = RTC.now();
//  now = RTC.now();
   
lcd.gotoLine(7);
Serial.print("                     ");
delay(10);
lcd.gotoLine(7);
Serial.print(now.month(), DEC);
Serial.print("/");
delay(10);
Serial.print(now.day(), DEC);
Serial.print("/");
delay(10);
Serial.print(now.year(), DEC);
Serial.print(" ");
delay(10);
printDigits(now.hour());
Serial.print(":");
delay(10);
printDigits(now.minute());
Serial.print(" Now"); 
 
 
// setting cursor for printing on second line of display...
lcd.gotoLine(2);
Serial.print("                     ");
delay(10);
lcd.gotoLine(2);
Serial.print("Base ");
delay(10);
lcd.gotoPosition(31,8);
Serial.print(nodetemp4);
Serial.print("F ");
delay(10);
lcd.gotoPosition(61,8);
Serial.print(humid4);
Serial.print("%");
delay(10);
lcd.gotoPosition(85,8);
Serial.print(dewP4);
Serial.print("F");
delay(10);
lcd.gotoPosition(109,8);
Serial.print("A/C");
delay(10);

lcd.gotoLine(3);
Serial.print("                     ");
delay(10);
lcd.gotoLine(3);
Serial.print("Indr ");
delay(10);
lcd.gotoPosition(31,16);
Serial.print(nodetemp2  );
Serial.print("F ");
delay(10);
lcd.gotoPosition(61,16);
Serial.print(humid2);
Serial.print("%");
delay(10);
lcd.gotoPosition(85,16);
Serial.print(dewP2);
Serial.print("F");
delay(10);
lcd.gotoPosition(109,16);
Serial.print(voltage2);
delay(10);

lcd.gotoLine(4);
Serial.print("                     ");
delay(10);
lcd.gotoLine(4);
Serial.print("Attc ");
delay(10);
lcd.gotoPosition(31,24);
Serial.print(nodetemp3);
Serial.print("F ");
delay(10);
lcd.gotoPosition(61,24);
Serial.print(humid3);
Serial.print("%");
delay(10);
lcd.gotoPosition(85,24);
Serial.print(dewP3);
Serial.print("F");
delay(10);
lcd.gotoPosition(109,24);
Serial.print(voltage3);
delay(10);

lcd.gotoLine(5);
Serial.print("                     ");
delay(10);
lcd.gotoLine(5);
Serial.print("Otdr ");
delay(10);
lcd.gotoPosition(31,32);
Serial.print(nodetemp1);
Serial.print("F ");
delay(10);
lcd.gotoPosition(61,32);
Serial.print(humid1);
Serial.print("%");
delay(10);
lcd.gotoPosition(85,32);
Serial.print(dewP1);
Serial.print("F");
delay(10);
lcd.gotoPosition(109,32);
Serial.print(voltage1);
delay(10);

  }
}
//-------------------------------------------------------------------------------------

//------------------------- Node dew point calc ------------------------

double dewPoint(double celsius, double humidity)
{
        double A0= 373.15/(273.15 + celsius);
        double SUM = -7.90298 * (A0-1);
        SUM += 5.02808 * log10(A0);
        SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/A0)))-1) ;
        SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ;
        SUM += log10(1013.246);
        double VP = pow(10, SUM-3) * humidity;
        double T = log(VP/0.61078);   // temp var
        return (241.88 * T) / (17.558-T);
}

//---------------------- Base dew point calc -------------------------

double dewPoint4(double celsius4, double humidity4)
{
        double A0= 373.15/(273.15 + celsius4);
        double SUM = -7.90298 * (A0-1);
        SUM += 5.02808 * log10(A0);
        SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/A0)))-1) ;
        SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ;
        SUM += log10(1013.246);
        double VP = pow(10, SUM-3) * humidity4;
        double T = log(VP/0.61078);   // temp var
        return (241.88 * T) / (17.558-T);
}

//------------------------- SD write --------------------------------------

void sdWrite()
{
 
  // blink LED to show we are syncing data to the card & updating FAT!
//  digitalWrite(redLEDpin, HIGH);
logfile.flush();
syncTime = millis();
}


void printDigits(int digits){
  // utility function for digital clock display: prints leading 0
   if(digits < 10)
    Serial.print('0');
   Serial.print(digits);
}
rob drizzle
 
Posts: 101
Joined: Wed May 04, 2011 5:14 pm

Re: Reading and using data from SD?

Postby pylon » Wed May 02, 2012 8:01 am

Assuming the content of your file on the SD is plain text (and not some binary format), change your reading while loop as:

Code: Select all
    // read from the file until there's nothing else in it (or a non-digit is reached):
    while (myFile.available()) {
      int c = myFile.read();
      if (c >= '0' && c <= '9') {
        interval = interval * 10 + c - '0';
      } else {
        break;
      }
    }


That way it reads in your file until the first non-digit character is found. So "300" is ok as well as "3" would be. But it must be at the start of the file else you have to make the parsing code a bit more elaborated.

Hope this helps.
pylon
 
Posts: 14
Joined: Tue Apr 24, 2012 10:27 am

Re: Reading and using data from SD?

Postby rob drizzle » Mon May 07, 2012 10:48 pm

thank you for your help... I kinda figured it out after your first post... But this helps too!
rob drizzle
 
Posts: 101
Joined: Wed May 04, 2011 5:14 pm


Return to Arduino

Who is online

Users browsing this forum: Exabot [Bot] and 11 guests

Stuff to buy from the Adafruit store and links to product documentation!


New Products [103]

Raspberry Pi[80]
 
FLORA[23]
 
Bunnie Studios[9]
 
FPGA[1]
 
mbed[11]
Arduino[60]
 
NETduino[14]
 
BeagleBone[24]
 
Android[6]
 
XBee[10]
More Dev Boards[30]


 
BoArduino[8]
 
SpokePOV[4]
 
TV-B-Gone[4]
 
MiniPOV[3]
 
SIM reader[3]
 
Microtouch[5]
 
Clocks & Watches[18]
 
Drawdio[4]
 
Brain Machine[1]
 
Game of Life[2]
 
MintyBoost[2]
More DIY Kits[16]


 
MaKey MaKey[3]
 
Tweet-a-Watt[5]
 
Young Engineers[33]
 
Discover Electronics[2]
 
Snap Circuits[4]
 
littleBits[3]
 
Project packs[8]


 
Breakout Boards[33]
LCDs & Displays[48]
Components & Parts[69]
Batteries & Power[49]
EL Wire/Tape/Panel[52]
LEDs[109]
 
Wireless[14]
Cables[61]
 
Lasers[6]
Sensors/Parts[145]
 
Enclosures/Cases[11]
 
Solar[11]
 
RFID / NFC[13]
Prototyping[70]
 
iDevices[13]
Tools[71]
 
Wearables[39]
 
CNC[37]
 
Robotics[29]
 
3D printing[1]
 
Materials[24]


 
Stickers[41]
 
Skill badges[55]
 
Books[25]
 
Circuit Playground[7]
 
Gift Certificates[4]