First commit
This commit is contained in:
parent
671953c98c
commit
513e06487b
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
build
|
||||
bdist*
|
||||
lib
|
||||
dist
|
||||
*.egg-info
|
||||
*/__pycache__
|
||||
4
MANIFEST.in
Normal file
4
MANIFEST.in
Normal file
@ -0,0 +1,4 @@
|
||||
include LICENSE
|
||||
include README.md
|
||||
include pyproject.toml
|
||||
recursive-include examples *.py
|
||||
47
README.md
47
README.md
@ -1,2 +1,49 @@
|
||||
# PyBMA400
|
||||
|
||||
A Python library for the Bosch BMA400 accelerometer, providing easy access to accelerometer data and configuration.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
pip install pybma400
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
- Read acceleration data
|
||||
- Read temperature data in Celsius
|
||||
- Configure power modes, sampling rates, and ranges
|
||||
- Low-level register access for advanced users
|
||||
- Simple orientation detection functionality
|
||||
|
||||
## Requirements
|
||||
|
||||
- Python 3.6 or later
|
||||
- Raspberry Pi or other Linux system with I2C enabled
|
||||
- SMBus library (automatically installed as a dependency)
|
||||
|
||||
## Usage Example
|
||||
|
||||
```python
|
||||
from pybma400 import BMA400
|
||||
|
||||
# Initialize the sensor
|
||||
sensor = BMA400() # Default I2C bus=1, address=0x14
|
||||
|
||||
# Read acceleration data
|
||||
x, y, z = sensor.acceleration
|
||||
print(f"Acceleration: X={x:.2f}, Y={y:.2f}, Z={z:.2f} m/s²")
|
||||
|
||||
# Read temperature
|
||||
temp = sensor.temperature
|
||||
print(f"Temperature: {temp:.1f}°C")
|
||||
|
||||
# Configure the sensor
|
||||
sensor.power_mode = BMA400.NORMAL_MODE
|
||||
sensor.output_data_rate = BMA400.ACCEL_100HZ
|
||||
sensor.acc_range = BMA400.ACC_RANGE_4 # ±4g range
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the LICENSE file for details.
|
||||
|
||||
42
examples/basic_usage.py
Normal file
42
examples/basic_usage.py
Normal file
@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Basic example of using the PyBMA400 library to read
|
||||
acceleration and temperature data from the BMA400 sensor.
|
||||
"""
|
||||
import time
|
||||
from pybma400 import BMA400
|
||||
|
||||
def main():
|
||||
# Initialize the sensor
|
||||
try:
|
||||
sensor = BMA400() # Default I2C bus=1, address=0x14
|
||||
print("BMA400 sensor initialized successfully!")
|
||||
|
||||
# Configure the sensor
|
||||
sensor.power_mode = BMA400.NORMAL_MODE
|
||||
sensor.output_data_rate = BMA400.ACCEL_100HZ
|
||||
sensor.acc_range = BMA400.ACC_RANGE_4 # ±4g range
|
||||
|
||||
print(f"Power mode: {sensor.power_mode}")
|
||||
print(f"Output data rate: {sensor.output_data_rate}")
|
||||
print(f"Acceleration range: {sensor.acc_range}")
|
||||
print(f"Filter bandwidth: {sensor.filter_bandwidth}")
|
||||
print(f"Oversampling rate: {sensor.oversampling_rate}")
|
||||
|
||||
# Read and display sensor data
|
||||
for i in range(10):
|
||||
# Read acceleration
|
||||
x, y, z = sensor.acceleration
|
||||
print(f"Acceleration: X={x:.2f}, Y={y:.2f}, Z={z:.2f} m/s²")
|
||||
|
||||
# Read temperature
|
||||
temp = sensor.temperature
|
||||
print(f"Temperature: {temp:.1f}°C")
|
||||
|
||||
time.sleep(0.5)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
44
examples/orientation_detection.py
Normal file
44
examples/orientation_detection.py
Normal file
@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Example of using PyBMA400 to detect orientation changes.
|
||||
This shows how to use the watcher module to detect flips between
|
||||
landscape and portrait orientations.
|
||||
"""
|
||||
import asyncio
|
||||
from pybma400 import BMA400, detect_orientation_flip, is_landscape
|
||||
|
||||
async def main():
|
||||
try:
|
||||
# Initialize the sensor
|
||||
sensor = BMA400() # Default I2C bus=1, address=0x14
|
||||
print("BMA400 sensor initialized successfully!")
|
||||
|
||||
# Start with the current orientation state
|
||||
current_state = is_landscape(sensor.acceleration)
|
||||
print(f"Initial orientation: {'Landscape' if current_state else 'Portrait'}")
|
||||
|
||||
# Monitor for orientation changes
|
||||
while True:
|
||||
print("Monitoring for orientation changes...")
|
||||
|
||||
# Call the detect_orientation_flip function with our sensor
|
||||
# We'll use is_landscape as our evaluation function
|
||||
new_state = await detect_orientation_flip(
|
||||
current_state=current_state,
|
||||
eval_func=is_landscape,
|
||||
flip_delay=0.5, # Shorter delay for demonstration purposes
|
||||
sensor=sensor
|
||||
)
|
||||
|
||||
# Update our state
|
||||
if new_state != current_state:
|
||||
current_state = new_state
|
||||
print(f"Orientation changed to: {'Landscape' if current_state else 'Portrait'}")
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\nMonitoring stopped by user")
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
11
pyBMA400/__init__.py
Normal file
11
pyBMA400/__init__.py
Normal file
@ -0,0 +1,11 @@
|
||||
"""
|
||||
PyBMA400 - Python driver for the Bosch BMA400 accelerometer.
|
||||
|
||||
This package provides a Python interface for the Bosch BMA400 accelerometer,
|
||||
allowing reading of acceleration data and configuration of sensor parameters.
|
||||
"""
|
||||
|
||||
from .driver import BMA400
|
||||
from .watcher import detect_orientation_flip, is_landscape, is_inverted
|
||||
|
||||
__version__ = "0.1.1"
|
||||
363
pyBMA400/driver.py
Normal file
363
pyBMA400/driver.py
Normal file
@ -0,0 +1,363 @@
|
||||
# bma400.py - BMA400 Accelerometer Library for Python
|
||||
|
||||
import time
|
||||
import struct
|
||||
from typing import Tuple, Optional, Union, List
|
||||
|
||||
try:
|
||||
import smbus
|
||||
except ImportError:
|
||||
pass # Allow for non-Raspberry Pi environments
|
||||
|
||||
|
||||
class BMA400:
|
||||
"""
|
||||
Python driver for the Bosch BMA400 Accelerometer.
|
||||
|
||||
This library provides access to the BMA400 accelerometer over I2C,
|
||||
allowing reading of acceleration data and configuration of sensor parameters.
|
||||
|
||||
:param i2c_bus: The I2C bus number (usually 1 on Raspberry Pi 3+)
|
||||
:param address: The I2C device address, defaults to 0x14
|
||||
"""
|
||||
|
||||
# Register addresses
|
||||
_REG_WHOAMI = 0x00
|
||||
_ACC_CONFIG0 = 0x19
|
||||
_ACC_CONFIG1 = 0x1A
|
||||
_ACC_CONFIG2 = 0x1B
|
||||
_ACCEL_DATA = 0x04
|
||||
_TEMP_DATA = 0x11
|
||||
|
||||
# Constants for conversion
|
||||
_ACC_CONVERSION = 9.80665 # Convert to m/s²
|
||||
|
||||
# Power mode values
|
||||
SLEEP_MODE = 0x00
|
||||
LOW_POWER_MODE = 0x01
|
||||
NORMAL_MODE = 0x02
|
||||
SWITCH_TO_SLEEP = 0x03
|
||||
|
||||
# Output data rate values
|
||||
ACCEL_12_5HZ = 0x05
|
||||
ACCEL_25HZ = 0x06
|
||||
ACCEL_50HZ = 0x07
|
||||
ACCEL_100HZ = 0x08
|
||||
ACCEL_200HZ = 0x09
|
||||
ACCEL_400HZ = 0xA4
|
||||
ACCEL_800HZ = 0xB8
|
||||
|
||||
# Filter bandwidth values
|
||||
ACC_FILT_BW0 = 0x00 # 0.48 x ODR
|
||||
ACC_FILT_BW1 = 0x01 # 0.24 x ODR
|
||||
|
||||
# Oversampling values
|
||||
OVERSAMPLING_0 = 0x00
|
||||
OVERSAMPLING_1 = 0x01
|
||||
OVERSAMPLING_2 = 0x02
|
||||
OVERSAMPLING_3 = 0x03
|
||||
|
||||
# Acceleration range values
|
||||
ACC_RANGE_2 = 0x00 # ±2g
|
||||
ACC_RANGE_4 = 0x01 # ±4g
|
||||
ACC_RANGE_8 = 0x02 # ±8g
|
||||
ACC_RANGE_16 = 0x03 # ±16g
|
||||
|
||||
# Range factors for converting raw values
|
||||
_acc_range_factor = {
|
||||
ACC_RANGE_2: 1024,
|
||||
ACC_RANGE_4: 512,
|
||||
ACC_RANGE_8: 256,
|
||||
ACC_RANGE_16: 128
|
||||
}
|
||||
|
||||
# Data source register values
|
||||
ACC_FILT1 = 0x00
|
||||
ACC_FILT2 = 0x01
|
||||
ACC_FILT_LP = 0x02
|
||||
|
||||
def __init__(self, i2c_bus: int = 1, address: int = 0x14):
|
||||
"""
|
||||
Initialize the BMA400 sensor.
|
||||
|
||||
:param i2c_bus: The I2C bus number
|
||||
:param address: The I2C device address
|
||||
:raises RuntimeError: If the sensor is not found
|
||||
"""
|
||||
self._bus = smbus.SMBus(i2c_bus)
|
||||
self._address = address
|
||||
|
||||
# Check device ID
|
||||
device_id = self._read_byte(BMA400._REG_WHOAMI)
|
||||
if device_id != 0x90:
|
||||
raise RuntimeError(f"Failed to find BMA400, got device ID: 0x{device_id:02X}")
|
||||
|
||||
# Initialize with default settings
|
||||
self._power_mode = self.NORMAL_MODE
|
||||
self._acc_range = self.ACC_RANGE_2
|
||||
self._output_data_rate = self.ACCEL_100HZ
|
||||
self._oversampling_rate = self.OVERSAMPLING_3
|
||||
self._filter_bandwidth = self.ACC_FILT_BW0
|
||||
self._source_data_registers = self.ACC_FILT1
|
||||
|
||||
# Apply default settings
|
||||
self._write_register_bits(self._ACC_CONFIG0, 0, 2, self._power_mode)
|
||||
self._write_register_bits(self._ACC_CONFIG0, 7, 1, self._filter_bandwidth)
|
||||
self._write_register_bits(self._ACC_CONFIG1, 0, 4, self._output_data_rate)
|
||||
self._write_register_bits(self._ACC_CONFIG1, 4, 2, self._oversampling_rate)
|
||||
self._write_register_bits(self._ACC_CONFIG1, 6, 2, self._acc_range)
|
||||
self._write_register_bits(self._ACC_CONFIG2, 2, 2, self._source_data_registers)
|
||||
|
||||
def _read_byte(self, register: int) -> int:
|
||||
"""Read a single byte from the specified register"""
|
||||
return self._bus.read_byte_data(self._address, register)
|
||||
|
||||
def _read_bytes(self, register: int, length: int) -> List[int]:
|
||||
"""Read multiple bytes from the specified register"""
|
||||
return self._bus.read_i2c_block_data(self._address, register, length)
|
||||
|
||||
def _write_byte(self, register: int, value: int) -> None:
|
||||
"""Write a single byte to the specified register"""
|
||||
self._bus.write_byte_data(self._address, register, value)
|
||||
|
||||
def _write_register_bits(self, register: int, pos: int, length: int, value: int) -> None:
|
||||
"""
|
||||
Write specific bits in a register
|
||||
|
||||
:param register: Register address
|
||||
:param pos: Position of the LSB (0-indexed)
|
||||
:param length: Number of bits to modify
|
||||
:param value: Value to write
|
||||
"""
|
||||
current = self._read_byte(register)
|
||||
mask = (1 << length) - 1
|
||||
current &= ~(mask << pos) # Clear the bits
|
||||
current |= (value & mask) << pos # Set the bits
|
||||
self._write_byte(register, current)
|
||||
|
||||
def _read_register_bits(self, register: int, pos: int, length: int) -> int:
|
||||
"""
|
||||
Read specific bits from a register
|
||||
|
||||
:param register: Register address
|
||||
:param pos: Position of the LSB (0-indexed)
|
||||
:param length: Number of bits to read
|
||||
:return: Value of the specified bits
|
||||
"""
|
||||
value = self._read_byte(register)
|
||||
mask = (1 << length) - 1
|
||||
return (value >> pos) & mask
|
||||
|
||||
@property
|
||||
def power_mode(self) -> str:
|
||||
"""
|
||||
Get the current power mode.
|
||||
|
||||
:return: String describing the current power mode
|
||||
"""
|
||||
mode = self._read_register_bits(self._ACC_CONFIG0, 0, 2)
|
||||
modes = ["SLEEP_MODE", "LOW_POWER_MODE", "NORMAL_MODE", "SWITCH_TO_SLEEP"]
|
||||
return modes[mode]
|
||||
|
||||
@power_mode.setter
|
||||
def power_mode(self, value: int) -> None:
|
||||
"""
|
||||
Set the power mode.
|
||||
|
||||
:param value: Power mode value (use BMA400.XXX_MODE constants)
|
||||
:raises ValueError: If the value is invalid
|
||||
"""
|
||||
if value not in [self.SLEEP_MODE, self.LOW_POWER_MODE, self.NORMAL_MODE, self.SWITCH_TO_SLEEP]:
|
||||
raise ValueError("Value must be a valid power mode setting")
|
||||
self._write_register_bits(self._ACC_CONFIG0, 0, 2, value)
|
||||
self._power_mode = value
|
||||
|
||||
@property
|
||||
def output_data_rate(self) -> str:
|
||||
"""
|
||||
Get the current output data rate.
|
||||
|
||||
:return: String describing the current output data rate
|
||||
"""
|
||||
odr = self._read_register_bits(self._ACC_CONFIG1, 0, 4)
|
||||
rates = {
|
||||
0x05: "ACCEL_12_5HZ",
|
||||
0x06: "ACCEL_25HZ",
|
||||
0x07: "ACCEL_50HZ",
|
||||
0x08: "ACCEL_100HZ",
|
||||
0x09: "ACCEL_200HZ",
|
||||
0xA4: "ACCEL_400HZ",
|
||||
0xB8: "ACCEL_800HZ"
|
||||
}
|
||||
return rates.get(odr, f"UNKNOWN (0x{odr:02X})")
|
||||
|
||||
@output_data_rate.setter
|
||||
def output_data_rate(self, value: int) -> None:
|
||||
"""
|
||||
Set the output data rate.
|
||||
|
||||
:param value: Output data rate value (use BMA400.ACCEL_XXX constants)
|
||||
:raises ValueError: If the value is invalid
|
||||
"""
|
||||
valid_values = [self.ACCEL_12_5HZ, self.ACCEL_25HZ, self.ACCEL_50HZ,
|
||||
self.ACCEL_100HZ, self.ACCEL_200HZ, self.ACCEL_400HZ,
|
||||
self.ACCEL_800HZ]
|
||||
if value not in valid_values:
|
||||
raise ValueError("Value must be a valid output data rate setting")
|
||||
self._write_register_bits(self._ACC_CONFIG1, 0, 4, value)
|
||||
self._output_data_rate = value
|
||||
|
||||
@property
|
||||
def oversampling_rate(self) -> str:
|
||||
"""
|
||||
Get the current oversampling rate.
|
||||
|
||||
:return: String describing the current oversampling rate
|
||||
"""
|
||||
osr = self._read_register_bits(self._ACC_CONFIG1, 4, 2)
|
||||
rates = ["OVERSAMPLING_0", "OVERSAMPLING_1", "OVERSAMPLING_2", "OVERSAMPLING_3"]
|
||||
return rates[osr]
|
||||
|
||||
@oversampling_rate.setter
|
||||
def oversampling_rate(self, value: int) -> None:
|
||||
"""
|
||||
Set the oversampling rate.
|
||||
|
||||
:param value: Oversampling rate value (use BMA400.OVERSAMPLING_X constants)
|
||||
:raises ValueError: If the value is invalid
|
||||
"""
|
||||
if value not in [self.OVERSAMPLING_0, self.OVERSAMPLING_1,
|
||||
self.OVERSAMPLING_2, self.OVERSAMPLING_3]:
|
||||
raise ValueError("Value must be a valid oversampling rate setting")
|
||||
self._write_register_bits(self._ACC_CONFIG1, 4, 2, value)
|
||||
self._oversampling_rate = value
|
||||
|
||||
@property
|
||||
def acc_range(self) -> str:
|
||||
"""
|
||||
Get the current acceleration range.
|
||||
|
||||
:return: String describing the current acceleration range
|
||||
"""
|
||||
range_val = self._read_register_bits(self._ACC_CONFIG1, 6, 2)
|
||||
ranges = ["ACC_RANGE_2", "ACC_RANGE_4", "ACC_RANGE_8", "ACC_RANGE_16"]
|
||||
return ranges[range_val]
|
||||
|
||||
@acc_range.setter
|
||||
def acc_range(self, value: int) -> None:
|
||||
"""
|
||||
Set the acceleration range.
|
||||
|
||||
:param value: Acceleration range value (use BMA400.ACC_RANGE_X constants)
|
||||
:raises ValueError: If the value is invalid
|
||||
"""
|
||||
if value not in [self.ACC_RANGE_2, self.ACC_RANGE_4,
|
||||
self.ACC_RANGE_8, self.ACC_RANGE_16]:
|
||||
raise ValueError("Value must be a valid acceleration range setting")
|
||||
self._write_register_bits(self._ACC_CONFIG1, 6, 2, value)
|
||||
self._acc_range = value
|
||||
|
||||
@property
|
||||
def filter_bandwidth(self) -> str:
|
||||
"""
|
||||
Get the current filter bandwidth.
|
||||
|
||||
:return: String describing the current filter bandwidth
|
||||
"""
|
||||
bw = self._read_register_bits(self._ACC_CONFIG0, 7, 1)
|
||||
bandwidths = ["ACC_FILT_BW0", "ACC_FILT_BW1"]
|
||||
return bandwidths[bw]
|
||||
|
||||
@filter_bandwidth.setter
|
||||
def filter_bandwidth(self, value: int) -> None:
|
||||
"""
|
||||
Set the filter bandwidth.
|
||||
|
||||
:param value: Filter bandwidth value (use BMA400.ACC_FILT_BWx constants)
|
||||
:raises ValueError: If the value is invalid
|
||||
"""
|
||||
if value not in [self.ACC_FILT_BW0, self.ACC_FILT_BW1]:
|
||||
raise ValueError("Value must be a valid filter bandwidth setting")
|
||||
self._write_register_bits(self._ACC_CONFIG0, 7, 1, value)
|
||||
self._filter_bandwidth = value
|
||||
|
||||
@property
|
||||
def source_data_registers(self) -> str:
|
||||
"""
|
||||
Get the current source data register setting.
|
||||
|
||||
:return: String describing the current source data register
|
||||
"""
|
||||
src = self._read_register_bits(self._ACC_CONFIG2, 2, 2)
|
||||
sources = ["ACC_FILT1", "ACC_FILT2", "ACC_FILT_LP"]
|
||||
return sources[src] if src < len(sources) else f"UNKNOWN (0x{src:02X})"
|
||||
|
||||
@source_data_registers.setter
|
||||
def source_data_registers(self, value: int) -> None:
|
||||
"""
|
||||
Set the source data register.
|
||||
|
||||
:param value: Source data register value (use BMA400.ACC_FILT_X constants)
|
||||
:raises ValueError: If the value is invalid
|
||||
"""
|
||||
if value not in [self.ACC_FILT1, self.ACC_FILT2, self.ACC_FILT_LP]:
|
||||
raise ValueError("Value must be a valid source data register setting")
|
||||
self._write_register_bits(self._ACC_CONFIG2, 2, 2, value)
|
||||
self._source_data_registers = value
|
||||
|
||||
@property
|
||||
def acceleration(self) -> Tuple[float, float, float]:
|
||||
"""
|
||||
Get the current acceleration measurements in m/s².
|
||||
|
||||
:return: Tuple of (x, y, z) acceleration values
|
||||
"""
|
||||
# Read 6 bytes (2 bytes per axis, x, y, z)
|
||||
data = self._read_bytes(self._ACCEL_DATA, 6)
|
||||
|
||||
# Convert data to 16-bit signed integers
|
||||
rawx = (data[1] << 8) | data[0]
|
||||
rawy = (data[3] << 8) | data[2]
|
||||
rawz = (data[5] << 8) | data[4]
|
||||
|
||||
# Apply two's complement if needed
|
||||
if rawx > 2047:
|
||||
rawx -= 4096
|
||||
if rawy > 2047:
|
||||
rawy -= 4096
|
||||
if rawz > 2047:
|
||||
rawz -= 4096
|
||||
|
||||
# Convert to m/s² based on range setting
|
||||
factor = self._acc_range_factor[self._acc_range] * self._ACC_CONVERSION
|
||||
|
||||
return (rawx / factor, rawy / factor, rawz / factor)
|
||||
|
||||
@property
|
||||
def temperature(self) -> float:
|
||||
"""
|
||||
Get the current temperature in Celsius.
|
||||
The temperature sensor is calibrated with a precision of ±5°C.
|
||||
|
||||
:return: Temperature in Celsius
|
||||
"""
|
||||
raw_temp = self._read_byte(self._TEMP_DATA)
|
||||
|
||||
# Apply two's complement for 8-bit value
|
||||
if raw_temp > 127:
|
||||
raw_temp -= 256
|
||||
|
||||
# Convert to Celsius according to datasheet
|
||||
return (raw_temp * 0.5) + 23.0
|
||||
|
||||
def soft_reset(self) -> None:
|
||||
"""
|
||||
Perform a soft reset of the sensor.
|
||||
This resets all registers to their default values.
|
||||
"""
|
||||
# Command register and soft reset command
|
||||
CMD_REG = 0x7E
|
||||
SOFT_RESET_CMD = 0xB6
|
||||
|
||||
self._write_byte(CMD_REG, SOFT_RESET_CMD)
|
||||
time.sleep(0.2) # Wait for reset to complete
|
||||
54
pyBMA400/watcher.py
Normal file
54
pyBMA400/watcher.py
Normal file
@ -0,0 +1,54 @@
|
||||
import asyncio
|
||||
from .driver import BMA400
|
||||
|
||||
def is_landscape(accel):
|
||||
x, y, z = accel
|
||||
# Return True if device is in landscape orientation
|
||||
return abs(x) > abs(y)
|
||||
|
||||
def is_inverted(accel):
|
||||
x, y, z = accel
|
||||
# Return True if device is in landscape orientation
|
||||
return 0 > abs(y)
|
||||
|
||||
async def detect_orientation_flip(current_state: bool, eval_func, flip_delay: float = 1.0, sensor = None) -> bool:
|
||||
"""
|
||||
Asynchronously detect orientation flip using the BMA400 accelerometer.
|
||||
|
||||
Args:
|
||||
current_state (bool): The current orientation state.
|
||||
eval_func (Callable[[tuple], bool]): A function that evaluates the acceleration (x, y, z)
|
||||
and returns True if flipped, False otherwise.
|
||||
flip_delay (float): Delay in seconds after detecting a flip before confirming the state change.
|
||||
|
||||
Returns:
|
||||
bool: The updated orientation state.
|
||||
"""
|
||||
try:
|
||||
# Initialize sensor if not provided
|
||||
if sensor is None:
|
||||
sensor = BMA400()
|
||||
|
||||
sensor.power_mode = BMA400.LOW_POWER_MODE
|
||||
sensor.output_data_rate = BMA400.ACCEL_12_5HZ
|
||||
sensor.acc_range = BMA400.ACC_RANGE_2
|
||||
sensor.oversampling_rate = BMA400.OVERSAMPLING_0
|
||||
|
||||
while True:
|
||||
accel = sensor.acceleration
|
||||
flipped = eval_func(accel)
|
||||
|
||||
if flipped != current_state:
|
||||
# Possible orientation change detected, wait for confirmation
|
||||
await asyncio.sleep(flip_delay)
|
||||
|
||||
# Check again to confirm
|
||||
accel = sensor.acceleration
|
||||
if eval_func(accel) == flipped:
|
||||
return flipped
|
||||
|
||||
await asyncio.sleep(0.1) # Polling interval
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
return current_state
|
||||
29
pyproject.toml
Normal file
29
pyproject.toml
Normal file
@ -0,0 +1,29 @@
|
||||
[build-system]
|
||||
requires = ["setuptools>=42", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "pybma400"
|
||||
description = "Python driver for the Bosch BMA400 accelerometer"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.6"
|
||||
license = "MIT"
|
||||
authors = [
|
||||
{name = "Duncan Tourolle", email = "duncan@tourolle.paris"}
|
||||
]
|
||||
classifiers = [
|
||||
"Programming Language :: Python :: 3",
|
||||
"Operating System :: OS Independent",
|
||||
"Topic :: System :: Hardware",
|
||||
]
|
||||
dependencies = [
|
||||
"smbus-cffi; platform_system!='Windows'",
|
||||
]
|
||||
dynamic = ["version"]
|
||||
|
||||
[tool.setuptools]
|
||||
packages = ["pybma400"]
|
||||
package-dir = {"pybma400" = "pyBMA400"}
|
||||
|
||||
[tool.setuptools.dynamic]
|
||||
version = {attr = "pyBMA400.__version__"}
|
||||
26
setup.py
Normal file
26
setup.py
Normal file
@ -0,0 +1,26 @@
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
with open("README.md", "r", encoding="utf-8") as fh:
|
||||
long_description = fh.read()
|
||||
|
||||
setup(
|
||||
name="pybma400",
|
||||
version="0.1.1",
|
||||
author="Duncan Tourolle",
|
||||
description="Python driver for the Bosch BMA400 accelerometer",
|
||||
long_description=long_description,
|
||||
long_description_content_type="text/markdown",
|
||||
url="https://gitea.tourolle.paris/dtourolle/PyBMA400",
|
||||
packages=["pybma400"],
|
||||
package_dir={"pybma400": "pyBMA400"},
|
||||
classifiers=[
|
||||
"Programming Language :: Python :: 3",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Operating System :: OS Independent",
|
||||
"Topic :: System :: Hardware",
|
||||
],
|
||||
python_requires=">=3.6",
|
||||
install_requires=[
|
||||
"smbus-cffi; platform_system!='Windows'",
|
||||
],
|
||||
)
|
||||
Loading…
x
Reference in New Issue
Block a user