Hi all, I'm very new to Arduino. The project that I'm working on is taking measurements from a pressure sensor over a period of time, then I want to find out how much it changes over time (what I'm hoping to see is the pressure to stay the same or within an acceptable range). My problem is the data I'm getting at 0 PSI are quite constant but they are not 0 (for example -0.43). The way I scale it is my pressure sensor range from 0.5-4.5V so I calculated 1024*(0.5/5) for min and 1024*(4.5/5) for max and that is my analog range.
My goal is I want to be able to measure it at any pressure, fox example 30 PSI. Make 30 to be 0, then if the pressure leaks and goes down to 29 PSI, it will show 1 PSI drop. So that I can also maybe (?) overlook the problem that it's been giving me -0.43, can I just make -.43 be 0, the any data after that becomes data+0.43?
And I don't know how to code it either. So do you guys have any advice? Thank you in advance!!
Couple of points
*By default the analog input uses the 5v power supply as its reference , if your transducer is separately powered any drift here will change the output .in this case you would be better off using the internal 1.1v reference - if you put a link to the data sheet up we can tell.
given the above , you can’t therefore use the sort of calculation you have in your sketch , you need to calibrate that analog input .
-look at the spec of the transducer and calculate what the error figures really mean.
I'm currently connecting my pressure sensor to the 5V supply from the arduino, I don't know if that helps clarify things or not. I don't know how to calibrate the input, right now I have the output at -0.2 to -0.3 pretty consistently, sometimes 0.
The one I have is 100 PSI. It is in PSI, I mapped 0.5V to 0 PSI, 4.5V to 100 PSI. I thought it was the sensor problem at first but I've watched some videos where the exact same sensor was used and they got it to show at 0 PSI. In addition, I also tried to replace this sensor to a 4-20mA sensor that has 0.01% accuracy and I had the same problem of not reach 0 (always a couple decimals off). I'm so frustrated, please send help.
update: i'm suspecting that the problem is my sensor is not giving out an output at exact 0.5V when no pressure was applied (0 PSI) so my mapping is off. But I'm not really sure what the best way to solve this problem is.
Maybe just include a calibration/offset routine that measures the sensor's output at 0 PSI and subtract that offset from subsequent measurements? Or do you have documentation that says the zero point offset should be exactly 0.5000V?
Do not be frustrated! ALL instruments, if the documentation is truthful, will tell you there is a huge error as the zero point is approached. That is why documentation only gives the full scale error.
Paul
If your automobile speedometer is analog, it will not have any numbers between 0 and perhaps 5 mph.
Once you have calibrated the sensor, you will need to ignore any readings close to zero. Or if close to zero is important, you will need to find a sensor with documentation showing it really is able to correctly show values as close to zero as you want.
Mathematically, the becomes a larger number the closer to the number zero you get. It is a percent, after all.
Paul
Thank you all for all your responds! If I can only get close to 0, is there a way I can do what koraks said that include a calibration/offset routine that measures the sensor's output (subtract an amount to make it 0) then subtract the same amount from the rest of the measurements? Because this way would help me when I'm measuring something that already has pressure in it too.
What I generally do in a case like this is write a routine that runs once during startup, with the routine ensuring that the sensor is decoupled from any input, read a couple of values (let's say 10 or 20 or so), average them and then store that as the offset for use later on in the software.
I'm really new, I kind of understand what you mean but can you give me an example? I'm trying to include an average calculation right now (hopefully I can reduce some noises and get a more stable reading). Once I finish adding the average part in, I'll put the code up
#define NUM_MEASUREMENTS 20 //Let's say we use 20 measurements to get a stable average
uint8_t PIN_SENSOR = 14; //I don't know what pin you use; pick an ADC pin
int offset_measurement = 0; //We can use this throughout our sketch after we have filled it with the appropriate value at the start
void setup() {
pinMode (PIN_SENSOR, INPUT);
offset_measurement = determine_offset();
}
void loop() {
// put your main code here, to run repeatedly:
// In any measurement you do, you can now use offset_measurement to subtract it from the value you get
//Your other code goes here...
}
int determine_offset ()
{
unsigned long offset_measurements = 0; //Let's used unsigned long so we don't run into overflows or anything
for (uint8_t i = 0; i < NUM_MEASUREMENTS; i ++)
{
offset_measurements += analogRead(PIN_SENSOR);
}
return int(offset_measurements / NUM_MEASUREMENTS);
}
No guarantees that the code works, BTW. I compiled it, but didn't test it. It's just to illustrate the principle.
Please note that @Boffin's comment still stands. The above code is a way to determine the offset. It's not a complete calibration, as it does not determine the slope yet.
const int numMeasurements = 20;
uint8_t pinSensor = A0;
int offsetMeasurement = 0;
const double pressureZero = 102.3; //analog reading of pressure transducer at 0psi
const double pressureMax = 920.7; //analog reading of pressure transducer at 100psi
const int pressuretransducermaxPSI = 100; //psi value of transducer being used
const int baudRate = 9600; //constant integer to set the baud rate for serial monitor
const int sensorreadDelay = 5000; //constant integer to set the sensor read delay in milliseconds
double pressureValue = 0;
void setup() {
Serial.begin(9600);
pinMode (pinSensor, INPUT);
offsetMeasurement = determine_offset();
}
void loop() {
pressureValue = analogRead(pinSensor) - offsetMeasurement;
pressureValue = ((pressureValue-pressureZero)*pressuretransducermaxPSI)/(pressureMax-pressureZero);
Serial.println(pressureValue, 1);
delay(sensorreadDelay);
}
int determine_offset()
{
unsigned long offsetMeasurement = 0;
for (uint8_t i = 0; i<numMeasurements; i++)
{
offsetMeasurement += analogRead(pinSensor);
}
return int(offsetMeasurement/numMeasurements);
}
Thank you so so much! This is what I have so far. Does it look right to you? And I don't really understand @Boffin's comment. What else do I need to add in?
I think you may need to remove the pressureZero variable from your loop(). Weve replaced it now with something else, right?
Boffin's comment is essentially about your pressureMax variable. Just like with the offset, do you know for sure that the maximum value that you determined theoretically is actually what the ADC reads in the real world?
You're right about the pressureZero but I don't think we can remove it. The way I calculated pressureZero is 1024*(0.5/5), so does it mean I'll have to add the offset in the pressureZero?
That's also a part of the problem, I have no way to make sure that I'm putting in exactly 100 PSI but I'm not too worried about that since the larger the PSI the more accurate it gets (full scale right?).
Another concern is that I'll usually get -0.2 to -0.3 as my output when there's no pressure, so what should I do if that is the case (because right now we're assuming that the reading values are higher than the expected, what if it's the other way around?)