reading data from sd card for test fixture project

Hello all,

I am building a test fixture to test stepping switches (AKA stepping relay AKA a uniselector). The stepping switches are driven off a PWM signal. The switch rotates to the next position (12 positions total) when the interrupt signal which is built into the switch is triggered (based off time since PWM input). The main thing I’m checking for is the time between the PWM signal going high and the interrupt signal kicking in. (some of these switches have the wrong time built in so they can not be used) So far I have a code that works well. I have a start button that once pushed causes the script to begin. The times between the 12 “steps” are read and displayed on an LCD. The 12 readings are then stored into an array and are saved onto an sd card.

Here is the issue that I’m encountering. I need to be able to pull the 12 readings from the SD card and display them back on the LCD.
I have a separate code that can read the content and display it on the serial monitor but I am unable to figure out how to pull the information from the SD and put it back on the LCD screen. Preferably I would be able to scroll through the values using an “up” and a “down” button.

MAIN CODE

// -------------------------------------------LIBRARIES-------------------------------------------------------------------------------
#include <LiquidCrystal.h>
//initialize the library by associating any needed LCD interface pin
//with the arduino pin number it is connected to
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 10, d7 = 9;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
#include <SD.h>
#include <SPI.h>
// -----------------------------------------CONSTANTS (won't change)------------------------------------------------------------------

const int pwmPin =  22;                    // the pin numbers for PWM Signal
const int PulseLowTime = 970;              // number of millisecs that the PWM signal is LOW
const int PulseHighTime = 30;              // number of millisecs that the PWM signal is HIGH
const int Signal_A_Pin = 2;                //Detects PWM Signal "A"
const int Signal_B_Pin = 3;                //Interupt Signal "B"
int buttonPin;
byte start;
// --------------------------------------VARIABLES (will changes)---------------------------------------------------------------------
int numbPositions=12;
int i=1;
unsigned long currentMillis = 0;           // stores the value of millis() in each iteration of loop()             
unsigned long previousPWM_Millis = 0;      // will store last time the PWM signal was updated
byte pwmState = LOW;                       //   LOW = initally LOW
byte Signal_A_State = LOW;                 //   LOW = initally LOW
byte Signal_B_State = LOW;                 //   LOW = initally LOW
int ReadA= digitalRead(Signal_A_Pin);
int ReadB= digitalRead(Signal_B_Pin);
unsigned long Signal_A_Time =0;
unsigned long Signal_B_Time =0;
unsigned long Delta_T =0;
int TimeArray[12];

int chipSelect=53; //sets chip select= 53
File myFile;
// ------------------------------------------VOID SETUP--------------------------------------------------------------------------

void setup() {
Serial.begin(9600);
Serial.println("Stepping Swich Test Unit");           // This is printed for testing to ensure program is running
Serial.println("");
pinMode (53, OUTPUT); //Reserves 53 as an output for sd card
pinMode(pwmPin, OUTPUT);                              //Set pwmPin as OUTPUT
pinMode(Signal_A_Pin, INPUT);                         //Set Signal_A_Pin as Input
pinMode(Signal_B_Pin, INPUT_PULLUP);                 //Set Signal_B_Pin as Input
lcd.begin(16, 2);                                    // set up the LCD's number of columns and rows:
  buttonPin = 34; //whatever pin your button is plugged into
  pinMode(buttonPin, INPUT_PULLUP);
lcd.print("Step Switch Test");                       // Print a message to the LCD.
SD.begin (chipSelect);
SD.remove ("Read.txt");
}

// ------------------------------------------VOID LOOP--------------------------------------------------------------------------------

void loop() {
  if(digitalRead(buttonPin) == HIGH) //functions based off of button pulling input pin LOW
  {start=HIGH;}
  if(start==HIGH){
//i=i+1;
//Serial.println (i);
// none of the actions happen in loop() apart from reading millis()
// it just calls the functions that perform the actions
currentMillis = millis();   
// capture the latest value of millis()
// this is equivalent to noting the time from a clock
update_PWM_State();
update_Signal_A_State();
update_Signal_B_State();
//update_display();


  }}


// ------------------------------------------------FUNCTIONS--------------------------------------------------------------------------


// ----------update_PWM_State FUNCTION----------------

void update_PWM_State() {
if (pwmState == LOW) {
// if the PWM signal coming from pwmPin is LOW----we must wait until the low period is over
if (currentMillis - previousPWM_Millis >= PulseLowTime) {
// time is up, so change the state to HIGH
pwmState = HIGH; //Changes the reference state from low to high
digitalWrite (pwmPin, HIGH); //Sends PWM pulse high
// and save the time when we made the change
previousPWM_Millis += PulseLowTime; //
// NOTE: The previous line could alternatively be
//previousPWM_Millis = currentMillis
//Which is the style used in the BlinkWithoutDelay example sketch
//Adding on the interval is a better way to ensure that succesive periods are identical
//Serial.println ("PWM Pulse HIGH");         
}
 }
else {  // i.e. if pwmState is HIGH
//if the PWM is HIGH, we must wait for the duration to expire before turning it LOW
if (currentMillis - previousPWM_Millis >= PulseHighTime) {
// time is up, so change the state to LOW
pwmState = LOW;
digitalWrite (pwmPin, LOW);
//and save the time when we made the change
previousPWM_Millis += PulseHighTime;
//Serial.println ("PWM PULSE LOW ");     
} 
 }
  }
// ----------update_Signal_A_State FUNCTION----------------

void update_Signal_A_State() {
ReadA=digitalRead(Signal_A_Pin);
if (Signal_A_State == LOW) {
//Serial.println (" Signal A State LOW");
if (ReadA==HIGH) {
Signal_A_State=ReadA;
//Serial.println ("ReadA HIGH");
Signal_A_Time=micros();
// Serial.println (Signal_A_Time);
}
 }
if(Signal_A_State == HIGH) {
//Serial.println (" Signal A State HIGH");
if (ReadA==LOW) {
Signal_A_State=ReadA;
// Serial.println ("ReadA LOW");          
}
 }
  }
  
// ----------update_Signal_B_State FUNCTION----------------

void update_Signal_B_State() {
ReadB=digitalRead(Signal_B_Pin);
if (Signal_B_State == LOW) {
// Serial.println (" Signal B State LOW");
if (ReadB==HIGH) {
Signal_B_State=ReadB;
//Serial.println ("ReadB HIGH");
Signal_B_Time=micros();
 //Serial.println (Signal_B_Time);
if (i<numbPositions+1) {
if (Signal_A_State==Signal_B_State){
Delta_T = (Signal_B_Time-Signal_A_Time);
TimeArray[i] = Delta_T;
Serial.print( "Time" );
Serial.print(i);
Serial.print (": ");
Serial.print (TimeArray[i]);
Serial.println (" uS");
myFile= SD.open("Read.txt", FILE_WRITE);//open Read.txt on the sd card as a file to write to
if (myFile) {//Serial.print ("File opened");
 myFile.print( "Time" );
myFile.print(i);
myFile.print (": ");
myFile.print (TimeArray[i]);
myFile.print (" uS");
myFile.print (", ");
myFile.close();
  
}

//Serial.print( "Time between Pulses : " );
//Serial.print (Delta_T);
//Serial.println( "uS " );
lcd.setCursor(0, 1);
lcd.print(Delta_T);
lcd.setCursor(5, 1);
lcd.print(" uS");
lcd.setCursor(9, 1);
lcd.print("Step#");
lcd.setCursor(14, 1);
lcd.print(i);
i=i+1; 
if (i==numbPositions+1){
  delay (750);

  Serial.println ("");
  Serial.println ("Test Complete");
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print ("Test Complete");
  }
}}
 
}}


if(Signal_B_State == HIGH) {
// Serial.println (" Signal B State HIGH");
if (ReadB==LOW) {
Signal_B_State=ReadB;
//  Serial.println ("ReadA LOW");     
}
 }
}


// ----------update_display FUNCTION----------------

//void update_display() {



 // }
//}

READ CODE

#include <SD.h>
 
File myFile;
 
void setup()
{
  Serial.begin(9600);
  Serial.print("Initializing SD card...");
   pinMode(53, OUTPUT);
 
  if (!SD.begin(53)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
 
  // open the file for reading:
  myFile = SD.open("Read.txt");
  if (myFile) {
    Serial.println("Read.txt:");
 
    // read from the file until there's nothing else in it:
    while (myFile.available()) {
        Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening Read.txt");
  }
}
 
void loop()
{
  // nothing happens after setup
}

Your read code is just the SD datadumper example sketch. When you read the data from the file, rather than just printing it to the Serial monitor, you need to store it in an array and then parse that array to retrieve the values and then send them to the lcd.

Based on the code that writes the data, you never insert a newline so your data will look like "Time 1: 12345 uS, Time 2: 3456 uS, Time 3: 4567 uS, " ....

If you want to more easily retrieve these values, I'd suggest a better format when writing the data. Ignore all the text around the numbers and put each pair on a separate line.

Also, C arrays begin at index 0, not 1 which means you are writing beyond the end of your TimeArray[]. It goes from 0..11 and your index 'i' goes from 1..12 before stopping.

"you need to store it in an array and then parse that array to retrieve the values and then send them to the lcd."

This is what I'm having trouble doing.

I changed the format as you suggested so now it stores on the sd card in the following format:

Initializing SD card...initialization done. Read.txt: 16996 16972 16968 16968 16972 16972 16996 16968 16968 16972 16968 16968

how can I write these values to an array so that I can use them with the LCD?

blh64: Your read code is just the SD datadumper example sketch. When you read the data from the file, rather than just printing it to the Serial monitor, you need to store it in an array and then parse that array to retrieve the values and then send them to the lcd.

Based on the code that writes the data, you never insert a newline so your data will look like "Time 1: 12345 uS, Time 2: 3456 uS, Time 3: 4567 uS, " ....

If you want to more easily retrieve these values, I'd suggest a better format when writing the data. Ignore all the text around the numbers and put each pair on a separate line.

Also, C arrays begin at index 0, not 1 which means you are writing beyond the end of your TimeArray[]. It goes from 0..11 and your index 'i' goes from 1..12 before stopping.

Can you please provide guidance on how to "to store it in an array and then parse that array to retrieve the values and then send them to the lcd."

#include <SD.h>
 
File myFile;

const int numArray = 12;
int TempArray[numArray];

void setup()
{
  Serial.begin(9600);
  Serial.print("Initializing SD card...");
   pinMode(53, OUTPUT);
 
  if (!SD.begin(53)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
 
  // open the file for reading:
  myFile = SD.open("Read.txt");
  if (myFile) {
    Serial.println("Read.txt:");
 
    // read from the file until there's nothing else in it:
    int currentIdx = 0;
    int currentValue = 0;
    while (myFile.available()) {
        int c = myFile.read();
        if ( c == '\n' ) {
          // new value, so store the old one and increment
          TempArray[currentIdx] = currentValue;
          currentValue = 0;
          currentIdx++;
          if ( currentIdx >= numArray ) break;
        }
        else {
          currentValue = currentValue * 10 + (c - '0');
        }
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening Read.txt");
  }
}
 
void loop()
{
  // nothing happens after setup
}