Hardware: AD-PQMON-SL
Question
Active energy import didn’t accumulated when energy register value is updated
- Confirmed that energy per seconds value are correct
Input Voltage: 63.5V ∠ 45 ⁰
Input Current: 2A ∠ 0 ⁰
Formula :
Active energy import value =63.52cos45 * (Seconds/3600)
Expected Output:
|
Seconds |
Wh |
|
70 |
1.7462 |
|
303 |
7.5584 |
|
534 |
13.3207 |
|
681 |
16.9877 |
Error Output:
|
Seconds |
Wh |
|
70 |
0.1014 |
|
303 |
0.1268 |
|
534 |
0.1521 |
|
681 |
0.1521 |
Coding:
pqlib_example.c
(1)
volatile unsigned int energy_ready = 0;
(2)
void energy_import_export(EnergyStructure* structure)
{
// Static local is initialized once and keeps its value across calls.
static float active_energy_import, active_energy_export, reactive_energy_import, reactive_energy_export;
// Step 1.0 '+' Energy = Import Energy, '-' Energy = Export Energy
if (structure->active_energy_total >= 0) {
active_energy_import += structure->active_energy_total;
structure->active_energy_total = 0;
}
else {
active_energy_export += structure->active_energy_total;
}
if (structure->reactive_energy_total >= 0) {
reactive_energy_import += structure->reactive_energy_total;
}
else {
reactive_energy_export += structure->reactive_energy_total;
}
// Step 2.0 Pass calculated values to structure (iio_pqm.c)
structure->active_energy_import = active_energy_import;
structure->active_energy_export = active_energy_export;
structure->reactive_energy_import = reactive_energy_import;
structure->reactive_energy_export = reactive_energy_export;
}
(3)
int pqm_one_cycle(void)
{
if (configChanged) {
printf("Recallibrating\n\r");
pqm_start_measurement(false);
configChanged = false;
pqlibExample.state = PQLIB_STATE_WAITING_FOR_TRIGGER;
}
process_and_prepare_output();
if (energy_ready) {
// Step 6 - Add formula for parameters >> (5)
energy_import_export (&energyStruct);
energy_ready = 0;
}
return 0;
}
pqlib_afe.h
extern volatile unsigned int energy_ready;
pqlib_afe.c
status = afe_read_status0((uint32_t *)&pOneCycle->STATUS0);
if ((status == 0) && (pOneCycle->STATUS0 & BITM_STATUS0_RMSONERDY)) {
status = afe_read_rms_one((uint32_t *)&pOneCycle->AVRMSONE, 3);
if (status == 0) {
status =
afe_read_angle((uint16_t *)&pOneCycle->ANGL_VA_VB, 3, ANGLE_VOLTAGE);
}
if (status == 0) {
status =
afe_read_angle((uint16_t *)&pOneCycle->ANGL_IA_IB, 3, ANGLE_CURRENT);
}
if (status == 0) {
status = afe_read_period((uint32_t *)&pOneCycle->PERIOD, 1);
}
if (status == 0) {
status = afe_read_status_1((uint32_t *)&pOneCycle->STATUS1);
}
// Proceed to read energy registers only if no previous errors occurred, and the energy data is ready (i.e., accumulation is done).
if ((status == 0) && (pOneCycle->STATUS0 & BITM_STATUS0_EGYRDY)) {
// Active Energy
if (status == 0) {
status = afe_read_active_energy_pha_LSB((int32_t*)&energy_value->active_energy_phase_A_LSB);
}
if (status == 0) {
status = afe_read_active_energy_pha_MSB((int32_t*)&energy_value->active_energy_phase_A_MSB);
}
if (status == 0) {
status = afe_read_active_energy_phb_LSB((int32_t*)&energy_value->active_energy_phase_B_LSB);
}
if (status == 0) {
status = afe_read_active_energy_phb_MSB((int32_t*)&energy_value->active_energy_phase_B_MSB);
}
if (status == 0) {
status = afe_read_active_energy_phc_LSB((int32_t*)&energy_value->active_energy_phase_C_LSB);
}
if (status == 0) {
status = afe_read_active_energy_phc_MSB((int32_t*)&energy_value->active_energy_phase_C_MSB);
}
if (status == 0) {
energy_ready = 1;
}
}
// Clear the EGYRDY bit in STATUS0 register
if (status == 0) {
uint32_t reg_val = 0;
if (status == 0) {
// Bit masking: Clear the EGYRDY bit only, other bits remain unchanged
reg_val |= BITM_STATUS0_EGYRDY;
// Write back the modified value
status = afe_write_32bit_reg(REG_STATUS0, ®_val);
if (status != 0) {
status = SYS_STATUS_AFE_STATUS0_FAILED;
}
}
}
}
if ((status == 0) && (pOneCycle->STATUS0 & BITM_STATUS0_COH_PAGE_RDY)) {
status = afe_read_waveform(
(uint16_t *) & (pqlibExample.inputWaveform.waveform),
ADI_PQLIB_WAVEFORM_BLOCK_SIZE * ADI_PQLIB_TOTAL_WAVEFORM_CHANNELS);
pWaveform->isDataProcessed = 0;
pWaveform->sequenceNumber++;
if (pqlibExample.no_os_cb_desc && !processData) {
no_os_cb_write(pqlibExample.no_os_cb_desc,
(uint8_t *) & (pqlibExample.inputWaveform.waveform),
ADI_PQLIB_WAVEFORM_BLOCK_SIZE
* ADI_PQLIB_TOTAL_WAVEFORM_CHANNELS
* sizeof(uint16_t));
}
}
if ((status == 0) && (pOneCycle->STATUS0 & BITM_STATUS0_RMS1012RDY)) {
status = afe_read_rms_1012((uint32_t *)&p1012Cycle->AIRMS1012, 7);
if (status == 0) {
p1012Cycle->isDataProcessed = 0;
p1012Cycle->sequenceNumber++;
}
}
return status;
}