Store values from a sensor on arrays

I'm using the Adafruit AS7262 6-channel Visible Light Sensor (LINK) and I just need to store the orange values from the sensor.

/***************************************************************************
  This is a library for the Adafruit AS7262 6-Channel Visible Light Sensor

  This sketch reads the sensor

  Designed specifically to work with the Adafruit AS7262 breakout
  ----> http://www.adafruit.com/products/3779
  
  These sensors use I2C to communicate. The device's I2C address is 0x49
  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_AS726x.h"

//create the object
Adafruit_AS726x ams;

//buffer to hold raw values
uint16_t sensorValues[AS726x_NUM_CHANNELS];

//buffer to hold calibrated values (not used by default in this example)
//float calibratedValues[AS726x_NUM_CHANNELS];

void setup() {
  Serial.begin(9600);
  while(!Serial);
  
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);

  //begin and make sure we can talk to the sensor
  if(!ams.begin()){
    Serial.println("could not connect to sensor! Please check your wiring.");
    while(1);
  }
}

void loop() {

  //read the device temperature
  uint8_t temp = ams.readTemperature();
  
  //ams.drvOn(); //uncomment this if you want to use the driver LED for readings
  ams.startMeasurement(); //begin a measurement
  
  //wait till data is available
  bool rdy = false;
  while(!rdy){
    delay(5);
    rdy = ams.dataReady();
  }
  //ams.drvOff(); //uncomment this if you want to use the driver LED for readings

  //read the values!
  ams.readRawValues(sensorValues);
  //ams.readCalibratedValues(calibratedValues);

  Serial.print("Temp: "); Serial.print(temp);
  Serial.print(" Violet: "); Serial.print(sensorValues[AS726x_VIOLET]);
  Serial.print(" Blue: "); Serial.print(sensorValues[AS726x_BLUE]);
  Serial.print(" Green: "); Serial.print(sensorValues[AS726x_GREEN]);
  Serial.print(" Yellow: "); Serial.print(sensorValues[AS726x_YELLOW]);
  Serial.print(" Orange: "); Serial.print(sensorValues[AS726x_ORANGE]);
  Serial.print(" Red: "); Serial.print(sensorValues[AS726x_RED]);
  Serial.println();
  Serial.println();
}

The idea is to store, for example, ten values of the orange sensor reading in a vector and then make an arithmetical average of these values, and then that value will be thrown into an equation. How could I proceed?

Start with something like the following, and check out the tutorials on averaging.

x = sensorValues[AS726x_ORANGE];

sebnil/Moving-Avarage-Filter--Arduino-Library-: A moving average, also called rolling average, rolling mean or running average, is a type of finite impulse response filter (FIR) used to analyze a set of datum points by creating a series of averages of different subsets of the full data set. (github.com)

consider updating a running avg for each channel as follows

    const  float K  = 8.0;
    static float avg [AS726x_NUM_CHANNELS];
    for (unsigned n = 0; n < AS726x_NUM_CHANNELS; n++)
        avg [n] += (sensorValues [n] - avg [n]) / K;

why did you define K = 8.0 ?

arbitrary.
the avg approached the value of sample after 3*K iterations.

The reason I'm doing this is because I want my sensor reads 10 values for example and stop the readings, after this I'll try to make to run the smoothing average ( Smoothing | Arduino)

My other doubt about the smoothing avg code is if this code only runs on analogRead(inputPin) or I can change the anologRead(inputPin) for sensorValues[AS726x_ORANGE]

void loop() {
  // subtract the last reading:
  total = total - readings[readIndex];
  // read from the sensor:
  // readings[readIndex] = analogRead(inputPin);
  readings[readIndex] = sensorValues[AS726x_ORANGE];

  // add the reading to the total:
  total = total + readings[readIndex];
  // advance to the next position in the array:
  readIndex = readIndex + 1;

you could initialize the avg to the first sample being read to avoid the lag

shouldn't you have an avg for each sensor

float sensorAvg [AS726x_NUM_CHANNELS];

I just need to average the orange reading, that's why I used the sensor values for the orange one, the code I'm running now is this, but isnt working properly with the avg

#include <Wire.h>
#include "Adafruit_AS726x.h"

//create the object
Adafruit_AS726x ams;

//buffer to hold raw values
uint16_t sensorValues[AS726x_NUM_CHANNELS];

//buffer to hold calibrated values (not used by default in this example)
//float calibratedValues[AS726x_NUM_CHANNELS];

int cont = 0;

const int numReadings = 10;

int readings[numReadings];      //the readings from the analog input
int readIndex = 0;              //the index of the current reading
int total = 0;                  //the running total
int average = 0;                //the average

void setup() {
  Serial.begin(9600);
  while(!Serial);
  
  //initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);

  //begin and make sure we can talk to the sensor
  if(!ams.begin()){
    Serial.println("could not connect to sensor! Please check your wiring.");
    while(1);
  }

  do {
   //read the device temperature
   uint8_t temp = ams.readTemperature();
  
   //ams.drvOn(); //uncomment this if you want to use the driver LED for readings
   ams.startMeasurement(); //begin a measurement
  
   //wait till data is available
   bool rdy = false;
   while(!rdy){
     delay(5);
     rdy = ams.dataReady();
   }
   //ams.drvOff(); //uncomment this if you want to use the driver LED for readings

   //read the values!
   ams.readRawValues(sensorValues);
   //ams.readCalibratedValues(calibratedValues);

   //Serial.print("Temp: "); Serial.print(temp);
   //Serial.print(" Violet: "); Serial.print(sensorValues[AS726x_VIOLET]);
   //Serial.print(" Blue: "); Serial.print(sensorValues[AS726x_BLUE]);
   //Serial.print(" Green: "); Serial.print(sensorValues[AS726x_GREEN]);
   //Serial.print(" Yellow: "); Serial.print(sensorValues[AS726x_YELLOW]);
   Serial.print(" Orange: "); Serial.print(sensorValues[AS726x_ORANGE]);
   //Serial.print(" Red: "); Serial.print(sensorValues[AS726x_RED]);
   Serial.println();
   Serial.println();
   cont++;
  } while(cont < 10); 

  delay(1000);
  //initialize all the readings to 0
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
   readings[thisReading] = 0;
  }
  //subtract the last reading:
  total = total - readings[readIndex];
  //read from the sensor:
  readings[readIndex] = sensorValues[AS726x_ORANGE];
  //add the reading to the total:
  total = total + readings[readIndex];
  //advance to the next position in the array:
  readIndex = readIndex + 1;

  //if we're at the end of the array...
  if (readIndex >= numReadings) {
   //...wrap around to the beginning:
   readIndex = 0;
  }

  //calculate the average:
  average = total / numReadings;
  //send it to the computer as ASCII digits
  Serial.print(" Orange Average: "); Serial.print(average);
  delay(1);        // delay in between reads for stability
}

void loop() {
}

since the code only executes one time in setup, it looks like you total i a single value that you divide by numReadings

I'm having some issues to make this properly. I just need to sum the 10 values reads from the sensor and than make an average with this values

#include <Wire.h>
#include "Adafruit_AS726x.h"

//create the object
Adafruit_AS726x ams;

//buffer to hold raw values
uint16_t sensorValues[AS726x_NUM_CHANNELS];

//buffer to hold calibrated values (not used by default in this example)
//float calibratedValues[AS726x_NUM_CHANNELS];

int cont = 0;

int sensor;
int sum;
int average;

void setup() {
  Serial.begin(9600);
  while(!Serial);
  
  //initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);

  //begin and make sure we can talk to the sensor
  if(!ams.begin()){
    Serial.println("could not connect to sensor! Please check your wiring.");
    while(1);
  }

  do {
   //read the device temperature
   uint8_t temp = ams.readTemperature();
  
   //ams.drvOn(); //uncomment this if you want to use the driver LED for readings
   ams.startMeasurement(); //begin a measurement
  
   //wait till data is available
   bool rdy = false;
   while(!rdy){
     delay(5);
     rdy = ams.dataReady();
   }
   //ams.drvOff(); //uncomment this if you want to use the driver LED for readings

   //read the values!
   ams.readRawValues(sensorValues);
   //ams.readCalibratedValues(calibratedValues);

   for (int k = 0; k < 10; k++){
    sensor = sensorValues[AS726x_ORANGE];
    sum += sensor;
   }

   //Serial.print("Temp: "); Serial.print(temp);
   //Serial.print(" Violet: "); Serial.print(sensorValues[AS726x_VIOLET]);
   //Serial.print(" Blue: "); Serial.print(sensorValues[AS726x_BLUE]);
   //Serial.print(" Green: "); Serial.print(sensorValues[AS726x_GREEN]);
   //Serial.print(" Yellow: "); Serial.print(sensorValues[AS726x_YELLOW]);
   Serial.print(" Orange: "); Serial.print(sensorValues[AS726x_ORANGE]);
   //Serial.print(" Red: "); Serial.print(sensorValues[AS726x_RED]);
   Serial.println();
   Serial.println();
   cont++;
  } while(cont < 10); 

   average = sum;
   Serial.print(average);
}

void loop() {
}

Don't averages normally involve a division?

The value looks to be in the right ball-park

Sorry, I just forgot to change the line, but isn't working as well

   average = sum/10;
   Serial.print(average);

What does that mean?

Isn't working as well as what?

As I wrote, the values printed look to be in the right sort of area.


The average here should be 9/10

But an int can't represent 0.9.

Right! but the average isnt being devided by 10, it's just making the sum for some reason that I dont know

Look carefully at the loops in your code.

1 Like

You are summing 100 times, not 10 times.

  do 
  {
    for (int k = 0; k < 10; k++) 
  } while (cont < 10);
1 Like

Thank you guys! but what would be the smartest way to do this?

#include <Wire.h>
#include "Adafruit_AS726x.h"

//create the object
Adafruit_AS726x ams;

//buffer to hold raw values
uint16_t sensorValues[AS726x_NUM_CHANNELS];

//buffer to hold calibrated values (not used by default in this example)
//float calibratedValues[AS726x_NUM_CHANNELS];

int numReads = 10;
int cont;
int sensor;
float sum;
float average;

void setup() {
  Serial.begin(9600);
  while(!Serial);
  
  //initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);

  //begin and make sure we can talk to the sensor
  if(!ams.begin()){
    Serial.println("could not connect to sensor! Please check your wiring.");
    while(1);
  }

  do {
   //read the device temperature
   uint8_t temp = ams.readTemperature();
  
   //ams.drvOn(); //uncomment this if you want to use the driver LED for readings
   ams.startMeasurement(); //begin a measurement
  
   //wait till data is available
   bool rdy = false;
   while(!rdy){
     delay(5);
     rdy = ams.dataReady();
   }
   //ams.drvOff(); //uncomment this if you want to use the driver LED for readings

   //read the values!
   ams.readRawValues(sensorValues);
   //ams.readCalibratedValues(calibratedValues);

   for (int k = 0; k < numReads; k++){
    sensor = sensorValues[AS726x_ORANGE];
    sum += sensor;
   }

   //Serial.print("Temp: "); Serial.print(temp);
   //Serial.print(" Violet: "); Serial.print(sensorValues[AS726x_VIOLET]);
   //Serial.print(" Blue: "); Serial.print(sensorValues[AS726x_BLUE]);
   //Serial.print(" Green: "); Serial.print(sensorValues[AS726x_GREEN]);
   //Serial.print(" Yellow: "); Serial.print(sensorValues[AS726x_YELLOW]);
   Serial.print(" Orange: "); Serial.print(sensorValues[AS726x_ORANGE]);
   //Serial.print(" Red: "); Serial.print(sensorValues[AS726x_RED]);
   Serial.println();
   Serial.println();
   cont++;
  } while(cont < numReads); 

   average = sum/(numReads*10);
   Serial.print(" Orange Average: "); Serial.print(average);
}

void loop() {
}