Example #1
0
class caliMagCtrl():
    def __init__(self, buf=array('H', [100]), ch=1):
        self.timer = Timer(6)
        self.dac = DAC(ch, bits=12)
        self.buf = buf
        self.dac_on = 0

    def reset_buf(self, buf):
        self.buf = buf

    def start(self, freq=10):
        self.dac.write_timed(self.buf, self.timer, mode=DAC.CIRCULAR)
        self.timer.init(freq=freq * len(self.buf))
        self.dac_on = 1

    def stop(self):
        self.timer.deinit()
        self.dac.write(0)
        self.dac_on = 0

    def toggle(self, freq=5):
        if self.dac_on:
            self.stop()
        else:
            self.start(freq)
Example #2
0
def main():
    ## 统一分配引脚
    bc = BoardCtrl('X1', 'X2', 'X3', 'X4')
    bufs = generate_bufs()
    DAC_ch = 'X5'
    sync_sig = syncSignal('X6')
    # record_sig = syncSignal('X7')

    freqs = [13]
    repeat = 1
    timer_num = 6
    mctrl = magCtrl(bufs, freqs, DAC_ch, sync_sig, bc, repeat, timer_num)

    # record_sig.falling_edge()   # 发送启动记录的信号
    led = ledCue()

    ## timer3,用于循环测试
    tim3 = Timer(3)
    tim3.init(freq=0.2)
    tim3.callback(mctrl.next)

    while not mctrl.end_flg:
        if mctrl.new_block:
            led.next(mctrl.stimulus_level)
            mctrl.new_block = False
        time.sleep_us(500000)  # 每50ms

    # record_sig.falling_edge()   # 发送结束记录的信号
    led.end()
Example #3
0
class caliMagCtrl1():
    def __init__(self, amps=[], freqs=[], bufs=[], ch=1):
        # amps: 幅值序列
        # bufs: 对应幅值的正弦序列

        self.timer = Timer(6)
        self.dac = DAC(ch, bits=12)
        self.amps = amps
        self.bufs = bufs

        self.freqs = freqs
        self.indx = range(len(amps))
        self.newtask = False

    def next(self):
        ind = self.indx.pop(0)
        self.indx.append(ind)

        self.amp = self.amps[ind]
        buf = self.bufs[ind]
        self.freq = self.freqs[ind]

        if self.amp == 0:
            self.timer.deinit()
            self.dac.write(0)
        else:
            self.dac.write_timed(buf, self.timer, mode=DAC.CIRCULAR)
            self.timer.init(freq=self.freq * len(buf))

        self.newtask = True
def main():
    ## 创建测试磁场对象,统一分配引脚
    tiny = pyb.Pin('X1', pyb.Pin.OUT_PP)  # 对应小电阻,  接CM1
    big = pyb.Pin('X2', pyb.Pin.OUT_PP)  # 对应大电阻,  接CM2
    rw = resistSwitch(big_resist_pin=big, tiny_resist_pin=tiny)

    bufs = generate_bufs()
    record_sig = syncSignal(pyb.Pin('X3', pyb.Pin.OUT_PP))  # X3 对应光耦IN1
    sync_sig = syncSignal(pyb.Pin('X4', pyb.Pin.OUT_PP))  # X4 对应光耦IN2

    freqs = [10]
    ch = 1  # X5 标定磁场输出
    repeat = 20
    timer_num = 6
    mctrl = magCtrl(bufs, freqs, ch, sync_sig, rw, repeat, timer_num)

    record_sig.falling_edge()  # 发送启动记录的信号
    led = ledCue()

    ## timer3,用于循环测试
    tim3 = Timer(3)
    tim3.init(freq=0.1)
    tim3.callback(mctrl.next)

    while not mctrl.end_flg:
        if mctrl.new_block:
            led.next(mctrl.stimulus_typ)
            mctrl.new_block = False
        time.sleep_us(500000)  # 每50ms

    record_sig.falling_edge()  # 发送结束记录的信号
    led.end()
Example #5
0
class PidTimer(Pid):
    '''
    Implements the PID-stabilization algorithm as a Timer callback
    
    IMPORTANT!!! It seems it is not allowed to allocate memory within the timer callback. 
    Therefore, this class won't work.
    '''
    def __init__(self, timerId, length, readInputDelegate, setOutputDelegate,
                 pidName):
        '''
        Constructor
        
        @param timerId: Timer to be used
        @param length: Number of items to stabilize
        @param readInputDelegate: Method to gather current values.
         Must return an array with the same number of items to stabilize
        @param setOutputDelegate: Delegate's parameter is an array with the values to react,
         one for each item to stabilize. 
        @param pidName: (optional) Name to identify the PID-thread among other ones.
        '''

        super().__init__(length, readInputDelegate, setOutputDelegate, pidName)

        self._timer = Timer(timerId)

    def _doCalculate(self, timer):

        print("_doCalculate")
        self._calculate()

    def init(self, freq, initRunning=True):
        '''
        Initializes stabilization as a coroutine.
        Initializes a thread to perform calculations in background
        
        @param freq: Frequency of the stabilization. This value is ignored if period is provided
        @param initRunning: Starts stabilization immediately
        '''

        self._timer.init(freq=freq)
        self._timer.callback(lambda t: self._doCalculate(t))

    def stop(self):
        '''
        Stops the coroutine
        '''

        self._timer.callback(None)
        self._timer.deinit()
Example #6
0
class PWM:
    def __init__(self, pin_name):
        tim_num = PWM_PINS[pin_name.name()][0]
        ch_num = PWM_PINS[pin_name.name()][1]
        self.p = Pin(pin_name)
        self.tim = Timer(tim_num)
        self.tim.init(freq=10000)  # need 5k+ for VNH5019 current sense to work
        # TODO is this right?
        self.ch = self.tim.channel(ch_num,
                                   mode=Timer.PWM,
                                   pin=self.p,
                                   pulse_width_percent=0)  # especially this

    def duty_cycle(self, dc):
        # dc is duty cycle from 0 to 100
        self.ch.pulse_width_percent(dc)
Example #7
0
    class LEDState(
            State
    ):  # Output is determined by ``__enter__`` and ``__exit__`` (common in embedded machines).
        def __init__(self, led_num, time_on, event):
            super().__init__(ident=led_num)  # Use the LED num as the ident.
            self.led = LED(self.ident)  # The LED to use.
            self.timer = Timer(timer0 + self.ident)  # The timer to use.
            self.timeout = time_on  # Time to wait before firing event.
            self.event = event  # Event to fire at end of time_on.

        def __enter__(self):
            self.led.on()
            self.timer.init(
                freq=1 / self.timeout,
                callback=lambda _: schedule(tl_fire_ref, self.event))
            return self

        def __exit__(self, exc_type, exc_value, traceback):
            self.led.off()
            self.timer.deinit()
            return False
Example #8
0
    class FlashingRed(State):  # Special fault state that should never exit.
        def __init__(self):
            super().__init__(ident='error')
            self.timer = Timer(timer0 + 4)
            self.led = LED(1)

            # noinspection PyUnusedLocal
            def toggle_with_arg(
                not_used
            ):  # Toggle func that accepts an arg, because ``schedule`` *needs* an arg.
                self.led.toggle()

            self.led_tog_ref = toggle_with_arg  # Store the function reference locally to avoid allocation in interrupt.

        def __enter__(self):
            self.timer.init(
                freq=2, callback=lambda _: schedule(self.led_tog_ref, None))
            return self

        def __exit__(self, exc_type, exc_val, exc_tb):
            self.led.off()
            self.timer.deinit()
Example #9
0
def main():
    ## 预生成待测试的DAC序列
    m = magGen()
    m.reset_param(radius=11.34)
    bufs = []

    m.reset_param(resist=1100)  #1.1MOhm 磁场范围约为50pT
    for s in [10, 20, 30, 40, 50]:
        buf = m.gen_ay(s)
        bufs.append((s, 'bigmag', buf))

    bufs.append((0, 'cut', array('H', [0])))

    m.reset_param(resist=9300)  #9.3MOhm 磁场范围约为5pT
    for s in [1, 2, 3, 4, 5]:
        buf = m.gen_ay(s)
        bufs.append((s, 'tinymag', buf))

    bufs.append((0, 'cut', array('H', [0])))

    ## 创建测试磁场对象,统一分配引脚
    tiny = pyb.Pin('X1', pyb.Pin.OUT_PP)  # 对应小电阻,  接CM1
    big = pyb.Pin('X2', pyb.Pin.OUT_PP)  # 对应大电阻,  接CM2
    rw = resistSwitch(big_resist_pin=big, tiny_resist_pin=tiny)

    sport = pyb.Pin('X3', pyb.Pin.OUT_PP)  # 对应光耦IN1
    sync = syncSignal(sport)

    freqs = [5, 13]
    ch = 1  # 对应X5
    repeat = 2
    timer_num = 6
    mctrl = magCtrl(bufs, freqs, ch, sync, rw, repeat, timer_num)

    # timer3,用于循环测试
    tim3 = Timer(3)
    tim3.init(freq=0.2)
    tim3.callback(mctrl.next)
Example #10
0
class caliMagCtrl2():
    def __init__(self, freqs=[], bufs=[], ch=1, **kwargs):
        # freqs:待测试的频率
        # bufs: 对应幅值的正弦序列等消息,每个元素包含(amp,buf,port)
        # 其中port是指,使用可变电阻时对应控制的端口
        # ch:测试信号输出端口选择
        # kwargs: r_port,电阻选择的端口列表

        self.timer = Timer(6)
        self.dac = DAC(ch, bits=12)
        self.freqs = freqs
        self.bufs = bufs
        self.r_adapt = False
        if len(kwargs) > 0:
            if 'r_port' in kwargs:  #使用电阻自适应调整
                self.r_adapt = True
                (pyb.Pin(pin, pyb.Pin.OUT_PP) for pin in kwargs['r_port'])

        self.freqs = freqs
        self.indx = range(len(amps))
        self.newtask = False

    def next(self):
        ind = self.indx.pop(0)
        self.indx.append(ind)

        self.amp = self.amps[ind]
        buf = self.bufs[ind]
        self.freq = self.freqs[ind]

        if self.amp == 0:
            self.timer.deinit()
            self.dac.write(0)
        else:
            self.dac.write_timed(buf, self.timer, mode=DAC.CIRCULAR)
            self.timer.init(freq=self.freq * len(buf))

        self.newtask = True
Example #11
0
# Untitled - By: skywoodsz - 周五 10月 19 2018
import time
from pyb import LED
from pyb import Timer
led = LED(1)
led.on()


#绑定事件方式1
def led_on_off():
    global led  #向全局寻求led变量
    led.toggle()  #反转led


timer = Timer(4)  #设置定时器4
timer.init(freq=1)  #设置定时器频率:1s执行几次
timer.callback(lambda t: led_on_off())  #定时器中断函数/回调函数
while (True):  #其后必须有语句体
    time.sleep(1000)

#绑定事件方式2
'''
def led_on_off(timer):#不同!
    global led#向全局寻求led变量
    led.toggle()#反转led

timer=Timer(4)#设置定时器4
timer.init(freq=1)#设置定时器频率:1s执行几次
timer.callback(led_on_off)#定时器中断函数/回调函数。不同!
while(True):#其后必须有语句体
    time.sleep(1000)
Example #12
0
class Controller:
    def __init__(self, uart, pwm_freq):
        self.uart = uart

        self.i_state = array('i', [0] * len(INAMES))
        self.f_state = array('f', [0] * len(FNAMES))

        # controller timer
        self.controller_timer = Timer(1)

        # motor power control
        self.nstby = Pin('NSTBY', mode=Pin.OUT_PP)
        self.nstby.value(0)

        # motors
        motor_pwm_timer = Timer(8, freq=pwm_freq)
        self.motor1 = TB6612(
            motor_pwm_timer.channel(3, Timer.PWM_INVERTED, pin=Pin('PWM_A')),
            Pin('AIN1', mode=Pin.OUT_PP), Pin('AIN2', mode=Pin.OUT_PP))
        self.motor2 = TB6612(
            motor_pwm_timer.channel(1, Timer.PWM_INVERTED, pin=Pin('PWM_B')),
            Pin('BIN1', mode=Pin.OUT_PP), Pin('BIN2', mode=Pin.OUT_PP))

        # encoders
        self.enc1 = init_encoder(4, 'ENC_A1', 'ENC_A2', Pin.AF2_TIM4)
        self.enc2 = init_encoder(3, 'ENC_B1', 'ENC_B2', Pin.AF2_TIM3)

        # gyro
        i2c = I2C(1, freq=400_000)
        imu = BNO055(i2c, crystal=True, transpose=(2, 0, 1), sign=(0, 0, 1))
        imu.mode(NDOF_FMC_OFF_MODE)
        sleep_ms(800)
        imu.iget(QUAT_DATA)
        self.imu = imu

        # pid controllers
        self.pid = [
            PID(1, 7, 50, 0, -100, 100),
            PID(1, 7, 50, 0, -100, 100),
        ]

    def start(self, fs, controller_name="duty_control"):
        self.stop()
        self.control_laws = getattr(self, controller_name)
        self.set_fs(fs)
        self.nstby.value(1)
        gc.collect()
        self.controller_timer.init(freq=fs, callback=self.control)

    def stop(self):
        self.controller_timer.callback(None)
        self.nstby.value(0)

    def shutdown(self):
        self.controller_timer.deinit()
        self.nstby.value(0)

    def set_fs(self, fs):
        for pid in self.pid:
            pid.Ts = 1 / fs

    def set_kp(self, pid_index, kp):
        self.pid[pid_index].kp = kp

    def set_ki(self, pid_index, ki):
        self.pid[pid_index].ki = ki

    def set_kd(self, pid_index, kd):
        self.pid[pid_index].kd = kd

    def control(self, timer):
        start_us = ticks_us()

        # locals
        i_state = self.i_state
        f_state = self.f_state

        # time index
        i_state[_ISTATE_K] += 1

        # encoders
        enc1 = self.enc1
        enc2 = self.enc2
        cps1 = -c2(enc1.counter())
        enc1.counter(0)
        cps2 = c2(enc2.counter())
        enc2.counter(0)
        i_state[_ISTATE_ENC1] += cps1
        i_state[_ISTATE_ENC2] += cps2
        f_state[_FSTATE_CPT1] = cps1
        f_state[_FSTATE_CPT2] = cps2

        # gyro
        imu = self.imu
        imu.iget(QUAT_DATA)
        f_state[_FSTATE_QUAT_W] = w = imu.w / (1 << 14)
        f_state[_FSTATE_QUAT_X] = x = imu.x / (1 << 14)
        f_state[_FSTATE_QUAT_Y] = y = imu.y / (1 << 14)
        f_state[_FSTATE_QUAT_Z] = z = imu.z / (1 << 14)
        sinp = 2 * (w * y - z * x)
        if abs(sinp) >= 1:
            # use 90 degrees if out of range
            pitch = math.copysign(math.pi / 2, sinp)
        else:
            pitch = math.asin(sinp)
        pitch *= RAD2DEG
        f_state[_FSTATE_PITCH] = pitch

        # call control code
        self.control_laws()

        # controller execution time
        i_state[_ISTATE_DT1] = ticks_diff(ticks_us(), start_us)

        # status
        uart = self.uart
        uart.writechar(CMD_STATE)
        uart.write(i_state)
        uart.write(f_state)

        # total execution time
        i_state[_ISTATE_DT2] = ticks_diff(ticks_us(), start_us)

    def duty_control(self):
        f_state = self.f_state
        self.motor1.speed(f_state[_FSTATE_DUTY1])
        self.motor2.speed(f_state[_FSTATE_DUTY2])

    def speed_control(self):
        f_state = self.f_state
        pid = self.pid
        cps1 = f_state[_FSTATE_CPT1]
        cps2 = f_state[_FSTATE_CPT2]

        # control
        pid[PID_CPT1].setpoint = f_state[_FSTATE_CPT1_SP]
        pid[PID_CPT2].setpoint = f_state[_FSTATE_CPT2_SP]
        duty1 = pid[PID_CPT1].update(cps1)
        duty2 = pid[PID_CPT2].update(cps2)
        self.motor1.speed(duty1)
        self.motor2.speed(duty2)
        f_state[_FSTATE_DUTY1] = duty1
        f_state[_FSTATE_DUTY2] = duty2
Example #13
0
import pyb
from pyb import Timer

tim = Timer(4)
tim = Timer(4, prescaler=100, period=200)
print(tim.prescaler())
print(tim.period())
tim.prescaler(300)
print(tim.prescaler())
tim.period(400)
print(tim.period())

tim = Timer(4, freq=1)
tim.init(freq=2000)


def f(t):
    print(1)
    t.callback(None)


tim.callback(f)
pyb.delay(10)


# f3 closes over f2.y
def f2(x):
    y = x

    def f3(t):
        print(2, y)
Example #14
0
class IR:
    _active_high = True  # Hardware turns IRLED on if pin goes high.
    _space = 0  # Duty ratio that causes IRLED to be off
    timeit = False  # Print timing info

    @classmethod
    def active_low(cls):
        if ESP32:
            raise ValueError('Cannot set active low on ESP32')
        cls._active_high = False
        cls._space = 100

    def __init__(self, pin, cfreq, asize, duty, verbose):
        if ESP32:
            self._rmt = RMT(0,
                            pin=pin,
                            clock_div=80,
                            carrier_freq=cfreq,
                            carrier_duty_percent=duty)  # 1μs resolution
        elif RP2:  # PIO-based RMT-like device
            self._rmt = RP2_RMT(pin_pulse=None,
                                carrier=(pin, cfreq, duty))  # 1μs resolution
        else:  # Pyboard
            if not IR._active_high:
                duty = 100 - duty
            tim = Timer(2,
                        freq=cfreq)  # Timer 2/pin produces 36/38/40KHz carrier
            self._ch = tim.channel(1, Timer.PWM, pin=pin)
            self._ch.pulse_width_percent(self._space)  # Turn off IR LED
            # Pyboard: 0 <= pulse_width_percent <= 100
            self._duty = duty
            self._tim = Timer(5)  # Timer 5 controls carrier on/off times
        self._tcb = self._cb  # Pre-allocate
        self._arr = array('H', 0 for _ in range(asize))  # on/off times (μs)
        self._mva = memoryview(self._arr)
        # Subclass interface
        self.verbose = verbose
        self.carrier = False  # Notional carrier state while encoding biphase
        self.aptr = 0  # Index into array

    def _cb(self, t):  # T5 callback, generate a carrier mark or space
        t.deinit()
        p = self.aptr
        v = self._arr[p]
        if v == STOP:
            self._ch.pulse_width_percent(self._space)  # Turn off IR LED.
            return
        self._ch.pulse_width_percent(self._space if p & 1 else self._duty)
        self._tim.init(prescaler=84, period=v, callback=self._tcb)
        self.aptr += 1

    # Public interface
    # Before populating array, zero pointer, set notional carrier state (off).
    def transmit(self,
                 addr,
                 data,
                 toggle=0,
                 validate=False):  # NEC: toggle is unused
        t = ticks_us()
        if validate:
            if addr > self.valid[0] or addr < 0:
                raise ValueError('Address out of range', addr)
            if data > self.valid[1] or data < 0:
                raise ValueError('Data out of range', data)
            if toggle > self.valid[2] or toggle < 0:
                raise ValueError('Toggle out of range', toggle)
        self.aptr = 0  # Inital conditions for tx: index into array
        self.carrier = False
        self.tx(addr, data, toggle)  # Subclass populates ._arr
        self.trigger()  # Initiate transmission
        if self.timeit:
            dt = ticks_diff(ticks_us(), t)
            print('Time = {}μs'.format(dt))

    # Subclass interface
    def trigger(self):  # Used by NEC to initiate a repeat frame
        if ESP32:
            self._rmt.write_pulses(tuple(self._mva[0:self.aptr]), start=1)
        elif RP2:
            self.append(STOP)
            self._rmt.send(self._arr)
        else:
            self.append(STOP)
            self.aptr = 0  # Reset pointer
            self._cb(self._tim)  # Initiate physical transmission.

    def append(self, *times):  # Append one or more time peiods to ._arr
        for t in times:
            self._arr[self.aptr] = t
            self.aptr += 1
            self.carrier = not self.carrier  # Keep track of carrier state
            self.verbose and print('append', t, 'carrier', self.carrier)

    def add(self, t):  # Increase last time value (for biphase)
        assert t > 0
        self.verbose and print('add', t)
        # .carrier unaffected
        self._arr[self.aptr - 1] += t
Example #15
0
class PID:
    def __init__(self, P, I, D, target_fn, target_freq):
        self.Kp = P
        self.Ki = I
        self.Kd = D
        self.target = 0  # Degrees, planner.dist_bearing(), returns flag, (dist, bear)
        self.feedback = 0  # Degrees
        self.error = 0  # Degrees
        self.pid_out = 0
        self.output = (0, 0)  # (left_pwr, right_pwr)
        self.prev_error = 0
        self.error_sum = 0
        self.base_speed = 0
        self.t_fn = target_fn
        self.target_flag = False  # Set to true by the timer interrupt
        self.t_c_top = round(
            500 / target_freq)  # Counter top values. Timer is set to 100 Hz
        self.t_c = 0  # Target counter incremented when the timer triggers
        self.timer = None  # Timer objects interrupting at period specified by user
        self.enable = False
        self.LIMITER = 1  # Limits the output for testing
        self.POWER_LIMIT = 90
        self.BASE_PWR = 50
        self.log_msg = None
        self.i = 0

    def pid(self):
        # Updating the target variable
        if self.target_flag is True:
            # t_fn is planner.dist_bearing()
            flag, (dist, bear) = self.t_fn()
            self.target_flag = False
            if flag is True:
                self.target = bear
            else:
                return False

        self.feedback = global_variables.fuse.heading

        # Error term
        self.error = self.target - self.feedback
        # Always rotating in the shortest direction
        if self.error > 180:
            self.error = 360 - self.error
        elif self.error < -180:
            self.error = 360 + self.error
        if (self.error > -20) and (self.error < 20):
            self.error_sum += self.error
        self.pid_out = self.Kp * self.error  # Proportional
        self.pid_out += self.Kd * self.prev_error  # Derivative
        self.pid_out += self.Ki * self.error_sum  # Integral
        self.prev_error = self.error

        self.base(self.error)
        # If error is negative (left turn needed to reduce error), so is pid_out. right speed increases, left speed decreases, vice versa
        self.output = (round(
            ((self.base_speed + self.pid_out / 2) * self.LIMITER),
            0), round(((self.base_speed - self.pid_out / 2) * self.LIMITER),
                      0))
        if (abs(self.output[0]) < self.POWER_LIMIT) and (abs(self.output[1]) <
                                                         self.POWER_LIMIT):
            motor.motor_abs(("l", self.output[0]), ("r", self.output[1]))
        else:
            cmd.send_uart("pid out of range\n", log_flag)
            self.error_sum = 0
        return True

    def base(self, error):
        abs_err = abs(error)
        self.base_speed = -(self.BASE_PWR / 180) * abs_err + self.BASE_PWR

    def update(self, timer):
        self.t_c += 1
        if self.t_c % self.t_c_top == 0:
            self.target_flag = True

    def start_update(self):
        # 16-bit timer
        self.timer = Timer(9)
        self.timer.init(freq=100)
        self.timer.callback(self.update)
        self.enable = True
        self.error_sum = 0
        cmd.send_uart("PID timers started\n", log_flag)

    def stop_update(self):
        try:
            self.timer.deinit()
        except AttributeError:
            cmd.send_uart("PID not initialised\n", log_flag)
        self.enable = False
        self.error_sum = 0
        motor.motor_abs(("l", 0), ("r", 0))
        cmd.send_uart("PID stopped\n", log_flag)

    def start_pid(self):
        # Allows time for the first IMU reading to be completed
        sleep_ms(12)
        cmd.send_uart("PID thread started", True)
        print("PID thread started")
        self.enable = False
        i = 0
        while True:
            if i % 5 == 0:
                if self.enable:
                    self.pid()
            if i % 3 == 0:
                try:
                    acc = global_variables.imu.accel.xyz
                    gyr = global_variables.imu.gyro.xyz
                    mag = global_variables.imu.mag.xyz
                except:
                    cmd.send_uart("MPU reading error", log_flag)
            if i % 300 == 0:
                msg = {
                    "type": "gps",
                    "func": "heading",
                    "head": str(global_variables.fuse.heading)
                }
                msg = ujson.dumps(msg)
                cmd.send_uart(msg, log_flag)
                # print(global_variables.fuse.heading)
            global_variables.fuse.update(acc, gyr, mag)
            i += 1

    def set_pid(self, P, I, D):
        self.Kp = P
        self.Ki = I
        self.Kd = D
        if debug_flag is True:
            cmd.debug("PID set", debug_flag)

    def get_pid(self):
        return self.Kp, self.Ki, self.Kd

    def set_pwr(self, base_pwr):
        if (base_pwr >= 0) and (base_pwr <= 100):
            self.BASE_PWR = base_pwr
            return True
        else:
            return False

    def get_pwr(self):
        return self.BASE_PWR
Example #16
0
        print("cb4", y)
        t.callback(None)
    return cb4

# create a timer with a callback, using callback(None) to stop
tim = Timer(1, freq=100, callback=cb1)
pyb.delay(5)
print("before cb1")
pyb.delay(15)

# create a timer with a callback, using deinit to stop
tim = Timer(2, freq=100, callback=cb2)
pyb.delay(5)
print("before cb2")
pyb.delay(15)

# create a timer, then set the freq, then set the callback
tim = Timer(4)
tim.init(freq=100)
tim.callback(cb1)
pyb.delay(5)
print("before cb1")
pyb.delay(15)

# test callback with a closure
tim.init(freq=100)
tim.callback(cb3(3))
pyb.delay(5)
print("before cb4")
pyb.delay(15)
max_ticks = 0
avg_ticks = 0
std_dev_ticks = 0
n = 0
timer = Timer(2)

logger = logging.getLogger(__name__)
logger.info("Latency test CAN")

logger.info("Initializing interface.")
interface = can_tmcl_interface()

logger.info("Performing test.")
while (n < N_SAMPLES):
    timer.counter(0)
    timer.init(prescaler=0, period=16800000, callback=timeout)
    # send invalid (for all modules) TMCL Request
    reply = interface.send_request(TMCL_Request(MODULE_ID, 1, 2, 3, 4, 5),
                                   host_id=HOST_ID,
                                   module_id=MODULE_ID)
    timer.deinit()
    if (not (tout)):
        counter = timer.counter()
        logger.debug("Measured delta ticks: {}".format(counter))
        # update values
        value = counter
        if (n == 0):
            min_ticks = value
            max_ticks = value
            avg_ticks = value
            std_dev_ticks = 0
from pyb import Pin, Timer

out = Pin('X1')  # X1 has TIM2, CH1
tim = Timer(4)  # create a timer object using timer 4
tim.init(freq=2)  # trigger at 2Hz
tim.callback(lambda t: out.toggle())
Example #19
0
class magCtrl():
    def __init__(self,
                 bufs,
                 freqs,
                 DAC_ch,
                 sync,
                 BoardCtrl,
                 repeat=50,
                 timer_num=6):
        '''
        bufs: list, DAC output array
        typ: list, the same length with bufs, 'tiny','big','cut' to describe which type of the buf
        freqs: list, tested frequences
        ch: DAC output channel, 1: 'X5'  2: 'X6'
        sync: object for output synchronus signal to record client
        resistset: object for adjusting resist according to the magnet strength
        timer: internal timer, default 6
        '''

        self.bufs = bufs
        self.freqs = freqs

        if DAC_ch == 'X5':
            self.dac = DAC(1, bits=12)
        elif DAC_ch == 'X6':
            self.dac = DAC(2, bits=12)
        else:
            raise ValueError('DAC pin should be X5 or X6')

        self.sync = sync
        self.boardctrl = BoardCtrl
        self.timer = Timer(timer_num)
        self.buf_indx = 0
        self.fre_indx = 0
        self.fre_len = len(self.freqs)
        self.buf_len = len(self.bufs)
        self.repeat = repeat
        self.rcount = 0
        self.end_flg = False
        self.new_block = False
        self.stimulus_level = 0

    def next(self, t):
        self.new_block = True
        if not self.end_flg:
            freq = self.freqs[self.fre_indx]
            s, self.stimulus_level, buf = self.bufs[self.buf_indx]
            self.boardctrl.update(self.stimulus_level)
            print('new trial:', s, 'pT ', freq, 'Hz')

            self.buf_indx += 1
            if self.buf_indx == self.buf_len:
                self.buf_indx = 0
                self.fre_indx += 1
                if self.fre_indx == self.fre_len:
                    self.fre_indx = 0
                    self.rcount += 1
                    if self.rcount == self.repeat:
                        self.end_flg = True

            self.timer.deinit()
            self.dac.write_timed(buf, self.timer,
                                 mode=DAC.CIRCULAR)  #启动定时器,写DAC
            self.timer.init(freq=freq * len(buf))
            self.sync.falling_edge()  # 发送同步信号
Example #20
0
import pyb
from pyb import Timer

tim = Timer(4)
tim = Timer(4, prescaler=100, period=200)
print(tim.prescaler())
print(tim.period())
tim.prescaler(300)
print(tim.prescaler())
tim.period(400)
print(tim.period())

tim = Timer(4, freq=1)
tim.init(freq=2000)
def f(t):
    print(1)
    t.callback(None)
tim.callback(f)
pyb.delay(10)

# f3 closes over f2.y
def f2(x):
    y = x
    def f3(t):
        print(2, y)
        t.callback(None)
    return f3
tim.callback(f2(3))
pyb.delay(10)
import time

led = Pin('LED1', Pin.OUT)
#adc_pin = Pin(Pin.cpu.C2, mode=Pin.ANALOG)
adc_pin = Pin(Pin.cpu.C3, mode=Pin.ANALOG)
#adc_pin = Pin(Pin.cpu.A0, mode=Pin.ANALOG)
#adc_pin = Pin(Pin.cpu.A1, mode=Pin.ANALOG)
#adc_pin = Pin(Pin.cpu.B0, mode=Pin.ANALOG) #on testpad
#adc_pin = Pin(Pin.cpu.B1, mode=Pin.ANALOG) #on testpad

dac_pin = Pin(Pin.cpu.A4, mode=Pin.ANALOG)
adc = ADC(adc_pin)
dac = DAC(dac_pin)

tim = Timer(6)
tim.init(freq=5)
tim.counter() # get counter value

def tick(timer):                # we will receive the timer object when being called
    if led.value()==0:
        led.on()
    else:
        led.off()
    print(adc.read())

tim.callback(tick)

time.sleep(10)
tim.deinit()

    
Example #22
0
sensor.skip_frames(time=2000)

sensor.skip_frames(10)  # Let new settings take affect.
sensor.set_auto_whitebal(False)

img = sensor.snapshot()
code = img.find_qrcodes()

find_code = False  # 初始化为没有数据读入


def is_code_finded():

    global find_code

    if img.find_qrcodes():
        find_code = True
    else:
        find_code = False


timer = Timer(4)
timer.init(freq=10)
timer.callback(is_code_finded())

while True:

    if find_code:
        print("finded")
    time.sleep(1000)
Example #23
0
class tv:
    def __init__(self,hres=64,progressive=False,lines=None,linetime=64,buf=None):
        if lines == None:
            lines = 262 if progressive else 525
        self.lines = lines
        if buf == None:
            if progressive:
                self.buf = bytearray(262*hres)
            else:
                self.buf = bytearray(525*hres)
        else:
            self.buf = buf
        self.hres = hres
        self.line_time = linetime
        self.progressive = progressive
        
        self.sync_level = 0
        self.blanking_level = 56
        self.black_level = 58
        self.white_level = 73

        self.phase = 0
        self.buffer_dac = True
        self.reinit()
    def redac(self):
        self.dac = DAC(Pin('X5'),buffering=self.buffer_dac)
        self.bmv = memoryview(self.buf)[:len(self)]
        self.dac_tim = Timer(6, freq=int(self.hres*1000000/self.line_time))
        self.dac.write_timed(self.bmv,self.dac_tim,mode=DAC.CIRCULAR)
        self.frame_tim = Timer(5, prescaler=self.dac_tim.prescaler(),period=self.dac_tim.period()*len(self))
        self.frame_tim.counter(self.phase)
    def reinit(self):
        self.calc_porch_magic_numbers()
        self.init()
    def set_progressive(self,prog=True):
        self.progressive = prog
        self.calc_porch_magic_numbers()
        self.init()
    
    def __len__(self):
        return self.hres*self.lines
    def calc_porch_magic_numbers(self):
        br = self.hres/self.line_time

        w = round(4.7*br)
        t = int(10.9*br+0.9)#round mostly up
        s = round(1.5*br)
        self.h_blank = [s,s+w,t]
        self.v_blank_e = [6,12,18]
        self.v_blank_o = [6,12,19]

        hsl = round(18*br)
        hsh = round(58*br)
        
        self.h_safe = [hsl-t,hsh-t]
        self.v_safe = [32*(2-self.progressive),208*(2-self.progressive)]
        
    def init(self):
        self.carrier = Pin('X1') 
        self.tim = Timer(2, prescaler=1,period=1)
        self.ch = self.tim.channel(1, Timer.PWM, pin=self.carrier)
        self.ch.pulse_width(1)

        self.redac()
        
        self.be = self.bmv
        if not self.progressive:
            self.bo = self.be[len(self)//2:]
        self.fb = framebuf.FrameBuffer(self.buf,self.hres,self.lines,framebuf.GS8)
        self.fbe_mv = self.be[self.hres*21+self.h_blank[2]:]
        if not self.progressive:
            self.fbo_mv = self.bo[self.hres*43//2+self.h_blank[2]:]
        h = self.y_dim()//(2-self.progressive)
        self.fbe = framebuf.FrameBuffer(self.fbe_mv,self.hres-self.h_blank[2],h,framebuf.GS8,self.hres)
        if not self.progressive:
            self.fbo = framebuf.FrameBuffer(self.fbo_mv,self.hres-self.h_blank[2],h,framebuf.GS8,self.hres)
        self.clear()

    def set_pixel(self,x,y,v):
        if self.progressive:
            self.fbe.pixel(x,y,int(v*(self.white_level-self.black_level)+self.black_level))
        else:
            [self.fbe,self.fbo][y&1].pixel(x,y//2,int(v*(self.white_level-self.black_level)+self.black_level))
    def get_pixel(self,x,y):
        if self.progressive:
            return (self.fbe_mv[x+y*self.hres]-self.black_level)/(self.white_level-self.black_level)
        else:
            return ([self.fbe_mv,self.fbo_mv][y&1][x+(y//2)*self.hres]-self.black_level)/(self.white_level-self.black_level)
    def set_carrier(self,pre=1,per=1,w=1):
        self.tim.init(prescaler=pre,period=per)
        self.ch.pulse_width(w)
    def clear(self):
        self.fb.fill(self.black_level)
        self.syncs()
    def syncs(self):
        self.fb.fill_rect(0,0,self.h_blank[2],self.lines,self.blanking_level)
        self.fb.fill_rect(self.h_blank[0],0,self.h_blank[1]-self.h_blank[0],self.lines,self.sync_level)
        for y in range(self.v_blank_e[2]):
            inv = self.v_blank_e[0] <= y < self.v_blank_e[1]
            for x in range(self.hres//2):
                val = self.blanking_level
                if (self.h_blank[0] <= x < self.h_blank[1]) ^ inv:
                    val = self.sync_level
                self.buf[y*self.hres//2+x] = val
        if not self.progressive:
            for y in range(self.v_blank_o[2]):
                inv = self.v_blank_o[0] <= y < self.v_blank_o[1]
                for x in range(self.hres//2):
                    val = self.blanking_level
                    if (self.h_blank[0] <= x < self.h_blank[1]) ^ inv:
                        val = self.sync_level
                    self.bo[y*self.hres//2+x] = val
    def x_dim(self):
        return self.hres-self.h_blank[2]
    def y_dim(self):
        return self.lines-(21 if self.progressive else 43)
    
    def mandelbrot(self,imax=8,p=0,s=2,julia=False,il=0,x0=None,y0=None,x1=None,y1=None,asm=True,julia_seed=0):
        
        x0 = self.h_safe[0] if x0 == None else x0
        x1 = self.h_safe[1] if x1 == None else x1
        y0 = self.v_safe[0] if y0 == None else y0
        y1 = self.v_safe[1] if y1 == None else y1
        
        for x in range(x0,x1):
            for y in range(y0,y1):
                c = (((x-x0)/(x1-x0-1)-.5)*2 + ((y-y0)/(y1-y0-1)-.5)*2j)*s+p
                z = c
                if julia:
                    c = julia_seed
                if asm:
                    i = a_mandelbrot(z,c,imax)
                else:
                    for i in range(imax):
                        if z.real*z.real+z.imag*z.imag > 4:
                            break
                        z = z*z+c
                    else:
                        self.set_pixel(x,y,il)
                        continue
                if i == -1:
                    self.set_pixel(x,y,il)
                else:
                    self.set_pixel(x,y,i/imax)
    def demo(self,x0=None,y0=None,x1=None,y1=None):

        x0 = self.h_safe[0] if x0 == None else x0
        x1 = self.h_safe[1] if x1 == None else x1
        w = x1-x0
        y0 = self.v_safe[0] if y0 == None else y0
        y1 = self.v_safe[1] if y1 == None else y1
        h = y1-y0
        
        mx = x0
        my = y0
        import pyb
        import time
        acc = pyb.Accel()
        btn = pyb.Switch()
        p = self.get_pixel(int(mx),int(my))
        pos = 0
        zoom = 2
        it = 16
        julia = False
        jp = 0
        self.mandelbrot(it,pos,zoom,julia,0,x0,y0,x1,y1,julia_seed=jp)

        def paddles(c):
            x = int(mx-.125*w)
            xw = w//4
            y = int(my-.125*h)
            yw = h//4
            y_0 = y0
            y_1 = y1
            if not self.progressive:
                y //= 2
                yw //= 2
                y_0 //= 2
                y_1 //= 2
            self.fbe.hline(x,y_0,xw,c)
            self.fbe.vline(x0,y,yw,c)
            self.fbe.hline(x,y_1,xw,c)
            self.fbe.vline(x1,y,yw,c)
            if not self.progressive:
                self.fbo.hline(x,y_0,xw,c)
                self.fbo.vline(x0,y,yw,c)
                self.fbo.hline(x,y_1,xw,c)
                self.fbo.vline(x1,y,yw,c)
        
        while 1:
            paddles(self.black_level)
            mx = min(x1-2,max(x0,mx*.98+(-acc.x()/24+.5)*w*.02))
            my = min(y1-2,max(y0,my*.98+(acc.y()/24+.5)*h*.02))
            paddles(self.white_level)
            p = self.get_pixel(int(mx),int(my))
            self.set_pixel(int(mx),int(my),(p+.5)%1)
            pyb.delay(10)
            self.set_pixel(int(mx),int(my),p)
            if btn():
                st = time.ticks_ms()
                nit = it*2
                while btn():
                    if time.ticks_diff(time.ticks_ms(),st) > 1000:
                        if acc.z()>0:
                            nit = it*2
                        else:
                            nit = "Julia"
                        self.fbe.fill_rect(x0,y0,w,10,self.black_level)
                        if not self.progressive:
                            self.fbo.fill_rect(x0,y0,w,10,self.black_level)
                        self.fbe.text(str(nit),x0+1,y0+1,self.white_level)
                        if not self.progressive:
                            self.fbo.text(str(nit),x0+1,y0+1,self.white_level)
                cp = (((mx-x0)/w-.5)*2+2j*((my-y0)/h-.5))*zoom
                if time.ticks_diff(time.ticks_ms(),st) > 1000:
                    if nit == "Julia":
                        julia ^= 1
                        jp = pos + cp
                        pos = 0
                        zoom = 2
                        it = 16
                    else:
                        it = nit
                else:
                    pos += cp
                    zoom *= .25
                self.mandelbrot(it,pos,zoom,julia,0,x0,y0,x1,y1,julia_seed=jp)
Example #24
0
import pyb
from pyb import Pin
from ds18x20 import DS18X20
from pyb import Timer
import micropython

micropython.alloc_emergency_exception_buf(100)
tempValue = 0
print('pin init')
Pin('Y11',Pin.OUT_PP).low() #GND
Pin('Y9',Pin.OUT_PP).high() #VCC

def displayTemp(t):
 print('Current Temperature:')
 print(tempValue)
 
tim1 = Timer(1)
tim1.callback(displayTemp)
tim1.init(freq=1/5)
 
if __name__=='__main__':
 DQ=DS18X20(Pin('Y10')) #DQ
 while True:
  tempValue = DQ.read_temp()
  
Example #25
0
    if tval == 0:
        return

    average = tval / NumSamples
    v = (Vcc * average)/4096

    if v >= Vcc:
        raise OSError("Thermistor not connected")
    if v <= 0:
        raise OSError("Short circuit")

    r = (v * R1) / (Vcc - v)
    t = (Beta / math.log(r / Rinf)) - CelsiusToKelvin

    return t


ttim = Timer(5)
ttim.init(freq=10)
ttim.callback(getValue)

if __name__ == 'builtins':
    try:
        print("-- start thermistor --")
        while True:
            print(getTemperature())
            time.sleep(1)
            pass
    except:
        print("-- Failed to start thermistor --")
timer = Timer(2)

logger = logging.getLogger(__name__)
logger.info("Latency test RS232")

logger.info("Initializing interface.")
interface = rs232_tmcl_interface(data_rate=DATA_RATE)

logger.info("Performing test.")
ticks = (WORST_CASE_LATENCY * PAYLOAD * pyb.freq()[2] * 2) / 1000
prescaler = int(ticks / 0x3fffffff)
period = int((WORST_CASE_LATENCY * PAYLOAD * pyb.freq()[2] * 2) /
             (1000 * (prescaler + 1)))
while (n < N_SAMPLES):
    timer.counter(0)
    timer.init(prescaler=prescaler, period=period, callback=timeout)
    for i in range(0, PAYLOAD):
        interface.send_request_only(TMCL_Request(MODULE_ID, 1, 2, 3, 4, 5),
                                    host_id=HOST_ID,
                                    module_id=MODULE_ID)
    try:
        for i in range(0, PAYLOAD):
            interface.receive_reply(module_id=MODULE_ID, host_id=HOST_ID)
    except:
        pass
    timer.deinit()
    if (not (tout)):
        counter = timer.counter()
        logger.debug("Measured delta ticks: {}".format(counter))
        # update values
        value = (2 * PAYLOAD) / counter
class TX:
    _active_high = True

    @classmethod
    def active_low(cls):
        if ESP32:
            raise ValueError('Cannot set active low on ESP32')
        cls._active_high = False

    def __init__(self, pin, fname, reps=5):
        self._pin = pin
        self._reps = reps
        with open(fname, 'r') as f:
            self._data = ujson.load(f)
        # Time to wait between nonblocking transmissions. A conservative value in ms.
        self._latency = (reps + 2) * max(
            (sum(x) for x in self._data.values())) // 1000
        gc.collect()
        if ESP32:
            self._rmt = RMT(0, pin=pin, clock_div=80)  # 1μs resolution
        elif RP2:  # PIO-based RMT-like device
            self._rmt = RP2_RMT(pin_pulse=pin)  # 1μs resolution
            # Array size: length of longest entry + 1 for STOP
            asize = max([len(x) for x in self._data.values()]) + 1
            self._arr = array('H',
                              (0 for _ in range(asize)))  # on/off times (μs)
        else:  # Pyboard
            self._tim = Timer(5)  # Timer 5 controls carrier on/off times
            self._tcb = self._cb  # Pre-allocate
            asize = reps * max([len(x) for x in self._data.values()
                                ]) + 1  # Array size
            self._arr = array('H',
                              (0 for _ in range(asize)))  # on/off times (μs)
            self._aptr = 0  # Index into array

    def _cb(self, t):  # T5 callback, generate a carrier mark or space
        t.deinit()
        p = self._aptr
        v = self._arr[p]
        if v == STOP:
            self._pin(self._active_high ^ 1)
            return
        self._pin(p & 1 ^ self._active_high)
        self._tim.init(prescaler=84, period=v, callback=self._tcb)
        self._aptr += 1

    def __getitem__(self, key):
        return self._data[key]

    def keys(self):
        return self._data.keys()

    def show(self, key):
        res = self[key]
        if res is not None:
            for x, t in enumerate(res):
                print('{:3d} {:6d}'.format(x, t))

    def latency(self):
        return self._latency

    # Nonblocking transmit
    def __call__(self, key):
        gc.collect()
        lst = self[key]
        if lst is not None:
            if ESP32:
                # TODO use RMT.loop() cancelled by a soft timer to do reps.
                # This would save RAM. RMT.loop() is now fixed. I remain
                # unconvinced because of the huge latency of soft timers on
                # boards with SPIRAM. It would save ram if a half-word array
                # could be passed. But it can't (as of 9th March 2021).
                self._rmt.write_pulses(lst * self._reps,
                                       start=1)  # Active high
            elif RP2:
                for x, t in enumerate(lst):
                    self._arr[x] = t
                self._arr[x + 1] = STOP
                self._rmt.send(self._arr, self._reps)
            else:
                x = 0
                for _ in range(self._reps):
                    for t in lst:
                        self._arr[x] = t
                        x += 1
                self._arr[x] = STOP
                self._aptr = 0  # Reset pointer
                self._cb(self._tim)  # Initiate physical transmission.

    # Blocking transmit: proved necessary on Pyboard Lite
    @micropython.native
    def send(self, key):
        gc.collect()
        pin = self._pin
        q = self._active_high ^ 1  # Pin inactive state
        lst = self[key]
        if lst is not None:
            for _ in range(self._reps):
                pin(q)
                for t in lst:
                    pin(pin() ^ 1)
                    sleep_us(t)
        pin(q)
Example #28
0
class TX:
    timeit = False  # Print timing info
    _active_high = True

    @classmethod
    def active_low(cls):
        if ESP32:
            raise ValueError('Cannot set active low on ESP32')
        cls._active_high = False

    def __init__(self, pin, fname, reps=5):
        self._pin = pin
        self._reps = reps
        try:
            with open(fname, 'r') as f:
                self._data = ujson.load(f)
        except OSError:
            print("Can't open file '{}' for reading.".format(fname))
            return
        gc.collect()
        if ESP32:
            self._rmt = RMT(0, pin=pin, clock_div=80)  # 1μs resolution
        else:  # Pyboard
            self._tim = Timer(5)  # Timer 5 controls carrier on/off times
            self._tcb = self._cb  # Pre-allocate
            asize = reps * max([len(x) for x in self._data.values()
                                ]) + 1  # Array size
            self._arr = array('H', 0
                              for _ in range(asize))  # on/off times (μs)
            self._aptr = 0  # Index into array

    def _cb(self, t):  # T5 callback, generate a carrier mark or space
        t.deinit()
        p = self._aptr
        v = self._arr[p]
        if v == STOP:
            self._pin(self._active_high ^ 1)
            return
        self._pin(p & 1 ^ self._active_high)
        self._tim.init(prescaler=84, period=v, callback=self._tcb)
        self._aptr += 1

    def __getitem__(self, key):
        if key in self._data:
            return self._data[key]
        print('Key "{}" does not exist'.format(key))

    def keys(self):
        return self._data.keys()

    def show(self, key):
        res = self[key]
        if res is not None:
            for x, t in enumerate(res):
                print('{:3d} {:6d}'.format(x, t))

    # Nonblocking transmit
    def __call__(self, key):
        gc.collect()
        lst = self[key]
        if lst is not None:
            lst = lst * self._reps
            if ESP32:
                self._rmt.write_pulses(lst, start=1)  # Active high
            else:
                for x, t in enumerate(lst):
                    self._arr[x] = t
                x += 1
                self._arr[x] = STOP
                self._aptr = 0  # Reset pointer
                self._cb(self._tim)  # Initiate physical transmission.

    # Blocking transmit: proved necessary on Pyboard Lite
    @micropython.native
    def send(self, key):
        gc.collect()
        pin = self._pin
        q = self._active_high ^ 1  # Pin inactive state
        lst = self[key]
        if lst is not None:
            for _ in range(self._reps):
                pin(q)
                for t in lst:
                    pin(pin() ^ 1)
                    sleep_us(t)
        pin(q)
Example #29
0
class Buzzer(object):
    '''
    Plays sounds through the buzzer module
    '''
    def __init__(self, pin, timerId, channelId):
        '''
        Constructor
        
        @param pin: Pin where the module is attached to
        @param timerId: Timer associated to the pin
        @param channelId: Channel of the timer
        '''

        self._pin = pin
        #20200407 DPM: The timer must be initialized with a frequency, otherwise it won't beep.
        self._timer = Timer(timerId, freq=440)
        self._channel = self._timer.channel(channelId,
                                            Timer.PWM,
                                            pin=self._pin,
                                            pulse_width=0)

        self._buzzing = False

    def startBuzz(self, freq):
        '''
        Starts beeping. Use the stopBuzz method to finish.
        @see Buzzer.stopBuzz
        
        @param freq: Frequency of the sound
        '''

        if self._buzzing:
            self._timer.freq(freq)
        else:
            self._timer.init(freq=freq)
            self._buzzing = True

        self._channel.pulse_width_percent(50.0)

    def stopBuzz(self):
        '''
        Stops beeping.
        @see Buzzer.startBuzz
        '''

        self._channel.pulse_width(0)
        self._buzzing = False

    def buzz(self, freq, millisecs):
        '''
        Beeps a sound during a time
        
        @param freq: Frequency of the sound
        @param millisecs: Time to play
        '''

        self.startBuzz(freq)
        sleep_ms(millisecs)
        self.stopBuzz()

    def trill(self, freq, millisecs, playTime=10, muteTime=10):
        '''
        Makes a vibrating sound
        
        @param freq: Frequency of the sound
        @param millisecs: Duration of the sound
        @param playTime: (default=10) Time the buzzer beeps, as milliseconds
        @param muteTime: (default=10) Time the buzzer is muted, as milliseconds
        '''

        startTime = ticks_ms()

        while millisecs > ticks_diff(ticks_ms(), startTime):
            self.startBuzz(freq)
            sleep_ms(playTime)
            self.stopBuzz()
            sleep_ms(muteTime)

    def slide(self, freq1, freq2, millisecs):
        '''
        Slides sound between frequencies
        
        @param freq1: Starting frequency
        @param freq2: End frequency
        @param millisecs: Duration of the effect
        '''

        step = (freq2 - freq1) / millisecs
        freq = freq1
        t = 0
        while t < millisecs:
            self.startBuzz(freq)
            sleep_ms(1)
            t += 1
            freq += step

        self._channel.pulse_width(0)

    def cleanup(self):
        '''
        Removes resources
        '''

        self._channel.pulse_width(0)
        self._buzzing = False
        self._timer.deinit()
    return cb4


# create a timer with a callback, using callback(None) to stop
tim = Timer(1, freq=100, callback=cb1)
pyb.delay(5)
print("before cb1")
pyb.delay(15)

# create a timer with a callback, using deinit to stop
tim = Timer(2, freq=100, callback=cb2)
pyb.delay(5)
print("before cb2")
pyb.delay(15)

# create a timer, then set the freq, then set the callback
tim = Timer(4)
tim.init(freq=100)
tim.callback(cb1)
pyb.delay(5)
print("before cb1")
pyb.delay(15)

# test callback with a closure
tim.init(freq=100)
tim.callback(cb3(3))
pyb.delay(5)
print("before cb4")
pyb.delay(15)
Example #31
0
class Button(object):
    '''
    This button can handle short and long press
    '''
    def __init__(self, pin, timerId=6, thresholdTime=1000, lowOnPress=False):
        '''
        Constructor
        
        @param pin: Pin object where the button is
        @param timerId: (default=6) Timer to determine the long press
        @param thresholdTime: Waiting time to determine a long press as milliseconds
        @param lowOnPress: Indicates whether the value is 0 when the button is pressed (pull-down)
                            The user (blue) button on the NUCLEO-L476RG board must have this parameter as True,
                            but for the case of the NUCLEO-F767ZI board, this parameter must be False
        '''

        self._pin = Pin(pin)
        self._pin.init(mode=Pin.IN)
        self._pin.irq(handler=self._onPinIrq)
        self._lowOnPress = lowOnPress

        self._thresholdTime = thresholdTime
        self._pressTime = 0

        self._timer = Timer(timerId)

        self._shortPressHandler = None
        self._longPressHandler = None

        self._isTimeout = False

    def _onPinIrq(self, _):

        self._pin.irq(handler=None)
        self._timer.callback(None)
        self._timer.deinit()
        #debounce signal
        sleep_ms(50)
        if self._pin.value() == (1 if self._lowOnPress else 0):

            if not self._isTimeout:
                schedule(self._shortPressHandler, self)
        else:

            self._isTimeout = False
            self._timer.init(freq=1000 / self._thresholdTime,
                             callback=self._onTimeout)

        self._pin.irq(handler=self._onPinIrq)

    def _onTimeout(self, t):

        t.deinit()

        self._isTimeout = True
        schedule(self._longPressHandler, self)

    def setShortPressHandler(self, handler):
        '''
        Sets the handler for short press
        '''

        self._shortPressHandler = handler

        return self

    def setLongPressHandler(self, handler):
        '''
        Sets the handler for long press
        '''

        self._longPressHandler = handler

        return self

    def cleanup(self):
        '''
        Releases resources
        Deinits the timer and removes handler for the pin's IRQ
        '''

        self._timer.deinit()
        self._pin.irq(handler=None)