register int x; register int y; register int z; register unsigned char k; cycle_sample_count[0] += 128; cycle_sample_count[1] += 128; cycle_sample_count[2] += 128; for(check1=0;check1<1;check1++) { if (abs(V_Act[check1] - last_V_sample[check1]) <= since_last * MAX_PER_SAMPLE_VOLTAGE_SLEW) { /* This doesn't look like a spike - do mains cycle detection, and estimate the precise mains period */ if (V_Act[check1] < 0) { /* Log the sign of the signal */ p_status[check1] &= ~V_POS; } else { if (!(p_status[check1] & V_POS)) { /* Apply limits to the sample count, to avoid spikes or dying power lines disturbing the frequency reading too much */ /* The mains should be <40Hz or >70Hz to fail this test! */ if (128*SAMPLES_PER_10_SECONDS/700 <= cycle_sample_count[check1] && cycle_sample_count[check1] <= 128*SAMPLES_PER_10_SECONDS/400) { /* A mains frequency measurement procedure based on interpolating zero crossings, to get a fast update rate for step changes in the mains frequency */ /* Interpolate the zero crossing by successive approx. */ z = V_Act[check1] - last_V_sample[check1]; x = 0; y = 0; for (k = 0; k < 8; k++) { y <<= 1; z >>= 1; x += z; if (x > V_Act[check1]) x -= z; else y |= 1; } /* Now we need to allow for skipped samples, due to spike detection */ z = y; while (since_last > 1) { z += y; since_last--; } /* z is now the fraction of a sample interval between the zero crossing and the current sample, in units of 1/256 of a sample */ /* A lightly damped filter should now be enough to remove noise and get a stable value for the frequency */ mains_period[check1] += ((int32_t) (cycle_sample_count[check1] - z) << 12) - (mains_period[check1] >> 4); /* Start the next cycle with the residual fraction of a sample */ cycle_sample_count[check1] = z; } else { cycle_sample_count[check1] = 0; } } /* Log the sign of the signal */ p_status[check1] |= V_POS; } since_last = 0; last_V_sample[check1] = V_Act[check1]; } since_last++; } Idle_Sample_Count++; } }