timer isr function problem

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
wwsheldons
Posts: 31
Joined: Wed Dec 02, 2015 1:47 pm

timer isr function problem

Post by wwsheldons » Wed Feb 28, 2018 1:47 pm

g = Pin(Pin('Y10'), Pin.OUT_PP)
def tick4(timer):
global g
g.value(not g.value())

tim4 = Timer(4, freq=100000)
tim4.callback(tick4)

the program is above, but if I use the Oscilloscope to see the freq of Pin('Y10') , the value is 14.59KHz. so why? it is why not 50KHz.

User avatar
Roberthh
Posts: 1697
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: timer isr function problem

Post by Roberthh » Wed Feb 28, 2018 3:42 pm

The code itself looks fine, so it#s most likely that the Python code cannot run that fast. Try lower speeds and see, at what frequency it is not working any more as expeced. If you need higher frequency signals, use PWM.

chuckbook
Posts: 107
Joined: Fri Oct 30, 2015 11:55 pm

Re: timer isr function problem

Post by chuckbook » Wed Feb 28, 2018 8:42 pm

Just out of curiosity and not that it would make any sense.

If I try on my pyboard:

Code: Select all

from pyb import Pin, Timer

g = Pin(Pin('Y10'), Pin.OUT_PP)

@micropython.viper
def tick(t):
    g(not g())

t4=Timer(4, freq=100000)
t4.callback(tick)
I get 50 kHz on Y10 and REPL is still responding.

wwsheldons
Posts: 31
Joined: Wed Dec 02, 2015 1:47 pm

Re: timer isr function problem

Post by wwsheldons » Thu Mar 01, 2018 12:40 am

chuckbook wrote:
Wed Feb 28, 2018 8:42 pm
Just out of curiosity and not that it would make any sense.

If I try on my pyboard:

Code: Select all

from pyb import Pin, Timer

g = Pin(Pin('Y10'), Pin.OUT_PP)

@micropython.viper
def tick(t):
    g(not g())

t4=Timer(4, freq=100000)
t4.callback(tick)
I get 50 kHz on Y10 and REPL is still responding.
no, I get 35.78KHz on Y10 , and REPL is not reponding

wwsheldons
Posts: 31
Joined: Wed Dec 02, 2015 1:47 pm

Re: timer isr function problem

Post by wwsheldons » Thu Mar 01, 2018 12:48 am

chuckbook wrote:
Wed Feb 28, 2018 8:42 pm
Just out of curiosity and not that it would make any sense.

If I try on my pyboard:

Code: Select all

from pyb import Pin, Timer

g = Pin(Pin('Y10'), Pin.OUT_PP)

@micropython.viper
def tick(t):
    g(not g())

t4=Timer(4, freq=100000)
t4.callback(tick)
I get 50 kHz on Y10 and REPL is still responding.
my whole question is I want to generate a M code in 50KHz, so my program is :

Code: Select all

from pyb import Pin, Timer
N_seq = 1023
loc = 0
seq = [1,-1,1,1,-1,-1,-1,...]
g = Pin(Pin('Y10'), Pin.OUT_PP)

@micropython.viper
def tick(t):
    global loc,N,seq,g
    g.value(not (not seq[loc]))
    loc = (loc+1) % N_seq
    
t4=Timer(4, freq=100000)
t4.callback(tick)
and then I can get the M sequence on Y10, but I get "ViperTypeError: can't do binary op between 'object' and 'int''" in line "loc = (loc+1) % N_seq"


but 10KHz is OK

User avatar
pythoncoder
Posts: 3651
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: timer isr function problem

Post by pythoncoder » Thu Mar 01, 2018 6:48 am

The problem here is that Viper likes to know the type of variables. Where variables are passed as function arguments you can use Python type hinting to solve this, but this isn't an option in a timer ISR. One solution is to use the Native decorator, but the code won't be as fast. You could do

Code: Select all

def tick(t):
    func(loc, N_seq)

@micropython.viper
def func(loc: int, N_seq: int):
    g.value(not (not seq[loc]))
    loc = (loc + 1) % N_seq
but I don't know if the overhead of the function call might negate the advantage of the viper code emitter.

Other optimisations might be possible. Is N_seq a constant? If so, you could save the time taken by a variable lookup by
declaring it a constant (using micropython.const). Further, if it is always of form 0b1111...11 perhaps this might be faster as there's no implied division operation:

Code: Select all

loc += 1
loc &= N_seq
Incidentally are you sure the line

Code: Select all

g.value(not (not seq[loc]))
does what you want it to do?
Peter Hinch

wwsheldons
Posts: 31
Joined: Wed Dec 02, 2015 1:47 pm

Re: timer isr function problem

Post by wwsheldons » Thu Mar 01, 2018 1:57 pm

Code: Select all

g.value(not (not seq[loc]))
its for changing the element in seq to the logic variable, which can be accepted by g.value().

Code: Select all

@micropython.viper
def func(loc: int, N_seq: int):
    g.value(not (not seq[loc]))
    loc = (loc + 1) % N_seq
as above program , why not set the variable "seq" and "g" in the input parameters. and it can not implement, I print the "loc", its value is always "1" :?: :?:

User avatar
Roberthh
Posts: 1697
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: timer isr function problem

Post by Roberthh » Thu Mar 01, 2018 2:31 pm

in your code snippet, you set
seq = [1,-1,1,1,-1,-1,-1,...]
but both not (not (1)) and not (not (-1)) evaluate to True. That's what @pythoncoder was suspicious about, I guess.
If you write:
seq = [1,0,1,1,0,0,0,...]
then you can directly write that into the pin with:
g(seq[loc])

pin(x) is a shortcut for pin.value(x)

User avatar
pythoncoder
Posts: 3651
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: timer isr function problem

Post by pythoncoder » Thu Mar 01, 2018 4:49 pm

Quite ;)
Peter Hinch

Post Reply