我正在开发一个基于终端、RPI 控制的传感器阵列项目!问题是,我是一名临时 Java 开发人员,没有使用 Python 的经验,而且我的所有组件都在后者上运行。以下脚本包含我用来确保相关五个设备均正常运行的代码。目前,我想做的是将它们合并到一个文件中,该文件在执行时生成一个简单的 HUD,聚合并显示每个板的实时数字读数(或者在 MLX90640 的情况下为 ASCII 艺术) .
# i2c = board.STEMMA_I2C() # For using the built-in STEMMA QT connector on a m>
bme680 = adafruit_bme680.Adafruit_BME680_I2C(i2c, debug=False)
# change this to match the location's pressure (hPa) at sea level
bme680.sea_level_pressure = 1013.25
# You will usually have to add an offset to account for the temperature of
# the sensor. This is usually around 5 degrees but varies by use. Use a
# separate temperature sensor to calibrate this one.
temperature_offset = -5
while True:
print("\nTemperature: %0.1f C" % (bme680.temperature + temperature_offset))
print("Gas: %d ohm" % bme680.gas)
print("Humidity: %0.1f %%" % bme680.relative_humidity)
print("Pressure: %0.3f hPa" % bme680.pressure)
print("Altitude = %0.2f meters" % bme680.altitude)
time.sleep(1)
# SPDX-FileCopyrightText: 2020 Bryan Siepert, written for Adafruit Industries
#
# SPDX-License-Identifier: Unlicense
import time
import board
import busio
from adafruit_bno08x import (
BNO_REPORT_ACCELEROMETER,
BNO_REPORT_GYROSCOPE,
BNO_REPORT_MAGNETOMETER,
BNO_REPORT_ROTATION_VECTOR,
)
from adafruit_bno08x.i2c import BNO08X_I2C
i2c = busio.I2C(board.SCL, board.SDA, frequency=400000)
bno = BNO08X_I2C(i2c)
bno.enable_feature(BNO_REPORT_ACCELEROMETER)
bno.enable_feature(BNO_REPORT_GYROSCOPE)
bno.enable_feature(BNO_REPORT_MAGNETOMETER)
while True:
time.sleep(0.5)
print("Acceleration:")
accel_x, accel_y, accel_z = bno.acceleration # pylint:disable=no-member
print("X: %0.6f Y: %0.6f Z: %0.6f m/s^2" % (accel_x, accel_y, accel_z))
print("")
print("Gyro:")
gyro_x, gyro_y, gyro_z = bno.gyro # pylint:disable=no-member
print("X: %0.6f Y: %0.6f Z: %0.6f rads/s" % (gyro_x, gyro_y, gyro_z))
print("")
print("Magnetometer:")
mag_x, mag_y, mag_z = bno.magnetic # pylint:disable=no-member
print("X: %0.6f Y: %0.6f Z: %0.6f uT" % (mag_x, mag_y, mag_z))
print("")
print("Rotation Vector Quaternion:")
quat_i, quat_j, quat_k, quat_real = bno.quaternion # pylint:disable=no-mem>
print(
"I: %0.6f J: %0.6f K: %0.6f Real: %0.6f" % (quat_i, quat_j, quat_k, q>
)
print("")
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT
import time
import board
import busio
import adafruit_mlx90640
PRINT_TEMPERATURES = False
PRINT_ASCIIART = True
i2c = busio.I2C(board.SCL, board.SDA, frequency=800000)
mlx = adafruit_mlx90640.MLX90640(i2c)
print("MLX addr detected on I2C")
print([hex(i) for i in mlx.serial_number])
mlx.refresh_rate = adafruit_mlx90640.RefreshRate.REFRESH_2_HZ
frame = [0] * 768
while True:
stamp = time.monotonic()
try:
mlx.getFrame(frame)
except ValueError:
# these happen, no biggie - retry
continue
print("Read 2 frames in %0.2f s" % (time.monotonic() - stamp))
for h in range(24):
for w in range(32):
t = frame[h * 32 + w]
if PRINT_TEMPERATURES:
print("%0.1f, " % t, end="")
if PRINT_ASCIIART:
c = "&"
# pylint: disable=multiple-statements
if t < 20:
c = " "
elif t < 23:
c = "."
elif t < 25:
c = "-"
elif t < 27:
c = "*"
elif t < 29:
c = "+"
elif t < 31:
c = "x"
elif t < 33:
c = "%"
elif t < 35:
c = "#"
elif t < 37:
c = "X"
# pylint: enable=multiple-statements
print(c, end="")
print()
print()
import time
import sys
import board
import busio
import adafruit_gps
i2c = board.I2C()
gps = adafruit_gps.GPS_GtopI2C(i2c, debug=False) # Use I2C interface
# Initialize the GPS module by changing what data it sends and at what rate.
gps.send_command(b"PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0")
# Turn on just minimum info (RMC only, location):
# gps.send_command(b'PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0')
# Turn off everything:
# gps.send_command(b'PMTK314,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0')
# Turn on everything (not all of it is parsed!)
# gps.send_command(b'PMTK314,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0')
# Set update rate to once a second (1hz) which is what you typically want.
gps.send_command(b"PMTK220,1000")
# Or decrease to once every two seconds by doubling the millisecond value.
# Be sure to also increase your UART timeout above!
# gps.send_command(b'PMTK220,2000')
# You can also speed up the rate, but don't go too fast or else you can lose
# data during parsing. This would be twice a second (2hz, 500ms delay):
# gps.send_command(b'PMTK220,500')
# Main loop runs forever printing the location, etc. every second.
last_print = time.monotonic()
while True:
gps.update()
current = time.monotonic()
if current - last_print >= 1.0:
last_print = current
if not gps.has_fix:
# Try again if we don't have a fix yet.
print("Waiting for fix...")
continue
# We have a fix! (gps.has_fix is true)
# Print out details about the fix like location, date, etc.
print("=" * 40) # Print a separator line.
print(
"Fix timestamp: {}/{}/{} {:02}:{:02}:{:02}".format(
gps.timestamp_utc.tm_mon, # Grab parts of the time from the
gps.timestamp_utc.tm_mday, # struct_time object that holds
gps.timestamp_utc.tm_year, # the fix time. Note you might
gps.timestamp_utc.tm_hour, # not get all data like year, day,
gps.timestamp_utc.tm_min, # month!
gps.timestamp_utc.tm_sec,
)
)
print("Latitude: {0:.6f} degrees".format(gps.latitude))
print("Longitude: {0:.6f} degrees".format(gps.longitude))
print(
"Precise Latitude: {} degs, {:2.4f} mins".format(
gps.latitude_degrees, gps.latitude_minutes
)
)
print(
"Precise Longitude: {} degs, {:2.4f} mins".format(
gps.longitude_degrees, gps.longitude_minutes
)
)
print("Fix quality: {}".format(gps.fix_quality))
# Some attributes beyond latitude, longitude and timestamp are optional
# and might not be present. Check if they're None before trying to use!
if gps.satellites is not None:
print("# satellites: {}".format(gps.satellites))
if gps.altitude_m is not None:
print("Altitude: {} meters".format(gps.altitude_m))
if gps.speed_knots is not None:
print("Speed: {} knots".format(gps.speed_knots))
if gps.track_angle_deg is not None:
print("Track angle: {} degrees".format(gps.track_angle_deg))
if gps.horizontal_dilution is not None:
print("Horizontal dilution: {}".format(gps.horizontal_dilution))
if gps.height_geoid is not None:
print("Height geoid: {} meters".format(gps.height_geoid))
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT
import time
import board
from adafruit_apds9960.apds9960 import APDS9960
i2c = board.I2C() # uses board.SCL and board.SDA
# i2c = board.STEMMA_I2C() # For using the built-in STEMMA QT connector on a m>
apds = APDS9960(i2c)
apds.enable_proximity = True
while True:
print(apds.proximity)
time.sleep(0.2)
ChatGPT 和我尝试了一下并取得了一些成果,但最终并没有走得太远。我们一起设法从数组中获取数据,显示它,并按一定时间间隔刷新它。 但是,这里出了问题。
import subprocess
import time
import sys
# Define functions to run each sensor script and capture its ou>
def run_sensor_script(script_name):
return subprocess.Popen([sys.executable, script_name], stdo>
# Define HUD display function
def display_hud(sensor_outputs):
# Parse and display data from each sensor
for sensor_name, output in sensor_outputs.items():
print(f"--- {sensor_name} ---")
print(output.decode().strip()) # Print decoded output >
print() # Add newline for clarity
if __name__ == "__main__":
# Define the list of sensor scripts to run
sensor_scripts = {
"BME680": "i2c-air-test.py",
"BNO08X": "i2c-dof-test.py",
"MLX90640": "i2c-ir-test.py",
"GPS": "i2c-gps-test.py",
"APDS9960": "i2c-light-test.py"
}
# Start subprocesses for each sensor script
sensor_processes = {name: run_sensor_script(script) for nam>
try:
while True:
# Read output from each sensor subprocess
sensor_outputs = {name: proc.stdout.readline() for >
# Display the HUD with live sensor readouts
display_hud(sensor_outputs)
# Wait a short interval before updating HUD (adjust>
time.sleep(1)
except KeyboardInterrupt:
# Terminate all subprocesses if the program is interrup>
for proc in sensor_processes.values():
proc.terminate()
*/home/raziel/i2c-example/i2c/lib/python3.11/site-packages/adafruit_blinka/microcontroller/generic_linux/i2c.py:30: RuntimeWarning: I2C frequency is not settable in python, ignoring!
warnings.warn(
/home/raziel/i2c-example/i2c/lib/python3.11/site-packages/adafruit_blinka/microcontroller/generic_linux/i2c.py:30: RuntimeWarning: I2C frequency is not settable in python, ignoring!
warnings.warn(
Traceback (most recent call last):
File "/home/raziel/i2c-example/i2c-array-test/i2c-dof-test.py", line 26, in <module>
accel_x, accel_y, accel_z = bno.acceleration # pylint:disable=no-member
^^^^^^^^^^^^^^^^
File "/home/raziel/.local/lib/python3.11/site-packages/adafruit_bno08x/__init__.py", line 598, in acceleration
self._process_available_packets()
File "/home/raziel/.local/lib/python3.11/site-packages/adafruit_bno08x/__init__.py", line 803, in _process_available_packets
self._handle_packet(new_packet)
File "/home/raziel/.local/lib/python3.11/site-packages/adafruit_bno08x/__init__.py", line 863, in _handle_packet
raise error
File "/home/raziel/.local/lib/python3.11/site-packages/adafruit_bno08x/__init__.py", line 858, in _handle_packet
_separate_batch(packet, self._packet_slices)
File "/home/raziel/.local/lib/python3.11/site-packages/adafruit_bno08x/__init__.py", line 373, in _separate_batch
required_bytes = _report_length(report_id)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/raziel/.local/lib/python3.11/site-packages/adafruit_bno08x/__init__.py", line 362, in _report_length
return _AVAIL_SENSOR_REPORTS[report_id][2]
~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
KeyError: 123*
========================================
--- APDS9960 ---
0
--- BME680 ---
Pressure: 995.852 hPa
--- BNO08X ---
--- MLX90640 ---
************-*-*-*---*-*--******
--- GPS ---
Fix timestamp: 4/14/2024 03:39:43
--- APDS9960 ---
0
--- BME680 ---
Altitude = 145.87 meters
--- BNO08X ---
--- MLX90640 ---
*********-**--***---------***-**
--- GPS ---
Latitude: 32.963751 degrees
--- APDS9960 ---
0
--- BME680 ---
--- BNO08X ---
--- MLX90640 ---
**********-*-*-*-------*---*-***
--- GPS ---
Longitude: -96.697693 degrees
--- APDS9960 ---
0
--- BME680 ---
Temperature: 21.0 C
--- BNO08X ---
--- MLX90640 ---
*********--**-**------*-*-*-*-**
--- GPS ---
Precise Latitude: 32 degs, 57.8251 mins
--- APDS9960 ---
0
--- BME680 ---
Gas: 69245 ohm
--- BNO08X ---
--- MLX90640 ---
**********-**--*---*---*-***--**
--- GPS ---
Precise Longitude: -96 degs, 41.8616 mins
--- APDS9960 ---
0
--- BME680 ---
Humidity: 39.6 %
--- BNO08X ---
--- MLX90640 ---
*********---*-***-*----*--***-**
--- GPS ---
Fix quality: 2
--- APDS9960 ---
0
--- BME680 ---
Pressure: 995.853 hPa
--- BNO08X ---
--- MLX90640 ---
****************-----*-*--**-***
--- GPS ---
# satellites: 7
--- APDS9960 ---
1
--- BME680 ---
Altitude = 145.86 meters
--- BNO08X ---
--- MLX90640 ---
*********-**--**---**-*---**-***
--- GPS ---
Altitude: 204.1 meters
--- APDS9960 ---
0
--- BME680 ---
--- BNO08X ---
--- MLX90640 ---
************-****--***-*--**-***
--- GPS ---
Speed: 0.93 knots
--- APDS9960 ---
0
--- BME680 ---
Temperature: 21.1 C
--- BNO08X ---
--- MLX90640 ---
*************-**---*****--******
--- GPS ---
Track angle: 65.26 degrees
--- APDS9960 ---
0
--- BME680 ---
Gas: 69811 ohm
--- BNO08X ---
--- MLX90640 ---
************-***-*-*************
--- GPS ---
Horizontal dilution: 1.25
--- APDS9960 ---
0
--- BME680 ---
Humidity: 39.5 %
--- BNO08X ---
--- MLX90640 ---
*************-***-**************
--- GPS ---
Height geoid: -24.1 meters
--- APDS9960 ---
0
--- BME680 ---
Pressure: 995.855 hPa
--- BNO08X ---
--- MLX90640 ---
************-***-***************
--- GPS ---
========================================
--- APDS9960 ---
0
--- BME680 ---
Altitude = 145.84 meters
--- BNO08X ---
--- MLX90640 ---
--- GPS ---
Fix timestamp: 4/14/2024 03:39:45
--- APDS9960 ---
0
--- BME680 ---
--- BNO08X ---
--- MLX90640 ---
Read 2 frames in 1.23 s
--- GPS ---
Latitude: 32.963746 degrees
--- APDS9960 ---
0
--- BME680 ---
Temperature: 21.1 C
--- BNO08X ---
--- MLX90640 ---
++***************************+**
--- GPS ---
Longitude: -96.697683 degrees
--- APDS9960 ---
0
--- BME680 ---
Gas: 69868 ohm
--- BNO08X ---
--- MLX90640 ---
x++*****************************
--- GPS ---
Precise Latitude: 32 degs, 57.8248 mins
--- APDS9960 ---
0
--- BME680 ---
Humidity: 39.5 %
--- BNO08X ---
--- MLX90640 ---
#%++****************************
--- GPS ---
Precise Longitude: -96 degs, 41.8610 mins
--- APDS9960 ---
0
--- BME680 ---
Pressure: 995.851 hPa
--- BNO08X ---
--- MLX90640 ---
#%x+*************************-**
--- GPS ---
Fix quality: 2
--- APDS9960 ---
0
--- BME680 ---
Altitude = 145.88 meters
--- BNO08X ---
--- MLX90640 ---
%%xx+*****-***********-*--******
--- GPS ---
# satellites: 7
--- APDS9960 ---
0
--- BME680 ---
--- BNO08X ---
--- MLX90640 ---
xxxx++***************--**-**--**
--- GPS ---
Altitude: 204.1 meters
--- APDS9960 ---
0
--- BME680 ---
Temperature: 21.1 C
--- BNO08X ---
--- MLX90640 ---
xx+x+++*****-*****-*-*-*-****--*
--- GPS ---
Speed: 0.33 knots
--- APDS9960 ---
0
--- BME680 ---
Gas: 70271 ohm
--- BNO08X ---
--- MLX90640 ---
xx++++***-**--***-**--**-*******
--- GPS ---
Track angle: 65.26 degrees
--- APDS9960 ---
0
--- BME680 ---
Humidity: 39.5 %
--- BNO08X ---
--- MLX90640 ---
++++******-*-***--*---*---******
--- GPS ---
Horizontal dilution: 1.25
--- APDS9960 ---
0
--- BME680 ---
Pressure: 995.855 hPa
--- BNO08X ---
--- MLX90640 ---
++********--*-***---*-**-*******
--- GPS ---
Height geoid: -24.1 meters
--- APDS9960 ---
0
--- BME680 ---
Altitude = 145.84 meters
--- BNO08X ---
--- MLX90640 ---
**********-*---*-------*--***-**
--- GPS ---
您遇到的很可能是硬件限制,如此讨论所示。
您有几个脚本几乎同时尝试访问 i2c,并且全部实例化新的 i2c 总线,您可能会因此感到头疼。
由于您的某些脚本有 1 秒的延迟,我假设速度或时间对此应用程序并不重要。上面的线程提到一一运行每个脚本并捕获脚本输出,而不是尝试维护 4 个活动子进程,每个子进程都尝试访问 i2c 硬件。
如果您的所有 i2c 设备都可以以相同的时钟速度运行(例如 100000Hz,默认 rpi),您可以尝试创建 i2c 总线的单个实例并在传感器类之间共享该实例。这意味着有一个脚本实例化并读取所有传感器。