Skip to content

Commit

Permalink
Make laser flashes more responsive
Browse files Browse the repository at this point in the history
  • Loading branch information
furbrain committed May 5, 2024
1 parent e419709 commit e494584
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 14 deletions.
22 changes: 20 additions & 2 deletions firmware/hardware.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import asyncio

import async_button
import async_buzzer

Expand Down Expand Up @@ -26,6 +28,9 @@ class HardwareBase:
bt: bluetooth.BluetoothServices
batt_voltage: float

def __init__(self):
self.laser_task: Optional[asyncio.Task] = None

def __enter__(self):
return self

Expand All @@ -41,11 +46,24 @@ def laser_enable(self, value):
pass

@abstractmethod
def laser_on(self, value):
async def laser_on(self, value):
pass

def flash_laser(self, count: int, speed: float):
if self.laser_task:
if not self.laser_task.done():
self.laser_task.cancel()
self.laser_task = asyncio.create_task(self._flash_laser(count, speed))

async def _flash_laser(self, count: int, speed: float):
for _ in range(count):
await self.laser_on(False)
await asyncio.sleep(speed)
await self.laser_on(True)
await asyncio.sleep(speed)

@abstractmethod
def laser_measure(self):
async def laser_measure(self):
pass

@abstractmethod
Expand Down
15 changes: 4 additions & 11 deletions firmware/measure.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ async def get_raw_measurement(devices: hardware.HardwareBase, disp: display.Disp
logger.debug(f"Mag: {mag}")
grav = devices.accelerometer.acceleration
logger.debug(f"Grav: {grav}")
await asyncio.sleep(0.1)
await devices.laser_on(True)
finally:
disp.sleep(wake=True)
Expand Down Expand Up @@ -135,26 +134,20 @@ async def take_reading(devices: hardware.HardwareBase,
logger.info(f"Measurement error: {repr(exc)}")
if not isinstance(exc, asyncio.TimeoutError):
# don't wibble the laser if it's timed out, it'll just get more confused
for i in range(5):
await devices.laser_on(False)
await asyncio.sleep(0.1)
await devices.laser_on(True)
await asyncio.sleep(0.1)
devices.flash_laser(5,0.1)
devices.beep_sad()
await asyncio.sleep(0)
return False
else:
leg = Leg(azimuth, inclination, distance)
readings.store_reading(leg, cfg)
devices.bt.disto.send_data(azimuth, inclination, distance)
if readings.triple_shot():
for _ in range(2):
await devices.laser_on(False)
await asyncio.sleep(0.2)
await devices.laser_on(True)
await asyncio.sleep(0.2)
devices.flash_laser(2,0.2)
devices.beep_happy()
else:
devices.beep_bip()
await asyncio.sleep(0)
return True


Expand Down
13 changes: 12 additions & 1 deletion firmware/versions/hardware_v1.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import asyncio
import time

import async_button
Expand All @@ -21,6 +22,7 @@
class Hardware(HardwareBase):
def __init__(self, pins):
logger.debug("Initialising hardware")
super().__init__()
import displayio
displayio.release_displays()
self._las_en_pin = digitalio.DigitalInOut(pins.LASER_EN)
Expand All @@ -36,7 +38,7 @@ def __init__(self, pins):
self._drdy_io.direction = digitalio.Direction.INPUT
# noinspection PyTypeChecker
self.magnetometer = rm3100.RM3100_I2C(self._i2c, drdy_pin=self._drdy_io, cycle_count=2000)
self._uart = busio.UART(pins.TX, pins.RX, baudrate=9600)
self._uart = busio.UART(pins.TX, pins.RX, baudrate=9600, timeout=0.1)
self._uart.reset_input_buffer()
self._laser = laser_egismos.AsyncLaser(self._uart)
if pins.BUZZER_B is None:
Expand Down Expand Up @@ -73,9 +75,18 @@ def laser_enable(self, value: bool) -> None:
self._las_en_pin.value = value

async def laser_on(self, value: bool) -> None:
await self._laser_mutex()
await self._laser.set_laser(value)

async def _laser_mutex(self):
"""This function waits for the laser task to complete before proceeding"""
if self.laser_task and not self.laser_task.done():
if asyncio.current_task() is not self.laser_task:
#don't wait if we're actually *in* the laser task
await self.laser_task

async def laser_measure(self) -> float:
await self._laser_mutex()
self._laser.async_reader.s.read() # clear the buffer
return await self._laser.measure()

Expand Down

0 comments on commit e494584

Please sign in to comment.