Using data retrieved from an SD card...

Been playing with the Arduino's for a while, just basic programming and having a blast doing so.

But now I ran into something that's over my head I believe, and need some help/examples.
I've created a variable frequency oscillator (VFO) for use with an older radio that I have and it's all with an Arduino Due and some add-on shields.
Whenever the frequency is changed, I store the data (of the new frequency) on an SD card as a text file. The object with this is upon power up, I return to the same (last stored) frequency in Mhz. For example 6500000
The writing and reading of the SD card works fine, it reads 6500000, but getting this (value) back into the program as my "start" frequency has me completely baffled.
How can I convert this data (in a text format I presume) back to an integer value (probably needs to be a long int value).

I've hunted the net, found examples of atoi(), atol(), but I cannot get it to work. It is 100% related to my lack of C knowledge so i'm hoping to get some help and or examples.

Regards, Bart

How can I convert this data (in a text format I presume) back to an integer value (probably needs to be a long int value).

Well, I was going to suggest atol() or strtoul(), but you say that you've tried them.

Of source, you didn't post any code, or explain what happened when you tried them. So, all we can do is offer condolences.

Here is a snippet of the code;

    VFO_A_Stored = SD.open("VFO_A.TXT");
    if (VFO_A_Stored) {
      Serial.println("Reading  VFO_A.TXT:");
      while (VFO_A_Stored.available()) {
        Serial.write(VFO_A_Stored.read());
      }
      VFO_A_Stored.close();
    }
    rx = atol(VFO_A_Stored.read());
    Serial.print("Stored-RX =");
    Serial.println(rx);

The result is an invalid conversion error.(s) It seems I'm missing something and do not know the proper usage of atol...

AD9850_DDS_Bart_Due.ino: In function 'void setup()':
AD9850_DDS_Bart_Due:395: error: invalid conversion from 'int' to 'const char*'
AD9850_DDS_Bart_Due:395: error: initializing argument 1 of 'long int atol(const char*)'

It seems I'm missing something and do not know the proper usage of atol...

It's quite simple, really. atol() converts a string to a long. A string is a NULL terminated array of chars. NOT ONE CHAR!

PaulS

Thanks, but it's not that simple for me. I'm a noob at this picking up bits and pieces from this forum and the net.
I'm not sure what the term NULL terminated is....if an array of characters is a series of characters then I should have that when the value of xxxxxxxx is in the file being read correct?

if an array of characters is a series of characters then I should have that when the value of xxxxxxxx is in the file being read correct?

It may be, but you are only reading ONE character at a time, and trying to convert that ONE character to an unsigned long. AND, the character that you are trying to read is beyond the end of the closed file.

In the while loop, you need to store the characters in an array, NULL terminating it after each character is added. Then, after you close the file, call atol() with the array as the argument.

You might want to look at An Arduino based DDS-60 controller | The Ladder Line.

I built the circuit described therein to use as a signal generator, rather than a VFO. Frequency storage is accomplished in EEPROM rather than an external SD card.

The routines may give you some ideas on how to store your last used frequency data.

73,
-__-

Thanks Ross,
I had a look at the link and using the Uno, or Mega the save to eeprom works, but in my case I'm using a Due which has no eeprom memorry function.

Paul, looks like I have to hunt down some examples somewhere on array's to get a better understanding of it all.

Thanks,

Bart

Bartje64:
Thanks Ross,
I had a look at the link and using the Uno, or Mega the save to eeprom works, but in my case I'm using a Due which has no eeprom memorry function.

Paul, looks like I have to hunt down some examples somewhere on array's to get a better understanding of it all.

Thanks,

Bart

Pity...the DDS VFO would have been a great alternative.

Regards,
John (Ross is the DDS project author)

Pity...the DDS VFO would have been a great alternative.

Regards,
John (Ross is the DDS project author)
[/quote]

John,
This project started because I had a desire to couple my TS-830 to my pc, so that the LP pan-adapter would track the radio.
I've got a TS 590 that does that, but wanted to play and learn.
Arduino is a great learning platform, parts/pieces are easily obtainable over the net (flea-bay) and are low cost. This makes it great for beginners (me).

I solved the problem after three days of searching, trying, failing and trying again. The forum here is a great source of info although for some it is easy to say "you could do it like this". it may be easy for some but not to all (myself included).
Here is how I got it to work, I'm sure there may be a better way...

  VFO_A_Stored = SD.open("VFO_A.TXT");
  if (VFO_A_Stored) {
    CTE_LCD.Put_Text("Reading  VFO_A.TXT", VFO_A_HOR, VFO_A_VERT + 29, BVS_74);
    //Serial.println("Reading  VFO_A.TXT:");
    while (VFO_A_Stored.available()) {
      Vfa_Mill = VFO_A_Stored.parseInt();
      Vfa_Hthou = VFO_A_Stored.parseInt();
      Vfa_Tthou = VFO_A_Stored.parseInt();
      Vfa_thou = VFO_A_Stored.parseInt();
      Vfa_hun = VFO_A_Stored.parseInt();
      Vfa_ten = VFO_A_Stored.parseInt();
      Vfa_one = VFO_A_Stored.parseInt();
      Vfa_end = VFO_A_Stored.parseInt();       // dummy read to terminate parseInt(), without it it returns all zeros for some reason.
      delay(75);
      //(VFO_A_Stored.read());
      //Serial.write(VFO_A_Stored.read());
    }
    VFO_A_Stored.close();
    CTE_LCD.Put_Text("Reading  VFO_A.TXT.......  Done", VFO_A_HOR, VFO_A_VERT + 29, BVS_74);
  } else {
    delay(1500);
    CTE_LCD.Put_Text("Error opening VFO_A.TXT              ", VFO_A_HOR, VFO_A_VERT + 29, BVS_74);
    //Serial.println("Error opening VFO_A.TXT");
  }
    String ABC = ( String(Vfa_Mill) + String(Vfa_Hthou) + String(Vfa_Tthou) + String(Vfa_thou) + String(Vfa_hun) + String(Vfa_ten) + String(Vfa_one) );
    char VfO_A_Read[8];
    ABC.toCharArray(VfO_A_Read, 8);
    rx = atoi(VfO_A_Read);
    //Serial.print("Stored-RX =");
    //Serial.println(rx);

Not the complete code, just the segments.......I can post it all, just let me know.

73

Bart

Can you please post the full code... i am too facing the same problem in retrieving value from sd card..

Bartje64:
John,
This project started because I had a desire to couple my TS-830 to my pc, so that the LP pan-adapter would track the radio.
I've got a TS 590 that does that, but wanted to play and learn.
Arduino is a great learning platform, parts/pieces are easily obtainable over the net (flea-bay) and are low cost. This makes it great for beginners (me).

I solved the problem after three days of searching, trying, failing and trying again. The forum here is a great source of info although for some it is easy to say "you could do it like this". it may be easy for some but not to all (myself included).

73

Bart

Glad you got it working. I'll copy your code for reference as I'll be saving and recalling data from an SD card to send to a display program I wrote (unfinished) in Real Basic a while back for my Mac.

73,
John

Here it is....not fully completed yet...
I cannot post the entire code as it exceeds the max characters allowed, so here is the part on reading the card and converting the read data.
I will also post how I write to the card.

  //******************** Initialize the SPI ******************************************************************//

  SPI.begin(52); // initialize the bus for a device on pin 52, This is the SPI Flash for the text.

  SPI.begin(53); // initialize the bus for a device on pin 53, This is the SD card.

  //******************************** Initialize the LCD screen ************************************************//
  CTE_LCD.SPI_Flash_init(FLASH_CS_PIN);
  myGLCD.InitLCD();
  myGLCD.clrScr();

  // **************** LCD background colors, text colors, text background color *****************//

  myGLCD.setColor(0, 0, 0);                   // for all the draw fill and print commands
  myGLCD.setBackColor(R, G, B);               // background for all the draw fill and print commands
  myGLCD.fillScr(R, G, B);                    // fill the screen color

  //***************************** Define the pin for storage on the SD card and read the data on the card ************************************//

  CTE_LCD.Put_Text("Initializing  SD  card...", VFO_A_HOR, VFO_A_VERT + 29, BVS_74);
  //Serial.print("Initializing SD card...");
  delay(1500);
  pinMode(SS, OUTPUT);

  if (!SD.begin(chipSelect)) {
    CTE_LCD.Put_Text("Initialization  failed !", VFO_A_HOR, VFO_A_VERT + 29, BVS_74);
    CTE_LCD.Put_Text("Check  card  or  configuration", VFO_B_HOR, VFO_B_VERT + 29, BVS_74);
    //Serial.println("initialization failed!");
    delay(1500);
    return;
  }
  CTE_LCD.Put_Text("Initialization  done.       ", VFO_A_HOR, VFO_A_VERT + 29, BVS_74);
  //Serial.println("initialization done.");
  delay(3000);

  VFO_A_Stored = SD.open("VFO_A.TXT");
  if (VFO_A_Stored) {
    CTE_LCD.Put_Text("Reading  VFO_A.TXT", VFO_A_HOR, VFO_A_VERT + 29, BVS_74);
    //Serial.println("Reading  VFO_A.TXT:");
    while (VFO_A_Stored.available()) {
      Vfa_Mill = VFO_A_Stored.parseInt();
      Vfa_Hthou = VFO_A_Stored.parseInt();
      Vfa_Tthou = VFO_A_Stored.parseInt();
      Vfa_thou = VFO_A_Stored.parseInt();
      Vfa_hun = VFO_A_Stored.parseInt();
      Vfa_ten = VFO_A_Stored.parseInt();
      Vfa_one = VFO_A_Stored.parseInt();
      Vfa_end = VFO_A_Stored.parseInt();       // dummy read to terminate parseInt(), without it it returns all zeros for some reason.
      delay(75);
      //(VFO_A_Stored.read());
      //Serial.write(VFO_A_Stored.read());
    }
    VFO_A_Stored.close();
    CTE_LCD.Put_Text("Reading  VFO_A.TXT.......  Done", VFO_A_HOR, VFO_A_VERT + 29, BVS_74);
  } else {
    delay(1500);
    CTE_LCD.Put_Text("Error opening VFO_A.TXT              ", VFO_A_HOR, VFO_A_VERT + 29, BVS_74);
    //Serial.println("Error opening VFO_A.TXT");
  }

  VFO_B_Stored = SD.open("VFO_B.TXT");
  if (VFO_B_Stored) {
    CTE_LCD.Put_Text("Reading  VFO_B.TXT", VFO_A_HOR, VFO_A_VERT + 29, BVS_74);
    Serial.println("Reading  VFO_B.TXT:");
    while (VFO_B_Stored.available()) {
      delay(75);
      (VFO_B_Stored.read());
      //Serial.write(VFO_B_Stored.read());
    }
    VFO_B_Stored.close();
    CTE_LCD.Put_Text("Reading  VFO_B.TXT.......   Done", VFO_A_HOR, VFO_A_VERT + 29, BVS_74);
  } else {
    delay(1500);
    CTE_LCD.Put_Text("Error opening VFO_B.TXT                ", VFO_A_HOR, VFO_A_VERT + 29, BVS_74);
    //Serial.println("Error opening VFO_B.TXT");
    delay(1500);
  }
  //------------------------ Convert the values stored on the SD card --------------------------------------------------//
  /* Notes:
     The values stored on the SD card are in text format, seperated by commas.
     These values are read as individual integers by the "parseInt" command.....and placed in a string "VFO_A_Stored_Freq".
     From there the string "VFO_A_Stored_Freq" is converted to a char array "char VFO_A_Read[8]"...
     and finally handed to the atoi (char to integer) command "rx=atoi(VfO_A_Read)".
  */
  if (ForceFreq == 1) {

    String VFO_A_Stored_Freq = ( String(Vfa_Mill) + String(Vfa_Hthou) + String(Vfa_Tthou) + String(Vfa_thou) + String(Vfa_hun) + String(Vfa_ten) + String(Vfa_one) );
    char VfO_A_Read[8];
    VFO_A_Stored_Freq.toCharArray(VfO_A_Read, 8);
    rx = atoi(VfO_A_Read);
    //Serial.print("Stored-RX =");
    //Serial.println(rx);
  }

Here is the "write" part to the SD card..
It's crude, but it works....
Also you may see a lot of //Serial.print(xxxx) in my code. I found these to be my best friend when troubleshooting. I just "un comment" them when I needed to.

void storeMEM() {
  //Serial.println("loop store mem");

  int_fast32_t rxprnt = (rx + (Multiplier * 1000000));

  SD.remove("VFO_A.TXT");

  VFO_A_Stored = SD.open("VFO_A.TXT", FILE_WRITE);

  // if the file opened okay, write to it:
  if (VFO_A_Stored) {
    //Serial.print("Writing to VFO_A.TXT...");
    VFO_A_Stored.print(rx / 1000000);
    VFO_A_Stored.print(",");
    VFO_A_Stored.print((rx / 100000) % 10);
    VFO_A_Stored.print(",");
    VFO_A_Stored.print((rx / 10000) % 10);
    VFO_A_Stored.print(",");
    VFO_A_Stored.print((rx / 1000) % 10);
    VFO_A_Stored.print(",");
    VFO_A_Stored.print((rx / 100) % 10);
    VFO_A_Stored.print(",");
    VFO_A_Stored.print((rx / 10) % 10);
    VFO_A_Stored.print(",");
    VFO_A_Stored.println((rx / 1) % 10);
    // close the file:
    VFO_A_Stored.close();
    //Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    //Serial.println("error opening VFO_A.TXT");
  }
  memstatus = 1;  // Let program know memory has been written

};