I am supported by our readers and may earn a commission if you buy through our Affiliate Links at no cost to you. Thank you so much for your support. Read More
This is a fun project that I have wanted to build for a long time. It’s highly customizable energy meter that can measure:
-
-
- Voltage
- Watts
- Energy in aH or wH (example shows aH)
-
I intend to use mine to monitor the total energy consumpution of my telescope when I shoot all night long. I have calculated this but cannot tell precisely how much energy is being consumed. It’s important because I need to have enough storage capacity to go all night without external power.
Parts Required:
Arduino Nano (or similar)
AC712 Sensor and a precision voltage sensor. Kit to the right has both.
SH1106 OLED Dispaly
The video below shows step by step how to build the meter. I noticed a bug in the code after I published the video. In the video I had an elapsed time of 2 seconds, but I accidentally had 3 seconds of processing time. Instead of hard coding the time in the loop – I changed the code to use the millis() function to measure the total time elapsed during the measurement phase. This is a lot better and now the energy measurements will be accurate.
The millis() function in Arduino returns the time elapsed since the program started. I used this to count how long in seconds had passed for each loop.
Energy is measured in watt (or amps) times time. This will return either wH, kwH, or aH. I chose aH since the math is easy and if you know your battery size such as 20 aH, it’s easy to see how much capacity you have left.
/** * My Engineering Projects - Current, power, and energy meter * current meter - Ac712 * voltage meter - Voltage Sensor Module DC0-25V * connect current sensor to A0 * connect battery voltage sensor to A1 */ #include#include #include #include #define i2c_Address 0x3c //initialize with the I2C addr 0x3C Typically eBay OLED's #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels #define OLED_RESET -1 // QT-PY / XIAO Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); //const double scale_factor = 0.185; // 5A 185 mv/A const double scale_factor = 0.1; // 20A 100 mv/A //const double scale_factor = 0.066; // 30A 66 mv/A double current_sensor_voltage = 0.00; double current = 0; double power = 0; float energy = 0; float twosec_energy = 0; double zero_point = 2.5; float current_sensor_value = 0; int cycle_count = 1000; float elapsed_time = 0; //voltage divider float battery_sensor_value = 0; float battery_sendor_voltage = 0; float battery_voltage = 0; float R1 = 30000.0; float R2 = 7500.0; void setup() { Serial.begin(9600); delay(250); // wait for the OLED to power up display.begin(i2c_Address, true); // Address 0x3C default display.setContrast (0); // dim display // Clear the buffer. display.clearDisplay(); //analogReference(INTERNAL); //Read from 0 to 1.1 V so we can measure millivolts analogReference(DEFAULT); // No need for this line if Default } void loop() { display.setTextSize(1); //options are 1, 2, or 3 display.setTextColor(SH110X_WHITE); display.setCursor(0, 0); display.clearDisplay(); //must clear so displayed values can change from previous loop long current_milli = millis(); //need an accurate time elapsed value so energy can be calculated // Loop many times for better precison for(int i = 0; i < cycle_count; i++) { //Current current_sensor_value = analogRead(A0); current_sensor_voltage = (current_sensor_voltage + (current_sensor_value*5/1024 ) ); //Voltage battery_sensor_value = analogRead(A1); battery_sendor_voltage = (battery_sensor_value * 5.0) / 1024.0; battery_voltage = battery_sendor_voltage / (R2/(R1+R2)) + battery_voltage; delay(1); //1 milli second delay - total time is 1 second } delay(1000); //wait full 1 second // Calculate sensor voltage by dividing by cycle count current_sensor_voltage = current_sensor_voltage / cycle_count; battery_voltage = battery_voltage / cycle_count; // Convert current sensor voltage into Current using Scale Factor, any value above 2.5 is positive, below 2.5 is negative. if at 2.5 current is zero current = (current_sensor_voltage - zero_point)/ scale_factor; power = battery_voltage * current; //measure the elapsed time since loop started long now = millis(); elapsed_time = (now - current_milli) / 1000; //outputs in seconds, should be 2 twosec_energy = current * elapsed_time / 3600; // 3600 s per hour energy = twosec_energy + energy; //show in aH // show results display.print ("Voltage: "); display.print(battery_voltage); display.println(" V"); display.print ("Current: "); display.print(current); display.println(" A"); display.print ("Power: "); display.print(power); display.println(" W"); display.print ("Energy: "); display.print(energy); display.println(" aH"); //display.print ("Elapsed Time:"); display.print(elapsed_time); display.println(" s"); //for debugging, shows elapsed time in seconds per loop (i.e. 2) display.display(); //display.clearDisplay(); //don't clear the display here, clear it on start of loop }
questo progetto si può fare con un Aduino nano 33IoT ?
Yes it should work fine