Although readThermistor returns a higher value than the specs, that's no problem.
Up to 2 metes the sensor and also my code works fine to detect my presence.
But the accuracy is a big issue for that real scenario when the sensor has a distance of 4 meters.
But the accuracy of my readings are dropping after a distance of 2 meters.
Please be specific. What are your actual vs expected values? A change in values at longer distances is to be expected, since the background will occupy a larger percentage of the FOV.
I also don't get ~26°, instead I get ~29° when calling
~26° means "about 26°". The actual value will depend on your actual room temperature - plus any localized heating of the circuitry. 29° sounds like a reasonable value.
Up to 2 metes the sensor and also my code works fine to detect my presence.
But the accuracy is a big issue for that real scenario when the sensor has a distance of 4 meters.
Please post your code and describe the scenario you are testing against.
Such sensors work (of course) with temperature (radiation) difference. In a 37°C room you can not detect an object having also 37°C (provided same emissivity)
If the sensor isn't going to work in my use case after a distance of 2 meters, the product description should really not state that it's up to 7 meters.
At least there should be a note next to it, stating that the accuracy is not going to be as satisfying or not as expteced as you read "7 meters".
/***************************************************************************
This is a library for the AMG88xx GridEYE 8x8 IR camera
This sketch tries to read the pixels from the sensor
Designed specifically to work with the Adafruit AMG88 breakout
----> http://www.adafruit.com/products/3538
These sensors use I2C to communicate. The device's I2C address is 0x69
Adafruit invests time and resources providing this open source code,
please support Adafruit andopen-source hardware by purchasing products
from Adafruit!
Written by Dean Miller for Adafruit Industries.
BSD license, all text above must be included in any redistribution
***************************************************************************/
#include <Wire.h>
#include <Adafruit_AMG88xx.h>
#define CHECK_MEAN 0
#define CHECK_MEDIAN 1
Adafruit_AMG88xx amg;
float pixels[AMG88xx_PIXEL_ARRAY_SIZE];
#if CHECK_MEAN == 1
const int DURCH = 250;
float mean[DURCH] = { 0 };
#endif
#if CHECK_MEDIAN == 1
const int PIKS = 250;
boolean peaked[PIKS] = { false };
#endif
int pos = 0;
void setup() {
Serial.begin(9600);
bool status;
// default settings
status = amg.begin();
if (!status) {
Serial.println("Could not find a valid AMG88xx sensor, check wiring!");
while (1);
}
delay(500); // let sensor boot up
}
#if CHECK_MEDIAN == 1
void loop() {
//read all the pixels
amg.readPixels(pixels);
int peak_count = 0;
for (int i = 1; i <= AMG88xx_PIXEL_ARRAY_SIZE; ++i) {
if (pixels[i - 1] > 24.5) {
++peak_count;
}
}
Serial.print("peaked:");
Serial.print(peak_count);
Serial.print(',');
Serial.print("threshold:");
if (peak_count >= 20) {
peaked[pos] = true;
Serial.print(40);
} else {
peaked[pos] = false;
Serial.print(0);
}
int peakSum = 0;
for (int i = 0; i < PIKS; ++i) {
if (peaked[i]) {
++peakSum;
}
}
Serial.print(',');
Serial.print("PEAKING:");
if (peakSum >= PIKS/2) {
Serial.println(64);
} else {
Serial.println(0);
}
if (++pos >= PIKS) {
pos = 0;
}
//delay a second
delay(1000);
}
#endif
#if CHECK_MEAN == 1
void loop() {
//Serial.print("Thermistor:");
//Serial.print(amg.readThermistor());
//read all the pixels
amg.readPixels(pixels);
mean[pos] = 0;
//Serial.println("[");
for (int i = 1; i <= AMG88xx_PIXEL_ARRAY_SIZE; ++i) {
mean[pos] += pixels[i - 1];
//Serial.print(pixels[i - 1]);
//if (i < AMG88xx_PIXEL_ARRAY_SIZE) {
// Serial.print(", ");
//}
//if ( i % 8 == 0 ) Serial.println();
}
//Serial.println("]");
//Serial.println();
if (mean[pos] != 0) {
mean[pos] /= AMG88xx_PIXEL_ARRAY_SIZE;
}
int count = 0;
float allmean = 0;
for (int i = 0; i < DURCH; ++i) {
if (mean[i] != 0) {
allmean += mean[i];
++count;
}
}
allmean /= count;
//Serial.print("Pos:");
//Serial.print(pos);
//Serial.print(',');
Serial.print("mean:");
Serial.print(mean[pos]);
Serial.print(',');
Serial.print("DURCHSCHNITT:");
Serial.print(allmean);
Serial.print(',');
Serial.print("PEAKED:");
if (allmean >= 24.25) {
Serial.println(50);
} else {
Serial.println(0);
}
if (++pos >= DURCH) {
pos = 0;
}
//delay a second
delay(1000);
}
#endif
jps2000 wrote:Such sensors work (of course) with temperature (radiation) difference. In a 37°C room you can not detect an object having also 37°C (provided same emissivity)
The temparature of the room, the mean value of all pixels were about 24°.
So that should not be an issue, up to 2 meters everything works as expected.
To detect an object against the background, you first need a precise pixel-by-pixel baseline reading of the background. Then look for changes relative to that. As explained above, the changes will diminish with target distance since the target will occupy a smaller percentage of the FOV. This means that fewer pixels will be affected and the magnitude of change per pixels will decrease.
I don't see any baseline calibration phase in your code. It appears to use an arbitrary threshold of 24.5 and applied uniformly to all pixels, and requires at least 20 pixels to be affected.
adafruit_support_bill wrote:To detect an object against the background, you first need a precise pixel-by-pixel baseline reading of the background. Then look for changes relative to that. As explained above, the changes will diminish with target distance since the target will occupy a smaller percentage of the FOV. This means that fewer pixels will be affected and the magnitude of change per pixels will decrease.
I don't see any baseline calibration phase in your code. It appears to use an arbitrary threshold of 24.5 and applied uniformly to all pixels, and requires at least 20 pixels to be affected.
Ok, I will try to do a baseline calibration when powered up.
100 readings should be enough I guess?
But that there is still a problem that nobody can be in front of the sensor in that phase and it is impossible to detect that to do a clear baseline reading.
It doesn't necessarily have to be automatic at startup. You can add a pushbutton or other input so that you can control the conditions while establishing the baseline. If the operating environment is reasonably stable, you could persist the baseline readings in EEPROM or Flash - depending on what is available in the processor you are using.
This short, professional video on the 8x8 thermal sensor array explains why the simple approach in your posted code is insufficient to reliably detect human presence.