Skip to content

Commit

Permalink
Merge branch 'class_refactorings'
Browse files Browse the repository at this point in the history
  • Loading branch information
r0f1 committed Dec 14, 2024
2 parents 77bc9ca + 0c6e9d3 commit 79c2a70
Show file tree
Hide file tree
Showing 41 changed files with 789 additions and 1,340 deletions.
2 changes: 1 addition & 1 deletion .python-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.13
3.11
36 changes: 30 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,53 @@

# sts1-sensors

Streamline the process of handling sensors on the Raspi-Hat / EDU module.
Streamline the process of handling sensors for the STS1 project.

The following sensors are available on the EDU module:
The following sensors are available both on the satellite and **on the EDU module**:
* [`ADXL345`](https://www.analog.com/en/products/adxl345.html) - Digital accelerometer.
* [`BME688`](https://www.bosch-sensortec.com/products/environmental-sensors/gas-sensors/bme688/) - Pressure, humidity, temperature and gas sensor.
* [`BMM150`](https://www.bosch-sensortec.com/products/motion-sensors/magnetometers/bmm150/) - Geomagnetic sensor.
* [`GUVA_C32`](https://www.digikey.de/de/products/detail/genicom-co-ltd/GUVA-C32SM/9960949) - Ultraviolet light sensor.
* [`L3GD20H`](https://www.pololu.com/file/0J731/L3GD20H.pdf) - Three-axis gyroscope.
* [`TMP112`](https://www.ti.com/product/TMP112) - High-accuracy temperature sensor.

The following sensors are available **on the satellite only**:
* [`GUVA_C32`](https://www.digikey.de/de/products/detail/genicom-co-ltd/GUVA-C32SM/9960949) - Ultraviolet light sensor.

## Quickstart

```python
from sts1_sensors import ADXL345, TMP112
from sts1_sensors import ADXL345, BME688, BMM150, L3GD20H, TMP112

# Accelerometer
accel = ADXL345(range=2, datarate=50)
accel = ADXL345()
x, y, z = accel.get_g()
print(f"X: {x:.2f}g, Y: {y:.2f}g, Z: {z:.2f}g")
print(f"{x=:.2f} g, {y=:.2f} g, {z=:.2f} g")

# Temperature, pressure, humidity and gas sensor
multi = BME688(enable_gas_measurements=True)
t = multi.get_temperature()
p = multi.get_pressure()
h = multi.get_humidity()
heat = multi.get_heat_stable()
res = multi.get_gas_resistance()
print(f"{t:.2f} °C, {p:.2f} hPa, {h:.2f} %RH, {heat=}, {res:.2f} Ohms")

# Geomagnetic sensor
mag = BMM150()
x, y, z = mag.get_magnetic_data()
print(f"{x=:.2f} µT, {y=:.2f} µT, {z=:.2f} µT")
print(f"Heading: {mag.get_heading():.2f}°")

# Gyroscope
gyro = L3GD20H()
x, y, z = gyro.get_position()
print(f"{x=:.2f} dpfs, {y=:.2f} dpfs, {z=:.2f} dpfs")

# Temperature sensor
temp = TMP112()
print(f"{temp.get_temp():.2f} °C")
```
More examples, see examples folder.

## Installation

Expand Down Expand Up @@ -61,6 +84,7 @@ pip install sts1-sensors
## For Developers

* Install [just](https://github.com/casey/just?tab=readme-ov-file#pre-built-binaries): `curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to ~/bin`
* Add it to `~/.bashrc`: `export PATH="$PATH:$HOME/bin"`
* Install the [package manager uv](https://docs.astral.sh/uv/getting-started/installation/): `curl -LsSf https://astral.sh/uv/install.sh | sh`
* Add its path to your `~/.bashrc` such that the command `uv` is available: `export PATH=$HOME/.local/bin:$PATH`
* Clone this repo: `git clone https://github.com/SpaceTeam/STS1_sensor_libraries`
Expand Down
12 changes: 0 additions & 12 deletions examples/BMM150Example.py

This file was deleted.

13 changes: 0 additions & 13 deletions examples/L3GD20HExample.py

This file was deleted.

13 changes: 0 additions & 13 deletions examples/allSensors.py

This file was deleted.

5 changes: 3 additions & 2 deletions examples/ADXL345_example.py → examples/edu/ADXL345.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import time

import structlog

from sts1_sensors import ADXL345

log = structlog.get_logger()

accel = ADXL345(range=2, datarate=50,
x_offset=-0.04570, y_offset=-0.00697, z_offset=0.04614)
accel = ADXL345(range=2, datarate=50)

while True:
x, y, z = accel.get_g()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
import time
from sts1_sensors import ADXL345

accel = ADXL345(address=0x53, range=2, datarate=50)
accel = ADXL345(datarate=1.56)

# takes 20 secs
measurements = []
for _ in range(200):
for _ in range(100):
measurements.append(accel.get_g())
time.sleep(.1)
time.sleep(.2)

x_vals, y_vals, z_vals = zip(*measurements)

Expand Down
23 changes: 23 additions & 0 deletions examples/edu/BME688.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import time

import structlog

from sts1_sensors import BME688

sensor = BME688()
log = structlog.get_logger()

sensor.enable_gas_measurements = True
sensor.gas_heater_temperature = 320
sensor.gas_heater_duration = 150

for i in range(10):
t = sensor.get_temperature()
p = sensor.get_pressure()
h = sensor.get_humidity()

heat = sensor.get_heat_stable()
res = sensor.get_gas_resistance()

log.info(f"{t:.2f} °C, {p:.2f} hPa, {h:.2f} %RH, {heat=}, {res:.2f} Ohms")
time.sleep(1)
9 changes: 9 additions & 0 deletions examples/edu/BMM150.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from sts1_sensors import BMM150

mag = BMM150()
x, y, z = mag.get_magnetic_data()
print(f"{x=:.2f} µT, {y=:.2f} µT, {z=:.2f} µT")

degrees = mag.get_heading()
print(f"Heading: {degrees:.2f}°")

12 changes: 12 additions & 0 deletions examples/edu/L3GD20H.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import time
import structlog
from sts1_sensors import L3GD20H

log = structlog.get_logger()

gyro = L3GD20H(range=245, datarate=12.5)

while True:
x, y, z = gyro.get_position()
log.info(f"X: {x:.2f}dpfs, Y: {y:.2f}dpfs, Z: {z:.2f}dpfs")
time.sleep(.25)
File renamed without changes.
36 changes: 36 additions & 0 deletions examples/edu/all_sensors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import time

import structlog
from sts1_sensors import ADXL345, BME688, BMM150, L3GD20H, TMP112

log = structlog.get_logger()

accel = ADXL345() # Accelerometer
mag = BMM150() # Geomagnetic sensor
gyro = L3GD20H() # Gyroscope
temp = TMP112() # Temperature sensor
multi = BME688(enable_gas_measurements=True) # Pressure, humidity, temperature and gas sensor

for _ in range(10):
gx, gy, gz = accel.get_g()
s = f"{gx=:.2f}, {gy=:.2f}, {gz=:.2f}"

mx, my, mz = mag.get_magnetic_data()
s += f", {mx=:.2f} µT, {my=:.2f} µT, {mz=:.2f} µT"
s += f", Heading: {mag.get_heading():.2f}°"

px, py, pz = gyro.get_position()
s += f", {px=:.2f} dpfs, {py=:.2f} dpfs, {pz=:.2f} dpfs"

t1 = temp.get_temp()
s += f", temp1 {t1:.2f} °C"

t2 = multi.get_temperature()
p = multi.get_pressure()
h = multi.get_humidity()
heat = multi.get_heat_stable()
res = multi.get_gas_resistance()
s += f", temp2 {t2:.2f} °C, {p:.2f} hPa, {h:.2f} %RH, {heat=}, {res:.2f} Ohms"

log.info(s)
time.sleep(2)
File renamed without changes.
13 changes: 0 additions & 13 deletions examples/raspiHat.py

This file was deleted.

2 changes: 1 addition & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ clean_docs:

test:
# Works only on Rasperry Pi
pytest
uv run pytest
6 changes: 4 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ name = "sts1_sensors"
version = "0.3.5"
description = "A sensor library for the CubeSat STS1 (TU Wien Space Team)."
readme = "README.md"
requires-python = ">=3.13"
requires-python = ">=3.11,<3.12"
dependencies = [
"smbus2>=0.5.0",
"bme680>=2.0.0",
"bmm150>=0.2.2",
"smbus2>=0.4.2,<0.5.0",
"structlog>=24.4.0",
]
authors = [
Expand Down
2 changes: 1 addition & 1 deletion src/sts1_sensors/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from .sensors import *
from .edu import *
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import os

from sts1_sensors.sensors.AbstractSensor import AbstractSensor
from sts1_sensors.utils.AbstractSensor import AbstractSensor

class ADXL345(AbstractSensor):
"""Digital accelerometer.
"""
_possible_addresses = [0x1D, 0x3A, 0x3B, 0x53]
_possible_datarates = [0.10, 0.20, 0.39, 0.78, 1.56, 3.13, 6.25, 12.5, 25, 50, 100, 200, 400, 800, 1600, 3200]
_possible_ranges = [2, 4, 8, 16]

Expand All @@ -19,10 +18,8 @@ def __init__(self, range=2, datarate=50, x_offset=0, y_offset=0, z_offset=0, add
:param int z_offset: z-axis offset, defaults to 0.
:param hexadecimal address: Physical address of the sensor on the board (see `i2cdetect` command). Allowed values: `[0x1D, 0x3A, 0x3B, 0x53]`. If None, the environment variable `STS1_SENSOR_ADDRESS_AVXL345` will be used. If environment variable is not found, 0x53 will be used.
:param SMBus bus: A SMBus object. If None, this class will generate its own, defaults to None.
:meta public:
"""
super().__init__(bus)
super().__init__(possible_addresses=[0x1D, 0x3A, 0x3B, 0x53], bus=bus)

self.address = address or int(os.environ.get("STS1_SENSOR_ADDRESS_AVXL345", "0x53"), 16)
self.datarate = datarate
Expand All @@ -34,26 +31,14 @@ def __init__(self, range=2, datarate=50, x_offset=0, y_offset=0, z_offset=0, add
self.bus.write_byte_data(self.address, 0x2D, 0b1000)
self.bus.write_byte_data(self.address, 0x31, 0b1011 & self._possible_ranges.index(self.range))

@property
def address(self):
return self._address

@address.setter
def address(self, address):
if address not in self._possible_addresses:
s = f"The address {hex(address)} does not exist."
s += f" Choose one of {self._possible_addresses}."
raise ValueError(s)
self._address = address

@property
def datarate(self):
return self._datarate

@datarate.setter
def datarate(self, datarate):
if datarate not in self._possible_datarates:
s = f"The datarate {hex(datarate)} does not exist."
s = f"The datarate {datarate} does not exist."
s += f" Choose one of {self._possible_datarates}."
raise ValueError(s)
self._datarate = datarate
Expand All @@ -65,7 +50,7 @@ def range(self):
@range.setter
def range(self, range):
if range not in self._possible_ranges:
s = f"The range {hex(range)} does not exist."
s = f"The range {range} does not exist."
s += f" Choose one of {self._possible_ranges}."
raise ValueError(s)
self._range = range
Expand Down
Loading

0 comments on commit 79c2a70

Please sign in to comment.