Page 1 of 1

timer isr function problem

Posted: Wed Feb 28, 2018 1:47 pm
by wwsheldons
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.

Re: timer isr function problem

Posted: Wed Feb 28, 2018 3:42 pm
by Roberthh
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.

Re: timer isr function problem

Posted: Wed Feb 28, 2018 8:42 pm
by chuckbook
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.

Re: timer isr function problem

Posted: Thu Mar 01, 2018 12:40 am
by wwsheldons
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

Re: timer isr function problem

Posted: Thu Mar 01, 2018 12:48 am
by wwsheldons
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

Re: timer isr function problem

Posted: Thu Mar 01, 2018 6:48 am
by pythoncoder
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?

Re: timer isr function problem

Posted: Thu Mar 01, 2018 1:57 pm
by wwsheldons

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" :?: :?:

Re: timer isr function problem

Posted: Thu Mar 01, 2018 2:31 pm
by Roberthh
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)

Re: timer isr function problem

Posted: Thu Mar 01, 2018 4:49 pm
by pythoncoder
Quite ;)