ESP32 MicroPython采集模拟传感器数值

使用了 MicroPython 库,通过 定时器(Timer) 和 ADC(模数转换器) 功能来实时读取传感器数据。使用定时器可以实现高精度、非阻塞、低资源消耗的周期性任务,保证实时性和可靠性,特别适用于嵌入式系统中的多任务处理和低功耗场景。

代码如下:

from machine import Pin, ADC, Timer
import utime
 
class Config:
    SENSOR_PINS = [2, 4, 36, 39]  # 定义传感器引脚
    SAMPLING_PERIOD_MS = 20  # 采样周期 (ms)
 
# 初始化传感器函数
def init_sensor(pin):
    """初始化ADC传感器"""
    sensor = ADC(Pin(pin))
    sensor.width(ADC.WIDTH_12BIT)  # 设置12位分辨率,读取范围0-4096
    sensor.atten(ADC.ATTN_11DB)   # 设置衰减,测量范围为0-3.3V
    return sensor
 
def init_sensors(pins):
    """初始化所有传感器"""
    return [init_sensor(pin) for pin in pins]
 
class DataLogger:
    def __init__(self, sensor_pins, sampling_period_ms):
        self.sensors = init_sensors(sensor_pins)
        self.sampling_period_ms = sampling_period_ms
        self.counter = 1
        self.timer = Timer(-1)
 
    def sample_callback(self, timer):
        """定时器回调函数,采集数据"""
        # 获取时间戳
        timestamp = utime.ticks_ms()
 
        # 读取所有传感器值
        sensor_values = [sensor.read_u16() for sensor in self.sensors]
 
        # 打印时间戳、计数和传感器值
        print(f"{timestamp},{self.counter},{','.join(map(str, sensor_values))}")
 
        # 增加计数
        self.counter += 1
 
    def start(self):
        """启动数据采集"""
        self.timer.init(period=self.sampling_period_ms, mode=Timer.PERIODIC, callback=self.sample_callback)
 
    def stop(self):
        """停止数据采集"""
        self.timer.deinit()
 
# 主程序
if __name__ == "__main__":
    logger = DataLogger(Config.SENSOR_PINS, Config.SAMPLING_PERIOD_MS)
 
    try:
        logger.start()
        while True:
            utime.sleep(1)  # 主线程空转,避免退出
    except KeyboardInterrupt:
        logger.stop()
        print("程序已停止")
 

传感器的引脚和采样周期都可以通过配置类Config进行调整,方便扩展和修改配置。如果要增加采集的模拟传感器数量,更改class Config里面的SENSOR_PINS = [2, 4, 36, 39]就可以。

代码讲解:

利用定时器确保在设定的采样周期内周期性地获取传感器数据,能够实时反映传感器的变化。同时由于使用了定时器进行回调,主线程(通过while True空转)不会被阻塞,可以继续执行其他任务,或者在采集停止时优雅地退出。

通过ADC.WIDTH_12BIT设置传感器的输出范围是 0 到 4095,能够提供更高精度的数值。传感器设置了 11dB 的衰减,适用于 0-3.3V 的电压范围,适合大部分传感器应用。传感器的引脚和采样周期都通过配置类Config进行调整,方便扩展和修改配置。DataLogger类封装了数据采集的逻辑,使代码更具可读性和模块化,便于后期扩展或重用。主程序通过utime.sleep(1)使主线程空转,避免程序频繁退出。使用定时器回调的方式减少了主程序的计算负担,从而节省了资源。

优化版代码

加入MAX_SAMPLIE参数,可以自定义每次采集的点数。采集到设定点数时候自动停止采集。

from machine import Pin, ADC, Timer
import utime
 
class Config:
    SENSOR_PINS = [4, 2]  # 定义传感器引脚
    SAMPLING_PERIOD_MS = 20  # 采样周期 (ms)
    MAX_SAMPLES = 1000  # 最大采样次数
 
# 初始化传感器函数
def init_sensor(pin):
    """初始化ADC传感器"""
    sensor = ADC(Pin(pin))
    sensor.width(ADC.WIDTH_12BIT)  # 设置12位分辨率,读取范围0-4096
    sensor.atten(ADC.ATTN_11DB)   # 设置衰减,测量范围为0-3.3V
    return sensor
 
def init_sensors(pins):
    """初始化所有传感器"""
    return [init_sensor(pin) for pin in pins]
 
class DataLogger:
    def __init__(self, sensor_pins, sampling_period_ms, max_samples):
        self.sensors = init_sensors(sensor_pins)
        self.sampling_period_ms = sampling_period_ms
        self.counter = 1
        self.max_samples = max_samples  # 最大采样次数
        self.timer = Timer(-1)
 
    def sample_callback(self, timer):
        """定时器回调函数,采集数据"""
        if self.counter > self.max_samples:
            # 达到最大采样次数,停止定时器
            self.stop()
            print(f"采集完成,共采集数据 {self.max_samples} 次")
            return
 
        # 获取时间戳
        timestamp = utime.ticks_ms()
 
        # 读取所有传感器值
        sensor_values = [sensor.read_u16() for sensor in self.sensors]
 
        # 打印时间戳、计数和传感器值
        print(f"{timestamp},{self.counter},{','.join(map(str, sensor_values))}")
 
        # 增加计数
        self.counter += 1
 
    def start(self):
        """启动数据采集"""
        self.timer.init(period=self.sampling_period_ms, mode=Timer.PERIODIC, callback=self.sample_callback)
 
    def stop(self):
        """停止数据采集"""
        self.timer.deinit()
 
# 主程序
if __name__ == "__main__":
    logger = DataLogger(Config.SENSOR_PINS, Config.SAMPLING_PERIOD_MS, Config.MAX_SAMPLES)
 
    try:
        logger.start()
        while True:
            utime.sleep(1)  # 主线程空转,避免退出
    except KeyboardInterrupt:
        logger.stop()
        print("程序已停止")

增加了最大采样次数MAX_SAMPLES和if判断语句,当counter>max_samples时候,停止采集数据,如果想取消这个功能,把以下代码删掉即可

if self.counter > self.max_samples:
    # 达到最大采样次数,停止定时器
    self.stop()
    print(f"采集完成,共采集数据 {self.max_samples} 次")
    return

来源:https://blog.csdn.net/m0_54740856/article/details/144103457

- 本文内容来自网络,如有侵权,请联系本站处理。

01-11   阅读(4)   评论(0)
 标签: maker ESP32 MicroPython

涨知识
舵机

舵机是一种位置(角度)伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。在高档遥控玩具,如飞机、潜艇模型,遥控机器人中已经得到了普遍应用。

评论:
相关文章
小鹏物联网 MicroPython 智能浇花方案

相信很多人都有把绿植给养死的经历,可能是浇水过多、忘记浇水、较长时间不在家不能浇水等,本文介绍一种可以灵活定制的智能浇花方案。


MicroPython 开发ESP32应用之线程介绍及实例分析

MicroPython 在 ESP32 上支持线程(Thread)功能,通过_thread模块实现。线程允许程序并发执行多个任务,适合处理需要同时运行的场景,例如传感器数据采集和网络通信。


盛思发布掌控板3.0

掌控板3.0升级了主控,还主打AI。带有双麦克风阵列,增加了音频解码芯片,板载了一个1W喇叭,还把之前的单色屏幕换成了1.47寸的彩色屏幕,有更多的可玩性。


ESP32 使用DAC模拟输出完成两路呼吸灯

ESP32的DAC函数可以实现真正的模拟输出。


在 ESP32 上使用 LEDC (PWM)

ESP32 没有Arduino输出 PWM 的 analogWrite(pin, value) 方法,取而代之的 ESP32 有一个 LEDC 来实现PWM功能。


MicroPython PWM类

machine.pwm是MicroPython中用于控制PWM输出的模块之一,它提供了一些方法和属性,用于设置和控制PWM输出的频率、占空比等参数,从而实现对各种应用场景的控制。


Micropython Pin类

Pin 类是 machine 模块下面的一个硬件类,用于对引脚的配置和控制,提供对 GPIO 的操作方法。


Micropython基于ESP32的多线程开发

本文学习如何使用ESP32开发板来进行多线程的开发。


MicroPython SPI类

MicroPython的SPI是一个用于进行串行外设接口总线协议的类。


ESP32 使用 MicroPython:I2C 总线

本文以一个简单的例程帮助大家在 MicroPython 下使用 I2C

搜索
小鹏STEM教研服务

专属教研服务系统,助您构建STEM课程体系,打造一站式教学环境。