Nicla Sense ME - BME688 sensor

I've been messing around over the last few days creating a machine learning model for small thermal imager.

In my code I create the model and then have the model compare against live images. Every 6 minutes the learned model self updates to compensate for the background getting warmer as the day heats up.

#include <Wire.h>
#include <Adafruit_AMG88xx.h>
#include <LinearRegression.h>
////
Adafruit_AMG88xx amg;
LinearRegression lr;
////
const int pixels = 64;
float CurrentFrame[pixels] = { 0 };
int   sensorDelay = 125;
float dpAtom = 1.0f / 80.0f; // low/high from data sheet
float tsAtom = 1.0f / 64.0f; // 64 data points 64 time stamps.
double valuesModel[2];
double values[2];
////
void setup() {
  Serial.begin(115200);
  //Serial.println("AMG88xx thermal camera!");
  bool status;
  // default settings
  status = amg.begin();
  if (!status) {
    Serial.println("Could not find a valid AMG88xx sensor, check wiring!");
    while (1);
  }
  delay(sensorDelay);
  BackgroundImage();
} // setup()
//
int count = 0;
float daChange = 0.0f;
float avg = 0.0f;
float stdD = 0.0f; //standard deviation
void loop()
{
  lr.reset();
  amg.readPixels( CurrentFrame );
  for (int i = 0; i < pixels; i++)
  {
    lr.learn( ((float)i + 1.0f) * tsAtom, (float(CurrentFrame[i]) * dpAtom) );
    avg += (float(CurrentFrame[i]));
  }
  avg /= pixels; // an average of all the readings
  // calculate the standard deviation
  for (int i = 0; i < pixels; i++) {
    stdD += pow(CurrentFrame[i] - avg, 2);
  }
  stdD = sqrt(stdD / pixels);
  stdD *= 10;
  /*
  // if the current value is more than a standard deviation above the mean,
  // then that counts as a peak. also make sure that the current value is
  // more than 25 above the mean, in case there is just some noise in a
  // pretty flat signal
  //    if (sensorFiltered[0] - avg > std && sensorFiltered[0] - avg > 50 )
  //    {
  //        return true;
  //    } else {
  //        return false;
  //    }
*/

  lr.parameters(values);
  daChange = 100 * ((valuesModel[1] - values[1]) / valuesModel[1]);
  //Serial.print("ValuesModel: ");
  //Serial.print(" *X + ");
  //Serial.print(valuesModel[1], 6);
  //Serial.print(" Values: ");
  //Serial.print(" *X + ");
  //Serial.print(values[1], 6);
  //Serial.print(" %ofChange ");
  Serial.print( daChange, 6 );
  Serial.print( "," );
  Serial.print( stdD );
  Serial.println();
  delay(sensorDelay);
  count++;
  //6(150 times 60 seconds) 6 minutes
  if ( count == 54000 )
  {
    BackgroundImage();
  }
}
//
void BackgroundImage()
{
  // gather a background image
  // load model
  for (int i = 0; i < 2; i++)
  {
    lr.reset();
    amg.readPixels( CurrentFrame ); // discard several readings
    delay(sensorDelay);
  }
  lr.reset();
  amg.readPixels( CurrentFrame );
  for (int i = 0; i < pixels; i++)
  {
    lr.learn( ((float)i + 1.0f) * tsAtom, (CurrentFrame[i] * dpAtom) );
  }
  //Serial.print("Values: ");
  lr.parameters(valuesModel);
  //Serial.print(" *X + ");
  //Serial.println(valuesModel[1], 6);
}

I am also using standard deviation to see how it stacks up against Liner Regression, not so well.

1 Like