IR distance sweep scan

I'm setting up two short range Sharp IR sensors on a servo, 90* away from each other. The servo is set to sweep a range from 30*-135* in 15* increments. I'm storing the range scans in an array to be used by a robot for obstacle avoidance. I'm running into a silly snag though. I've got some code written to calibrate the IR sensors on start-up but the rest of the loop is not using the calibration as I expected it to. I expected the code to take the initial calibration value and subtract it from new readings. It doesn't look like that is happening and I'm not sure why.

Here's the code:

#include <Servo.h>
#define leftIR 1
#define rightIR 0

#define Diagnostic1 1 // serial print reading. Set to 1 to print, else 0.
#define Diagnostic2 1 // serial print count etc. Set to 1 to print, else 0.
#define rotate 0 // sets as 1 for servo to rotate, 0 for still

Servo servo1;

int arraysize = 17; // sets size of the scanner arrray
int scanarray[17]; // sets up array variable, set same as arraysize

int Lcalibration;
int Rcalibration;
int calibrationcount = 0;

int wait = 20; // set wait time between angle changes and readings
int angle = 0; // sets initial angle

int i; // variable for counters
int L = 0; // left side counter variable
int R = 8; // right side counter variable

void setup ()
{
  servo1.attach(13);
  Serial.begin(9600);
  calibrate();
}

void loop ()
{  
 scanright();
 
#if Diagnostic1
 for (i = 0; i < arraysize;) {
 Serial.print(scanarray[i]);
 Serial.print(", ");
 i = i + 1;
 } 
 Serial.println();
#endif
 
 scanleft();
 
#if Diagnostic1
 for (i = 0; i < arraysize;) {
 Serial.print(scanarray[i]);
 Serial.print(", ");
 i = i + 1;
 }
 Serial.println();
#endif
 
}

int scanright() {

  for (angle = 30; angle < 150;)
  {
#if rotate
    servo1.write(angle); // rotate the servo to the specified angle
#endif

#if Diagnostic2
    Serial.print(angle);
    Serial.print(", ");
#endif

    delay(wait);
    scanarray[L] = ((analogRead(leftIR)) - Lcalibration);
    scanarray[R] = ((analogRead(rightIR)) - Rcalibration);

#if Diagnostic2
   Serial.print(scanarray[L]);
   Serial.print(", ");
   Serial.print(L);
   Serial.print(", ");
   Serial.print(scanarray[R]);
   Serial.print(", ");
   Serial.println(R);
#endif

    L = L + 1;
    R = R + 1;
    angle = angle + 15;
  }
}

int scanleft(){
  delay(wait);
 for (angle = 150; angle > 30;)
  {
#if rotate
    servo1.write(angle); // rotate the servo to the specified angle
#endif
    
#if Diagnostic2
    Serial.print(angle);
    Serial.print(", ");
#endif
    
    delay(wait);
    scanarray[L] = ((analogRead(leftIR)) - Lcalibration);
    scanarray[R] = ((analogRead(rightIR)) - Rcalibration);
    
#if Diagnostic2
   Serial.print(scanarray[L]);
   Serial.print(", ");
   Serial.print(L);
   Serial.print(", ");
   Serial.print(scanarray[R]);
   Serial.print(", ");
   Serial.println(R);
#endif

    L = L - 1;
    R = R - 1;
    angle = angle -15;


  } 
}

int calibrate()
{
 servo1.write(90);
 delay(500);
 int Lcalibration = analogRead(leftIR); // calibrate IR sensors
 int Rcalibration = analogRead(rightIR);

 Serial.println(Lcalibration);
 Serial.println(Rcalibration);

}

I also have a little bug where the IR readings are piling into the array backwards. I wanted the readings from the middle to be in the middle of the arrray but they are on the outside edges. Probably something simple and dumb that I missed. Any help with either issue is appreciated.

Please modify your post. Remove the code you posted. Then, in the IDE, simply select all your code and paste it in place of that mess there.

The Format for Forum option in the damned IDE should be removed. It does a lousy job.

Yeah, I noticed that and was fixing it when you posted :slight_smile: Thanks!

 int Lcalibration = analogRead(leftIR); // calibrate IR sensors
 int Rcalibration = analogRead(rightIR);

Local variables (in calibrate()) with the same name as global variables are rarely a good idea.

    L = L + 1;
    R = R + 1;
    angle = angle + 15;

Were you a FORTRAN programmer? Don't you like the simplicity of

L++;
R++:
angle += 15;

I've updated my counters to "modern" methods :wink:

PaulS:
Local variables (in calibrate()) with the same name as global variables are rarely a good idea.

In this case I'm using the calibration variables to correct readings in the loop. I tried using different names in the calibrate() function and then setting the Rcalibration an Lcalibration variables equal to them and it still doesn't work.

To clarify my intent: I wish to take an initial reading from the IR sensors at start-up, then subtract that from all future readings as a way to compensate for bright lighting conditions which can affect the IR sensors.

and it still doesn't work.

How do you know it doesn't work? You don't print the before adjustment values read from the sensors, only the after adjustment values. Therefore, you don't know whether the before and after values are different. At least, not in the posted code.

I'd recommend that you use two arrays for the sensor values - one for the left sensor and one for the right sensor, rather than one for both sensors.

You are taking 8 reading from each sensor, in scanleft() and scanright() (but not at the same set of angles). You store the 16 readings in scanarray, which is sized to hold 17. Why 17?

The values from scanleft() are overwritten in scanright(), with nothing done in between except printing. Why is that?

I print the calibration value at the end of the calibrate() function then get roughly the same values back during the loop.

Any particular reason for suggesting two arrays? I used one because I thought it'd be easier to deal with later on for logic decisions. So far this code is just for getting the IR system working. After that is a go I'll be writing in the logic to determine what path the robot should take and adding the motor control systems (already written).

Any particular reason for suggesting two arrays?

You can have one array containing two kinds of data - left sensor data and right sensor data - with two indexes that you need to keep straight, or you can have two arrays, each of which contains one kind of data - left sensor data or right sensor data - with one index.

Your choice.

I print the calibration value at the end of the calibrate() function then get roughly the same values back during the loop.

You should not get roughly the same values in loop. You should get EXACTLY the same values in loop. Assuming we are talking the left and right calibration values.

If the left and right calibration values are the same during scanleft() and scanright() as they are in calibrate(), what is the problem?

PaulS:
You should not get roughly the same values in loop. You should get EXACTLY the same values in loop. Assuming we are talking the left and right calibration values.

These IR sensors have noise in the readings so roughly the same is as good as it gets. Even with a capacitor and a resistor in the data line they vary constantly. This is when the sensors and the area they are reading are static.

If the left and right calibration values are the same during scanleft() and scanright() as they are in calibrate(), what is the problem?

The problem is that I want to take the calibration values and subtract them from future readings as a way to zero the sensors, ie. the scanleft() and scanright() values should return zeros until an object comes into their reading range. I cannot figure out why the code isn't doing that.

I'm not trying to be argumentative, btw, just clarifying. I do appreciate the help you're giving.

These IR sensors have noise in the readings so roughly the same is as good as it gets.

What I meant was that whatever values you come up with (and print out) in calibrate() for Lcalibration and Rcalibration ought to be exactly the same value that Lcalibration and Rcalibration have in scanleft() and scanright().

The problem is that I want to take the calibration values and subtract them from future readings as a way to zero the sensors

I got that. What I don't get is what the problem is, and what proof you have that you have a problem.

Are you printing Lcalibration and Rcalibration in calibrate()? Are you printing Lcalibration and Rcalibration in scanleft() and scanright()? Are the same values printed in each function?

I'm not trying to be argumentative

I'm not, either. But, I don't have your latest code, or your sensors, to try myself. So, I can only rely on you to show your code, show your output, and explain how what-you-get-is-not-what-you-want.

So I added lines to print the Rcalibration and Lcalibration values during the scanright function and both values are reporting as zero. This is after they reported values around 170-200 from the calibration function.

Soooo.... it looks like the values are not being remembered. I changed the initial values of Lcal and Rcal 5 and 6 and those are the values being brought up during the scan loops. The calibrate function runs, reports a real reading and then fails to store it for the other loops to use. I'm thinking it is because the calibration() function is called during a void function (setup), meaning it doesn't return any values later on. Is this the case? Can I call the function some other way before the main loop begins to run? Should I just have it call it once at the beginning of the void loop using a counter and then ignore it thereafter?

EDIT: Tried that to no affect. Then on a whim I deleted the word int from each variable in the calibration() function and now it works. Go figure. I guess they don't like being called an int more than once or something.

Go figure. I guess they don't like being called an int more than once or something.

When the keyword int (or float or double or byte or char) appears, it creates a NEW variable. When that happens inside a function or block, the variable is local to that function and hides a global (or local with larger scope) variable of the same name, until it goes out of scope.

Ah, that explains it. Still new to coding and these details don't seem to be explained anywhere I can find them.

these details don't seem to be explained anywhere I can find them