Passing Arrays and Arrays of Strings to Functions

Hello Everyone,

Below is a module from a program I have written for a jig for use with a table saw.

The cutSteps function setups up an array for stepping a stepper motor, the printSteps function prints the results to the serial monitor. The problem I am having is highlighted with // PROBLEM HERE //. Although I’m not exactly sure the problem is there.

If the the code is executed the printSteps function prints an index,cutArr and strArr to the serial monitor. If the cutArr[ i ] = fingerSteps; is enabled the first element in the strArr prints jibberish to the serial monitor. All of the indices AFTER the first element of both cutArr and strArr print as they should. If cutArr[ i ] = fingerSteps; is disabled the first element in strArr prints like it should, ie. CUT. I’ve attached a screenshot that shows the output of the code with cutArr[ i ] = fingerSteps; enabled.

What is most puzziling is the cutArr[ i ] = fingerSteps; is modifying cutArr not strArr. I can’t seem to make sense of why strArr would print jibberish for its first element when it is not the array being modified. To add to the confusion this only happens sometimes when bladeWidth and jointWidth are not equal to each other. Try changing bladeWidth and jointWidth to other values with cutArr[ i ] = fingerSteps; enabled.

Am I passing cutArr and strArr to cutSteps properly? Could this be an issue with memory? I have the baud rate set correctly.

Thanks!

float bladeWidth = 2.55;
float jointWidth = 6.50;
float distPerStep = 0.00635;
int cutArr[75];
char *strArr[75];

void cutSteps( int *cutArr, char **strArr, float glue ){

  int i = 1;
  int j = 0;

  int bladeSteps = floor(bladeWidth / distPerStep);
  int firstSlotSteps = floor(( jointWidth + glue ) / distPerStep);
  int fingerSteps = floor(( jointWidth - ( 2 * glue ) ) / distPerStep);
  int slotSteps = floor(( jointWidth + ( 2 * glue ) ) / distPerStep);

  for ( j = 0; j < 75; j++ ){
    cutArr[ j ] = 0;
    strArr[ j ] = " ";
  }

  while ( firstSlotSteps > 0 ){
    if ( firstSlotSteps > bladeSteps ){
      cutArr[ i ] = bladeSteps;
      strArr[ i ] = "CUT";
    }
    if ( firstSlotSteps <= bladeSteps && firstSlotSteps > 0 ){
      cutArr[ i ] = firstSlotSteps;
      strArr[ i ] = "CUT";
    }
    firstSlotSteps = ( firstSlotSteps - bladeSteps );
    i++;
  }

  cutArr[ i ] = fingerSteps;
  strArr[ i ] = "NO CUT";
  i++;

  for ( i; i < 75; ){
    while ( slotSteps > 0 ){
      if ( slotSteps > bladeSteps ){
        cutArr[ i ] = bladeSteps;
        strArr[ i ] = "CUT";
      }
      if ( slotSteps <= bladeSteps && slotSteps > 0 ){
        cutArr[ i ] = slotSteps;
        strArr[ i ] = "CUT";
      }
      slotSteps = ( slotSteps - bladeSteps );
      i++;
    }  

    ////////// PROBLEM HERE ///////////////////////////////////////////
    //cutArr[ i ] = fingerSteps;
    ///////////////////////////////////////////////////////////////////
    strArr[ i ] = "NO CUT";
    slotSteps = ( ( jointWidth + ( 2 * glue ) ) / distPerStep );  
    i++;
  }
}

void printSteps( int *cutArr, char **strArr ){

  int i;

  for ( i = 1; i < 75 ; i++ ){
    if ( i < 10 ){
      Serial.print( i );
      Serial.print( "    |  " );
    }
    else{
      Serial.print( i );
      Serial.print( "   |  " );
    }
    Serial.print( cutArr[ i ] );
    if ( cutArr[ i ] < 10 )
      Serial.print("     |   ");
    if ( cutArr[ i ] < 100 && cutArr[ i ] >= 10 )
      Serial.print("    |   ");
    if ( cutArr[ i ] >= 100 && cutArr[ i ] < 1000 )
      Serial.print("   |   ");
    if ( cutArr[ i ] >= 1000 )
      Serial.print("  |   ");
    Serial.print( strArr[ i ] );
    Serial.println();
  }
}

void setup(){
  Serial.begin( 9600 );
  cutSteps( cutArr, strArr, 0.00 );
  printSteps( cutArr, strArr);
}

void loop(){
}

First of all, with absolutely no comments, it's hard to follow. Since we don't really know about the application, we don't know what a finger, a blade or a cut or a slot really is. It isn't that we need to know for itself, but for an understanding of why you're doing things. In other words, how things might supposed to work. Otherwise, it's clever puzzle solving. That can sometimes be fun, but the reward has a point of diminishing returns. Having said that, I will look at it.

to make it easier for me to open a terminal in time, I changed setup() like this:

void setup(){
  delay(5000);
  Serial.begin( 9600 );
  cutSteps( cutArr, strArr, 0.00 );
  printSteps( cutArr, strArr);
}

With that, I'm not seeing gibberish, with or without the "problem here" line.

(minus update - now I think I was looking crooked. basically though I'd worry that "i" could be out of bounds, greater than 74, at that problem line)

I've had that problem before, but it was intermittent. I put anything like a delay in the code because for me, it never happened with anything but a demo sketch. Anybody know more about this? Is it in the Serial or in the IDE? Is there a more elegant fix?

By the way, this sketch produces no output for me. Just sits there doing nothing.

When I increase the size of the arrays to 175, it works with or without the problem line. So you likely have an overflow.

aarg & johnhikes -

thank you for the responses. im still not quite sure what the problem is but increasing the arrays seems to have solved the problem. i tried adding delay (5000); in setup but the problem persisted for me.

aarg - i didn’t comment the original code because it was working how it was designed with the exception of the first element of the strArr behaving strangely. the explanation of the code is tied pretty tightly to the physical machine it controls but i’ve tried to add comments to help conceptually understand what is going on.

the machine is used with a table saw for cutting finger joints, i’ve attached images of what a finger joints are. the cutSteps function below basically sets up all of the steps required to create finger joints using a single table saw blade and making consecutive passes to achieve a desired width. hope that makes sense, its not the easiest thing to describe.

if this is an overflow problem can anyone with more experience chime in?

thanks!

float bladeWidth = 2.55;
float jointWidth = 6.50;
float distPerStep = 0.00635;
int cutArr[75];
char *strArr[75];

void cutSteps( int *cutArr, char **strArr, float glue ){

  int i = 1;
  int j = 0;

//simple math to determine different groups of steps for the stepper motor
//relative to the width of a table saw blade and the desired joint width
  int bladeSteps = floor(bladeWidth / distPerStep);
  int firstSlotSteps = floor(( jointWidth + glue ) / distPerStep);
  int fingerSteps = floor(( jointWidth - ( 2 * glue ) ) / distPerStep);
  int slotSteps = floor(( jointWidth + ( 2 * glue ) ) / distPerStep);

  for ( j = 0; j < 75; j++ ){
    cutArr[ j ] = 0;
    strArr[ j ] = " ";
  }

//firstSlotSteps is broken up into bladeSteps sized chunks and placed in cutArr
  while ( firstSlotSteps > 0 ){
    if ( firstSlotSteps > bladeSteps ){
      cutArr[ i ] = bladeSteps;
//CUT and NO CUT are displayed on a 16x2 LCD screen 
      strArr[ i ] = "CUT";
    }
    if ( firstSlotSteps <= bladeSteps && firstSlotSteps > 0 ){
      cutArr[ i ] = firstSlotSteps;
      strArr[ i ] = "CUT";
    }
    firstSlotSteps = ( firstSlotSteps - bladeSteps );
    i++;
  }

//after the firstSlotSteps is complete a finger is added
  cutArr[ i ] = fingerSteps;
  strArr[ i ] = "NO CUT";
  i++;

//the rest of the slots are broken up into bladeSteps sized chunks
  for ( i; i < 75; ){
    while ( slotSteps > 0 ){
      if ( slotSteps > bladeSteps ){
        cutArr[ i ] = bladeSteps;
        strArr[ i ] = "CUT";
      }
      if ( slotSteps <= bladeSteps && slotSteps > 0 ){
        cutArr[ i ] = slotSteps;
        strArr[ i ] = "CUT";
      }
      slotSteps = ( slotSteps - bladeSteps );
      i++;
    }  

//a finger is added everytime slotSteps reaches 0 (or less)
    ////////// PROBLEM HERE ///////////////////////////////////////////
    //cutArr[ i ] = fingerSteps;
    ///////////////////////////////////////////////////////////////////
    strArr[ i ] = "NO CUT";
//slotSteps is reset allowing the pattern to continue
    slotSteps = ( ( jointWidth + ( 2 * glue ) ) / distPerStep );  
    i++;
  }
}

//just a print function for the serial monitor, pretty self explanatory
void printSteps( int *cutArr, char **strArr ){

  int i;

  for ( i = 1; i < 75 ; i++ ){
    if ( i < 10 ){
      Serial.print( i );
      Serial.print( "    |  " );
    }
    else{
      Serial.print( i );
      Serial.print( "   |  " );
    }
    Serial.print( cutArr[ i ] );
    if ( cutArr[ i ] < 10 )
      Serial.print("     |   ");
    if ( cutArr[ i ] < 100 && cutArr[ i ] >= 10 )
      Serial.print("    |   ");
    if ( cutArr[ i ] >= 100 && cutArr[ i ] < 1000 )
      Serial.print("   |   ");
    if ( cutArr[ i ] >= 1000 )
      Serial.print("  |   ");
    Serial.print( strArr[ i ] );
    Serial.println();
  }
}

void setup(){
  Serial.begin( 9600 );
  cutSteps( cutArr, strArr, 0.00 );
  printSteps( cutArr, strArr);
}

void loop(){
}


bradburydoom: What is most puzziling is the cutArr[ i ] = fingerSteps; is modifying cutArr not strArr. I can't seem to make sense of why strArr would print jibberish for its first element when it is not the array being modified.

Because cutArrr and stringArr are lying next to each other in memory, and the value of i at this point is outside the range 0-74. C treats the index of an array as an offset. If you go x[-3]=2, it will happily scribble the number 2 over whatever happened to by lying in memory 6 bytes in front of the space allocated to array x.