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
@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
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
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
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
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
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.
well except resetting the Interrupt
Yes chief I will work on that
Thanks chief, i will implement it using flags
I wouldn't mind seeing the whole project as well though
For sure, i will drop the link.
GitHub
GitHub - DevHeadsCommunity/AC_CURRENT_MEASUREMENT
Contribute to DevHeadsCommunity/AC_CURRENT_MEASUREMENT development by creating an account on GitHub.
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.
i have used the internal RTC, If i remember correctly its on SPI 1 and that connection was hard to get going.
could you share the line of code where you put in the change?
Line 30 to line 82
what do you mean RTC is on SPI 1, please? I think RTC is a stand-alone peripheral on the STM32
they share pins
Oh i see
Actually i am not using its pin, I am just reading the date and time after i have written to it
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.
I can share code if you want @Afuevu