def makegauge(self): ''' Generator refreshing the raw measurments. ''' delays = (5, 8, 14, 25) while True: self.i2c.writeto_mem(self.addr, 0xF4, b'\x2E') t_start = utime.ticks_ms() while utime.ticks_diff(t_start, utime.ticks_ms()) <= 5: yield None try: self.UT_raw = self.i2c.readfrom_mem(self.addr, 0xF6, 2) except: yield None self.i2c.writeto_mem(self.addr, 0xF4, str.encode(hex(0x34+(self.oversample_setting << 6)))) t_pressure_ready = delays[self.oversample_setting] t_start = utime.ticks_ms() while utime.ticks_diff(t_start, utime.ticks_ms()) <= t_pressure_ready: yield None try: self.MSB_raw = self.i2c.readfrom_mem(self.addr, 0xF6, 1) self.LSB_raw = self.i2c.readfrom_mem(self.addr, 0xF7, 1) self.XLSB_raw = self.i2c.readfrom_mem(self.addr, 0xF8, 1) except: yield None yield True
def Proc0(loops=LOOPS): global IntGlob global BoolGlob global Char1Glob global Char2Glob global Array1Glob global Array2Glob global PtrGlb global PtrGlbNext starttime = ticks_ms() for i in range(loops): pass nulltime = ticks_diff(ticks_ms(), starttime) PtrGlbNext = Record() PtrGlb = Record() PtrGlb.PtrComp = PtrGlbNext PtrGlb.Discr = Ident1 PtrGlb.EnumComp = Ident3 PtrGlb.IntComp = 40 PtrGlb.StringComp = "DHRYSTONE PROGRAM, SOME STRING" String1Loc = "DHRYSTONE PROGRAM, 1'ST STRING" Array2Glob[8 // 2][7 // 2] = 10 starttime = ticks_ms() for i in range(loops): Proc5() Proc4() IntLoc1 = 2 IntLoc2 = 3 String2Loc = "DHRYSTONE PROGRAM, 2'ND STRING" EnumLoc = Ident2 BoolGlob = not Func2(String1Loc, String2Loc) while IntLoc1 < IntLoc2: IntLoc3 = 5 * IntLoc1 - IntLoc2 IntLoc3 = Proc7(IntLoc1, IntLoc2) IntLoc1 = IntLoc1 + 1 Proc8(Array1Glob, Array2Glob, IntLoc1, IntLoc3) PtrGlb = Proc1(PtrGlb) CharIndex = 'A' while CharIndex <= Char2Glob: if EnumLoc == Func1(CharIndex, 'C'): EnumLoc = Proc6(Ident1) CharIndex = chr(ord(CharIndex)+1) IntLoc3 = IntLoc2 * IntLoc1 IntLoc2 = IntLoc3 // IntLoc1 IntLoc2 = 7 * (IntLoc3 - IntLoc2) - IntLoc1 IntLoc1 = Proc2(IntLoc1) benchtime = ticks_diff(ticks_ms(), starttime) - nulltime if benchtime == 0: loopsPerBenchtime = 0 else: loopsPerBenchtime = (loops * 1000 // benchtime) return benchtime, loopsPerBenchtime
def run(self): while True: iteration_start = utime.ticks_ms() self.perform_tasks() time_spent_on_tasks = utime.ticks_diff(utime.ticks_ms(), iteration_start) if time_spent_on_tasks < self.sleep_ms: utime.sleep_ms(utime.ticks_diff(self.sleep_ms, time_spent_on_tasks)) else: logger.warning('Skipping sleep - spent {}ms on tasks'.format(time_spent_on_tasks))
def master(): csn = Pin(cfg['csn'], mode=Pin.OUT, value=1) ce = Pin(cfg['ce'], mode=Pin.OUT, value=0) if cfg['spi'] == -1: spi = SPI(-1, sck=Pin(cfg['sck']), mosi=Pin(cfg['mosi']), miso=Pin(cfg['miso'])) nrf = NRF24L01(spi, csn, ce, payload_size=8) else: nrf = NRF24L01(SPI(cfg['spi']), csn, ce, payload_size=8) nrf.open_tx_pipe(pipes[0]) nrf.open_rx_pipe(1, pipes[1]) nrf.start_listening() num_needed = 16 num_successes = 0 num_failures = 0 led_state = 0 print('NRF24L01 master mode, sending %d packets...' % num_needed) while num_successes < num_needed and num_failures < num_needed: # stop listening and send packet nrf.stop_listening() millis = utime.ticks_ms() led_state = max(1, (led_state << 1) & 0x0f) print('sending:', millis, led_state) try: nrf.send(struct.pack('ii', millis, led_state)) except OSError: pass # start listening again nrf.start_listening() # wait for response, with 250ms timeout start_time = utime.ticks_ms() timeout = False while not nrf.any() and not timeout: if utime.ticks_diff(utime.ticks_ms(), start_time) > 250: timeout = True if timeout: print('failed, response timed out') num_failures += 1 else: # recv packet got_millis, = struct.unpack('i', nrf.recv()) # print response and round-trip delay print('got response:', got_millis, '(delay', utime.ticks_diff(utime.ticks_ms(), got_millis), 'ms)') num_successes += 1 # delay then loop utime.sleep_ms(250) print('master finished sending; successes=%d, failures=%d' % (num_successes, num_failures))
def test(spi=3, cs='PB0'): print("SPI flash") cs = Pin(cs, Pin.OUT) spi = SPI(spi, baudrate=42000000, polarity=0, phase=0) flash = SPIFlash(spi, cs) print("Getting chip ID...") flash.wait() id_ = flash.getid() print("ID:", ubinascii.hexlify(id_)) print("Reading block (32b) from address 0...") buf = bytearray(32) flash.read_block(0, buf) print(ubinascii.hexlify(buf)) addr = 12 * 600 + 8 print("Reading block (32b) from address {}...".format(addr)) flash.read_block(addr, buf) print(ubinascii.hexlify(buf)) addr = 524288 print("Erasing 4k block at address {}...".format(addr)) t1 = ticks_us() flash.erase(addr, '4k') # flash.erase(addr, '32k') # flash.erase(addr, '64k') # flash.erase_chip() t = ticks_diff(ticks_us(), t1) print("erase {} us".format(t)) print("Writing blocks (256b) at address {}...".format(addr)) buf = bytearray(range(256)) t1 = ticks_us() flash.write_block(addr, buf) t = ticks_diff(ticks_us(), t1) mbs = len(buf) * 8. / t print("write({}) {} us, {} mbs".format(len(buf), t, mbs)) print("Verifying write...") v = bytearray(256) flash.read_block(addr, v) if (v == buf): print("write/read ok") else: print("write/read FAILed") print("Timing 32k read from address 0...") gc.collect() buf = bytearray(32 * 1024) t1 = ticks_us() flash.read_block(0, buf) t = ticks_diff(ticks_us(), t1) mbs = len(buf) * 8. / t print("read({}) {} us, {} mbs".format(len(buf), t, mbs))
def initiator_thread(chan): yield so = ['test', 0, 0] for x in range(4): # Test full duplex by sending 4 in succession so[1] = x chan.send(so) yield while True: while not chan.any(): # wait for response yield while chan.any(): # Deal with queue si = chan.get() print('initiator received', si) yield if si[1] == 3: # received last one break while True: yield 2 tim = utime.ticks_ms() chan.send(so) while not chan.any(): # wait for response yield so = chan.get() duration = utime.ticks_diff(tim, utime.ticks_ms()) print('initiator received', so, 'timing', duration)
async def loop(self) : if self._verbose : logging.info("TaskBase: loop starting.") while self.isRunning() : if not self.disabled : try : self.num_calls += 1 start_ticks_us = utime.ticks_us() result = self.perform() self.ticks_us += utime.ticks_diff(utime.ticks_us(), start_ticks_us) if not result: return self.last_retry_ms = None except Exception as e : if not self.last_retry_ms : self.last_retry_ms = 500 else : self.last_retry_ms = min(self.sleep_ms, self.last_retry_ms * 2) self.num_failures += 1 logging.info("An error occurred performing {}: {}".format(self, e)) sys.print_exception(e) await uasyncio.sleep_ms(self.sleep_ms if not self.last_retry_ms else self.last_retry_ms) else : await uasyncio.sleep_ms(914) self.state = TaskBase.STOPPED if self._verbose : logging.info("TaskBase: loop terminated.") return
def perform_tasks(self): for t in self.interval_tasks: now = utime.ticks_ms() if not t['last_called'] or \ utime.ticks_diff(now, t['last_called']) >= t['interval']: t['last_called'] = now t['callback']()
def scroll(self, data, speed=120): DISPLAY_WIDTH = 16 # Display width in pixels. DISPLAY_HEIGHT = 8 # Display height in pixels. # Initialize LED matrix. matrix = Display(i2c) matrix.clear() # Initialize font renderer using a helper function to flip the Y axis # when rendering so the origin is in the upper left. def matrix_pixel(x, y): matrix._pixel(x, y, 1) with BitmapFont(DISPLAY_WIDTH, DISPLAY_HEIGHT, matrix_pixel) as bf: # Global state: pos = DISPLAY_WIDTH # X position of the message start. message_width = bf.width(data) # Message width in pixels. last = utime.ticks_ms() # Last frame millisecond tick time. speed_ms = 1200 / speed / 1000.0 # Scroll speed in pixels/ms. # Main loop: while True: # Compute the time delta in milliseconds since the last frame. current = utime.ticks_ms() delta_ms = utime.ticks_diff(current, last) last = current # Compute position using speed and time delta. pos -= speed_ms*delta_ms if pos < -message_width: pos = DISPLAY_WIDTH return # Clear the matrix and draw the text at the current position. matrix.fill(0) bf.text(data, int(pos), 0) # Update the matrix LEDs. matrix._show()
def send(self, buf, timeout=500): self.send_start(buf) start = utime.ticks_ms() result = None while result is None and utime.ticks_diff(utime.ticks_ms(), start) < timeout: result = self.send_done() # 1 == success, 2 == fail if result == 2: raise OSError("send failed")
def tdiff(): new_semantics = utime.ticks_diff(2, 1) == 1 def func(old, new): nonlocal new_semantics if new_semantics: return utime.ticks_diff(new, old) return utime.ticks_diff(old, new) return func
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 __init__(self, timediff): if timediff is None: self.expect_ts = False if is_micropython: self.timediff = lambda start, end : time.ticks_diff(start, end)/1000000 else: raise ValueError('You must define a timediff function') else: self.expect_ts = True self.timediff = timediff self.start_time = None
def main(): threshold = 1000 * 60 * 6 #threshold = 1000 * 30 start = utime.ticks_ms() while True: now = utime.ticks_ms() seconds = now // 1000 if seconds % 2 == 0: display.show(Image.CLOCK3) else: display.show(Image.CLOCK9) beep1 = utime.ticks_ms() beep2 = beep1 + 200 while utime.ticks_diff(now, start) > threshold: buzz_start = now display.show(Image.HEART) # beep if utime.ticks_diff(utime.ticks_ms(), beep1) > 0: music.pitch(1760, 100, wait=False) beep1 = beep1 + 2000 # beep if utime.ticks_diff(utime.ticks_ms(), beep2) > 0: music.pitch(1760, 100, wait=False) beep2 = beep2 + 2000 # button if button_a.is_pressed(): action = utime.ticks_ms() spend = utime.ticks_diff(action, buzz_start) display.scroll(str(spend)) if spend < 3000: threshold = 1000 * 60 * 6 else: threshold = 1000 * 60 * 3 #if spend < 3000: threshold = 1000 * 30 #else: threshold = 1000 * 10 start = utime.ticks_ms() break sleep(1000)
def _gauge(self): now=utime.ticks_ms() if utime.ticks_diff(now,self._last_read_ts)>self._new_read_ms: self._last_read_ts=now r=self._t_os+(self._p_os<<3)+(1<<6) self._write(BMP280_REGISTER_CONTROL,r) utime.sleep_ms(100) d=self._read(BMP280_REGISTER_DATA,6) self._p_raw=(d[0]<<12)+(d[1]<<4)+(d[2]>>4) self._t_raw=(d[3]<<12)+(d[4]<<4)+(d[5]>>4) self._t_fine=0 self._t=0 self._p=0
def _gauge(self): # TODO limit new reads now = utime.ticks_ms() if utime.ticks_diff(now, self._last_read_ts) > self._new_read_ms: self._last_read_ts = now r = self._t_os + (self._p_os << 3) + (1 << 6) self._write(BMP280_REGISTER_CONTROL, r) utime.sleep_ms(100) # TODO calc sleep d = self._read(BMP280_REGISTER_DATA, 6) # read all data at once (as by spec) self._p_raw = (d[0] << 12) + (d[1] << 4) + (d[2] >> 4) self._t_raw = (d[3] << 12) + (d[4] << 4) + (d[5] >> 4) self._t_fine = 0 self._t = 0 self._p = 0
def time_since_fix(self): """Returns number of millisecond since the last sentence with a valid fix was parsed. Returns 0 if no fix has been found""" # Test if a Fix has been found if self.fix_time == 0: return -1 # Try calculating fix time using utime; if not running MicroPython # time.time() returns a floating point value in secs try: current = utime.ticks_diff(utime.ticks_ms(), self.fix_time) except NameError: current = (time.time() - self.fix_time) * 1000 # ms return current
def compute_output(self, desired_state, current_state, current_time = None, previous_time = None): if current_time is None: # print('Current Time is None') self.current_time = utime.ticks_us() else: self.current_time = current_time if previous_time is not None: self.previous_time = previous_time # print('Current State: {}\t Desired State: {}'.format(current_state, desired_state)) # print('Current Time: {}\t Previous Time: {}'.format(self.current_time, self.previous_time)) if utime.ticks_diff(self.current_time, self.previous_time) >= self.dt: self.error = desired_state - current_state # # Correct for heading 'wrap around' to find shortest turn # if self.error > 180: # self.error -= 360 # elif self.error < -180: # self.error += 360 self.integral_term += self.ki * self.error self.state_change = current_state - self.last_state self.last_state = current_state # print('Error: {:}\t Error_dot: {:.4f}'.format(self.error, self.state_change)) self.output = self.kp * self.error + self.integral_term - self.kd * self.state_change # limit the output to within the range of possible values if self.output > self.max_output: self.output = self.max_output # print('Limiting PID ouput to maximum') elif self.output < self.min_output: # print('Limiting PID output to minimum') self.output = self.min_output self.previous_time = self.current_time # print('PID output: {:}\n'.format(self.output)) # print('{},{}\n'.format(current_state, self.output)) return self.output
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 perform(self) : current_tick = utime.ticks_ms() if not self.initial_tick : self.initial_tick = current_tick else : x = utime.ticks_diff(current_tick, self.initial_tick) if x == 0 : pass elif 0 < x : rgb = self.get_color(x) if rgb != self.prev_rgb : if self.verbose : logging.info("Lamp: setting color to {} from x={}", rgb, x) self.fill_pixels(rgb) self.prev_rgb = rgb else : # wrap around; start over logging.info("Lamp: tick wrap") self.initial_tick = current_tick return True
def scroll(self,data,speed=120): DISPLAY_WIDTH=16 DISPLAY_HEIGHT=8 matrix=Display(i2c) matrix.clear() def matrix_pixel(x,y): matrix._pixel(x,y,1) with BitmapFont(DISPLAY_WIDTH,DISPLAY_HEIGHT,matrix_pixel)as bf: pos=DISPLAY_WIDTH message_width=bf.width(data) last=utime.ticks_ms() speed_ms=1200/speed/1000.0 while True: current=utime.ticks_ms() delta_ms=utime.ticks_diff(current,last) last=current pos-=speed_ms*delta_ms if pos<-message_width: pos=DISPLAY_WIDTH return matrix.fill(0) bf.text(data,int(pos),0) matrix._show()
def test(): """Bouncing sprite.""" try: # Baud rate of 14500000 seems about the max spi = SPI(1, baudrate=10000000, sck=Pin(14), mosi=Pin(13)) display = Display(spi, dc=Pin(4), cs=Pin(5), rst=Pin(2)) display.clear() # Load sprite saucer = BouncingSprite('images/saucer_48x26.mono', 48, 26, 128, 64, 1, display) while True: timer = ticks_us() saucer.update_pos() saucer.draw() # Attempt to set framerate to 30 FPS timer_dif = 33333 - ticks_diff(ticks_us(), timer) if timer_dif > 0: sleep_us(timer_dif) except KeyboardInterrupt: display.cleanup()
def __call__(self, key): print('Awaiting radio data') nedges = self._nedges x = 0 p = self._pin # ** Time critical ** while x < nedges: v = p() while v == p(): pass self._times[x] = ticks_us() x += 1 # ** End of time critical ** diffs = [] for x in range(nedges - 2): diffs.append(ticks_diff(self._times[x + 1], self._times[x])) # Perform error checking and averaging. res = self.process(diffs) if res is None: print('Capture failed: please try again.') else: self._data[key] = res print('Key "{}" stored.'.format(key))
async def _run(self): while True: # If hardware link exists reboot Responder await self.reboot() self.txbyt = b'' self.rxbyt = b'' await self._sync() await asyncio.sleep(1) # Ensure Responder is ready while True: gc.collect() try: tstart = utime.ticks_us() self._sendrx() t = utime.ticks_diff(utime.ticks_us(), tstart) except OSError: break await asyncio.sleep_ms(Initiator.t_poll) self.block_max = max(self.block_max, t) # self measurement self.block_cnt += 1 self.block_sum += t self.nboots += 1 if self.reset is None: # No means of recovery raise OSError('Responder fail.')
def run(): """ Loop forever, stepping through scheduled tasks and awaiting I/O events inbetween. Use `schedule` first to add a coroutine to the task queue. Tasks yield back to the scheduler on any I/O, usually by calling `await` on a `Syscall`. """ if __debug__: global log_delay_pos max_delay = const(1000000) # usec delay if queue is empty task_entry = [0, 0, 0] # deadline, task, value msg_entry = [0, 0] # iface | flags, value while _queue or _paused: # compute the maximum amount of time we can wait for a message if _queue: delay = utime.ticks_diff(_queue.peektime(), utime.ticks_us()) else: delay = max_delay if __debug__: # add current delay to ring buffer for performance stats log_delay_rb[log_delay_pos] = delay log_delay_pos = (log_delay_pos + 1) % log_delay_rb_len if io.poll(_paused, msg_entry, delay): # message received, run tasks paused on the interface msg_tasks = _paused.pop(msg_entry[0], ()) for task in msg_tasks: _step(task, msg_entry[1]) else: # timeout occurred, run the first scheduled task if _queue: _queue.pop(task_entry) _step(task_entry[1], task_entry[2])
def go(): avg_samples = 250 freq(160000000) # Trigger pin t = Pin(13, Pin.OUT) # Input pin i = Pin(12, Pin.IN) i.irq(trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=callback) DENSITY_TOPIC = "6hull/homebrew/ultrasonic" REPORT_TIME_MS = 0 REPORT_INTERVAL_MS = 200 c = None while True: if c == None: try: c = mqtt_connect() print("Successfully connected to broker") except Exception as e: print("Couldn't connect to broker. Try again later: {}".format( e)) c = None if ticks_diff(ticks_ms(), REPORT_TIME_MS) > REPORT_INTERVAL_MS: reading = 0 try: reading = get_avg_reading(t, i, avg_samples) print("Reading: {}".format(reading)) except ValueError as e: print("Failed to get reading: {}".format(e)) if c != None and reading != 0: try: c.publish(DENSITY_TOPIC, b'{}'.format(reading)) except Exception as e: print("Failed to publish to broker. Try again later: {}". format(e)) c = None REPORT_TIME_MS = ticks_ms() sleep_us(10000)
def run_forever(): ''' Loop forever, stepping through scheduled tasks and awaiting I/O events inbetween. Use `schedule_task` first to add a coroutine to the task queue. Tasks yield back to the scheduler on any I/O, usually by calling `await` on a `Syscall`. ''' if __debug__: global log_delay_pos task_entry = [0, 0, 0] # deadline, task, value while True: # compute the maximum amount of time we can wait for a message if _scheduled_tasks: delay = utime.ticks_diff(_scheduled_tasks.min_time(), utime.ticks_us()) else: delay = _MAX_SELECT_DELAY if __debug__: # add current delay to ring buffer for performance stats log_delay_rb[log_delay_pos] = delay log_delay_pos = (log_delay_pos + 1) % log_delay_rb_len msg_entry = msg.select(delay) if msg_entry: # message received, run tasks paused on the interface msg_iface, *msg_value = msg_entry msg_tasks = _paused_tasks.pop(msg_iface, ()) for task in msg_tasks: _step_task(task, msg_value) else: # timeout occurred, run the first scheduled task if _scheduled_tasks: _scheduled_tasks.pop(task_entry) _step_task(task_entry[1], task_entry[2])
def http_benchmark(url: str, num_samples: int) -> None: if num_samples < 1: print("Error, must collect at least one data sample!") return import urequests import utime data = [] for _ in range(num_samples): print("Sending request to %s..." % url) before = utime.ticks_ms() r = urequests.get(url) after = utime.ticks_ms() delta = utime.ticks_diff(after, before) data.append(delta) print("status_code=%s, content=%s, time=%s ms" % (r.status_code, r.content, delta)) # Calculate stats: data.sort() outliers = [] if len(data) > 2: outliers = [data[0], data[-1]] data = data[1:len(data) - 1] # Throw out 2 outliers. middle = len(data) // 2 odd_num = len(data) % 2 == 0 median = sum(data[middle - 1:middle + 1]) / 2.0 if odd_num else data[middle] mean = sum(data) / len(data) print("Outliers: %s" % outliers) print("Results (after eliminating outliers):") print(" Data: %s" % data) print(" Length: %s" % len(data)) print(" Median: %s" % median) print(" Mean: %s" % mean) print(" Min: %s" % min(data)) print(" Max: %s" % max(data))
def decode(self, _): try: nedges = self.edge # No. of edges detected if not 14 <= nedges <= 28: raise RuntimeError(self.OVERRUN if nedges > 28 else self.BADSTART) # Regenerate bitstream bits = 1 bit = 1 v = 1 # 14 bit bitstream, MSB always 1 x = 0 while bits < 14: # -1 convert count to index, -1 because we look ahead if x > nedges - 2: print('Bad block 1 edges', nedges, 'x', x) raise RuntimeError(self.BADBLOCK) # width is 889/1778 nominal width = ticks_diff(self._times[x + 1], self._times[x]) if not 500 < width < 2100: self.verbose and print('Bad block 3 Width', width, 'x', x) raise RuntimeError(self.BADBLOCK) short = width < 1334 if not short: bit ^= 1 v <<= 1 v |= bit bits += 1 x += 1 + int(short) self.verbose and print(bin(v)) # Split into fields (val, addr, ctrl) val = (v & 0x3f) | (0 if ((v >> 12) & 1) else 0x40) # Correct the polarity of S2 addr = (v >> 6) & 0x1f ctrl = (v >> 11) & 1 except RuntimeError as e: val, addr, ctrl = e.args[0], 0, 0 # Set up for new data burst and run user callback self.do_callback(val, addr, ctrl)
def scroll(self, data, speed=120): DISPLAY_WIDTH = 16 # Display width in pixels. DISPLAY_HEIGHT = 8 # Display height in pixels. # Initialize LED matrix. matrix = Display(i2c) matrix.clear() # Initialize font renderer using a helper function to flip the Y axis # when rendering so the origin is in the upper left. if type(data) == int: self.show(data) else: def matrix_pixel(x, y): matrix._pixel(x, y, 1) with BitmapFont(DISPLAY_WIDTH, DISPLAY_HEIGHT, matrix_pixel) as bf: # Global state: pos = DISPLAY_WIDTH # X position of the message start. message_width = bf.width(data) # Message width in pixels. last = utime.ticks_ms() # Last frame millisecond tick time. speed_ms = 1200 / speed / 1000.0 # Scroll speed in pixels/ms. # Main loop: while True: # Compute the time delta in milliseconds since the last frame. current = utime.ticks_ms() delta_ms = utime.ticks_diff(current, last) last = current # Compute position using speed and time delta. pos -= speed_ms * delta_ms if pos < -message_width: pos = DISPLAY_WIDTH return # Clear the matrix and draw the text at the current position. matrix.fill(0) bf.text(data, int(pos), 0) # Update the matrix LEDs. matrix._show()
def run(mqtt_obj, parameters): #Make mqtt object global, so it can be called from interrupts global mqtt mqtt = mqtt_obj #Set project name as prefix so we can easily filter topics #Final topic will be in form: #UID/prefix/user_topic mqtt.set_prefix("switch") s.set_limits(20, 120) s.set_angle(90) #Subscribe mqtt.sub("angle", callback_angle) mqtt.sub("duty", callback_duty) mqtt.sub("route", callback_route) #Setup callback for pin p0 = machine.Pin(0, machine.Pin.IN) p0.irq(trigger=machine.Pin.IRQ_FALLING | machine.Pin.IRQ_RISING, handler=pin_callback) #Main loop while True: #Call periodicaly to check if we have recived new messages. mqtt.check_msg() utime.sleep(0.1) global pin_down global pin_up_time if pin_down == True and pin_up_time > 0: dt = utime.ticks_diff(utime.ticks_ms(), pin_up_time) if dt > 1000: mqtt.pub("status", "free") pin_down = False
def detectPedestrian(frame, fileName, productKey, devName, devSecret): start = utime.ticks_ms() global dev # 上传图片到LP fileid = dev.uploadContent(fileName, frame, None) if fileid != None: ext = {'filePosition': 'lp', 'fileName': fileName, 'fileId': fileid} ext_str = json.dumps(ext) all_params = { 'id': 1, 'version': '1.0', 'params': { 'eventType': 'haas.faas', 'eventName': 'detectPedestrian', 'argInt': 1, 'ext': ext_str } } all_params_str = json.dumps(all_params) upload_file = { 'topic': '/sys/' + productKey + '/' + deviceName + '/thing/event/hli_event/post', 'qos': 1, 'payload': all_params_str } # 上传完成通知HaaS聚合平台 # print(upload_file) dev.publish(upload_file) while g_lk_service == False: continue else: print('filedid is none, upload content fail') time_diff = utime.ticks_diff(utime.ticks_ms(), start) print('get response time : %d' % time_diff)
def run() -> None: """ Loop forever, stepping through scheduled tasks and awaiting I/O events in between. Use `schedule` first to add a coroutine to the task queue. Tasks yield back to the scheduler on any I/O, usually by calling `await` on a `Syscall`. """ task_entry = [0, 0, 0] # deadline, task, value msg_entry = [0, 0] # iface | flags, value while _queue or _paused: # compute the maximum amount of time we can wait for a message if _queue: delay = utime.ticks_diff(_queue.peektime(), utime.ticks_ms()) else: delay = 1000 # wait for 1 sec maximum if queue is empty if __debug__: # process synthetic events if synthetic_events: iface, event = synthetic_events[0] msg_tasks = _paused.pop(iface, ()) if msg_tasks: synthetic_events.pop(0) for task in msg_tasks: _step(task, event) if io.poll(_paused, msg_entry, delay): # message received, run tasks paused on the interface msg_tasks = _paused.pop(msg_entry[0], ()) for task in msg_tasks: _step(task, msg_entry[1]) else: # timeout occurred, run the first scheduled task if _queue: _queue.pop(task_entry) _step(task_entry[1], task_entry[2]) # type: ignore
def check_valid_wifi(self): if not self.sta_if.isconnected(): if self.creds.load().is_valid(): # have credentials to connect, but not yet connected # return value based on whether the connection was successful return self.connect_to_wifi() # not connected, and no credentials to connect yet return False if not self.ap_if.active(): # access point is already off; do nothing return False # already connected to WiFi, so turn off Access Point after a delay if self.conn_time_start is None: self.conn_time_start = time.ticks_ms() remaining = self.AP_OFF_DELAY else: remaining = self.AP_OFF_DELAY - time.ticks_diff( time.ticks_ms(), self.conn_time_start) if remaining <= 0: self.ap_if.active(False) print("Turned off access point") return False
def distance_measure(): distance_samples = [] # trigger pulse LOW for 2us (just in case) trigger(0) utime.sleep_us(2) # trigger HIGH for a 10us pulse trigger(1) utime.sleep_us(10) trigger(0) # wait for the rising edge of the echo then start timer while echo() == 0: pass start = utime.ticks_us() # wait for end of echo pulse then stop timer while echo() == 1: pass finish = utime.ticks_us() # pause for 20ms to prevent overlapping echos utime.sleep_ms(500) # calculate distance by using time difference between start and stop # speed of sound 340m/s or .034cm/us. Time * .034cm/us = Distance sound travelled there and back # divide by two for distance to object detected. distance = ((utime.ticks_diff(start, finish)) * .034) / 2 for count in range(10): distance_samples.append(int(distance)) # sort the list distance_samples = sorted(distance_samples) distance_median = distance_samples[int(len(distance_samples) / 2)] return int(distance_median)
def set_network_to_sleep(self, time_till_next_tx): print("*** Sending the network to sleep for " + str(time_till_next_tx) + " msec ***") initTime = utime.ticks_ms() # Send multiple copies of blank broadcast REQs (fopr redundancy) numREQCopies = 3 interval = 2000 # 2 second intervals between REQ copies for n in range(numREQCopies): # Feed the watchdog if self.wdt: self.wdt.feed() # Transmit blank broadcast REQ ttnf = time_till_next_tx - utime.ticks_diff( utime.ticks_ms(), initTime) print("Sending Blank Broadcast REQ...") gwf.sendBroadcastREQ(self.nm, "S", n + 1, ttnf, True, []) # Wait for a set interval before transmitting it again pyb.delay(interval) # Loop through each relay node and send a blacnk unicast REQ to them (to reach their child nodes) interval = 7000 for r in self.relayAddr: # Feed the watchdog if self.wdt: self.wdt.feed() print("Sending Blank Unicast REQ to N" + "%03d" % r) gwf.sendUnicastREQ(self.nm, "S", 1, self.thisNode, r, True, [], self.wdt) pyb.delay(interval)
def play_next_note(self, play_next_note=False): try: try: time, frame_type, padding, frame_data = parse_bee_frame(self.__buzz_file.file.read(8)) except: return time = time * self.__tempo // self.__buzz_file.ticks_per_beat // 1000 # us -> ms # play next note self.__frame_pointer += 1 if self.__frame_pointer < self.__buzz_file.frame_count and play_next_note and time > 0: # set timer event as soon as possible self.__target_note_time = ticks_add(self.__target_note_time, time) target_period = ticks_diff(self.__target_note_time, ticks_ms()) self.__timer_id = self.__timer.init(mode=ONE_SHOT, period=target_period, callback=self._timer_callback) # deal with frame if frame_type == TYPE_SET_TEMPO: self.__tempo = int.from_bytes(frame_data, 'big') elif frame_type == TYPE_NOTE_OFF: self.note_off() elif frame_type == TYPE_NOTE_ON: self.note_on(frame_data[0], self.__volume) elif frame_type == TYPE_EMIT_EVENT and self.__event_callback != None: self.__event_callback(frame_data, padding) # control next note if self.__frame_pointer < self.__buzz_file.frame_count and play_next_note and time <= 0: self.play_next_note(True) return time if self.__frame_pointer >= self.__buzz_file.frame_count: if self.__loop: self.start(True) else: self.stop() return time except Exception as e: import usys usys.print_exception(e)
def get_past_captive_portal(ssid, ip_addr, mac_addr): captive, redirect_url = is_captive() if not captive: return if redirect_url is False: raise CaptivePortalError( 'Not connected to the Internet and did not get a redirect to a ' 'captive portal.') if redirect_url.startswith(CAPTIVE_STARBUCKS_URL_PREFIX): submit_starbucks_captive_portal(mac_addr) else: raise CaptivePortalError( 'Not connected to the Internet and redirect is to an ' 'unsupported redirect URL: %s' % redirect_url) # Getting access to the Internet may take a few seconds after # submitting the form on the captive portal. start = utime.ticks_ms() while is_captive()[0]: if utime.ticks_diff(utime.ticks_ms(), start) > 10000: raise CaptivePortalError('Could not get past captive portal') utime.sleep_ms(1000)
async def connect_as(): global wlan_stable log.debug("create station interface - Standard WiFi client") if not wlan.isconnected(): log.debug('activate') activate() # Note that this may take some time, so we need to wait await asyncio.sleep_ms(500) # Wait 5 sec or until connected t = time.ticks_ms() timeout = 5000 while wlan.status() == network.STAT_CONNECTING and time.ticks_diff( time.ticks_ms(), t) < timeout: log.debug('connecting...') await asyncio.sleep_ms(200) else: log.debug("Wlan already active") await check_stable(duration=100) if wlan_stable: log_ifconfig() else: cause = 'reason unknown' if wlan.status() == network.STAT_WRONG_PASSWORD: cause = 'wrong password' elif wlan.status() == network.STAT_NO_AP_FOUND: cause = 'SSID not found' elif wlan.status() == network.STAT_ASSOC_FAIL: cause = 'assoc fail' elif wlan.status() == network.STAT_CONNECTING: cause = 'cannot find SSID' #deactivate ( to re-activate later) wlan.active(False) wlan_stable = False log.error("Unable to connect to Wlan {}; {}".format( cfg.homenet['SSID'], cause))
def poll(self): value = self.touchpin.read() weighted_value = sum(self.readings[-2:] + [value]) / 3 mean = self.get_current_mean() thresh = mean * self.threshold ratio = weighted_value / mean #logger.debug( # '[{}] Mean: {:04.0f}, Threshold: {:04.0f}, This: {:04.0f}, This weighted: {:04.0f} / {:.0%}' # .format(utime.ticks_ms(), mean, thresh, value, weighted_value, ratio) #) logger.debug('{} {} {}'.format(mean, weighted_value, int(ratio*100))) if weighted_value < thresh: now = utime.ticks_ms() if (utime.ticks_diff(now, self.callback_triggered_last) < self.debounce_ms): logger.info('Debounced') # Make reading affect mean less - this allows for slow recalibration #value += (thresh - value)*0.9 else: self.callback() self.callback_triggered_last = now self.readings.pop(0) self.readings.append(weighted_value)
def poll(self): value = self.touchpin.read() weighted_value = sum(self.readings[-2:] + [value]) / 3 mean = self.get_current_mean() thresh = mean * self.threshold ratio = weighted_value / mean #logger.debug( # '[{}] Mean: {:04.0f}, Threshold: {:04.0f}, This: {:04.0f}, This weighted: {:04.0f} / {:.0%}' # .format(utime.ticks_ms(), mean, thresh, value, weighted_value, ratio) #) # logger.debug('{} {} {}'.format(mean, weighted_value, int(ratio*100))) if weighted_value < thresh: now = utime.ticks_ms() if (utime.ticks_diff(now, self.callback_triggered_last) < self.debounce_ms): logger.info('Debounced') # Make reading affect mean less - this allows for slow recalibration #value += (thresh - value)*0.9 else: self.callback() self.callback_triggered_last = now self.readings.pop(0) self.readings.append(weighted_value)
def tick(self): try: delta_t = 0.001 * utime.ticks_diff(utime.ticks_us(), self.previous_tick) except Exception: delta_t = 0.01 # Decide what to show: year, month, day, hour, minute, second, milisecond, microsecond = utime.localtime( ) if second >= 0 and second <= 20: self.write_amb('temp') elif second >= 30 and second <= 35: self.write_amb('hum') else: self.write_time() for segment in self.displays: segment.tick(delta_t) segment.write_to_strip(self.np) self.np.write() self.previous_tick = utime.ticks_us()
def new_func(*args, **kwargs): t0 = utime.ticks_us() timed_function_stack.append(myname) result = f(*args, **kwargs) if myname not in profile_stats_time_including_children: profile_stats_time_including_children[myname] = 0 profile_stats_calls[myname] = 0 t1 = utime.ticks_us() delta_us = utime.ticks_diff(t1, t0) profile_stats_time_including_children[myname] += delta_us profile_stats_calls[myname] += 1 if len(timed_function_stack) >= 2: stack_last_two = tuple(timed_function_stack[-2:]) if stack_last_two not in stack_history: stack_history[stack_last_two] = 0 stack_history[stack_last_two] += delta_us timed_function_stack.pop() return result
def __measure_once(self): # Stabilize the sensor self.trigger(0) utime.sleep_us(2) # Send a 10us pulse. self.trigger(1) utime.sleep_us(10) self.trigger(0) # wait for the rising edge of the echo then start timer start = utime.ticks_us() while self.echo() == 0: if utime.ticks_us() - start > 1000000: raise Exception("Timeout starting HCSR04 distance sensor.") pass start = utime.ticks_us() # wait for end of echo pulse then stop timer while self.echo() == 1: # timeout after one second if utime.ticks_us() - start > 1000000: raise Exception("Timeout reading HCSR04 distance sensor.") finish = utime.ticks_us() # pause for 20ms to prevent overlapping echos utime.sleep_ms(20) # calculate distance by using time difference between start and stop # speed of sound 340m/s or .034cm/us. Time * .034cm/us = Distance sound travelled there and back # divide by two for distance to object detected. return int(((utime.ticks_diff(start, finish)) * .034) / -2) return distance
def _callback(self, pin): irq_state = machine.disable_irq() if self._debounce: t0 = utime.ticks_us() while True: t1 = utime.ticks_us() dt = utime.ticks_diff(t1, t0) if dt > timeout: if self._debug: print("Timeout !") break self._register[0] <<= 1 self._register[0] |= pin.value() #print("{:08b}".format(self._register[0])) # All bits set, button has been released for L loops if self._register[0] is mask: self._current_state = False break # All bits unset, button has been pressed for L loops if self._register[0] is zero: self._current_state = True break else: self._current_state = (self._pin.value() == 0) # Handle edge case of two consequent rising interrupts if self._current_state is not self._previous_state: self._previous_state = self._current_state if self._user_callback is not None: self._user_callback(self._pin, self._current_state) machine.enable_irq(irq_state)
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 update(self, error): # Calculate dt curr_time = utime.ticks_us() dt = float(utime.ticks_diff(curr_time, self.prev_time)) / float(1000000) # Calculate proportional Pout = self.params["kp"] * error # Calculate integral self.integral += error * dt Iout = self.params["ki"] * self.integral # Calculate derivative derivative = (error - self.prev_err) / dt Dout = self.params["kd"] * derivative '''print("------------------------------------") print("Pout {} | Iout {} | Dout {}".format(Pout, Iout, Dout)) print("kp {} | ki {} | kd {}".format(self.params["kp"], self.params["ki"], self.params["kd"])) print("------------------------------------")''' self.output = Pout + Iout + Dout # Apply maximums to output with anti windup if (self.output > self.max): self.output = self.max # Anti-windup self.integral -= error * dt elif (self.output < self.min): self.output = self.min # Anti-windup self.integral -= error * dt # Save error self.prev_err = error self.prev_time = utime.ticks_us()
def Loop(self): # Check if we are running if self.Running == False: return # Trigger the callback with argument try: if utime.ticks_diff(utime.ticks_ms(), self.Start_ms) < self.Timeout_ms: return except TypeError as e: raise self.Dobby.Sys_Modules['Timer'].Timer_Error( "Error: " + str(e) + " Name:" + str(self.Name) + " Timeout_ms:" + str(self.Timeout_ms) + " Callback:" + str(self.Callback) + " Argument:" + str(self.Argument)) # check if we ran all count's of the timer if self.Count <= 0: # Stop so we dont start again before told to do so self.Stop() # Trigger the timer and remove one from count else: self.Count = self.Count - 1 if self.Logging == True: # Log event self.Dobby.Log(0, "Timer", "Triggering callback: " + self.Name) if self.Argument != None: # Trigger the callback with argument # try: self.Callback(self.Argument) # except TypeError as e: # raise self.Dobby.Sys_Modules['Timer'].Timer_Error("Error running callback:" + str(self.Name) + " Argument:" + str(self.Argument) + " Error:" + str(e)) else: # Trigger the callback without arguemtn self.Callback()
def distance_measure(trigger, echo): # trigger pulse LOW for 2us (just in case) trigger(0) utime.sleep_us(2) # trigger HIGH for a 10us pulse trigger(1) utime.sleep_us(20) trigger(0) # wait for the rising edge of the echo then start timer while echo() == 0: pass start = utime.ticks_us() # wait for end of echo pulse then stop timer while echo() == 1: pass finish = utime.ticks_us() # pause for 20ms to prevent overlapping echos utime.sleep_ms(20) # calculate distance by using time difference between start and stop # speed of sound 340m/s or .034cm/us. Time * .034cm/us = Distance sound travelled there and back # divide by two for distance to object detected. # Note: changing the multiplying factor to 0.0133858 for inches distance = ((utime.ticks_diff(start, finish)) * 0.0133858) / 2 return distance * -1
def button_pressed(p): global time_last_button_press time_pressed = utime.ticks_ms() if button.value() and time_last_button_press > 0: # Button released, determine length since press hold_length = utime.ticks_diff(time_pressed, time_last_button_press) if hold_length > LONG_PRESS_TIME: # Long press print( utime.ticks_ms(), "Long press doesn't do anything yet! ({}ms)".format( hold_length)) elif hold_length > DEBOUNCE_TIME: # Short press change_relay_state() # Reset last pressed time time_last_button_press = 0 elif not button.value() and time_last_button_press == 0: # First button press since last release; record time time_last_button_press = time_pressed
dprint("-----") # h.dump() dprint("-----") h = utimeq(10) add(h, 0) add(h, MAX) add(h, MAX - 1) add(h, 101) add(h, 100) add(h, MAX - 2) dprint(h) l = pop_all(h) for i in range(len(l) - 1): diff = ticks_diff(l[i + 1][0], l[i][0]) assert diff > 0 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 dprint("===")
def hasExpired(self): return utime.ticks_diff(utime.ticks_ms(), self.start_time) >= self.duration_ms
#sw = pyb.Switch() # Choose test to run Calibrate = True Timing = True def getmag(): # Return (x, y, z) tuple (blocking read) return imu.mag.xyz if Calibrate: print("Calibrating. Press switch when done.") fuse.calibrate(getmag, sw, lambda : pyb.delay(100)) print(fuse.magbias) if Timing: mag = imu.mag.xyz # Don't include blocking read in time accel = imu.accel.xyz # or i2c gyro = imu.gyro.xyz start = time.ticks_us() # Measure computation time only fuse.update(accel, gyro, mag) # 1.97mS on Pyboard t = time.ticks_diff(time.ticks_us(), start) print("Update time (uS):", t) count = 0 while True: fuse.update(imu.accel.xyz, imu.gyro.xyz, imu.mag.xyz) # Note blocking mag read if count % 50 == 0: print("Heading, Pitch, Roll: {:7.3f} {:7.3f} {:7.3f}".format(fuse.heading, fuse.pitch, fuse.roll)) time.sleep_ms(20) count += 1
def run_forever(self): while True: if self.q: t, cb, args = heapq.heappop(self.q, True) if __debug__ and DEBUG: log.debug("Next coroutine to run: %s", (t, cb, args)) # __main__.mem_info() tnow = self.time() delay = time.ticks_diff(t, tnow) if delay > 0: self.wait(delay) else: self.wait(-1) # Assuming IO completion scheduled some tasks continue if callable(cb): cb(*args) else: delay = 0 try: if __debug__ and DEBUG: log.debug("Coroutine %s send args: %s", cb, args) if args == (): ret = next(cb) else: ret = cb.send(*args) if __debug__ and DEBUG: log.debug("Coroutine %s yield result: %s", cb, ret) if isinstance(ret, SysCall1): arg = ret.arg if isinstance(ret, Sleep): delay = arg elif isinstance(ret, IORead): # self.add_reader(ret.obj.fileno(), lambda self, c, f: self.call_soon(c, f), self, cb, ret.obj) # self.add_reader(ret.obj.fileno(), lambda c, f: self.call_soon(c, f), cb, ret.obj) # self.add_reader(arg.fileno(), lambda cb: self.call_soon(cb), cb) self.add_reader(arg.fileno(), cb) continue elif isinstance(ret, IOWrite): # self.add_writer(arg.fileno(), lambda cb: self.call_soon(cb), cb) self.add_writer(arg.fileno(), cb) continue elif isinstance(ret, IOReadDone): self.remove_reader(arg.fileno()) elif isinstance(ret, IOWriteDone): self.remove_writer(arg.fileno()) elif isinstance(ret, StopLoop): return arg elif isinstance(ret, type_gen): self.call_soon(ret) elif isinstance(ret, int): # Delay delay = ret elif ret is None: # Just reschedule pass else: assert False, "Unsupported coroutine yield value: %r (of type %r)" % (ret, type(ret)) except StopIteration as e: if __debug__ and DEBUG: log.debug("Coroutine finished: %s", cb) continue self.call_later_ms_(delay, cb, args)
def new_func(*args, **kwargs): t = utime.ticks_us() result = f(*args, **kwargs) delta = utime.ticks_diff(utime.ticks_us(), t) # Argument order new, old print('Function {} Time = {:6.3f}ms'.format(myname, delta/1000)) return result
h.push(v, 0, 0) dprint("-----") #h.dump() dprint("-----") h = utimeq(10) add(h, 0) add(h, MAX) add(h, MAX - 1) add(h, 101) add(h, 100) add(h, MAX - 2) dprint(h) l = pop_all(h) for i in range(len(l) - 1): diff = ticks_diff(l[i + 1][0], l[i][0]) assert diff > 0 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 dprint("===") diff = edge_case(MODULO_HALF - 1, 0) assert diff == MODULO_HALF - 1
import utime try: utime.sleep_ms except AttributeError: print("SKIP") raise SystemExit utime.sleep_ms(1) utime.sleep_us(1) print(utime.ticks_diff(utime.ticks_ms(), utime.ticks_ms()) <= 1) print(utime.ticks_diff(utime.ticks_us(), utime.ticks_us()) <= 500)
def TimeDiff(start, end): return time.ticks_diff(start, end)/1000000
def run_forever(self): cur_task = [0, 0, 0] while True: if self.q: # wait() may finish prematurely due to I/O completion, # and schedule new, earlier than before tasks to run. while 1: t = self.q.peektime() tnow = self.time() delay = time.ticks_diff(t, tnow) if delay <= 0: break self.wait(delay) self.q.pop(cur_task) t = cur_task[0] cb = cur_task[1] args = cur_task[2] if __debug__ and DEBUG: log.debug("Next coroutine to run: %s", (t, cb, args)) # __main__.mem_info() else: self.wait(-1) # Assuming IO completion scheduled some tasks continue if callable(cb): cb(*args) else: delay = 0 try: if __debug__ and DEBUG: log.debug("Coroutine %s send args: %s", cb, args) if args == (): ret = next(cb) else: ret = cb.send(*args) if __debug__ and DEBUG: log.debug("Coroutine %s yield result: %s", cb, ret) if isinstance(ret, SysCall1): arg = ret.arg if isinstance(ret, SleepMs): delay = arg elif isinstance(ret, IORead): self.add_reader(arg, cb) continue elif isinstance(ret, IOWrite): self.add_writer(arg, cb) continue elif isinstance(ret, IOReadDone): self.remove_reader(arg) elif isinstance(ret, IOWriteDone): self.remove_writer(arg) elif isinstance(ret, StopLoop): return arg else: assert False, "Unknown syscall yielded: %r (of type %r)" % (ret, type(ret)) elif isinstance(ret, type_gen): self.call_soon(ret) elif isinstance(ret, int): # Delay delay = ret elif ret is None: # Just reschedule pass else: assert False, "Unsupported coroutine yield value: %r (of type %r)" % (ret, type(ret)) except StopIteration as e: if __debug__ and DEBUG: log.debug("Coroutine finished: %s", cb) continue # Currently all syscalls don't return anything, so we don't # need to feed anything to the next invocation of coroutine. # If that changes, need to pass that value below. self.call_later_ms(delay, cb)
def run_forever(self): cur_task = [0, 0, 0] while True: # Expire entries in waitq and move them to runq tnow = self.time() while self.waitq: t = self.waitq.peektime() delay = time.ticks_diff(t, tnow) if delay > 0: break self.waitq.pop(cur_task) if __debug__ and DEBUG: log.debug("Moving from waitq to runq: %s", cur_task[1]) self.call_soon(cur_task[1], *cur_task[2]) # Process runq l = len(self.runq) if __debug__ and DEBUG: log.debug("Entries in runq: %d", l) while l: cb = self.runq.popleft() l -= 1 args = () if not isinstance(cb, type_gen): args = self.runq.popleft() l -= 1 if __debug__ and DEBUG: log.info("Next callback to run: %s", (cb, args)) cb(*args) continue if __debug__ and DEBUG: log.info("Next coroutine to run: %s", (cb, args)) self.cur_task = cb delay = 0 try: if args is (): ret = next(cb) else: ret = cb.send(*args) if __debug__ and DEBUG: log.info("Coroutine %s yield result: %s", cb, ret) if isinstance(ret, SysCall1): arg = ret.arg if isinstance(ret, SleepMs): delay = arg elif isinstance(ret, IORead): cb.pend_throw(False) self.add_reader(arg, cb) continue elif isinstance(ret, IOWrite): cb.pend_throw(False) self.add_writer(arg, cb) continue elif isinstance(ret, IOReadDone): self.remove_reader(arg) elif isinstance(ret, IOWriteDone): self.remove_writer(arg) elif isinstance(ret, StopLoop): return arg else: assert False, "Unknown syscall yielded: %r (of type %r)" % (ret, type(ret)) elif isinstance(ret, type_gen): self.call_soon(ret) elif isinstance(ret, int): # Delay delay = ret elif ret is None: # Just reschedule pass elif ret is False: # Don't reschedule continue else: assert False, "Unsupported coroutine yield value: %r (of type %r)" % (ret, type(ret)) except StopIteration as e: if __debug__ and DEBUG: log.debug("Coroutine finished: %s", cb) continue except CancelledError as e: if __debug__ and DEBUG: log.debug("Coroutine cancelled: %s", cb) continue # Currently all syscalls don't return anything, so we don't # need to feed anything to the next invocation of coroutine. # If that changes, need to pass that value below. if delay: self.call_later_ms(delay, cb) else: self.call_soon(cb) # Wait until next waitq task or I/O availability delay = 0 if not self.runq: delay = -1 if self.waitq: tnow = self.time() t = self.waitq.peektime() delay = time.ticks_diff(t, tnow) if delay < 0: delay = 0 self.wait(delay)