def loop(self): canTake = False deltaTake = utime.ticks_add(self.timeTake, self.timeBetweenTake) if utime.ticks_diff(utime.ticks_ms(), deltaTake) > 0 or self.timeTake == 0: self.timeTake = utime.ticks_ms() canTake = True if canTake: self.readSensor() client.publish("MoisturizeMe/raw/" + self.id, str(self.value)) if self.value < self.minMoistRatio: self.askWater = True client.publish( "MoisturizeMe/askWater/" + self.id, '{"minMoistRatio": ' + str(self.minMoistRatio) + ', "value": ' + str(self.value) + "}", ) deltaTimer = utime.ticks_add(self.lastWatering, self.timeBetweenWatering) if utime.ticks_diff(utime.ticks_ms(), deltaTimer) > 0: self.canWater = True if self.askWater and self.canWater: time.sleep_ms(self.valveTimer) self.lastWatering = utime.ticks_ms() self.canWater = False client.publish( "MoisturizeMe/watering/" + self.id, '{"valveTimer": ' + str(self.valveTimer) + "}", ) if (self.lastTake - self.value > self.minDelta) or ( self.lastTake - self.value < -self.minDelta ): self.lastTake = self.value client.publish("MoisturizeMe/values/" + self.id, str(self.value))
def trigger(self, duration=0): # Update end time if duration <= 0: duration = self.duration if self.can_alloc and self.tstop is None: # No killer task is running self.tstop = time.ticks_add(time.ticks_ms(), duration) # Start a task which stops the delay after its period has elapsed self.loop.create_task(self.killer()) self.tstop = time.ticks_add(time.ticks_ms(), duration)
def edge_case(edge, offset): h = utimeq(10) add(h, ticks_add(0, offset)) add(h, ticks_add(edge, offset)) dprint(h) l = pop_all(h) diff = ticks_diff(l[1][0], l[0][0]) dprint(diff, diff > 0) return diff
def connect(self, ssid, password, timeout=10): if not self._interface.active(): self._interface.active(True) # check if already connected to the current network if self._interface.isconnected() and \ self._interface.config('essid').encode('ascii') == ssid: self.check_connection() return True # attempt to connect for given timeout timeout = utime.ticks_add(utime.ticks_ms(), timeout * 1000) self._interface.connect(ssid, password) while not self._is_fully_connected() and utime.ticks_ms() < timeout: utime.sleep(0.5) completed = self._is_fully_connected() if not completed: # stop retrying to connect self._interface.disconnect() # update connection self.check_connection() return completed
def forever(self): while True: now = utime.ticks_ms() tout = None for cb in self.time_dict: d = utime.ticks_diff(self.time_dict[cb][0], now) if d < 0: cb(self, self.time_dict[cb][2]) d = self.time_dict[cb][1] self.time_dict[cb][0] = utime.ticks_add(now, d) if tout == None or d < tout: tout = d try: ok = self.p.poll(tout) except: # KeyboardInterrupt: release socket bindings for e in self.sock_list: e[0].close() return for s, mask in ok: for cb in self.sock_list: if cb[0] != s: continue if mask & uselect.POLLIN: cb[1](self, s, cb[3]) if mask & uselect.POLLOUT: # print('removing POLLOUT') self.p.register(s, uselect.POLLIN) if cb[2]: cb[2](self, s, cb[3])
def time_user(side, max_reaction_time): # Time user's reactions t1 = utime.ticks_ms() # Start timer while True: utime.sleep_ms(1) if ( (side == "<") and (display.is_pressed(display.BUTTON_B)) and (display.is_pressed(display.BUTTON_Y) == False) ) \ or ( (side == ">") and (display.is_pressed(display.BUTTON_Y)) and (display.is_pressed(display.BUTTON_B) == False) ): t2 = utime.ticks_ms() # End timer break elif utime.ticks_diff( utime.ticks_ms(), t1) > max_reaction_time: # If 3 seconds has passed t2 = utime.ticks_add( t1, max_reaction_time ) # End timer, set to max time even if it's slightly passed 3 seconds break # Calculate reaction time and display results reaction_time = utime.ticks_diff(t2, t1) / 1000 time_text = "T: " + "{:0<5}".format( str(reaction_time)) # Display reaction time to 3 decimals (ms) clear_screen() display.set_pen(255, 255, 255) display.text(time_text, 50, 30, 240, 4) display.update() utime.sleep_ms(750) # Pause to read reaction time return reaction_time
def update_melody(state, melody_changed): global _last_play global _melody_file global _tempo global _timer now = utime.ticks_ms() if melody_changed: _melody_file = None if not _last_play and play: buzzer_off() _last_play = play if not _melody_file: file_name = "melody/melody" + str(melody_index) + ".txt" _melody_file = open(file_name, "r") if state != 2 or not play or not activated or not rising: buzzer_off() if utime.ticks_diff( _timer, now) <= 0 and state == 2 and activated and play and rising: element = _melody_file.readline() element = element.replace('\n', '') element = element.split(' ') if element == ['']: _melody_file.close() _melody_file = None else: if len(element) == 3: play_tone(element) duration = round(float(element[1]) * 1000 * 60) // _tempo _timer = utime.ticks_add(now, duration) elif len(element) == 1: _tempo = int(element[0]) _timer = now
def init(self, mode=ONE_SHOT, period=0, callback=None): irq_id = self.__irq_id self.__irq_id += 1 irq = (irq_id, callback, ticks_add(ticks_ms(), period), mode, period) self._insert_irq(irq) self._set_timer() return irq_id
def draw_laps(self, img=None): img = img or self.img if len(self.lap_timestamps) > 1 and utime.ticks_diff( utime.ticks_add( self.lap_timestamps[-1], self.lap_notification_timeout), utime.ticks_ms()) >= 0: lap_time = utime.ticks_diff(self.lap_timestamps[-1], self.lap_timestamps[-2]) hours, remainder = divmod(lap_time, 3600000) minutes, remainder = divmod(remainder, 60000) seconds, milliseconds = divmod(remainder, 1000) lap_delta = '{:03}'.format(milliseconds) if seconds: lap_delta = '{:02}.'.format(int(seconds)) + lap_delta if minutes: lap_delta = '{:02}:'.format(int(minutes)) + lap_delta if hours: lap_delta = '{:02}:'.format(int(hours)) + lap_delta else: lap_delta = lap_delta + 's' else: lap_delta = lap_delta + 'ms' lap_delta = 'Lap: ' + lap_delta img.draw_string(10, int(sensor.height() / 2), lap_delta, string_vflip=self.flip_text, string_hmirror=self.mirror_text, string_rotation=self.rotate_text) return lap_time
def publish(A, topic, msg, retain=False, qos=0, dup=False, socket_timeout=-1): E = topic B = qos A._sock_timeout(socket_timeout) assert B in (0, 1) C = bytearray(b'0\x00\x00\x00\x00') C[0] |= B << 1 | retain | int(dup) << 3 F = 2 + len(E) + len(msg) if B > 0: F += 2 G = A._varlen_encode(F, C, 1) A._write(C, G) A._send_str(E) if B > 0: D = next(A.newpid) A._write(D.to_bytes(2, 'big')) A._write(msg) if B > 0: A.rcv_pids[D] = ticks_add(ticks_ms(), A.message_timeout * 1000) return D
def step(self, ticks): if self.mode == 'strobo': if ticks_diff(self.next_tick, ticks) < 0: for gill in self.lefts + self.rights: if self._strobo_on: gill.intensity = 0 self.next_tick = (ticks_add(ticks, STROBE_LENGTH * 3)) else: gill.intensity = 1 self.next_tick = (ticks_add(ticks, STROBE_LENGTH)) self._strobo_on = not self._strobo_on if ticks_diff(self.last_tick, ticks) < 0: self.setmode(self._last_mode) # print(intensity) self.all_pixels()
def subscribe(self, topic, qos=0, socket_timeout=-1): """ Subscribes to a given topic. :param topic: Topic you wish to publish to. Takes the form "path/to/topic" :type topic: byte :param qos: Sets quality of service level. Accepts values 0 to 1. This gives the maximum QoS level at which the Server can send Application Messages to the Client. :type qos: int :param socket_timeout: -1 = default socket timeout, None - socket blocking, positive number - seconds to wait :type socket_timeout: int :return: None """ assert qos in (0, 1) self._sock_timeout(socket_timeout) assert self.cb is not None, "Subscribe callback is not set" pkt = bytearray(b"\x82\0\0\0\0\0\0") pid = next(self.newpid) sz = 2 + 2 + len(topic) + 1 plen = self._varlen_encode(sz, pkt, 1) pkt[plen:plen + 2] = pid.to_bytes(2, 'big') self._write(pkt, plen + 2) self._send_str(topic) self._write( qos.to_bytes(1, "little") ) # maximum QOS value that can be given by the server to the client self.rcv_pids[pid] = ticks_add(ticks_ms(), self.message_timeout * 1000) return pid
def trigger(self, duration=0): # Update absolute end time, 0-> ctor default self._tend = ticks_add(ticks_ms(), duration if duration > 0 else self._durn) self._retn = None # Default in case cancelled. self._busy = True self._trig.set()
def multi_fields(t): print('multi_fields') refresh(ssd, True) # Clear any prior image nfields = [] dy = wri.height + 6 y = 2 col = 15 width = wri.stringlen('99.99') for txt in ('X:', 'Y:', 'Z:'): Label(wri, y, 0, txt) # Use wri default colors nfields.append(Label(wri, y, col, width, bdcolor=None)) # Specify a border, color TBD y += dy end = utime.ticks_add(utime.ticks_ms(), t * 1000) while utime.ticks_diff(end, utime.ticks_ms()) > 0: for field in nfields: value = int.from_bytes(uos.urandom(3), 'little') / 167772 overrange = None if value < 70 else YELLOW if value < 90 else RED field.value('{:5.2f}'.format(value), fgcolor=overrange, bdcolor=overrange) refresh(ssd) utime.sleep(1) Label(wri, 0, 64, ' OK ', True, fgcolor=RED) refresh(ssd) utime.sleep(1)
def send_frame_TX(self, device_to, msg, ack=True): device_from = self.device_id device_to = bytes([device_to]) frame_type = b'\x00' if ack == True else b'\x01' frame_cnt = b'\x00\x01' payload = msg.get_buffer() crc = b'\x00' msg.reset() tx_frame = self.device_id + device_to + frame_type + frame_cnt + payload + crc l.debug("tx: {}, ack: {}".format(ubinascii.hexlify(tx_frame), ack)) if ack == True: self.frame_ACK = None for i in range(0, self.tx_retries): self.lora_sock.send(tx_frame) ticks_sign = utime.ticks_diff( 1, 2) # get the sign of ticks_diff, e.g. in init code. deadline = utime.ticks_add(utime.ticks_ms(), self.tx_timeout) if self._user_handler_tx is not None: self._user_handler_tx(i) while (utime.ticks_diff(deadline, utime.ticks_ms()) * ticks_sign) < 0: if self.frame_ACK == frame_cnt: l.debug("tx OK") return self.frame_ACK_stats l.debug("tx NOK {}/{}".format(i + 1, self.tx_retries)) else: self.lora_sock.send(tx_frame) return None
def trigger(self, duration): # Update end time loop = asyncio.get_event_loop() self.tstop = time.ticks_add(loop.time(), duration) if not self._running: # Start a task which stops the delay after its period has elapsed loop.create_task(self.killer()) self._running = True
def publish(self, topic, msg, retain=False, qos=0, dup=False): """ Publishes a message to a specified topic. :param topic: Topic you wish to publish to. Takes the form "path/to/topic" :type topic: byte :param msg: Message to publish to topic. :type msg: byte :param retain: Have the MQTT broker retain the message. :type retain: bool :param qos: Sets quality of service level. Accepts values 0 to 2. PLEASE NOTE qos=2 is not actually supported. :type qos: int :param dup: Duplicate delivery of a PUBLISH Control Packet :type dup: bool :return: None """ assert qos in (0, 1) pkt = bytearray(b"\x30\0\0\0\0") pkt[0] |= qos << 1 | retain | int(dup) << 3 sz = 2 + len(topic) + len(msg) if qos > 0: sz += 2 plen = self._varlen_encode(sz, pkt, 1) self._write(pkt, plen) self._send_str(topic) if qos > 0: pid = next(self.newpid) self._write(pid.to_bytes(2, 'big')) self._write(msg) if qos > 0: self.rcv_pids[pid] = ticks_add(ticks_ms(), self.message_timeout * 1000) return pid
def start(deviceName): try: Ube_step = (Ube_max - Ube_min) / NUM_U_BE_STEPS scpi("*SAV 10") scpi("MEM:STAT:FREEze ON") scpi("INST:COUP:TRAC CGND") scpi("INST ch1") scpi("OUTP 0") scpi("CURR " + str(Ib)) scpi("VOLT 0") scpi("OUTP:DPR 1") scpi("SENS:CURR:RANG 50mA") scpi("INST ch2") scpi("OUTP 0") scpi("VOLT " + str(Uce)) scpi("CURR " + str(Ic_max)) scpi("SENS:CURR:RANG DEFault") scpi('SENS:DLOG:TRAC:COMMent "NPN Transfer curve for ' + deviceName + '"') scpi("SENS:DLOG:TRAC:X:UNIT VOLT") scpi("SENS:DLOG:TRAC:X:RANG:MIN " + str(Ube_min + Ube_step)) scpi("SENS:DLOG:TRAC:X:RANG:MAX " + str(Ube_max)) scpi("SENS:DLOG:TRAC:X:STEP " + str(Ube_step)) scpi("SENS:DLOG:TRAC:X:SCALE LIN") scpi('SENS:DLOG:TRAC:X:LABel "Ube"') scpi("SENS:DLOG:TRAC:Y1:UNIT AMPER") scpi("SENS:DLOG:TRAC:Y1:RANG:MIN 0") scpi("SENS:DLOG:TRAC:Y1:RANG:MAX " + str(Ic_max * 1.1)) scpi('SENS:DLOG:TRAC:Y1:LABel "Ic"') scpi('INIT:DLOG:TRACE "/Recordings/' + deviceName + '-transfer.dlog"') scpi("INST ch1") scpi("OUTP 1") scpi("INST ch2") scpi("OUTP 1") scpi("DISP:WINDOW:DLOG") t = ticks_ms() for ube_step_counter in range(NUM_U_BE_STEPS): Ube = Ube_min + (ube_step_counter + 1) * Ube_step setU(1, Ube) t = ticks_add(t, TIME_STEP_MS) sleep_ms(ticks_diff(t, ticks_ms())) dlogTraceData(getI(2)) finally: scpi("ABOR:DLOG") scpi("*RCL 10") scpi("MEM:STAT:FREEze OFF")
def connect(self): """ Ensure we have a network connection. If not connection, try each set of credentials in turn up to ten times before trying the next connection. """ # Give the WiFi five seconds to actually do something now = ticks_ms() if now < ticks_add(self.last_attempt, 5000): return self.last_attempt = now if self.sta.isconnected( ): # If we have an active connection, our work is done. if not self.connected: print("Connected to connection {}".format(self.connection)) self.connected = True return # We're not connected - so try the next connection self.connected = False self.connection += 1 self.connection %= len(self.config) print("Trying WiFi connection #{}".format(self.connection)) self.sta.active(True) sleep_ms(20) self.sta.config(dhcp_hostname=self.config[self.connection]['Hostname']) self.sta.connect(self.config[self.connection]['SSID'], self.config[self.connection]['Password'])
def loop(): global client global message_interval global data global sample_freq dt = int(1 / sample_freq * 1e6) deadline = ticks_add(ticks_us(), dt) #calculate the deadline while True: try: if ticks_diff(deadline, ticks_us()) <= 0: data.append(adc.read()) deadline = ticks_add(ticks_us(), dt) except OSError as e: restart_and_reconnect()
def canRun( self ): thisTime_us = utime.ticks_us() timeDiff_us = utime.ticks_diff( self.nextTime_us, thisTime_us ) if ( timeDiff_us < 0 ): self.nextTime_us = utime.ticks_add( self.nextTime_us, self.period_us ) return True else: return False
def loop(): global index next_column_time = 0 while True: esp.apa102_write(clock, data, mv[index:index + 200]) sleep_us(ticks_diff(next_column_time, ticks_us())) next_column_time = ticks_add(ticks_us(), segment_duration) index += 50
def test_publish_qos_1_no_puback(self, topic): self.client.connect() pid = self.client.publish(topic, 'test QoS 1', qos=1) pid = next(self.client.newpid) self.client.rcv_pids[pid] = utime.ticks_add(utime.ticks_ms(), self.client.message_timeout * 1000) out_pid, status = self.get_status_out(10, pid=pid) assert status == 0 self.client.disconnect()
def motor2_fun(): # A motor object pinENA = pyb.Pin(pyb.Pin.board.PC1, pyb.Pin.OUT_PP) pinIN1A = pyb.Pin(pyb.Pin.board.PA0, pyb.Pin.OUT_PP) pinIN2A = pyb.Pin(pyb.Pin.board.PA1, pyb.Pin.OUT_PP) mot = motor.MotorDriver([pinIN1A, pinIN2A, pinENA], 5, [1, 2]) # An encoder object enc = encoder.Encoder([pyb.Pin.board.PC6, pyb.Pin.board.PC7], 8, [1, 2]) # A controller object cont = controller.Controller(K_p=0.10) setup = True state = 0 while (True): # Stopped if state == 0: if pos_ctrl2.get(): state = 1 elif step_rsp2.get(): state = 2 elif get_data2.get(): state = 3 else: mot.set_duty_cycle(0) # Position Control elif state == 1: if pos_ctrl2.get(): cont.set_setpoint(setpoint1.get()) mot.set_duty_cycle(cont.run(enc.read())) else: state = 0 # Step Response elif state == 2: if setup: cont.clear_data() cont.set_setpoint(setpoint1.get()) enc.zero() stop = utime.ticks_add(utime.ticks_ms(), 1000) setup = False elif utime.ticks_diff(stop, utime.ticks_ms()) > 0: mot.set_duty_cycle(cont.run(enc.read())) else: step_rsp2.put(False) setup = True state = 0 # Get Data elif state == 3: for datum in cont.get_data(): print(str(datum[0]) + ', ' + str(datum[1])) state = 0 yield (state)
def main_loop(): import gc global app_pointer get_key_event = hal_keypad.get_key_event parse_key_event = hal_keypad.parse_key_event KEY_LEFT = hal_keypad.KEY_LEFT KEY_RIGHT = hal_keypad.KEY_RIGHT KEY_A = hal_keypad.KEY_A KEY_B = hal_keypad.KEY_B t_update_battery_ms = ticks_ms() cpu.set_cpu_speed(cpu.VERY_SLOW) while True: should_refresh_screen = False for event in get_key_event(): event_type, key = parse_key_event(event) if event_type == hal_keypad.EVENT_KEY_PRESS: if key == KEY_LEFT: app_pointer -= 1 if key == KEY_RIGHT: app_pointer += 1 # ensure pointer if key == KEY_LEFT or key == KEY_RIGHT: SIZE = len(app_list) if 0 > app_pointer or SIZE <= app_pointer: app_pointer = (app_pointer + SIZE) % SIZE with cpu.cpu_speed_context(cpu.FAST): render_point_app() render_battery_level() should_refresh_screen = True if key == KEY_A: with cpu.cpu_speed_context(cpu.FAST): run_app() if key == KEY_B: # entering setup mode with cpu.cpu_speed_context(cpu.FAST): render_loading() hal_sdcard.init() hal_sdcard.mount() gc.collect() app.call_component("ftp_mode") gc.collect() load_app_list() render_point_app() render_battery_level() t_update_battery_ms = ticks_ms() should_refresh_screen = True import gc gc.collect() # app.reset_and_run_app("") # reset if ticks_diff(ticks_ms(), t_update_battery_ms) >= 500: t_update_battery_ms = ticks_add(t_update_battery_ms, 500) with cpu.cpu_speed_context(cpu.FAST): render_battery_level() should_refresh_screen = True else: battery.measure() if should_refresh_screen: hal_screen.refresh()
def mainloop(): global timer100ms, timer20ms, timer1s, timer2s, timer30s, init_ok, prevminute ret = None amin = "" days = ['Mon', 'Tue', "Wed", "Thu", "Fri", "Sat", "Sun"] while init_ok: try: utime.sleep_ms(5) if (timeoutReached(timer20ms)): run50timespersecond() timer20ms = utime.ticks_add(utime.ticks_ms(), 20) if (timeoutReached(timer100ms)): run10timespersecond() timer100ms = utime.ticks_add(utime.ticks_ms(), 100) if (timeoutReached(timer1s)): runoncepersecond() timer1s = utime.ticks_add(utime.ticks_ms(), 1000) if (timeoutReached(timer30s)): runon30seconds() timer30s = utime.ticks_add(utime.ticks_ms(), 30000) ret = utime.localtime() amin = str('{:02}'.format(ret[4])) if (str(prevminute) != amin): try: commands.rulesProcessing( str('Clock#Time={},{:02}:{:02}'.format( days[int(ret[6])], ret[3], ret[4])), pglobals.RULE_CLOCK) prevminute = amin except Exception as e: print(e) gc.collect() if (timeoutReached(timer2s)): runon2seconds() timer2s = utime.ticks_add(utime.ticks_ms(), 2000) except SystemExit: init_ok = False except KeyboardInterrupt: init_ok = False except EOFError: init_ok = False except: pass
def wlan_wait_connected(timeout=10): if wlan.isconnected(): return True timeout_future = utime.ticks_add(utime.ticks_ms(), timeout * 1000) while utime.ticks_diff(timeout_future, utime.ticks_ms()) > 0: if wlan.isconnected(): return True return False
def do_connect(): AP_Name = "ESP32-AP" AP_Pass = "******" secWifi = { 'chata-dolce1': '', 'LonkKnotHomeAut': 'cMTWeMosD1', 'Spackovi': '123456789' } authmode = { 0: 'Open', 1: 'WEP', 2: 'WPA-PSK', 3: 'WPA2-PSK', 4: 'WPA/WPA2-PSK' } hidden = {0: 'false', 1: 'true'} wlan = network.WLAN(network.STA_IF) wlan.active(True) wlan.disconnect() nets = wlan.scan() for net in nets: print('Network: SSID:', net[0], ', MAC:', ubinascii.hexlify(net[1]), ', Channel:', net[2], ', RSSI:', net[3], ', Auth Mode:', authmode[net[4]], ', Hidden:', hidden[net[5]]) if net[0].decode() in secWifi: print('Network found!') wlan.connect(net[0].decode(), secWifi[net[0].decode()]) deadline = utime.ticks_add(utime.ticks_ms(), 10000) while (utime.ticks_diff(deadline, utime.ticks_ms()) > 0) and not wlan.isconnected(): machine.idle() if wlan.isconnected(): print('Network config:', wlan.ifconfig()) break else: print('WLAN connection failed!') else: print('Network not in list') if not wlan.isconnected(): print('Starting AP') ap = network.WLAN(network.AP_IF) ap.active(True) if (len(AP_Pass) > 0): ap.config(essid=AP_Name, authmode=network.AUTH_WPA_WPA2_PSK, password=AP_Pass) else: ap.config(essid=AP_Name) print('AP Started')
def get(name): #debug("Get: ",name) write_message('get %s' % name) # Give Nextion time to reply timeout = ut.ticks_add(ut.ticks_ms(), 50) while (ut.ticks_diff(timeout, ut.ticks_ms())) > 0: if serial.any(): return process_return() return False
def touch(self) -> None: """Wake up the idle timer. Events that represent some form of activity (USB messages, touches, etc.) should call `touch()` to notify the timer of the activity. All pending callback timers will reset. """ for callback, task in self.tasks.items(): timeout_us = self.timeouts[callback] deadline = utime.ticks_add(utime.ticks_ms(), timeout_us) loop.schedule(task, None, deadline, reschedule=True)
def poll_ms(self, timeout=-1): s = bytearray(self.evbuf) if timeout >= 0: deadline = utime.ticks_add(utime.ticks_ms(), timeout) while True: n = epoll_wait(self.epfd, s, 1, timeout) if not os.check_error(n): break if timeout >= 0: timeout = utime.ticks_diff(deadline, utime.ticks_ms()) if timeout < 0: n = 0 break res = [] if n > 0: vals = struct.unpack(epoll_event, s) res.append((vals[1], vals[0])) return res
def call_later_ms(self, delay, callback, *args): if not delay: return self.call_soon(callback, *args) self.call_at_(time.ticks_add(self.time(), delay), callback, args)
def call_later(self, delay, callback, *args): self.call_at_(time.ticks_add(self.time(), int(delay * 1000)), callback, args)
def call_later_ms(self, delay, callback, *args): self.call_at_(time.ticks_add(self.time(), delay), callback, args)
# Test for utimeq module which implements task queue with support for # wraparound time (utime.ticks_ms() style). try: from utime import ticks_add, ticks_diff from utimeq import utimeq except ImportError: print("SKIP") import sys sys.exit() DEBUG = 0 MAX = ticks_add(0, -1) MODULO_HALF = MAX // 2 + 1 if DEBUG: def dprint(*v): print(*v) else: def dprint(*v): pass # Try not to crash on invalid data h = utimeq(10) try: h.push(1) assert False except TypeError: pass try: