 # How to measure AC Line frequency using Lopy??

• I like to measure the AC line frequency using Lopy module. I am using optocoupler to convert 50Hz AC signal into a 50Hz pulse. Is there any builtin function (like PulseIn, micros as Arduino) by which i can do that. Please need expert advise to solve the problem.

• @vanclevector I do not know how you interface the diesel generator to you xxPy device. At leat the AC generated by the unit must be transformed to a clean 3.3 V square wave signal. I understood that this part is done. Do you have a schematic of the interface circuit of a oscilloscope dump of the signal the gets out of that?

• If the wareform generator set to 50HZ, how can the scrip get returns

• @mahmud021 The sources are strange, at least. get_pulses() will not finish until it gets a timeout, and with AC Lines that should not happen. And even if, it will then always return 128 pulses and not the specified number. But, i found a trick, shown in the sample script below. Before I run get_pulses(), I start a timer which will reconfigure the Pin after a while, and doing this force a timeout for get_pulses(). Nasty style, and you should not feed the signal to your device with a low impedance. So add a guard resistor into the line, like 1kOhm.

``````from machine import RMT, Timer, Pin
def kill_rmt(x):
pin = Pin("P10",mode=Pin.OUT)
pin(0)

def run():
alarm = Timer.Alarm(kill_rmt, 2, periodic=False)
rmt = RMT(channel=4)
rmt.init(gpio="P10", rx_idle_threshold=20000)

data = rmt.pulses_get()
sum = 0
for _ in data[2:]:
print(_, _)
sum += _
print(sum, len(data), ((len(data) - 2) * 1.e6)/sum/2)

run()
``````

The question then is, how precise you want to get the result. Obviously it is limited by two factors:

• the precision of the xxPy clock. If its deviation is more or less stable, you can compensate
• the length of the pulses_get sequence. You can take 63 periods. At 50Hz this is 1.260 s. And so the error is about 10E-6.

In my test set-up here with a waveform generator set to 50Hz the script returns something like 50.0002x Hz. But I do not know the error of either component.

• @mahmud021 At least I can confirm, that get_pulses() does not work as specified, or as I read it. It requites a timeout at the input to return, instead of returning after x pulses.
I'll glance into the sources.

• Can you suggest me a working code. I have tried some , but still no luck..

• @mahmud021 I assume that rmt is the best approach you can get. ISR's have a pretty varying latency. The longest pulse you can get with rmt is ~18ms. At 50Hz, the high/low pulses are ~10ms, if the trigger point is symmetric. If you for a a longer period, the accuracy you can get is pretty well.

• @mahmud021 Off the top of my head there are two ways you could approach it.

Have a look at RMT https://docs.pycom.io/chapter/tutorials/all/rmt.html allows you to send/receive pulses. - i haven't tried this.

Alternately is used pin iterrupts to measure RPM (hall effect) this would be accurate for RPM, but I doubt it would be for AC Freq

anyway

``````class RPM:

def __init__(self, pin):
self._pin = Pin(pin,mode=Pin.IN)
self._intvl = 0
self._pin.callback(Pin.IRQ_RISING,handler=self._callback,arg=self)
self._timer = Timer.Chrono()
self._timer.start()

def _callback(self,obj):
self._intvl = self._timer.read_ms()
self._timer.reset()

def rpm(self):
return 60000 / self._intvl
``````

I can simulate the RPM within reason by using PWM output on one of the other PINS.
That was accurate enough for my needs.