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(_[0], _[1])
            sum += _[1]
        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.


Log in to reply
 

Pycom on Twitter