//this program reads current sensors attached A0-A5 on an arduino mega2560
//needed for sqrt()
#include <math.h>
//analog voltage reference
#define vREF = 5.00
//number of current transformers to monitor, the compiler should yell at you if you change this number without changing pins and BURDEN_CAL at the same time
#define NUM_CURRENT_TRANSFORMERS_MONITORED 6
//transformer ratio 1000:1
#define TRANSFORMER_RATIO 1000
//current transformer pins
const int pins[NUM_CURRENT_TRANSFORMERS_MONITORED] = {A0, A1, A2, A3, A4, A5};
//burden resistor value for each current transformer
const float BURDEN_CAL[NUM_CURRENT_TRANSFORMERS_MONITORED] = {135.0, 135.0, 135.0, 135.0, 135.0, 135.0};
//value to multiply P-P value by to get RMS value
const float RMS_MULT = 1.0 / sqrt(2.0);
//current transformer sensor object
class current_transformer {
public:
//tried to sort by access frequency
//sampling start time
unsigned long start_time = millis();
//how long to sample each analog input for, in milliseconds
unsigned long sample_duration = 1000UL;
//place to put incoming sensor reading
int sensor_sample = 0;
//pin which this sensor is associated with
byte pin = 0;
//how many samples have been taken
int samples = 0;
//max analogRead() value
int max_value = 0;
//result in mV
float result = 0.0;
//mA peak-to-peak through resistor
float curr_resistor_pp = 0.0;
//mA rms through resistor
float curr_resistor_rms = 0.0;
//mA rms through monitored line
float curr_wire_rms = 0.0;
};//end class current_transformer
//create power_monitor[] objects
current_transformer power_monitor[NUM_CURRENT_TRANSFORMERS_MONITORED];
void setup() {
//set current transformer sensor pins
for (int i = 0; i < NUM_CURRENT_TRANSFORMERS_MONITORED; i++)
{
//current transformer input pins set to INPUT
pinMode(pins[i], INPUT);
//current_transformer class object array power_monitor[]
//set pin number in corresponding power_monitor[] object
power_monitor[i].pin = pins[i];
}
//serial monitor
Serial.begin(1000000);
}
void loop() {
get_current_transformer_reading();
}
void get_current_transformer_reading()
{
//cycle through sensors, pin numbers can be discontiguous
for (int i = 0; i < (NUM_CURRENT_TRANSFORMERS_MONITORED); i++)
{
//sample for power_monitor[i].sample_duration milliseconds
if ((millis() - power_monitor[i].start_time) <= power_monitor[i].sample_duration)
{
//get a reading from a sensor pin
power_monitor[i].sensor_sample = analogRead(power_monitor[i].pin);
//sample rate to help with code efficiency
power_monitor[i].samples++;
//if the sensed voltage is greater than the largest voltage seen this sample, set power_monitor[i].max_value
if (power_monitor[i].sensor_sample > power_monitor[i].max_value)
{
//to whatever was sensed
power_monitor[i].max_value = power_monitor[i].sensor_sample;
}
}
//if the time to sample is over, it's time to calculate some things
if ((millis() - power_monitor[i].start_time) >= power_monitor[i].sample_duration)
{
//try to avoid float division
//aref / resolution = MAX_VALUE_MULT 5.0 / 1024.0 = 0.00488
#define MAX_VALUE_MULT 0.0048828125
//power_monitor_results[].result is peak-to-peak voltage from current transformer
//cast max_value to float
power_monitor[i].result = float(power_monitor[i].max_value) * MAX_VALUE_MULT;
//power_monitor_results[].curr_resistor_pp is peak-to-peak current across the burden resistor
power_monitor[i].curr_resistor_pp = (power_monitor[i].result / BURDEN_CAL[i]) * TRANSFORMER_RATIO;
//convert peak-to-peak voltages to RMS 1/sqrt(2) approx. .707
power_monitor[i].curr_resistor_rms = power_monitor[i].curr_resistor_pp * RMS_MULT;
//derive the current through the ac wire
power_monitor[i].curr_wire_rms = power_monitor[i].curr_resistor_rms * TRANSFORMER_RATIO;
//print out the readings
log_current_transformer_reading(i);
//reset class variables for relevant pin
power_monitor[i].max_value = 0;
power_monitor[i].samples = 0;
power_monitor[i].start_time = millis();
}
}
}
void log_current_transformer_reading(int i)
{
Serial.print(F("A"));
Serial.print(i);
Serial.print(F(" Samples : "));
Serial.print(power_monitor[i].samples);
Serial.print(F(" peak-peak : "));
Serial.print((power_monitor[i].result * 1000.0), 3);
Serial.print(F("mV c_t_r (peak) : "));
Serial.print((power_monitor[i].curr_resistor_pp * 1000.0), 3);
Serial.print(F("mA RMS : "));
Serial.print((power_monitor[i].curr_resistor_rms * 1000.0), 3);
Serial.print(F("mA c_t_w : "));
Serial.print(power_monitor[i].curr_wire_rms, 3);
Serial.println(F("mA"));
}