Sampling Rate

Hi all, how do I find out my sampling rate? My code uploaded to the arduino does several things, one of which is to pick up pressure fluctuations through a microphone into analog port A4, and I seem to be getting uneven rates of samples transferred into excel.

In one second I'd have 5 different readings for voltage/current/mic reading, but in another I'd have 3. Is my sampling rate unstable or does it pick up readings only when there's a noticable change?

Still quite new to arduino, thanks so much for the help

// EmonLibrary examples openenergymonitor.org, Licence GNU GPL V3

#include "EmonLib.h"             // Include Emon Library



#define VOLT_CAL 269
#define CURRENT_CAL 60

EnergyMonitor emon1;             // Create an instance

void setup()
{  
  Serial.begin(9600);

  Serial.println("CLEARDATE");
  Serial.println("LABEL, DATE, TIME,Wall Voltage,Wall Current, Wall Power, Mic Voltage");
 
  emon1.voltage(A0, VOLT_CAL, 1.7);  // Voltage: input pin, calibration, phase_shift
  emon1.current(A1, CURRENT_CAL);       // Current: input pin, calibration.
}

void loop()
{
  emon1.calcVI(20,2000);         // Calculate all. No.of half wavelengths (crossings), time-out

  float currentDraw     = emon1.Irms;             //extract Irms into Variable
  float supplyVoltage   = emon1.Vrms;                    //extract Vrms into Variable
  int sensorValue = analogRead(A4);
  float voltage = sensorValue * (5.0 / 1023.0);
  
  Serial.println( (String) "DATA,DATE,TIME," + supplyVoltage + "," +  currentDraw + "," + supplyVoltage*currentDraw + "," + sensorValue);
  
}

this is an example of what my results tend to look like. as you can see i get different number of samples every other second so i can't quite figure out what my sampling rate is

Don't do this...

 Serial.println( (String) "DATA,DATE,TIME," + supplyVoltage + "," +  currentDraw + "," + supplyVoltage*currentDraw + "," + sensorValue);

Do this instead...

  Serial.print("DATA,DATE,TIME,");
Serial.print(supplyVoltage);
Serial.print(",");
Serial.print(currentDraw);
Serial.print(",");
Serial.print(supplyVoltage*currentDraw);
Serial.print(",");
Serial.print(sensorValue);

This way uses no dynamic memory.

The engery monitor library doesn't say anything in its documentation?

Rather than printing out the constant "DATA,DATE,TIME" + ....
why not try printing out the actual time so you have a timestamp on every data point you receive. You can use the millis() function which will return the number of milliseconds that have elapsed since the program started. Not exactly a date/time, but you will be able to see how much time has elapsed between readings.

Actual code left as an exercise for the reader :slight_smile:

could it be that I get fewer readings because of all that redundant code? nothing about sampling rate comes up on serial monitor/excel.

I've also read that the sampling rate with emonlib varies depending on what you're doing. thanks so much for the help guys :slight_smile:

You get the sampling rate by determining the time difference between two samples.

That depends on lots of things, like whether, how much and how fast you print or transmit the sample information, whether you unwisely use String objects, etc.

blh64:
Actual code left as an exercise for the reader :slight_smile:

think I've got it!

void setup()
{  
  Serial.begin(9600);

  Serial.println("CLEARDATE");
  Serial.println("LABEL, Time Elapsed,Wall Voltage,Wall Current, Wall Power, Mic Voltage");
 
  emon1.voltage(A0, VOLT_CAL, 1.7);  // Voltage: input pin, calibration, phase_shift
  emon1.current(A1, CURRENT_CAL);       // Current: input pin, calibration.
}

void loop()
{
  emon1.calcVI(20,2000);         // Calculate all. No.of half wavelengths (crossings), time-out
  
  float currentDraw     = emon1.Irms;             //extract Irms into Variable
  float supplyVoltage   = emon1.Vrms;                    //extract Vrms into Variable
  int sensorValue = analogRead(A4);
  float voltage = sensorValue * (5.0 / 1023.0);
  
  time = millis();

  Serial.print(time); //prints time since program started
  Serial.print(",");

Serial.print(supplyVoltage);
Serial.print(",");
Serial.print(currentDraw);
Serial.print(",");
Serial.print(supplyVoltage*currentDraw);
Serial.print(",");
Serial.println(sensorValue);
  
}

thanks so much (-:

given how I'm getting a reading roughly every 2 seconds, would it be safe to say that I've a sampling rate of 0.5/0.5Hz?

Since 1/(roughly every 2 seconds) is (roughly) 0.5 Hz, then yes.

Is it possible to speed up the communication? Serial.begin(9600) changed to Serial.begin(115200)? Would that give more space for Your loop?

will give all that a shot too, you guys have been a huge help thanks so much!!!!

Railroader:
Is it possible to speed up the communication? Serial.begin(9600) changed to Serial.begin(115200)? Would that give more space for Your loop?

I tried that, and weird things came out on my serial monitor instead...my arduino gives me just one reading every two seconds now..argh

You have to change your serial monitor baud rate to match your code. That little box at the bottom of your image still says 9600. If you code is at 115200, that needs to match.

Serial communication is accomplished with interrupts so the code doesn't really block waiting for the entire line to be transmitted before continuing so I'm not surprised it didn't help.

I'm afraid it is your sensor that is the bottleneck

emon1.calcVI(20,2000);         // Calculate all. No.of half wavelengths (crossings), time-out

This line. Scroll-right to see the comment if you don't see it. (I didn't, the first time.)

What do the 2 numbers mean? 20 is the number of crossings. On a 60Hz system that should only take 153 milliseconds to count that many.

2000 is the amout of time to wait to get a crossing. 2000ms = 2seconds.

The rest of your code is essesntialy one analogRead(). It should take a few microseconds.

So if you get only one reading every 2 seconds then it means it isn't plugged in and energymon is not seeing a signal.