easy question. grab data without constant update

howdy. been a while. my already rusty C++ skills are now fully oxidized.

  if(calibState > 3)
  {  
    long xPlane = map(ircam.Blob1.X,calibration[0],calibration[2],0,101);
    xPlane = constrain(xPlane,0,101);
    static int lastxPlane;
    if(xPlane != lastxPlane && xPlane != 101)
    {
//      Serial.println(xPlane);
      lastxPlane = xPlane;
    }
  }

so, i'm getting a stream of data from ircam.Blob1.X ircam starts and stops sending data at my control. when it does, it turns a bool "lightOn" true or false, respectively what i want is a variable that holds the FIRST ircam.Blob1.X data COLLECTED at every "lightOn" without it being constantly updated by subsequent data.

please let me know if i can explain any better.

I think it'll be easier if you post the entire code.

Is the constrain() call really necessary ? The map call already has 0, 101 as target limits.

Having a static variable defined inside an if {} block is not the best thing IMHO maintenance-wise. I usually declare and initialize the static vars right after the function signature.

My 2 cents...

Is the constrain() call really necessary ? The map call already has 0, 101 as target limits.

http://arduino.cc/en/Reference/map

Does not constrain values to within the range, because out-of-range values are sometimes intended and useful. The constrain() function may be used either before or after this function, if limits to the ranges are desired.

the code in its entirety is even uglier than the snippet i posted, and will all be rewritten as i rediscover what C++ i knew

#include <Wire.h>
#include <PVision.h>
PVision ircam;
byte result;

void setup()
{
  Serial.begin(9600);
  ircam.init();
}

void loop()
{
  static bool lightOn, lightPrint, calibOn;
  static int calibCell;
  static int calibState;
  
  result = ircam.read();
    
  if (result & BLOB1)
    {
      lightOn = true;
      calibOn = true;
      lightPrint = true;
      
  /*    
      Serial.print("BLOB1 detected. X:");
      Serial.print(ircam.Blob1.X);
      Serial.print(" Y:");
      Serial.print(ircam.Blob1.Y);
      Serial.print(" Size:");
      Serial.println(ircam.Blob1.Size);
  */
    }else
    {
      lightOn = false;
      if(lightOn == false && lightPrint == true)
      {
        if(calibState < 3){Serial.println(calibState);}
        lightPrint = false;
        calibState = calibState + 1;
      }
    }

  int calibration[4];
  int X1 = ircam.Blob1.X;
  int Y1 = ircam.Blob1.Y;   

// calibration button is pushed, setting calibCell = 0. additional button pushes ++ calibCell
  
  if(calibOn == true && calibState == 0)
  {
    calibOn = false;
    calibration[0] = X1;
    calibration[1] = Y1;
   }
  if(calibOn == true && calibState == 1)
  {
    calibOn = false;
    calibration[2] = X1;
    calibration[3] = Y1;
   }
  if(calibOn == true && calibState == 2)
  {
    calibOn = false;
    calibration[4] = Y1;
  }
    
  int bottomY;
  if(calibState == 3)
  {
    if(calibration[1] > calibration[3])
    {
      bottomY = calibration[1];
    }else
    {
      bottomY = calibration[3];
    }
    Serial.print("left point: x="); 
    Serial.print(calibration[0]);    //final X1
    Serial.print(", y="); 
    Serial.println(bottomY);  //final Y1
    Serial.print("right point: x="); 
    Serial.print(calibration[2]);    //final X2
    Serial.print(", y="); 
    Serial.println(bottomY);  //same as Y1
    Serial.print("top point: y="); 
    Serial.println(calibration[4]);    //final Y (top)
    Serial.println("__________");
    calibState++;
  }
  
  if(calibState > 3)
  {  
    long xPlane = map(ircam.Blob1.X,calibration[0],calibration[2],0,101);
    xPlane = constrain(xPlane,0,101);
    static int lastxPlane;
    if(xPlane != lastxPlane && xPlane != 101)
    {
//      Serial.println(xPlane);
      lastxPlane = xPlane;
    }
 
    int yPlane = map(ircam.Blob1.Y,calibration[1],calibration[4],0,127);
    yPlane = constrain(yPlane,0,101);
    static int lastyPlane;
    if(yPlane != lastyPlane && yPlane != 101)
    {
      Serial.println(yPlane);
      lastyPlane = yPlane;
    }
  }

  delay(5);
 

}

About map()... damn! I always forget to re-read the reference page before asking stupid questions ;-P

About the code... I'll just throw in other 2 cents, hoping they'll be useful nonetheless...

First thing is good indentation means better code. CTRL-T (if you're using the arduino ide) is your friend :-)

Next, I notice a strange thing:

    else
    {
        lightOn = false;
        if(lightOn == false && lightPrint == true)

Why do you ask yourself is lightOn is false when you just set it to that value ? Perhaps that if statement was meant to be put ouside the previous if else block ?

HTH

Oh, and btw: "my already rusty C++ skills are now fully oxidized." LOL :D

sweet, i had NO IDEA about ctrl T!! ctrl T hank you.

so back to my original question...whenever lightOn becomes true, i want the X blob data to be stored...but not updated. do you get me?

nym: what i want is a variable that holds the FIRST ircam.Blob1.X data COLLECTED at every "lightOn"

What is a ircam.Blob1.X data?

I mean, is it like a number, flag, value that is read by an atomic operation, or is a composite thing such as a frame of data read from a stream?

howdy, Pete. thanks for helping me to clarify.

it is a stream of numbers (the X of the X/Y coordinates) of a pixart infrared camera extracted from a wiimote. so i think you put it eloquently - "a frame of data read from a stream."

it’s from steve hobley’s pvision.h library for the pixart camera.

http://www.stephenhobley.com/blog/2009/03/01/pixartwiimote-sensor-library-for-arduino/

I want the X blob data to be stored...but not updated. do you get me?

"Stored" but not "updated" ? Sorry, no, I don't get you :( but I'll try...

You want to detect when lightOn goes from false to true, and store the X blob data you got in that cycle. In the subsequent cycles, you want that data not to be overwritten by the next X blob data that comes in from the camera... right ?

Maybe you need something like a previousLightOn and a XblogStorage (whatever that means). if previousLightOn is false and lightOn is true then XblobStorage = current X blob data endif previousLightOn = lightOn

I hope those 2 cents make sense... :)

You need to have a way to store a frame of data from the stream. For example, looking for something to tell you when the frame starts, keep reading from the stream until you determine that the frame is complete.

The code to do that needs to have a control variable to enable it.

For example:

  while (stream.available())
  {
    byte data = stream.read();
    if(grabbingFrame)
    {
      // append this to the frame buffer
      buffer[count++] = data;
      if(count > BUFFER_SIZE)
      {
         grabbingFrame = false; // buffer now holds the complete frame
      }
    }
    else
    {
      // discard the data
    }
  }

In the bit of code that handles button presses and works out whether to turn the LED on and off and so on, you would set grabbingFrame=true to make this code grab one frame.

I'm glossing over the code to detect the start and end of the frame because you'd need to know the format of the data stream to know how to do that.