How to Optimize Energy Calculations for STM32 Energy Meter Without Overloading Interrupts?

Hello team, so I have been working on an energy meter for some time using stm32f103c8t6 as my controller, zmct103 current transformer for measuring AC current and then using LM324 op-amp in differential mode to measure ac voltage. I have been able to get data with ac load, but my readings(adc readings) and calculations(energy calculation) are done inside interupt. I know the interrupt is meant to be short, is there a better way to handle calculations? I will appreciate your insights. here is the link to the calculations in the interrupt: https://github.com/Afuevu/dev_iot/blob/main/energy_meter
GitHub
dev_iot/energy_meter at main · Afuevu/dev_iot
Contribute to Afuevu/dev_iot development by creating an account on GitHub.
22 Replies
ZacckOsiemo
ZacckOsiemo5d ago
@Afuevu you know you can share a line number, Impressive too! I would do most of this work not in the handler, basically the handler should just get information and hand it over t a task, or some function if you are not using an OS
Afuevu
Afuevu5d ago
Thanks man. I'll look into it and see what I can do, I'm not using an OS so i just go with functions. The calculations start off from line 20. If needed i could work you through the lines so you better understand my thought processes as to why i decided to put it in interrupt
ZacckOsiemo
ZacckOsiemo5d ago
yeah we can do that but most of this work should not be in the handler it should go into some queue or something that you check in your idle or main loop
Marvee Amasi
Marvee Amasi5d ago
the interrupt can be kept short and the data safe if u try the flag system wher yo have the interrupt set a flag and store ADC values in a buffer, then you wil now let the main loop handle the processing based on that flag
Afuevu
Afuevu5d ago
I am using DMA for the ADC. The timer 2 interrupt is called every 50uS. Line 20 and 23, i am updating the variable to store the values of ADC read using DMA. There is a counter variable that increments every time the interrupt is called which is on line 3, the counter variable is value1. On line 23 the when value1 counter gets to 400, the counter is true at that point and i have gotten 20ms( 50uS*400= 20ms) = 50hz, meaning every 50hz or 20ms, i would have gotten 400 samples. From line 30 to 41, is where i get the main calculation for my voltage and current after taking many samples. For a detailed breakdown and understanding of how i came up with the voltage reading, this link explains more on how to use op-amp to measure ac voltagehttps://microcontrollerslab.com/ac-voltage-measurement-using-microcontroller/. For the measurement of the current, this link explains how to go about it https://microcontrollerslab.com/alternating-current-measurement-using-pic-micocontroller/#:~:text=To%20measure%20AC%20current%20with,drop%20across%20the%20shunt%20resistor. Then on line 47 there is a variable timer2_count that increments every 20ms. Then on line 51, when the timer2_count variable gets up to 50, the condition is true and that block of code is called, inside the block i calculate my energy consumed every second.
Microcontrollers Lab
Microcontrollers Lab
AC Voltage measurement using PIC16F877A microcontroller
AC voltage measurement using PIC microcontroller, also with difference amplifier, ADC, potential transformre/PT with code for voltage sensor
Microcontrollers Lab
Microcontrollers Lab
Alternating Current Measurement using Pic Microcontroller
AC Alternating current measurement using pic microcontroller, complete circuit diagram, code for AC current meter using pic16f877a
ZacckOsiemo
ZacckOsiemo5d ago
all the work after this https://github.com/Afuevu/dev_iot/blob/7055fff9c2fa26d6aed8bd3fadba1d5951001c7e/energy_meter#L25 should be done in your main loop, not in your ISR
GitHub
dev_iot/energy_meter at 7055fff9c2fa26d6aed8bd3fadba1d5951001c7e · ...
Contribute to Afuevu/dev_iot development by creating an account on GitHub.
ZacckOsiemo
ZacckOsiemo5d ago
well except resetting the Interrupt
Afuevu
Afuevu5d ago
Yes chief I will work on that
Afuevu
Afuevu5d ago
Thanks chief, i will implement it using flags
ZacckOsiemo
ZacckOsiemo5d ago
I wouldn't mind seeing the whole project as well though
Afuevu
Afuevu5d ago
For sure, i will drop the link.
Afuevu
Afuevu5d ago
GitHub
GitHub - DevHeadsCommunity/AC_CURRENT_MEASUREMENT
Contribute to DevHeadsCommunity/AC_CURRENT_MEASUREMENT development by creating an account on GitHub.
Afuevu
Afuevu4d ago
Hello everyone, Good day. I have been able to make the adjustment @ZacckOsiemo and @Marvee Amasi suggested that I moved the calculations from the interrupt to the while loop and just used flags to do the checks in the ISR. I have made a commit on the repo, here is the link https://github.com/DevHeadsCommunity/AC_CURRENT_MEASUREMENT/tree/master. I intend to save data on the EEPROM every 8 hours and 24 hours. I am considering using the internal RTC of the stm32 or a counter that keeps incrementing once the system turns on. What are our thoughts, have anyone used the internal RTC of the stm32f103c8t6 before?
GitHub
GitHub - DevHeadsCommunity/AC_CURRENT_MEASUREMENT at master
Contribute to DevHeadsCommunity/AC_CURRENT_MEASUREMENT development by creating an account on GitHub.
ZacckOsiemo
ZacckOsiemo4d ago
i have used the internal RTC, If i remember correctly its on SPI 1 and that connection was hard to get going.
ZacckOsiemo
ZacckOsiemo4d ago
could you share the line of code where you put in the change?
Afuevu
Afuevu4d ago
Line 30 to line 82
Afuevu
Afuevu4d ago
what do you mean RTC is on SPI 1, please? I think RTC is a stand-alone peripheral on the STM32
melta101
melta1014d ago
they share pins
Afuevu
Afuevu4d ago
Oh i see
Afuevu
Afuevu4d ago
Actually i am not using its pin, I am just reading the date and time after i have written to it
ZacckOsiemo
ZacckOsiemo4d ago
it turns out I was mistaken, i was talking about the MEMs sensor but I have used thr RTC as well, I faced some issues too but I don’t remember which means i fixed them.
ZacckOsiemo
ZacckOsiemo4d ago
I can share code if you want @Afuevu

Did you find this page helpful?