-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.cpp
128 lines (86 loc) · 3.18 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <cstdio>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <string.h>
#include <math.h>
#include "bcm2835.h"
#include "BCM2835_Driver.h"
#include "ADS1256_Driver.h"
#include "MetricLogger.h"
void exit_handler(int signum) {
BCM2835_GPIO_Exit();
exit(0);
}
int main() {
signal(SIGINT, exit_handler);
if (!BCM2835_SPI_Initialize()) {
return EXIT_FAILURE;
}
// Reset the chip to default values, avoid unexpected configurations
ADS1256_Reset();
// Keep trying to read the chip ID, which is set by the manufacturer as 0x3
while (ADS1256_Get_Id() != 3) {
std::cout << "Attemping to establish SPI communications.." << std::endl;
bcm2835_delay(1000);
}
ADS1256_Configure(ADS1256_GAIN_1, ADS1256_30000_SPS);
ADS1256_Set_Channel(ADS1256_AIN2);
if (OUTPUT_CONSOLE) {
std::cout
<< "# Chip ID : " << (int)ADS1256_Get_Id() << std::endl
<< "# Buffer : " << (ADS1256_BUFFEN() ? "Enabled" : "Disabled") << std::endl
<< "# Auto calibration : " << (ADS1256_ACAL() ? "Enabled" : "Disabled") << std::endl;
}
uint32_t rword;
double dataSum, dataAverage, vRms, i_sec, num_samples;
double power, acc_power;
for (;;) {
num_samples = 0;
dataSum = 0;
dataAverage = 0;
time_t now = time(0);
time_t next = now + 1;
// Collect exactly one second of samples
while (time(0) < next) {
// Sample a series of channels to reduce sinc filter decimation of the signal
// This is due to the signal often resembling noise
for (uint8_t i = ADS1256_AIN2; i < ADS1256_AINCOM; i++) {
ADS1256_Set_Channel(i);
rword = ADS1256_Read_Word(false);
if (i == ADS1256_AIN2) {
num_samples++;
dataSum += pow((rword * 5.0 / 0x7FFFFF) - 2.5, 2);
}
}
}
// Calculate power readings
dataAverage = dataSum / num_samples;
vRms = sqrt(dataAverage);
i_sec = vRms / SENSOR_RESISTANCE;
// 240V * Secondary current * Inductor Windings
power = 240 * (i_sec * 2000);
// Current drawn power for one second
acc_power += (power / 1000) / (60 * 60);
if (OUTPUT_CONSOLE) {
std::cout << "# Number of samples : " << num_samples << std::endl;
std::cout << "# Burden current : " << i_sec << std::endl;
std::cout << "# Primary current : " << i_sec * 2000 << std::endl;
std::cout << "# Power : " << power << std::endl;
// Move the cursor up 4 places
for (size_t i = 0; i < 4; i++) {
std::cout << "\x1b[A";
}
}
// Simple spike filter, should be adjusted based on circumstances
if (power < MAXIMUM_POWER_READING) {
MetricLogger::AppendToLiveData(power);
MetricLogger::AppendToHistoricData(power);
MetricLogger::SetMetrics(power, acc_power);
}
}
BCM2835_GPIO_Exit();
return 0;
}