Analog averaging

Hi!

What I'm doing:
I am reading 288 individual (pixels) values off a CMOS sensor, and writing these values to the serial port.

What I want to do:
Read the 288 individual values from the CMOS sensor, get the average of each 288 pixel over 50 read cycles and then write the average values to the serial port.

How the sensor program works
Set the ST pin high for x amount of time to indicate the integration time, when it is pulled low, integration time has stopped and you can read from the sensor.
The code:

#define SPEC_ST          A1
#define SPEC_CLK         A2
#define SPEC_VIDEO       A3

#define PIXELS    288 // 288 pixel values
uint16_t data[PIXELS];

void setup(){

  //Set desired pins to OUTPUT
  pinMode(SPEC_CLK, OUTPUT);
  pinMode(SPEC_ST, OUTPUT);

  Serial.begin(115200); // Baud Rate set to 115200
  digitalWrite(SPEC_ST, HIGH);
}

// This functions reads the data from the CMOS sensor

void readSpectrometer(){

  int delayTime = 1; // delay period
  
  // Start clock cycle for 30 us [Ignore time taken to execute digitalWrite ~ 100us]
  for(int i = 0; i < 15; i++){

      digitalWrite(SPEC_CLK, HIGH);
      delayMicroseconds(delayTime);
      digitalWrite(SPEC_CLK, LOW);
      delayMicroseconds(delayTime); 
 
  }

  //Set this pin low to finish integration time, prepare to read from sensor
  digitalWrite(SPEC_ST, LOW);


  //Read from SPEC_VIDEO, 1 pixel per clock cycle
  for(int i = 0; i < SPEC_CHANNELS; i++){

      data[i] = analogRead(SPEC_VIDEO);
      
      digitalWrite(SPEC_CLK, HIGH);
      delayMicroseconds(delayTime);
      digitalWrite(SPEC_CLK, LOW);
      delayMicroseconds(delayTime);
        
  }

  //Reading from sensor complete, set back to high to re-initialize integration time
  digitalWrite(SPEC_ST, HIGH);
  
  
// The function below prints out data to the serial port 
void printData(){
  
  for (int i = 0; i < PIXELS; i++){
    
    Serial.print(data[i]);
    Serial.print(',');
    
  }
  
  Serial.print("\n");
}

void loop(){
  readSpectrometer();
  printData();
  delay(1);  

}

Sounds cool, have fun with it!

What sensor are you using? Please post a link.

Does the code actually work?

1 Like

Yes, the code works and the read out works as well, tested with oscilloscope and spectral sources.

To run the code, it’s a bit more involved than setting ST low and high. It includes more
clock cycling. But, this version is a simplified snippet, more code wouldn’t provide any value or insight to the goal at hand :slight_smile: !
Sensor

Aaah, so the code does not work.

Did you notice that the minimum clock frequency is 200 kHz?

Hahah, technically this code doesn’t work with the sensor. It doesn’t need to, the programmatic solution can be reached without “working” code.

To average some measurements, add them up and divide by the number of measurements.

Thanks for the help. I am struggling how to employ this in the program. Not looking for the definition of average.

OK, here is an example of adding up ten readings from analog input A0, and calculating the average.

float x=0;
for (int i=0; i<10; i++)  {
  x += analogRead(A0);
}
x = x/10.0;

Don't count on this approach working with an ordinary Arduino, because they aren't fast enough to interface with that sensor. The "non working" snippet that you posted violates the sensor clock timing requirements, as well.

1 Like

Okay thanks for the guidance. I was thrown off by trying to average an array. Seems easy if it was just one value.

Why is it not possible? The clock cycle being used to read the video signal is .5 MHz, .5 > .2

delayMicroseconds() on a 16Mhz Arduino is AFAIK 4us minimum (4us steps),
so the 2x1us in your code is already 8us.
Leo..

No, it is not. You have an analogRead() in there. On an Arduino Uno, that defaults to 110 us. But then, you forgot to tell us what Arduino you are using, and to post ALL the code.

Also, digitalWrite() takes about 4 us on an Uno.

This comment is completely wrong:

// Start clock cycle for 30 us [Ignore time taken to execute digitalWrite ~ 100us]

You can treat an array element exactly as you would any other variable.

Gotcha! Well thanks for the feedback, I posted the simplest code. I’m running this on a black pill different data acquisition technique, whatever. This post has gotten completely derailed anyways, I’m not asking for advice on DAQ - all I was asking is how to get running averages in the readspec function lol.

No, you posted incorrect, oversimplified code that could never work.

It is almost always a bad idea to mislead people, when you are asking for advice.

All good! We can agree to disagree and open the topic for people who’d like to help.

Cheers + positive vibes!

With what? There are no open questions.

So not an Arduino.
Shouldn't you have mentioned this in the first line of your post.
Leo..

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.