Class_Terminate的缺陷

本文探讨了VB6中Class对象的生命周期管理问题,特别是在对象相互引用导致无法正常卸载时的解决方案。通过实例演示如何避免Terminate事件触发不当,并提供了一种主动释放资源的方法。

vb(6)的class在卸载前会触发Terminate事件,于是可以将一些卸载前需要处理的代码放到这里来,在object卸载时自动执行,这样子看上去很美,可以偷懒了.可是在某些情况下会有很大问题,请看下面的两个类,Class1,Class2 

' ====    Class1    ====
Option   Explicit

Private  m_cc  As  Class2

Public   Sub  Init() Sub  Init(cc  As  Class2)
Set  m_cc  =  cc
End Sub

Private   Sub  Class_Terminate()
Set  m_cc  =   Nothing
End Sub

 

' ====    Class2    ====
Option   Explicit

Private  m_cc  As  Class1

Public   Sub  Init() Sub  Init(cc  As  Class1)
Set  m_cc  =  cc
End Sub

Private   Sub  Class_Terminate()
Set  m_cc  =   Nothing
End Sub

 两个类都有一个成员变量m_cc,类型分别是另一个Class,如果这样使用

dim  c1  as  Class1 , c2  as  Class2
set  c1 = new  Class1
set  c2 = new  Class2
c1.Init c2
c2.Init c1

这样一来,即使将c1,c2都置为Nothing,对象都不会被卸载,因为各自的m_CC都有对另一个对象的引用,从而也不会触发Terminate事件.另外,事实上在Terminate中才将 m_cc置为Nothing 是没什么意义的,当该对象卸载后,它的成员变量也自然会被释放.当然这个例子有点极端,一般不会这样子用,但有些时候可能在不知不觉中就出现了这种状况,另外有些时候触发Terminate事件会比预期的时间晚了,从而也会存在问题,所以为了避免出现上面的情况,最好是在卸载前主动的处理卸载前需要做的事情,而不要完全依赖于vb的回收系统(是这么叫吧?大家都应该明白的啦),于是大概代码改为, 

====     Class1     ====
Option   Explicit

Private  m_cc  As  Class2

Public   Sub  Init() Sub  Init(cc  As  Class2)
Set  m_cc  =  cc
End Sub

Private   Sub  Class_Terminate()
Call  ReleaseMe
End Sub

Private   Sub  ReleaseMe()
Set  m_cc  =   Nothing
End Sub

准备卸载前调用一下ReleaseMe,这样就好很多了.

by lingll
http://blog.youkuaiyun.com/lingll/
lingll_xl@163.com
2006-12-4

import os import time import threading import RPi.GPIO as GPIO import cv2 import numpy as np import pyaudio import vosk import json import serial import pynmea2 import datetime import sqlite3 from pathlib import Path import logging import sys # ------------------- 硬件与模型配置 ------------------- BUZZER_PIN = 18 # BCM模式 FREQ_LOW = 1000 FREQ_HIGH = 2000 BUZZER_DURATION = 60 # 蜂鸣器持续秒数 PIR_PIN = 17 # BCM模式 FACE_CASCADE_PATH = '/home/pi/.local/lib/python3.7/site-packages/cv2/data/haarcascade_frontalface_alt2.xml' PROFILE_CASCADE_PATH = '/home/pi/.local/lib/python3.7/site-packages/cv2/data/haarcascade_profileface.xml' VOSK_MODEL_PATH = "/home/pi/vosk-model-small-cn-0.22" # ------------------- 全局变量 ------------------- pwm = None detection_triggered = False # 检测到人/救命标记 buzzer_active = False # 蜂鸣器运行标记 cap = None # 全局摄像头对象 face_cascade = None # 全局人脸分类器 profile_cascade = None # 全局侧脸分类器 # ------------------- 蜂鸣器控制 ------------------- def setup_buzzer(): global pwm GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) GPIO.setup(BUZZER_PIN, GPIO.OUT) pwm = GPIO.PWM(BUZZER_PIN, FREQ_LOW) def run_buzzer(): global buzzer_active, detection_triggered buzzer_active = True pwm.start(50) start_time = time.time() while (time.time() - start_time < BUZZER_DURATION) and buzzer_active and not detection_triggered: pwm.ChangeFrequency(FREQ_LOW) time.sleep(0.5) pwm.ChangeFrequency(FREQ_HIGH) time.sleep(0.5) pwm.stop() buzzer_active = False # ------------------- PIR + 人脸检测 ------------------- def setup_pir(): GPIO.setup(PIR_PIN, GPIO.IN) def setup_camera_and_cascades(): global cap, face_cascade, profile_cascade cap = cv2.VideoCapture(0) if not cap.isOpened(): print("错误:摄像头无法打开!") return False cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240) face_cascade = cv2.CascadeClassifier(FACE_CASCADE_PATH) profile_cascade = cv2.CascadeClassifier(PROFILE_CASCADE_PATH) if face_cascade.empty() or profile_cascade.empty(): print("错误:人脸分类器加载失败!") return False print("摄像头+分类器初始化完成") return True def detect_human(): global cap, face_cascade, profile_cascade if not cap or not cap.isOpened(): return False ret, img = cap.read() if not ret: return False img = cv2.flip(img, 1) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=2, minSize=(30, 30)) profiles = profile_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=2, minSize=(30, 30)) if len(faces) > 0 or len(profiles) > 0: print(f"检测到:正脸{len(faces)}个,侧脸{len(profiles)}个") return len(faces) > 0 or len(profiles) > 0 def monitor_pir(): global detection_triggered, buzzer_active print("PIR监控线程启动") while buzzer_active and not detection_triggered: current_val = GPIO.input(PIR_PIN) if current_val == 1: print("PIR检测到活动,持续人脸检测...") if detect_human(): detection_triggered = True print("1(检测到人体)") break time.sleep(0.5) print("PIR监控线程退出") # ------------------- Vosk 人声识别 ------------------- def setup_voice_recognition(): if not os.path.exists(VOSK_MODEL_PATH): print("错误:Vosk模型目录不存在!") return None, None, None model = vosk.Model(VOSK_MODEL_PATH) recognizer = vosk.KaldiRecognizer(model, 16000) p = pyaudio.PyAudio() stream = p.open( format=pyaudio.paInt16, channels=1, rate=16000, input=True, frames_per_buffer=4000, input_device_index=None ) return recognizer, stream, p def monitor_voice(recognizer, stream): global detection_triggered, buzzer_active while buzzer_active and not detection_triggered: data = stream.read(4000, exception_on_overflow=False) if recognizer.AcceptWaveform(data): result = json.loads(recognizer.Result()) text = result.get("text", "").strip() clean_text = text.replace(" ", "").replace("!", "").replace(",", "") if "救命" in clean_text: detection_triggered = True print("1(人声识别到'救命')") break # ------------------- 资源释放 ------------------- def cleanup(): global buzzer_active, detection_triggered, cap buzzer_active = False detection_triggered = False if cap and cap.isOpened(): cap.release() print("摄像头已释放") if pwm: pwm.stop() GPIO.cleanup() cv2.destroyAllWindows() if 'stream' in globals() and 'p_audio' in globals(): stream.stop_stream() stream.close() p_audio.terminate() print("程序已停止,资源已释放") # ------------------- GPS 功能 ------------------- def check_dialout_permission(): try: groups = os.popen('groups').read().strip() if 'dialout' in groups: return True else: logging.warning("当前用户不在dialout组中,可能无法访问串口") logging.warning("请运行: sudo usermod -aG dialout $USER,然后重新登录") return False except Exception as e: logging.warning(f"检查权限时出错: {e}") return False class ATK1218GPS: def __init__(self, port='/dev/ttyS0', baudrate=9600, timeout=2): self.port = port self.baudrate = baudrate self.timeout = timeout self.ser = None self.db_conn = None self.init_database() logging.info(f"配置为使用 {self.port} 串口") def connect(self): try: self.ser = serial.Serial( self.port, self.baudrate, timeout=self.timeout, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, xonxoff=False, rtscts=False ) if self.ser.is_open: logging.info(f"成功连接到GPS模块: {self.port}") return True else: logging.error(f"无法打开 {self.port} 端口") return False except PermissionError: logging.error(f"权限不足,无法访问 {self.port}") logging.error("请确保用户已加入dialout组并重新登录") return False except Exception as e: logging.error(f"连接GPS模块失败: {e}") return False def init_database(self): try: self.db_conn = sqlite3.connect("gps_data/location.db") cursor = self.db_conn.cursor() cursor.execute(''' CREATE TABLE IF NOT EXISTS locations ( id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp DATETIME, latitude REAL, longitude REAL, altitude REAL, satellites INTEGER, speed REAL, course REAL, fix_quality INTEGER ) ''') cursor.execute("PRAGMA table_info(locations)") columns = [column[1] for column in cursor.fetchall()] if 'speed' not in columns: cursor.execute("ALTER TABLE locations ADD COLUMN speed REAL") logging.info("已添加speed列到数据库表") if 'course' not in columns: cursor.execute("ALTER TABLE locations ADD COLUMN course REAL") logging.info("已添加course列到数据库表") self.db_conn.commit() logging.info("数据库初始化成功") except Exception as e: logging.error(f"数据库初始化失败: {e}") def parse_nmea_sentence(self, sentence): try: if not sentence.startswith('$'): return None msg = pynmea2.parse(sentence) if isinstance(msg, pynmea2.GGA): data = { 'timestamp': datetime.datetime.now(), 'latitude': self.convert_to_decimal(msg.lat, msg.lat_dir), 'longitude': self.convert_to_decimal(msg.lon, msg.lon_dir), 'altitude': float(msg.altitude) if msg.altitude else None, 'satellites': int(msg.num_sats) if msg.num_sats else None, 'speed': None, 'course': None, 'fix_quality': int(msg.gps_qual) if msg.gps_qual else 0 } return data elif isinstance(msg, pynmea2.RMC): data = { 'timestamp': datetime.datetime.now(), 'latitude': self.convert_to_decimal(msg.lat, msg.lat_dir), 'longitude': self.convert_to_decimal(msg.lon, msg.lon_dir), 'altitude': None, 'satellites': None, 'speed': float(msg.spd_over_grnd) if msg.spd_over_grnd else None, 'course': float(msg.true_course) if msg.true_course else None, 'fix_quality': 1 if msg.status == 'A' else 0 } return data return None except pynmea2.ParseError: return None except Exception as e: logging.warning(f"解析NMEA数据出错: {e}, 数据: {sentence}") return None def convert_to_decimal(self, value, direction): if not value: return None try: val = float(value) degrees = int(val // 100) minutes = val % 100 decimal_degrees = degrees + minutes / 60 if direction in ['S', 'W']: decimal_degrees = -decimal_degrees return round(decimal_degrees, 6) except: return None def save_location(seimport os import time import threading import RPi.GPIO as GPIO import cv2 import numpy as np import pyaudio import vosk import json import serial import pynmea2 import datetime import sqlite3 from pathlib import Path import logging import sys # ------------------- 硬件与模型配置 ------------------- BUZZER_PIN = 18 # BCM模式 FREQ_LOW = 1000 FREQ_HIGH = 2000 BUZZER_DURATION = 60 # 蜂鸣器持续秒数 PIR_PIN = 17 # BCM模式 FACE_CASCADE_PATH = '/home/pi/.local/lib/python3.7/site-packages/cv2/data/haarcascade_frontalface_alt2.xml' PROFILE_CASCADE_PATH = '/home/pi/.local/lib/python3.7/site-packages/cv2/data/haarcascade_profileface.xml' VOSK_MODEL_PATH = "/home/pi/vosk-model-small-cn-0.22" # ------------------- 全局变量 ------------------- pwm = None detection_triggered = False # 检测到人/救命标记 buzzer_active = False # 蜂鸣器运行标记 cap = None # 全局摄像头对象 face_cascade = None # 全局人脸分类器 profile_cascade = None # 全局侧脸分类器 # ------------------- 蜂鸣器控制 ------------------- def setup_buzzer(): global pwm GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) GPIO.setup(BUZZER_PIN, GPIO.OUT) pwm = GPIO.PWM(BUZZER_PIN, FREQ_LOW) def run_buzzer(): global buzzer_active, detection_triggered buzzer_active = True pwm.start(50) start_time = time.time() while (time.time() - start_time < BUZZER_DURATION) and buzzer_active and not detection_triggered: pwm.ChangeFrequency(FREQ_LOW) time.sleep(0.5) pwm.ChangeFrequency(FREQ_HIGH) time.sleep(0.5) pwm.stop() buzzer_active = False # ------------------- PIR + 人脸检测 ------------------- def setup_pir(): GPIO.setup(PIR_PIN, GPIO.IN) def setup_camera_and_cascades(): global cap, face_cascade, profile_cascade cap = cv2.VideoCapture(0) if not cap.isOpened(): print("错误:摄像头无法打开!") return False cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240) face_cascade = cv2.CascadeClassifier(FACE_CASCADE_PATH) profile_cascade = cv2.CascadeClassifier(PROFILE_CASCADE_PATH) if face_cascade.empty() or profile_cascade.empty(): print("错误:人脸分类器加载失败!") return False print("摄像头+分类器初始化完成") return True def detect_human(): global cap, face_cascade, profile_cascade if not cap or not cap.isOpened(): return False ret, img = cap.read() if not ret: return False img = cv2.flip(img, 1) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=2, minSize=(30, 30)) profiles = profile_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=2, minSize=(30, 30)) if len(faces) > 0 or len(profiles) > 0: print(f"检测到:正脸{len(faces)}个,侧脸{len(profiles)}个") return len(faces) > 0 or len(profiles) > 0 def monitor_pir(): global detection_triggered, buzzer_active print("PIR监控线程启动") while buzzer_active and not detection_triggered: current_val = GPIO.input(PIR_PIN) if current_val == 1: print("PIR检测到活动,持续人脸检测...") if detect_human(): detection_triggered = True print("1(检测到人体)") break time.sleep(0.5) print("PIR监控线程退出") # ------------------- Vosk 人声识别 ------------------- def setup_voice_recognition(): if not os.path.exists(VOSK_MODEL_PATH): print("错误:Vosk模型目录不存在!") return None, None, None model = vosk.Model(VOSK_MODEL_PATH) recognizer = vosk.KaldiRecognizer(model, 16000) p = pyaudio.PyAudio() stream = p.open( format=pyaudio.paInt16, channels=1, rate=16000, input=True, frames_per_buffer=4000, input_device_index=None ) return recognizer, stream, p def monitor_voice(recognizer, stream): global detection_triggered, buzzer_active while buzzer_active and not detection_triggered: data = stream.read(4000, exception_on_overflow=False) if recognizer.AcceptWaveform(data): result = json.loads(recognizer.Result()) text = result.get("text", "").strip() clean_text = text.replace(" ", "").replace("!", "").replace(",", "") if "救命" in clean_text: detection_triggered = True print("1(人声识别到'救命')") break # ------------------- 资源释放 ------------------- def cleanup(): global buzzer_active, detection_triggered, cap buzzer_active = False detection_triggered = False if cap and cap.isOpened(): cap.release() print("摄像头已释放") if pwm: pwm.stop() GPIO.cleanup() cv2.destroyAllWindows() if 'stream' in globals() and 'p_audio' in globals(): stream.stop_stream() stream.close() p_audio.terminate() print("程序已停止,资源已释放") # ------------------- GPS 功能 ------------------- def check_dialout_permission(): try: groups = os.popen('groups').read().strip() if 'dialout' in groups: return True else: logging.warning("当前用户不在dialout组中,可能无法访问串口") logging.warning("请运行: sudo usermod -aG dialout $USER,然后重新登录") return False except Exception as e: logging.warning(f"检查权限时出错: {e}") return False class ATK1218GPS: def __init__(self, port='/dev/ttyS0', baudrate=9600, timeout=2): self.port = port self.baudrate = baudrate self.timeout = timeout self.ser = None self.db_conn = None self.init_database() logging.info(f"配置为使用 {self.port} 串口") def connect(self): try: self.ser = serial.Serial( self.port, self.baudrate, timeout=self.timeout, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, xonxoff=False, rtscts=False ) if self.ser.is_open: logging.info(f"成功连接到GPS模块: {self.port}") return True else: logging.error(f"无法打开 {self.port} 端口") return False except PermissionError: logging.error(f"权限不足,无法访问 {self.port}") logging.error("请确保用户已加入dialout组并重新登录") return False except Exception as e: logging.error(f"连接GPS模块失败: {e}") return False def init_database(self): try: self.db_conn = sqlite3.connect("gps_data/location.db") cursor = self.db_conn.cursor() cursor.execute(''' CREATE TABLE IF NOT EXISTS locations ( id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp DATETIME, latitude REAL, longitude REAL, altitude REAL, satellites INTEGER, speed REAL, course REAL, fix_quality INTEGER ) ''') cursor.execute("PRAGMA table_info(locations)") columns = [column[1] for column in cursor.fetchall()] if 'speed' not in columns: cursor.execute("ALTER TABLE locations ADD COLUMN speed REAL") logging.info("已添加speed列到数据库表") if 'course' not in columns: cursor.execute("ALTER TABLE locations ADD COLUMN course REAL") logging.info("已添加course列到数据库表") self.db_conn.commit() logging.info("数据库初始化成功") except Exception as e: logging.error(f"数据库初始化失败: {e}") def parse_nmea_sentence(self, sentence): try: if not sentence.startswith('$'): return None msg = pynmea2.parse(sentence) if isinstance(msg, pynmea2.GGA): data = { 'timestamp': datetime.datetime.now(), 'latitude': self.convert_to_decimal(msg.lat, msg.lat_dir), 'longitude': self.convert_to_decimal(msg.lon, msg.lon_dir), 'altitude': float(msg.altitude) if msg.altitude else None, 'satellites': int(msg.num_sats) if msg.num_sats else None, 'speed': None, 'course': None, 'fix_quality': int(msg.gps_qual) if msg.gps_qual else 0 } return data elif isinstance(msg, pynmea2.RMC): data = { 'timestamp': datetime.datetime.now(), 'latitude': self.convert_to_decimal(msg.lat, msg.lat_dir), 'longitude': self.convert_to_decimal(msg.lon, msg.lon_dir), 'altitude': None, 'satellites': None, 'speed': float(msg.spd_over_grnd) if msg.spd_over_grnd else None, 'course': float(msg.true_course) if msg.true_course else None, 'fix_quality': 1 if msg.status == 'A' else 0 } return data return None except pynmea2.ParseError: return None except Exception as e: logging.warning(f"解析NMEA数据出错: {e}, 数据: {sentence}") return None def convert_to_decimal(self, value, direction): if not value: return None try: val = float(value) degrees = int(val // 100) minutes = val % 100 decimal_degrees = degrees + minutes / 60 if direction in ['S', 'W']: decimal_degrees = -decimal_degrees return round(decimal_degrees, 6) except: return None def save_location(self, location_data): if not location_data or not self.db_conn: return False try: cursor = self.db_conn.cursor() cursor.execute(''' INSERT INTO locations (timestamp, latitude, longitude, altitude, satellites, speed, course, fix_quality) VALUES (?, ?, ?, ?, ?, ?, ?, ?) ''', ( location_data['timestamp'], location_data['latitude'], location_data['longitude'], location_data['altitude'], location_data['satellites'], location_data['speed'], location_data['course'], location_data['fix_quality'] )) self.db_conn.commit() with open("gps_data/latest_location.txt", "w") as f: f.write(f"时间: {location_data['timestamp']}\n") f.write(f"纬度: {location_data['latitude']}\n") f.write(f"经度: {location_data['longitude']}\n") if location_data['altitude']: f.write(f"海拔: {location_data['altitude']} 米\n") if location_data['speed']: f.write(f"速度: {location_data['speed']} 节\n") f.write(f"航向: {location_data['course']} 度\n") if location_data['satellites']: f.write(f"卫星数量: {location_data['satellites']}\n") f.write(f"定位质量: {location_data['fix_quality']}\n") return True except Exception as e: logging.error(f"保存定位信息失败: {e}") return False def get_location(self, timeout=30): """获取有效位置信息,超时返回None""" if not self.ser or not self.ser.is_open: logging.warning("请先连接GPS模块") return None start_time = time.time() logging.info("开始获取GPS定位...") try: while time.time() - start_time < timeout: data = self.ser.readline().decode('utf-8', errors='ignore').strip() if data: location_data = self.parse_nmea_sentence(data) if location_data and location_data.get('fix_quality', 0) > 0: logging.info(f"成功获取定位: {location_data}") self.save_location(location_data) return location_data time.sleep(0.1) logging.warning("获取GPS定位超时") return None except Exception as e: logging.error(f"获取定位数据出错: {e}") return None def close(self): if self.ser and self.ser.is_open: self.ser.close() logging.info("已关闭GPS模块连接") if self.db_conn: self.db_conn.close() logging.info("已关闭数据库连接") # ------------------- LORA 功能 ------------------- class LoRaReceiver: def __init__(self, port='/dev/ttyACM0', baudrate=9600, timeout=0.1): self.port = port self.baaudrate = baudrate self.timeout = timeout self.ser = None self.running = False def open(self): try: self.ser = serial.Serial(self.port, self.baudrate, timeout=self.timeout) print(f"成功打开串口 {self.ser.name}") self.running = True return True except Exception as e: print(f"打开串口失败:{e}") return False def receive_data(self): if not self.ser or not self.ser.is_open: print("串口未打开,请先调用open()方法") return None if self.ser.in_waiting > 0: try: data = self.ser.read(self.ser.in_waiting).decode('utf-8', errors='ignore') timestamp = time.strftime('%H:%M:%S') return { 'timestamp': timestamp, 'data': data.strip() } except Exception as e: print(f"接收数据错误:{e}") return None return None def close(self): if self.ser and self.ser.is_open: self.ser.close() self.running = False print("串口已关闭") def start_listening(self, callback=None): if not self.open(): return try: print("开始监听LoRa数据... (按Ctrl+C停止)") while self.running: data = self.receive_data() if data: print(f"[{data['timestamp']}] 收到LoRa数据:{data['data']}") if callback and callable(callback): callback(data) time.sleep(0.1) except KeyboardInterrupt: print("\n用户中断监听") finally: self.close() class LoRaSender: def __init__(self, port='/dev/ttyACM0', baud_rate=9600, timeout=1): self.port = port self.baud_rate = baud_rate self.timeout = timeout self.ser = None def open(self): try: self.ser = serial.Serial(self.port, self.baud_rate, timeout=self.timeout) print(f"成功打开串口 {self.ser.name}") return True except Exception as e: print(f"打开串口失败:{e}") return False def send_message(self, message): if not self.ser or not self.ser.is_open: print("串口未打开,请先调用open()方法") return False if not message: print("消息为空,不发送") return False try: self.ser.write(message.encode('utf-8')) print(f"✅ 已发送:{message}") return True except Exception as e: print(f"发送失败:{e}") return False def close(self): if self.ser and self.ser.is_open: self.ser.close() print("串口已关闭") def send_and_close(self, message): try: if self.open(): self.send_message(message) time.sleep(0.1) finally: self.close() # ------------------- 主函数 ------------------- def main(): # 确保数据目录存在 data_dir = Path("gps_data") data_dir.mkdir(exist_ok=True) # 配置日志 logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler("gps_data/gps_log.log"), logging.StreamHandler() ] ) # 检查权限 if not check_dialout_permission(): logging.warning("串口访问权限可能存在问题") # 初始化LoRa接收器 lora_receiver = LoRaReceiver(port='/dev/ttyACM0') # 等待接收LoRa信号 print("等待接收LoRa信号...") lora_receiver.open() try: while True: data = lora_receiver.receive_data() if data: print(f"接收到LoRa信号: {data['data']}") # 如果接收到信号,启动检测流程 start_detection() # 检测完成后退出循环 break time.sleep(1) except KeyboardInterrupt: print("\n用户中断程序") finally: lora_receiver.close() cleanup() def start_detection(): global detection_triggered, buzzer_active # 初始化硬件 setup_buzzer() setup_pir() if not setup_camera_and_cascades(): cleanup() return recognizer, stream, p_audio = setup_voice_recognition() if not recognizer or not stream or not p_audio: cleanup() return # 启动状态 detection_triggered = False buzzer_active = True # 启动线程 buzzer_thread = threading.Thread(target=run_buzzer, daemon=True) pir_thread = threading.Thread(target=monitor_pir, daemon=True) voice_thread = threading.Thread(target=monitor_voice, args=(recognizer, stream), daemon=True) buzzer_thread.start() pir_thread.start() voice_thread.start() # 主线程等待 while buzzer_active and not detection_triggered: time.sleep(1) # 如果检测到人,获取GPS位置并通过LoRa发送 if detection_triggered: # 获取GPS位置 gps = ATK1218GPS(port='/dev/ttyAMA0', baudrate=38400) if gps.connect(): location_data = gps.get_location(timeout=30) gps.close() if location_data: # 格式化位置信息 location_str = f"紧急位置: 纬度 {location_data['latitude']}, 经度 {location_data['longitude']}" if location_data['altitude']: location_str += f", 海拔 {location_data['altitude']}米" # 通过LoRa发送位置信息 lora_sender = LoRaSender(port='/dev/ttyACM0') lora_sender.send_and_close(location_str) else: logging.error("无法获取GPS定位信息") else: logging.error("无法连接GPS模块") # 清理资源 cleanup() if __name__ == '__main__': try: main() except Exception as e: logging.error(f"程序执行出错: {e}") cleanup() sys.exit(1)我把多个入口程序合并成一个主函数入口,按照我的逻辑来写主函数的代码,首先需要用接收函数读出接收到的信息,如果接收到了这个信息以后那么进行原来靠前的_main_块(直接启动就行,不需要再让用户输入1),如果检测到有人就进行GPS的定位,然后读取出GPS的信息以后在通过LORA模块发送函数,把这个信息发送出去。你看我发给你的代码能不能满足我的要求,有什么缺陷,可以订正了一个给我完整
09-11
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值