More precise value needed for Sharp IR library

I am using the sharp 2y0a02 IR sensor to send liquid level values to my cell phone via SMS. The code I have below is working well and sending consistent values in CM. The problem is that I need more precision in the form of 2 more decimal places(21.75 as opposed to 22) and am uncertain as to how to do this. Also displayed are the library files being utilized. Do I have to modify the cpp and h files as well as the IDE code? Is there something simple I can do to accomplish this? Thanks in advance.

IDE code

#include <SharpIR.h>


#include <GSM.h>

#define PINNUMBER ""

char txt1[] = "full";
char txt2[] = "empty";
char remoteNum[] = "0123456789";

#define led6 8
#define ir A0
#define model 20150
// ir: the pin where your sensor is attached
// model: an int that determines your sensor:  1080 for GP2Y0A21Y
//                                            20150 for GP2Y0A02Y
//




SharpIR sharp(ir, 25, 93, model);

// initialize the library instance
GSM gsmAccess;
GSM_SMS sms;

void setup() {
 
  Serial.begin(9600);


  Serial.println("SMS Messages Sender");

  // connection state
  boolean notConnected = true;

  // Start GSM shield
  // If your SIM has PIN, pass it as a parameter of begin() in quotes
  while (notConnected) {
    if (gsmAccess.begin(PINNUMBER) == GSM_READY) {
      notConnected = false;
    } else {
      Serial.println("Not connected");
      delay(1000);
    }
  }

  Serial.println("GSM initialized");
}

      void loop() {
        // put your main code here, to run repeatedly:
       

        
        delay(2000);

        unsigned long pepe1 = millis(); // takes the time before the loop on the library begins

        int dis = sharp.distance(); // this returns the distance to the object you're measuring


        Serial.print("Mean distance: ");  // returns it to the serial monitor
        Serial.println(dis);

        if (dis <= 50) {
          sms.beginSMS(remoteNum);
          sms.print(txt1);
          sms.endSMS();         
           Serial.println("\nCOMPLETE!\n");
        }
        else {
          sms.beginSMS(remoteNum);
          sms.print(txt2);
          sms.endSMS();
           Serial.println("\nCOMPLETE!\n");
           delay(3600000);
        }
      }

.CPP file

#include "Arduino.h"
#include "SharpIR.h"



SharpIR::SharpIR(int irPin, int avg, int tolerance, int sensorModel) {
  
    _irPin=irPin;
    _avg=avg;
    _tol=tolerance/100;
    _model=sensorModel;
    
    analogReference(DEFAULT);
 
}
)
 

int SharpIR::cm() {
    
    int raw=analogRead(_irPin);
    float voltFromRaw=map(raw, 0, 1023, 0, 5000);
    
    int puntualDistance;
    
    if (_model==1080) {
        
        puntualDistance=27.728*pow(voltFromRaw/1000, -1.2045);
        
    }else if (_model==20150){
    
        puntualDistance=61.573*pow(voltFromRaw/1000, -1.1068);
        
    }
    
    
    return puntualDistance;


}



int SharpIR::distance() {

    _p=0;
    _sum=0;

    
    for (int i=0; i<_avg; i++){
        
        int foo=cm();
        
        if (foo>=(_tol*_previousDistance)){
        
            _previousDistance=foo;
            _sum=_sum+foo;
            _p++;
            
        }
        
        
    }

    
    int accurateDistance=_sum/_p;
    
    return accurateDistance;

}

.H file

#ifndef SharpIR_h
#define SharpIR_h

#include "Arduino.h"

class SharpIR
{
  public:
    SharpIR (int irPin, int avg, int tolerance, int sensorModel);
    int distance();
    
    
  private:
    
    int cm();
    
    int _irPin;
    int _model;
    int _avg;
    int _p;
    int _sum;
    int _previousDistance;
    int _tol;
    
};

#endif
        int dis = sharp.distance(); // this returns the distance to the object you're measuring

Why does the distance() function’s return value get stored in an int?

    int distance();

Why does the function return an int?

The problem is that I need more precision in the form of 2 more decimal places

Do you really think the sensor is accurate to a millimeter? When measuring the distance to a liquid?

PaulS,

I think its stored because it looks for 25 readings within a certain accuracy(93/100) range before it actually returns a value. I could be wrong. I started trying to change the "int" to "float" values but have only gotten it to return an integer with decimal 0's added(i.e. 52.00 instead of 52.34)

As for the sensor, that is what I am working with at the moment and it is possible that I will change it in the future. It is being placed in a closed environment with no external light sources so I feel that it will be close enough for my purposes at the moment. Its an early stage prototype right now. I just need to know how to return the distance value with one or two extra decimal places and I dont know how. Thanks

I started trying to change the "int" to "float" values but have only gotten it to return an integer with decimal 0's added(i.e. 52.00 instead of 52.34)

So, you've made some code changes. That means that you need to post the modified code. Both cm() and distance() need to be modified, in the header and source files.

PaulS,

I had made some code changes but what I posted is the unmodified code that returns a consistent value.

Do they need to be changed to floats instead of integers? Need a value between the ()? Both?

Do they need to be changed to floats instead of integers?

If "they" includes the cm() and distance() function and the variables puntualDistance, foo, _sum, _previousDistance, and accurateDistance, then the answer is yes.

Need a value between the ()?

Between what parentheses? cm() does not take an argument. That it needs to return a float instead does not change that. The same applies to distance().

Thank you so much! It works like I want it to now.

Now I want to add a function into this sensor system. I want the sensor to take a reference distance reading to which all subsequent distances are compared. The function would subtract the reference distance from the subsequent readings and return that value through the gsm network.

Can I use the sharp.distance() function for both of these instances(reference and real time readings) in the same program?

Do I create my own function after the setup and loop functions to return this distance difference?

Ive been fiddling with it and reading for a few hours and have only made myself more confused. If you have any input on the basic coding steps to make this happen, that would be very helpful. Sorry if my questions are elementary. IF you have a link to materials I can read relating to this, that is helpful too. Thanks.

Can I use the sharp.distance() function for both of these instances(reference and real time readings) in the same program?

Of course.

Do I create my own function after the setup and loop functions to return this distance difference?

You hardly need a function to subtract one value from another.

This is what I have so far. Its giving me a negative reference value instead of the difference between the reference and real time value(i.e. -50.00 instead of 0.00 when sensor hasnt moved). Im not sure what ive done wrong but i feel like its in the subtraction arithmetic of the sharp.distance() functions. Any ideas? Thanks

IDE code

#include <SharpIR.h>
#define led 13
#define ir A0
#define model 20150

// ir: the pin where your sensor is attached
// model: an int that determines your sensor:  1080 for GP2Y0A21Y
//                                            20150 for GP2Y0A02Y
//                                            (working distance range according to the datasheets)

SharpIR sharp(ir, 250, 93, model);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

 float dist=sharp.distance(); 
 Serial.print("Reference distance: ");
 Serial.println(dist); 

}

void loop() {
  delay(2000);   

float dist;
  float dis=sharp.distance();  // this returns the distance to the object you're measuring

float dif = dist - dis;
  Serial.print("Distance above reference: ");  // returns it to the serial monitor
  Serial.println(dif);
  

 if (dis <= 50) {
    digitalWrite(led, HIGH);
  }
  else {
    digitalWrite(led, LOW);}

delay(10000);
}

CPP file

#include "Arduino.h"
#include "SharpIR.h"



SharpIR::SharpIR(int irPin, int avg, int tolerance, int sensorModel) {
  
    _irPin=irPin;
    _avg=avg;
    _tol=tolerance/100;
    _model=sensorModel;
    
    analogReference(DEFAULT);
 
}


// When you initialize the library object on your sketch you have to pass all the above parameters:

// irPin is obviously the pin where the IR sensor is attached
// avg is the number of readings the library does
// tolerance indicates how similar a value has to be from the last value to be taken as valid. It should be a
//    value between 0 and 100, like a %. A value of 93 would mean that one value has to be, at least, 93% to the
//    previous value to be considered as valid.
// sensorModel is a int to differentiate the two sensor models this library currently supports:
//    1080 is the int for the GP2Y0A21Y and 20150 is the int for GP2Y0A02YK. The numbers reflect the
//    distance range they are designed for (in cm)
 



float SharpIR::cm() {
    
    int raw=analogRead(_irPin);
    float voltFromRaw=map(raw, 0, 1023, 0, 5000);
    
    float puntualDistance;
    
    if (_model==1080) {
        
        puntualDistance=27.728*pow(voltFromRaw/1000, -1.2045);
        
    }else if (_model==20150){
    
        puntualDistance=61.573*pow(voltFromRaw/1000, -1.1068);
        
    }
    
    
    return puntualDistance;


}



float SharpIR::distance() {

    _p=0.00;
    _sum=0.00;

    
    for (int i=0; i<_avg; i++){
        
        float foo=cm();
        
        if (foo>=(_tol*_previousDistance)){
        
            _previousDistance=foo;
            _sum=_sum+foo;
            _p++;
            
        }
        
        
    }

    
    float accurateDistance=_sum/_p;
    
    return accurateDistance;

}

H file

#ifndef SharpIR_h
#define SharpIR_h

#include "Arduino.h"

class SharpIR
{
  public:
    SharpIR (int irPin, int avg, int tolerance, int sensorModel);
    float distance();
    
    
  private:
    
    float cm();
    
    int _irPin;
    int _model;
    int _avg;
    int _p;
    float _sum;
    float _previousDistance;
    int _tol;
    
};

#endif
 float dist=sharp.distance();
 Serial.print("Reference distance: ");
 Serial.println(dist);

}

Your "reference distance" variable goes out of scope as soon as you print it.

float dist;
  float dis=sharp.distance();  // this returns the distance to the object you're measuring

float dif = dist - dis;

So, you create a new local variable called dist, with who knows what value as contents. Then, you assume that it contains the "reference distance", which is a completely unreasonable assumption.

Try again.

Thanks again! I got it working and returning the values I hoped it would. Here is the fixed code. If you see any possible errors or noob programming excess with it, please let me know.

#include <SharpIR.h>
#define led 13
#define ir A0
#define model 20150
float dist;
float dif;
// ir: the pin where your sensor is attached
// model: an int that determines your sensor:  1080 for GP2Y0A21Y
//                                            20150 for GP2Y0A02Y
//                                            (working distance range according to the datasheets)

SharpIR sharp(ir, 250, 93, model);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);



}

void loop() {
  delay(2000);  
   
 float dist=sharp.distance(); 
  
for(float dist = 0; dist < 2; dist++){

}

  float dis=sharp.distance();  // this returns the distance to the object you're measuring

dif = (dist - dis);

  Serial.print("Distance above reference: ");  // returns it to the serial monitor
  Serial.println(dif);
  

 if (dif <= 50) {
    digitalWrite(led, HIGH);
  }
  else {
    digitalWrite(led, LOW);}

delay(10000);
}

Actually its just looping. and giving a near zero value unless i move it around during one of the delays. Im assuming I need to put something in the for loop? More than that? Im leaning towards all wrong the more I test with it.

float dist=sharp.distance(); 
  
for(float dist = 0; dist < 2; dist++){

}

An empty for loop? Why two variables with the same name? Actually you have one by that name at global scope too, so there are at least three separate variables with the same name. Why?

float dist=sharp.distance(); 
  
for(float dist = 0; dist < 2; dist++){

}

  float dis=sharp.distance();  // this returns the distance to the object you're measuring

So these two reads happen within microseconds of one another. What do you thing the chances of them being different are? Why would you expect anything other than zero here?

Does it make sense to reread a new reference height every pass through loop? To me a reference point would be read once and stay the same.

I obviously have no idea what im doing. Ive abandoned the for loop and have been trying if and else loops and not been able to compile them. The goal is to take a reference reading and use it in a calculation later with a real time reading. Both use the same function. Ill keep messing with it and see where it goes.

gingerbeardman:
I obviously have no idea what im doing. Ive abandoned the for loop and have been trying if and else loops and not been able to compile them. The goal is to take a reference reading and use it in a calculation later with a real time reading. Both use the same function. Ill keep messing with it and see where it goes.

When do you want to take this reference reading? When the Arduino first starts? Whenever someone pushes a button? Every ten minutes?

Id like to take the reading when it first starts. And at some constraint, Im gonna want it to reset the reference(which could just be a command to reset the board). Thanks

Id like to take the reading when it first starts.

When what first starts?

If you mean “when the Arduino first starts”, then do it in setup(). Do NOT call the reference distance dist.

gingerbeardman:
Id like to take the reading when it first starts. And at some constraint, Im gonna want it to reset the reference(which could just be a command to reset the board). Thanks

Ok. What part of your program runs when the board first starts up and doesn't run again unless you reset?

And yeah, heed Pauls advice here. Don't call it dist. Give it a good name that lets you immediately know what it is.