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)
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()
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()
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()
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)
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
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()
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)
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
# 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)
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
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)
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
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
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())
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() # 发送同步信号
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()
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)
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)
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()
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)
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)
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)
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)