当前位置: 首页> 文旅> 酒店 > 第一ppt模板网官网_免费合作加工厂_搜索引擎营销sem包括_网页广告调词平台

第一ppt模板网官网_免费合作加工厂_搜索引擎营销sem包括_网页广告调词平台

时间:2025/8/9 17:08:45来源:https://blog.csdn.net/sqzr_ll/article/details/144870674 浏览次数:0次
第一ppt模板网官网_免费合作加工厂_搜索引擎营销sem包括_网页广告调词平台

前言

        改进是无止境的,我迟迟没有装配是因为我一直对我的代码不满意,一改再改。

改进日志类

        这个是在别人的基础上,根据自己的需要稍微改动,难度不大。代码放在gitcode上,详见这里。

改进状态指示灯类

        这是根据自己的想法,在AI的辅助下,经过多次迭代而成。然而我今天又有了新想法,而且很简单,经过测试可行,彻底将以前的结果推翻。那我前几天算不算白折腾?

        起初我是用的嵌套函数,执行外层函数传入Pin对象,返回内层函数,这样就得到该led的专属对象,然后可以传入频率去执行。

        以前测试led的闪烁时都是在主程序里。而我这个项目设计有3个指示灯,我认为需要在另一个线程中循环控制闪烁,于是使用了_thread类。而该类并不完善,使用中出现一个问题就是连接电脑调试时,当点击停止按钮,子线程仍在运行,导致与pico失去联系,只能重新插拔usb。为了避免这个问题又增加了代码的复杂性,最后弄成这样:

"""
功能: 状态指示灯的类, 使灯可以在另一个线程闪烁
最后更新: 241229
"""
import utime
import _threadclass StatusLed():_mainthread_heart_beat_data = 0  #  主线程心跳数据(时间戳)_mainthread_heart_beat_alive = 6  # 超过该时间算主线程退出,秒def __init__(self, led, frequency = 1):self.led = led  # Pin对象       self.blink_frequency = frequency  # 闪烁频率,单位Hzself.cycle_accuracy = 10  # 循环精度,毫秒(每次循环的时间)self.cycle_times = 0  # 改变led状态需要的循环次数self.cycle_count = 0  # 循环计次self.running = False  # 控制是否闪烁的指针self.lock = _thread.allocate_lock()  # 线程锁self.thread_id = None  # 保存线程idself.frequency_to_cycle_times()# 根据频率计算循环次数def frequency_to_cycle_times(self):self.cycle_times = int((1000 / self.blink_frequency)/10)# 心跳数据@classmethoddef heart_beat(cls):cls._mainthread_heart_beat_data = utime.time()# 检测主线程是否存活@propertydef is_mainthread_alive(self):if utime.time() - self.__class__._mainthread_heart_beat_data <= self.__class__._mainthread_heart_beat_alive:return Trueelse:return False# 闪烁def blink(self):while self.running and self.is_mainthread_alive:if self.cycle_count >= self.cycle_times:  # 达到次数,才改变led的状态self.led.toggle()self.cycle_count = 0 else:self.cycle_count += 1utime.sleep_ms(self.cycle_accuracy)self.thread_id = Noneself.led.off() # 退出循环时,关闭灯    # 停止闪烁def stop_blink(self):with self.lock:self.running = False# 等待子线程结束,但是最大等待时间为循环精度start_time = utime.ticks_ms()  # 起始时间while self.thread_id is not None:if utime.ticks_diff(utime.ticks_ms(), start_time) > self.cycle_accuracy:break # 启动闪烁def start_blink(self, frequency=None):if frequency and (0.1 <= frequency <= 100):with self.lock:self.blink_frequency = frequencyself.frequency_to_cycle_times()self.running = Trueif self.thread_id is None:     self.thread_id = _thread.start_new_thread(self.blink, ())else: # 频率为0或设置不符合要求,停止self.stop_blink()# 按档位闪烁def blink_adjust_speed_with_position(self, position):if position == 0:frequency = 0elif position == 1:frequency = 0.25    elif position == 2:frequency = 0.5elif position == 3:    frequency = 1elif position == 4:    frequency = 2elif position == 5:    frequency = 4elif position == 6:    frequency = 8elif position == 7:    frequency = 16elif position == 8:    frequency = 32else:frequency = 0self.start_blink(frequency)# 调试代码
if __name__ == '__main__':from machine import Pinled = StatusLed(Pin(25, Pin.OUT))led.blink_adjust_speed_with_position(8)utime.sleep(20)led.blink_adjust_speed_with_position(0)

        今天我又有新的想法,上面的代码是一个指示灯生成一个实例对象,就要新开一个线程。我可以让多个指示灯共用一个线程,节省资源。

        然而还没等这个想法实施,我又来灵感。项目中我使用Timer类来定时执行读取气象数据并发布到MQTT服务器和校时任务, 为啥我不能用来控制led的闪烁呢? 只要将运行周期设为要闪烁的周期啊。这样就非常简单,根本无需使用_thread,代码如下:

"""
功能: 状态指示灯的类,封装了Timer类,用来来控制led的闪烁
最后更新: 250101
"""
import utime
from machine import Timer, Pinclass StatusLed():def __init__(self, pin_no, period=1000):self.led = Pin(pin_no, Pin.OUT)  # Pin对象       self.default_period = period  # 闪烁周期,毫秒self.timer = Timer()# 执行闪烁, 传入的参数是Timer的要求def do_blink(self, timer):self.led.toggle()# 启动闪烁,传入周期def start_blink(self, period):if period > 0:if period > 10000 or period < 10:  # 超出范围,按默认周期闪烁period = self.default_period           self.timer.init(period=period, mode=Timer.PERIODIC, callback=self.do_blink)else:  # 其他情况表明停止self.stop_blink()  # 停止闪烁def stop_blink(self):self.timer.deinit()self.led.off()  # 停止后指示灯熄灭# 按档位闪烁def blink_with_position(self, position):if position == 1:period = 4000    elif position == 2:period = 2000elif position == 3:    period = 1000elif position == 4:    period = 500elif position == 5:    period = 250elif position == 6:    period = 125elif position == 7:    period = 62elif position == 8:    period = 31else:period = 0self.start_blink(period)        if __name__ == '__main__':green_led = StatusLed(25)for i in range(9):print(f"档位:{i}")green_led.blink_with_position(i)utime.sleep(10)green_led.stop_blink()    

总结

        虽然看起来白折腾,但是没有这个折腾过程,怎么会有这个结果呢?我还体验了使用多线程,对定时器的也有更深的理解。

关键字:第一ppt模板网官网_免费合作加工厂_搜索引擎营销sem包括_网页广告调词平台

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: