Read values from SD card

Good morning all, please can someone help me here.

I have a script as shown in the code. In my setup, I have connected an SD card, which I can access.
I would like to save the array (lats []) on the SDcard, and read the values from the SDcard, rather than declaring the array on the script.

#include <SdFat.h>
#include <EEPROM.h>

//new SPI pins
const uint8_t SD_CS_PIN     = 31;
const uint8_t SOFT_MOSI_PIN = 33;
const uint8_t SOFT_MISO_PIN = 35;
const uint8_t SOFT_SCK_PIN  = 37;

SoftSpiDriver<SOFT_MISO_PIN, SOFT_MOSI_PIN, SOFT_SCK_PIN> softSpi;
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SD_SCK_MHZ(0), &softSpi)
SdFat SD;


struct LatLon
{
    double Lat;
    double Lon;
    double X;
    double Y;
};


static const LatLon lats [] =
{
    {6.86899, 7.41179, 0, 0},
    {6.86898102641852, 7.41178940176106, 1.5, 2},
    {6.86897205283705, 7.41178880352213, 2.5, 3},
    {6.86896307925557, 7.41178820528321, 4, 5},
    {6.86895410567409, 7.4117876070443, 6, 7},
    {6.86894513209261, 7.4117870088054, 8, 9},
    {6.86893615851114, 7.41178641056651, 10, 11},
    {6.86892718492966, 7.41178581232764, 12, 13},
    {6.86891821134818, 7.41178521408877, 20, 21},
    {6.86890923776671, 7.41178461584992, 32, 34},
};

const int Nlat = sizeof(lats)/sizeof(LatLon);
byte Index = 0;

void setup ()
{
    Serial.begin (9600);
    EEPROM.get(0, Index);
    if (Index >= Nlat)
      Index = 0;

    Serial.print("Initializing SD card...");
    if (!SD.begin(SD_CONFIG)) 
    {
    SD.initErrorHalt();
    }
    else 
    {
    Serial.println("initialization done.");
    }
      
}

void loop ()
{
      float d2g, currentX, currentY;
      int a2g, a2gd;
      d2g = sqrt(sq(lats[Index].X - currentX)-sq(lats[Index].Y - currentY));//distance between two points
      a2g = ((atan2((lats[Index].X - currentX),(lats[Index].Y - currentY)))*57296)/1000;//angle converted from radians to degrees
      a2gd = (360%(a2g+360));//0 to 360 degrees
      
      static float movedX = (0.762/2)*cos(a2gd);
      static float movedY = (0.762/2)*sin(a2gd);
      float initialX = lats[Index].X;
      float initialY = lats[Index].Y;
      currentX = initialX - movedX;
      currentY = initialY + movedY;
      initialX = currentX;
      initialY = currentY;

      Index++;
      //delay(100);
      if (Index >= Nlat)
        Index = 0; // Start over when we run out of destinations
      EEPROM.put(0, Index);

      Serial.print(a2gd);
      Serial.println();
      Serial.print(currentX);
      Serial.println();
      Serial.print(currentY); 
}

What have you tried to achieve this goal? Post your best effort and people will assist.

Write a program to save the array information as CSV to the SD card. Each line on the card contains one entry just like in the code (omit { and }).

Alternatively you can use a spreadsheet program to generate the CSV.

In your final program, read the file on the card line by line.

1 Like

This is what my code looks like now. The GPS.txt data is shown on Serial monitor line by line.
With this, I can read the .txt file from the SD.card.

#include <SdFat.h>
#include <EEPROM.h>

//new SPI pins
const uint8_t SD_CS_PIN     = 31;
const uint8_t SOFT_MOSI_PIN = 33;
const uint8_t SOFT_MISO_PIN = 35;
const uint8_t SOFT_SCK_PIN  = 37;

SoftSpiDriver<SOFT_MISO_PIN, SOFT_MOSI_PIN, SOFT_SCK_PIN> softSpi;
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SD_SCK_MHZ(0), &softSpi)
SdFat SD;

File myFile;

struct LatLon
{
    double Lat;
    double Lon;
    double X;
    double Y;
};


static const LatLon lats [] =
{
    {6.86899, 7.41179, 0, 0},
    {6.86898102641852, 7.41178940176106, 1.5, 2},
    {6.86897205283705, 7.41178880352213, 2.5, 3},
    {6.86896307925557, 7.41178820528321, 4, 5},
    {6.86895410567409, 7.4117876070443, 6, 7},
    {6.86894513209261, 7.4117870088054, 8, 9},
    {6.86893615851114, 7.41178641056651, 10, 11},
    {6.86892718492966, 7.41178581232764, 12, 13},
    {6.86891821134818, 7.41178521408877, 20, 21},
    {6.86890923776671, 7.41178461584992, 32, 34},
};


const int Nlat = sizeof(lats)/sizeof(LatLon);
byte Index = 0;

int array_size = 0; 
int arraycount = 0;

void setup ()
{
    Serial.begin (9600);
    EEPROM.get(0, Index);
    if (Index >= Nlat)
      Index = 0;

    Serial.print("Initializing SD card...");
    if (!SD.begin(SD_CONFIG)) 
    {
    SD.initErrorHalt();
    }
    else 
    {
    Serial.println("initialization done.");
    }

    // Open the file for reading:
  myFile = SD.open("GPS.txt");
  if (myFile) {
    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 GPS.txt");
  }
      
}

void loop ()
{
      float d2g, currentX, currentY;
      int a2g, a2gd;
      d2g = sqrt(sq(lats[Index].X - currentX)-sq(lats[Index].Y - currentY));//distance between two points
      a2g = ((atan2((lats[Index].X - currentX),(lats[Index].Y - currentY)))*57296)/1000;//angle converted from radians to degrees
      a2gd = (360%(a2g+360));//0 to 360 degrees
      
      static float movedX = (0.762/2)*cos(a2gd);
      static float movedY = (0.762/2)*sin(a2gd);
      float initialX = lats[Index].X;
      float initialY = lats[Index].Y;
      currentX = initialX - movedX;
      currentY = initialY + movedY;
      initialX = currentX;
      initialY = currentY;

      Index++;
      //delay(100);
      if (Index >= Nlat)
        Index = 0; // Start over when we run out of destinations
      EEPROM.put(0, Index);

      Serial.print(a2gd);
      Serial.println();
      Serial.print(currentX);
      Serial.println();
      Serial.print(currentY); 
}

Please how can use the data being displayed on serial monitor to replace this part of the code?

static const LatLon lats [] =
{
    {6.86899, 7.41179, 0, 0},
    {6.86898102641852, 7.41178940176106, 1.5, 2},
    {6.86897205283705, 7.41178880352213, 2.5, 3},
    {6.86896307925557, 7.41178820528321, 4, 5},
    {6.86895410567409, 7.4117876070443, 6, 7},
    {6.86894513209261, 7.4117870088054, 8, 9},
    {6.86893615851114, 7.41178641056651, 10, 11},
    {6.86892718492966, 7.41178581232764, 12, 13},
    {6.86891821134818, 7.41178521408877, 20, 21},
    {6.86890923776671, 7.41178461584992, 32, 34},
};

Basically, I want to supply these values from the SDcard, rather than modifying the script and uploading into arduino board anytime the data changes.

Only you can see that. We can't because you didn't post it. Please do so.

Basically, you have to read from the SD card and store it in a char array until you hit the end of the line ('\n'). Then, you have to parse that array using something like strtok() to find the commas and then use atof() to convert the string into an actual floating point number. You will have to do that for all 4 values on the line.
Then store those values in your array (but you can no longer make it const since you are modifying it)

Ok
I will help you

Okay, I would appreciate that.