Variable corruption

I am using Arduino Uno and PixyCam5.

I'm having problems with x,y coordinates from Pixy. Hello World runs perfectly well as does one of my programs. But after I added some more code things began to behave weirdly. The blocks from Pixy always look good just as they do in Hello World. But immediately after picking up the y coordinate and executing a little math on it, it turns in to garbage or some very high or low number. Other variables become corrupt also like "leftLimit" & "rightLimit". And the weirdness is that there are times but infrequent when some of these variables may appear good. The source code is below; the first source behaves very well but not the second where you'll see I have added code. But for the life of me I can't see anything wrong with the code. However I'm not well versed in C. My only concern here is with the y coordinate that is captured in a variable called "moveNumber". So don't concern yourself with any motors or their behavior. They work very well when given the appropriate command.

Oh well, too many characters in the message so I'll only post the bad program and follow-up with the good program if requested.
Thanks,
Paul

This one NOT so well...
[code]//
// begin license header
//
// This file is part of Pixy CMUcam5 or "Pixy" for short
//
// All Pixy source code is provided under the terms of the
// GNU General Public License v2 (http://www.gnu.org/licenses/gpl-2.0.html).
// Those wishing to use Pixy source code, software and/or
// technologies under different licensing terms should contact us at
// cmucam@cs.cmu.edu. Such licensing terms are available for
// all portions of the Pixy codebase presented here.
//
// end license header
//
// This sketch is a simple tracking demo that uses the pan/tilt unit.  For
// more information, go here:
//
// http://cmucam.org/projects/cmucam5/wiki/Run_the_Pantilt_Demo
//

#include <SPI.h>  
#include <Pixy.h>
#include <AccelStepper.h>

int motorSpeed = 9600; //maximum steps per second (about 3rps / at 16 microsteps)
int motorAccel = 95000; //steps/second/second to accelerate
int microStepsPerPixel = 6;  // 100 microsteps ~= .75" - 1000 microsteps ~= 7.875"
int minStepCount = 64;  // about 1/4"
int minObjectSize = 100; //min Object Size
int minOneSize = 0;
int minTwoSize = 0;
int motorDirPin = 8; //digital pin 8
int motorStepPin = 7; //digital pin 7
int motorPin = 3;
int motorPin2 = 5;

//set up the accelStepper intance
//the "1" tells it we are using a driver
AccelStepper stepper(1, motorStepPin, motorDirPin); 
Pixy pixy;

#define X_CENTER        ((PIXY_MAX_X-PIXY_MIN_X)/2)       
#define Y_CENTER        ((PIXY_MAX_Y-PIXY_MIN_Y)/2)
void printTMF(uint16_t blocks);

void setup()
{
  Serial.begin(9600);
  Serial.print("Starting...\n");
  pixy.init();
  
  stepper.setMaxSpeed(motorSpeed);
  stepper.setSpeed(motorSpeed);
  TWBR = ((F_CPU /400000l) - 16) / 2; // Change the i2c clock to 400KHz
  //AFMS.begin(1000);  // OR with a different frequency, say 1KHz
  stepper.setAcceleration(motorAccel); 
  pinMode(motorPin, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  analogWrite(motorPin, LOW);
  analogWrite(motorPin2, LOW);
  analogWrite(motorPin, 200);
  analogWrite(motorPin2, 200);
}

void loop()
{ 
  static int i = 0;
  int j;
  uint16_t blocks;
  char buf[32]; 
  int32_t moveNumber, moveNumber2, paddelWheel, ballObject, leftLimit, rightLimit, leftLimitMax, rightLimitMax;
  moveNumber, paddelWheel, ballObject, leftLimit, rightLimit, leftLimitMax, rightLimitMax = 0;
  blocks = pixy.getBlocks();
  int ddistanceToGo;
  
  if (blocks)
  {
    delay(100);
    //blocks = pixy.getBlocks();
    ballObject, paddelWheel, leftLimit, rightLimit = 0;
    for (j=0; j<blocks; j++)
    {
      if (pixy.blocks[j].signature == 1 && paddelWheel == 0 &&
        pixy.blocks[j].width * pixy.blocks[j].height > minObjectSize)
          {
          paddelWheel = pixy.blocks[j].y;
          minOneSize = pixy.blocks[j].width * pixy.blocks[j].height;
          }
      if (pixy.blocks[j].signature == 3 && ballObject == 0 &&
        pixy.blocks[j].width * pixy.blocks[j].height > minObjectSize)
          {
          ballObject = pixy.blocks[j].y;
          minTwoSize = pixy.blocks[j].width * pixy.blocks[j].height;
          }
     if (pixy.blocks[j].signature == 10 && (leftLimit == 0 || rightLimit == 0) &&
        pixy.blocks[j].width * pixy.blocks[j].height > minObjectSize)
          {
          if (pixy.blocks[j].y < Y_CENTER)
            {
              Serial.print("Left limit before  = + 10...");
              Serial.println(leftLimit);
              leftLimit = pixy.blocks[j].y + 10;
              Serial.print("Left Limit after + 10...");
              Serial.println(leftLimit);
              delay(500);
            }
          else
            {
              Serial.print("Right limit before  = - 10...");
              Serial.println(rightLimit);
              rightLimit = pixy.blocks[j].y - 10;
              Serial.print("Right Limit after - 10...");
              Serial.println(rightLimit);
              delay(500);
            }
          }
    }
    moveNumber = (paddelWheel - ballObject)*(microStepsPerPixel);
    leftLimitMax = (paddelWheel - leftLimit)*(microStepsPerPixel);
    rightLimitMax = (rightLimit - paddelWheel)*(microStepsPerPixel);
    if (moveNumber > 0 && moveNumber > leftLimitMax)  //Moving Left and beyond the Max!
      {
        moveNumber = leftLimitMax;
      }
    if (moveNumber < 0 && abs(moveNumber) > rightLimitMax)  //Moving Right and beyond the Max!
      {
        moveNumber = -(rightLimitMax);
      }
    moveNumber = -moveNumber; 
    ddistanceToGo=stepper.distanceToGo();    
    if (abs(moveNumber) >= (minStepCount)&& paddelWheel>0 && (stepper.distanceToGo() == 0)) //min steps, not moving and we have a ball in play!
    {
      
      printTMF(blocks);
      Serial.print("Move Number...");
      Serial.println(moveNumber);
      Serial.print("Left Limit Move...");
      Serial.println(leftLimitMax);
      Serial.print("paddelWheel...");
      Serial.println(paddelWheel);
      Serial.print("ballObject...");
      Serial.println(ballObject);
      Serial.print("Right Limit Move...");
      Serial.println(rightLimitMax);
      Serial.print("Dist to go ...");
      Serial.println(ddistanceToGo);
      Serial.print("minOneSize...");
      Serial.println(minOneSize); 
      Serial.print("minTweoSize...");
      Serial.println(minTwoSize);
      stepper.move(moveNumber); //move & allign with ballObject
      while (stepper.distanceToGo()!=0)
      {
        stepper.run();
      }
      delay(50);
    }
    i++;

  }
  stepper.run();  
}

    // do this (print) every 50 frames because printing every
    // frame would bog down the Arduino
void printTMF(uint16_t blocks)
  {
    int j;
    char buf[32]; 
    sprintf(buf, "Detected %d:\n", blocks);
    Serial.print(buf);
    for (j=0; j<blocks; j++)
    {
      sprintf(buf, "  block %d: ", j);
      Serial.print(buf); 
      pixy.blocks[j].print();
    }
  }

[/code]

[/code]

  moveNumber, paddelWheel, ballObject, leftLimit, rightLimit, leftLimitMax, rightLimitMax = 0;This line probably won't do anything useful.

int motorAccel = 95000; //steps/second/second to accelerate

On a Uno, 95000 will not fit in an int.

   ballObject, paddelWheel, leftLimit, rightLimit = 0;

Don't do this crap. Use separate assignment statements, chain them:

   ballObject = paddelWheel = leftLimit = rightLimit = 0;

You are possibly running out of memory. Quit wasting SRAM:
Serial.print(F("Starting...\n"));

Memory issue! That never dawned on me. Could be. What did you mean by wasting SRAM: Serial.print(F("Starting...\n")); ??

String constants being printed should use F() macro (you can't use it in all cases where you could use a c string, but you can do it anywhere it's being fed to print or println), otherwise the string takes up both RAM and flash, instead of just flash - even though it's never going to change.

Thanks. This change alone reduced my variable space by 13%! Currently the compile shows the sketch uses 41% and variables use 26%.

Are these hard fixed numbers? Or can the program and/or variable space grow larger than this during execution?

The program can't grow bigger, but RAM usage could.

AWOL:
The program can't grow bigger, but RAM usage could.

I don't see any Strings, and pixy.h/pixy.cpp doesn't have any malloc calls in it - so unless you're throwing monstrous local variables onto the stack, you shouldn't be having ram problems...

Could you be overrunning the bounds of an array somewhere?

Good question. I did finally get it working by scaling back the code and changing my serial prints. And any time I try to add just one tiny function it blows up again. I don't know how to thank Y'all enough!! I should have posted this question a week ago!!

But I'm still unclear as to where all the memory is going. I was well under 50% of both variable & program space. Maybe DrAzzy is on to something from above. I wanted to tweak this and add on to it but that aint gonna happen in it's current state.

Here it is in action...
Hockey Game

Here is the code...

//
// begin license header
//
// This file is part of Pixy CMUcam5 or "Pixy" for short
//
// All Pixy source code is provided under the terms of the
// GNU General Public License v2 (http://www.gnu.org/licenses/gpl-2.0.html).
// Those wishing to use Pixy source code, software and/or
// technologies under different licensing terms should contact us at
// cmucam@cs.cmu.edu. Such licensing terms are available for
// all portions of the Pixy codebase presented here.
//
// end license header
//
// This sketch is a simple tracking demo that uses the pan/tilt unit.  For
// more information, go here:
//
// http://cmucam.org/projects/cmucam5/wiki/Run_the_Pantilt_Demo
//

#include <SPI.h>  
#include <Pixy.h>
#include <AccelStepper.h>

int motorSpeed = 9600; //maximum steps per second (about 3rps / at 16 microsteps)
int32_t motorAccel = 85000; //steps/second/second to accelerate
int microStepsPerPixel = 13;  // 100 microsteps ~= .75" - 1000 microsteps ~= 7.875"
int minStepCount = 28;  // about 1/4"
int minObjectSize = 100; //min Object Size
int minOneSize = 0;
int minTwoSize = 0;
int motorDirPin = 8; //digital pin 8
int motorStepPin = 7; //digital pin 7
int motorPin = 3;
int motorPin2 = 5;
int mcuMotorSpeed = 175;
int playerMotorSpeed = 175;
// Pixels/inch = 16
//set up the accelStepper intance
//the "1" tells it we are using a driver
AccelStepper stepper(1, motorStepPin, motorDirPin);
Pixy pixy;

#define X_CENTER        ((PIXY_MAX_X-PIXY_MIN_X)/2)       
#define Y_CENTER        ((PIXY_MAX_Y-PIXY_MIN_Y)/2)
void printTMF(uint16_t blocks);

void setup()
{
  //Serial.begin(9600);
  //Serial.print(F("Starting...\n"));
  pixy.init();
  
  stepper.setMaxSpeed(motorSpeed);
  stepper.setSpeed(motorSpeed);
  TWBR = ((F_CPU /400000l) - 16) / 2; // Change the i2c clock to 400KHz
  //AFMS.begin(1000);  // OR with a different frequency, say 1KHz
  stepper.setAcceleration(motorAccel); 
  pinMode(motorPin, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  analogWrite(motorPin, mcuMotorSpeed);
  analogWrite(motorPin2, playerMotorSpeed);
}

void loop()
{ 
  static int i = 0;
  int j;
  uint16_t blocks;
  char buf[32]; 
  int32_t moveNumber, paddelWheel, ballObject, leftLimit, rightLimit, leftLimitMax, rightLimitMax;
  blocks = pixy.getBlocks();
  int ddistanceToGo;
  
  if (blocks)
  {
    //delay(100);
    //blocks = pixy.getBlocks();
    ballObject = paddelWheel = leftLimit = rightLimit = moveNumber = leftLimitMax = rightLimitMax = 0;
    for (j=0; j<blocks; j++)
    {
      if (pixy.blocks[j].signature == 1 && paddelWheel == 0 &&
        pixy.blocks[j].width * pixy.blocks[j].height > minObjectSize)
          {
          paddelWheel = pixy.blocks[j].y;
          minOneSize = pixy.blocks[j].width * pixy.blocks[j].height;
          }
      if (pixy.blocks[j].signature == 3 && ballObject == 0 &&
        pixy.blocks[j].width * pixy.blocks[j].height > minObjectSize)
          {
          ballObject = pixy.blocks[j].y;
          minTwoSize = pixy.blocks[j].width * pixy.blocks[j].height;
          }

     if (pixy.blocks[j].signature == 10 && (leftLimit == 0 || rightLimit == 0) &&
        pixy.blocks[j].width * pixy.blocks[j].height > minObjectSize)
          {
          if (pixy.blocks[j].y < Y_CENTER)
            {
              leftLimit = pixy.blocks[j].y + 6;
            }
          else
            {
              rightLimit = pixy.blocks[j].y - 6;
            }
          }
    }
    moveNumber = (paddelWheel - ballObject)*(microStepsPerPixel);
    leftLimitMax = (paddelWheel - leftLimit)*(microStepsPerPixel);
    rightLimitMax = (rightLimit - paddelWheel)*(microStepsPerPixel);
    if (moveNumber > 0 && moveNumber > leftLimitMax)  //Moving Left and beyond the Max!
      {
        moveNumber = leftLimitMax;
      }
    if (moveNumber < 0 && abs(moveNumber) > rightLimitMax)  //Moving Right and beyond the Max!
      {
        moveNumber = -(rightLimitMax);
      }
    //moveNumber = -moveNumber; 
    ddistanceToGo=stepper.distanceToGo();    
    if (abs(moveNumber) >= (minStepCount) && ballObject>0 && paddelWheel>0 && (stepper.distanceToGo() == 0)) //min steps, not moving and we have a ball in play!
    {
      
//      printTMF(blocks);
//      Serial.print(F("Move Number..."));
//      Serial.println(moveNumber);
//      Serial.print(F("Left Limit Move..."));
//      Serial.println(leftLimitMax);
//      Serial.print(F("paddelWheel..."));
//      Serial.println(paddelWheel);
//      Serial.print(F("ballObject..."));
//      Serial.println(ballObject);
//      Serial.print(F("Right Limit Move..."));
//      Serial.println(rightLimitMax);
//      Serial.print(F("Dist to go ..."));
//      Serial.println(ddistanceToGo);
//      Serial.print(F("minOneSize..."));
//      Serial.println(minOneSize); 
//      Serial.print(F("minTweoSize..."));
//      Serial.println(minTwoSize);
      stepper.move(moveNumber); //move & allign with ballObject
      while (stepper.distanceToGo()!=0)
      {
        stepper.run();
      }
      //delay(50);
    }
    i++;

  }
  stepper.run();  
}

    // do this (print) every 50 frames because printing every
    // frame would bog down the Arduino
//void printTMF(uint16_t blocks)
//  {
//    int j;
//    char buf[32]; 
//    sprintf(buf, "Detected %d:\n", blocks);
//    Serial.print(buf);
//    for (j=0; j<blocks; j++)
//    {
//      sprintf(buf, "  block %d: ", j);
//      Serial.print(buf); 
//      pixy.blocks[j].print();
//    }
//  }
//