-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathpowerMeter_apr25b.ino
129 lines (112 loc) · 3.41 KB
/
powerMeter_apr25b.ino
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
/*
* original post by GreatScotLab is here https://www.instructables.com/id/Make-Your-Own-Power-MeterLogger/
* more about ina219 current sensor: https://learn.adafruit.com/adafruit-ina219-current-sensor-breakout/wiring
* changes by Binh Nguyen, April 26, 2018
* - use EEPROM to store ONE BYTE to icnrease one value, and write to header in setup loop
* - use one log file (data.txt) instead of three
* - add a message for logfile status in setup loop
* - enlarge to current display (minor)
* - add the time inverval in energy calculation (adding 100 ms)
* + stil using SSD_1306_32 in 128x64 OLED, remove comment line 73 to activate 128x64 mode.
* + memory on Arduino ProMini 328P is only enough for 128x32 mode.
*/
#include<EEPROM.h>
#include <Wire.h>
#include <Adafruit_INA219.h>
#include <Adafruit_SSD1306.h>
#include <SPI.h>
#include "SdFat.h"
SdFat SD;
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
Adafruit_INA219 ina219;
#define samplingFreq 10
int interval = 0;
unsigned long previousSecond = 0;
float current_mA = 0;
float loadvoltage = 0;
float energy = 0;
byte id;
String fileName = "";
File logFile;
void setup() {
SD.begin(10);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
ina219.begin();
id = EEPROM.read(1) + 1;
fileName = "f" + String(id)+ ".txt";
String header = "time, V, ma, mWh\ntest"+String(id);
EEPROM.write(1, id);
id = EEPROM.read(0) + 1;
String header = "time, mA, V, mWh\ntest"+String(id);
EEPROM.write(0, id);
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.print(fileName);
display.setCursor(10, 10);
interval = 1000/samplingFreq;
logFile = SD.open(fileName, FILE_WRITE);
if (logFile) {
logFile.println(header);
logFile.close();
display.print("OK");
} else display.print("failed");
display.display();
delay(1000);
}
void loop() {
unsigned long currentSecond = millis()/1000;
displaydata();
ina219reads();
if (currentSecond - previousSecond >= 10) {
previousSecond = currentSecond;
String buff = String(currentSecond) + "," + String(loadvoltage) + "," \
+ String(current_mA) + "," + String(energy);
logFile = SD.open("data.txt", FILE_WRITE);
if (logFile) {
logFile.println(buff);
logFile.close();
}
}
// delay(100);
}
void displaydata() {
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(50, 0);
display.print(round(current_avg));
display.setTextSize(1);
display.setCursor(105, 0);
display.print("mA");
display.setCursor(0, 0);
display.print(voltage_avg);
display.setCursor(30, 0);
display.print("V");
display.setCursor(0, 10);
display.print("f:");
display.print(id);
display.setCursor(0, 20);
display.print(round(voltage_avg * current_avg));
display.setCursor(35, 20);
display.print("mW");
display.setCursor(65, 20);
display.print(round(energy));
display.setCursor(100, 20);
display.print("mWh");
display.display();
}
void ina219reads(){
for (int i=0; i<samplingFreq; i++){
float current_mA = ina219.getCurrent_mA();
float loadvoltage = ina219.getBusVoltage_V() + (ina219.getShuntVoltage_mV() / 1000);
// float loadvoltage = ina219.getBusVoltage_V();
energy += loadvoltage * current_mA *1/ 3600;
current_avg += current_mA;
voltage_avg += loadvoltage;
delay(interval);
}
current_avg /=samplingFreq;
voltage_avg /=samplingFreq;
}