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?
VancleVector last edited by
If the wareform generator set to 50HZ, how can the scrip get returns
robert-hh last edited by robert-hh
@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
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.