Teensy 3.6 SD card INIFile and Datalogger

Status
Not open for further replies.
Hello everyone,

I am new with Teensy and some of the programming.
I will be very straight forward.

I am needing to statically define several variables to the .ini file on an SD card on the Teensy 3.6
API Key
IP Address, etc

I am using the INIfile library by Steve Marple. I keep getting a "SD.begin() failed".
The reason I believe this is happening, is that my SD selection is improper and not set to BUILTIN_SD.

I also am wanting to do some data logging to CSV files as well.

The code below is untouched example code by Steve Marple
Code:
#include <SD.h>

#include <SPI.h>
#include <IPAddress.h>
#include <IniFile.h>

// The select pin used for the SD card
#define SD_SELECT 4
//define SD_SELECT 22
#define ETHERNET_SELECT 10

void printErrorMessage(uint8_t e, bool eol = true)
{
  switch (e) {
  case IniFile::errorNoError:
    Serial.print("no error");
    break;
  case IniFile::errorFileNotFound:
    Serial.print("file not found");
    break;
  case IniFile::errorFileNotOpen:
    Serial.print("file not open");
    break;
  case IniFile::errorBufferTooSmall:
    Serial.print("buffer too small");
    break;
  case IniFile::errorSeekError:
    Serial.print("seek error");
    break;
  case IniFile::errorSectionNotFound:
    Serial.print("section not found");
    break;
  case IniFile::errorKeyNotFound:
    Serial.print("key not found");
    break;
  case IniFile::errorEndOfFile:
    Serial.print("end of file");
    break;
  case IniFile::errorUnknownError:
    Serial.print("unknown error");
    break;
  default:
    Serial.print("unknown error value");
    break;
  }
  if (eol)
    Serial.println();
}

void setup()
{
  // Configure all of the SPI select pins as outputs and make SPI
  // devices inactive, otherwise the earlier init routines may fail
  // for devices which have not yet been configured.
  pinMode(SD_SELECT, OUTPUT);
  digitalWrite(SD_SELECT, HIGH); // disable SD card
  
  pinMode(ETHERNET_SELECT, OUTPUT);
  digitalWrite(ETHERNET_SELECT, HIGH); // disable Ethernet

  const size_t bufferLen = 80;
  char buffer[bufferLen];

  const char *filename = "/net.ini";
  Serial.begin(9600);
  SPI.begin();
  if (!SD.begin(SD_SELECT))
    while (1)
      Serial.println("SD.begin() failed");
  
  IniFile ini(filename);
  if (!ini.open()) {
    Serial.print("Ini file ");
    Serial.print(filename);
    Serial.println(" does not exist");
    // Cannot do anything else
    while (1)
      ;
  }
  Serial.println("Ini file exists");

  // Check the file is valid. This can be used to warn if any lines
  // are longer than the buffer.
  if (!ini.validate(buffer, bufferLen)) {
    Serial.print("ini file ");
    Serial.print(ini.getFilename());
    Serial.print(" not valid: ");
    printErrorMessage(ini.getError());
    // Cannot do anything else
    while (1)
      ;
  }
  
  // Fetch a value from a key which is present
  if (ini.getValue("network", "mac", buffer, bufferLen)) {
    Serial.print("section 'network' has an entry 'mac' with value ");
    Serial.println(buffer);
  }
  else {
    Serial.print("Could not read 'mac' from section 'network', error was ");
    printErrorMessage(ini.getError());
  }
  
  // Try fetching a value from a missing key (but section is present)
  if (ini.getValue("network", "nosuchkey", buffer, bufferLen)) {
    Serial.print("section 'network' has an entry 'nosuchkey' with value ");
    Serial.println(buffer);
  }
  else {
    Serial.print("Could not read 'nosuchkey' from section 'network', error was ");
    printErrorMessage(ini.getError());
  }
  
  // Try fetching a key from a section which is not present
  if (ini.getValue("nosuchsection", "nosuchkey", buffer, bufferLen)) {
    Serial.print("section 'nosuchsection' has an entry 'nosuchkey' with value ");
    Serial.println(buffer);
  }
  else {
    Serial.print("Could not read 'nosuchkey' from section 'nosuchsection', error was ");
    printErrorMessage(ini.getError());
  }

  // Fetch a boolean value
  bool allowPut; // variable where result will be stored
  bool found = ini.getValue("/upload", "allow put", buffer, bufferLen, allowPut);
  if (found) {
    Serial.print("The value of 'allow put' in section '/upload' is ");
    // Print value, converting boolean to a string
    Serial.println(allowPut ? "TRUE" : "FALSE");
  }
  else {
    Serial.print("Could not get the value of 'allow put' in section '/upload': ");
    printErrorMessage(ini.getError());
  }
}


void loop()
{


}

When I run CardInfo. with the default pin definition it doesn't work.
The code below if from CardInfo.

Code:
// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
// Teensy audio board: pin 10
// Teensy 3.5 & 3.6 on-board: BUILTIN_SDCARD
// Wiz820+SD board: pin 4
// Teensy 2.0: pin 0
// Teensy++ 2.0: pin 20
const int chipSelect = 4;

When replace pin 4 with BUILTIN_SDCARD
I get the proper Serial Ouput telling me the card is communicating.

If anyone has a straight forward solutions for the INIFile integration I'd be very happy and grateful.
As I said I am really only needing a few values to be stored on the SD card.

Thanks!
 
Well, if Cardinfo works, and his example not, then the logical answer is: Something is wrong with his code.
Or with some hardware connected to your teensy.

Try to begin with minimal code:
Code:
#include <SD.h>

#define SD_SELECT BUILTIN_SDCARD

void setup()
{
 

  if (!SD.begin(SD_SELECT))
    while (1)
      Serial.println("SD.begin() failed");
  
  
  Serial.println("SD.begin() OK");
}


void loop()
{
}

Then try to add more and more of his code.
Inifile library first, ethernet last.
 
The example in https://github.com/stevemarple/IniFile works for me on T3.6. I copied net.ini to the microSD card, then on the T3.6 i ran SD example, File > Examples >SD > listfiles with const int chipSelect = BUILTIN_SDCARD; and confirmed net.ini was on the SD card. Then in IniFile example I used #define SD_SELECT BUILTIN_SDCARD
Code:
In setup() after Serial.begin(9600), I added
[B]  while(!Serial);
  Serial.println("hello");[/B]

and I got the following ouput on monitor

hello
Ini file exists
section 'network' has an entry 'mac' with value 01:23:45:67:89:AB
Could not read 'nosuchkey' from section 'network', error was key not found
Could not read 'nosuchkey' from section 'nosuchsection', error was section not found
The value of 'allow put' in section '/upload' is TRUE
 
The example in https://github.com/stevemarple/IniFile works for me on T3.6. I copied net.ini to the microSD card, then on the T3.6 i ran SD example, File > Examples >SD > listfiles with const int chipSelect = BUILTIN_SDCARD; and confirmed net.ini was on the SD card. Then in IniFile example I used #define SD_SELECT BUILTIN_SDCARD
Code:
In setup() after Serial.begin(9600), I added
[B]  while(!Serial);
  Serial.println("hello");[/B]

and I got the following ouput on monitor

hello
Ini file exists
section 'network' has an entry 'mac' with value 01:23:45:67:89:AB
Could not read 'nosuchkey' from section 'network', error was key not found
Could not read 'nosuchkey' from section 'nosuchsection', error was section not found
The value of 'allow put' in section '/upload' is TRUE

This was a huge help. Got it working. Thank you everyone!
 
I would love a snippet of code that will read the value from SD and use it in the program as a variable? I am failing to get it right lol.
 
That library on GitHub which was already liked above contains an example: https://github.com/stevemarple/IniFile
I am having a heck of a time on using one of the variables on the SD card as a variable in my program. Should be fairly simple to read and store as variable on setup.

I am trying to store API key and IP address.

Code:
#include <SD.h>

#include <SPI.h>
#include <IniFile.h>

// The select pin used for the SD card
#define SD_SELECT BUILTIN_SDCARD

void printErrorMessage(uint8_t e, bool eol = true)
{
  switch (e) {
  case IniFile::errorNoError:
    Serial.print("no error");
    break;
  case IniFile::errorFileNotFound:
    Serial.print("file not found");
    break;
  case IniFile::errorFileNotOpen:
    Serial.print("file not open");
    break;
  case IniFile::errorBufferTooSmall:
    Serial.print("buffer too small");
    break;
  case IniFile::errorSeekError:
    Serial.print("seek error");
    break;
  case IniFile::errorSectionNotFound:
    Serial.print("section not found");
    break;
  case IniFile::errorKeyNotFound:
    Serial.print("key not found");
    break;
  case IniFile::errorEndOfFile:
    Serial.print("end of file");
    break;
  case IniFile::errorUnknownError:
    Serial.print("unknown error");
    break;
  default:
    Serial.print("unknown error value");
    break;
  }
  if (eol)
    Serial.println();

}

void setup()
{
  // Configure all of the SPI select pins as outputs and make SPI
  // devices inactive, otherwise the earlier init routines may fail
  // for devices which have not yet been configured.
  pinMode(SD_SELECT, OUTPUT);
  digitalWrite(SD_SELECT, HIGH); // disable SD card

  const size_t bufferLen = 80;
  char buffer[bufferLen];
  String API;

  const char *filename = "/CONFIG.ini";
  Serial.begin(9600);
  SPI.begin();
  if (!SD.begin(SD_SELECT))
    while (1)
      Serial.println("SD.begin() failed");
  
  IniFile ini(filename);
  if (!ini.open()) {
    Serial.print("Ini file ");
    Serial.print(filename);
    Serial.println(" does not exist");
    // Cannot do anything else
    while (1)
      ;
  }
  Serial.println("Ini file exists");

  // Check the file is valid. This can be used to warn if any lines
  // are longer than the buffer.
  if (!ini.validate(buffer, bufferLen)) {
    Serial.print("ini file ");
    Serial.print(ini.getFilename());
    Serial.print(" not valid: ");
    printErrorMessage(ini.getError());
    // Cannot do anything else
    while (1)
      ;
  }
  
  // Fetch a value from a key which is present
  if (ini.getValue("network", "ip", buffer, bufferLen)) {
    Serial.print("section 'network' has an entry 'ip' with value ");
    Serial.println(buffer);
  }
  else {
    Serial.print("Could not read 'ip' from section 'network', error was ");
    printErrorMessage(ini.getError());
  }

  // Fetch a value from a key which is present
  if (ini.getValue("credentials", "apikey", buffer, bufferLen)) {
    Serial.print("section 'credentials' has an entry 'apikey' with value ");
  }
  else {
    Serial.print("Could not read 'apikey' from section 'credentials', error was ");
    printErrorMessage(ini.getError());
  }
 
}


void loop()
{
  delay(5000);


}
 
Status
Not open for further replies.
Back
Top