reading sd file line by line, intersected with "code"

Hi there,

I am working on having a sort of gcode interpreter for a animatronic puppet.
I made a little program to create animations in a simple file, with on each line the coordinates for all the joints.
The lines look like this:
xH -3.838107 yH 18.29 zH 1.292844 J -3.838107
xH -0.123238 yH -2.246664 zH -0.004836089 J -0.1232

I did find how i could go into reading line by line, but, just like with gcode, i need to separate the values so i can apply them to the joints.

Thus far i have not found something helpful, so i hope you can be of help!

The values seem to be separated by spaces. You could use strtok to pull them out one at a time.

Thanks for the reference to strtok.
I managed to get the following code, but with one last issue, in the void readSD, where i call the function readCode, i need to have to myFile.read converted to a char* i tried several options but couldn’t get it to work right.
Also the myFile.read is seen as an int, which should be a string as it contains non-numbers.

I managed to convert it to char, but then ofcourse i get the error cannot convert char to char*

Code:

#include <string.h>
#include <SPI.h>
#include <SD.h>

File myFile;

int SSPIN = 4;
int joints = 4;
char delimiters[] = " xH yH zH J ";
int frametime = 0;

void setup()
{
  Serial.begin(9600);
  while (!Serial) {
    ;
  }
  
  Serial.print("Initializing SD card...");

  if (!SD.begin(SSPIN)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  
  
  //char instring[] = "xH 16.3 yH 5.5 zH 40.5 J 30.3";
}
  


void loop()
{
  
}
void readSD ()
{
  myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("test.txt:");

    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      readCode(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
}
void readCode (char instring[])
{
    
  char* valPosition;
  
  //This initializes strtok with our string to tokenize
  valPosition = strtok(instring, delimiters);
  
 
  
  if(valPosition != NULL){
    for(int i=0; i < joints; i++)
    {
      if(i == 0)
        {
            Serial.println("Move Servo xH to:");
        }
      if(i == 1)
        {
            Serial.println("Move Servo yH to:");
        }
      if(i == 2)
        {
            Serial.println("Move Servo zH to:");
        }
      if(i == 3)
        {
            Serial.println("Frame Delay:");
        }
      Serial.println(valPosition);
    
      frametime = atof(valPosition);
      //Here we pass in a NULL value, which tells strtok to continue working with the previous string
      valPosition = strtok(NULL, delimiters);     
      }
    }
    Serial.println("Delay:");
    Serial.println(frametime);
    delay(frametime);
}

in the void readSD

You’d sound less like a clueless-newbie if you wrote “in the readSD() function”!

i need to have to myFile.read converted to a char*

Why? The read() method returns ONE character. Why do you need a pointer to point to one character?

      readCode(myFile.read());

You are passing ONE character to this function…

  valPosition = strtok(instring, delimiters);

It does not make sense to parse ONE character.

The delimiters are NOT space, x, H, space, y, H, space, z, H, space, J, and space.

The delimiters ARE space.

You need to decide what to do when the token is “xH”, “yH”, “zH”, “J”, or a string representing a numeric value.

Why are you sending the 'H’s anyway?

  char* valPosition;
  
  //This initializes strtok with our string to tokenize
  valPosition = strtok(instring, delimiters);

There is NO advantage in using two lines of code to accomplish this.

  //This initializes strtok with our string to tokenize
  char *valPosition = strtok(instring, delimiters);

The * can be put with the type OR with the variable. The reason for putting it with the variable is that it clearly indicates that the variable is a pointer.

   char *ptr, notPtr;

declares two variables - only one of which is a pointer.

   char* ptr, notPtr;

also declares two variables - only one of which is a pointer, but it is harder to see that the type of the second variable is not a pointer.

   char *ptr, *pAnotherPointer;

declares two variables - both of which are pointers.

Have a look at the parse example in Serial Input Basics. It should give you a sense of the process you need to implement.

…R

Robin2:
Have a look at the parse example in Serial Input Basics. It should give you a sense of the process you need to implement.

…R

Thanks, i will have a look at this!

PaulS:
You’d sound less like a clueless-newbie if you wrote “in the readSD() function”!

I’d also sound less like a cluesless newbie if I wasn’t one. but thanks :slight_smile: