课设-风速传感器 ESP32+MicroPython

该文描述了一个使用ESP32微控制器进行风速测量的课程设计项目。通过模拟风速(使用直流电机),ADC读取风杯式风速传感器的电压,然后利用PWM控制电机转速。此外,文章还涉及到使用MicroPython编程实现OLED显示、蓝牙通信以及风速的计算和警告功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传感器课程设计,老师布置做风速传感器。要求测0.5m/s-30m/s的风速,选用风杯式风速传感器,用ESP32片内ADC。关于风嘛,哪里有30m/s的风给我测哦,就拿直流电机模拟一个算了。ESP32读取外接电位器的电压值,用这个电压控制输出PWM波的占空比,送到TB6612电机驱动模块去控制风扇转速。风扇吹动风速传感器,带动内部直流发电机发电,ADC读这个电压,经过标定就知道风速了(模拟的)。

from machine import Pin, PWM, ADC, SoftI2C, Timer
import utime
from font import Font
from sd1306 import SSD1306_I2C, SSD1306
import bluetooth

#OLED部分
i2c = SoftI2C(scl=Pin(2), sda=Pin(1))
display= SSD1306_I2C(128, 32, i2c)
oled=Font(display)

#PWM
PWMOut = PWM(Pin(21)) #LED&驱动电机PWM
PWMOut.freq(1000)
#AD
Uin=ADC(Pin(11))      #电位器AD
Wind=ADC(Pin(10))     #风速传感器AD
Uin.width(ADC.WIDTH_12BIT) #读取的电压转为0-4096;ADC.WIDTH_9BIT:0-511
Uin.atten(ADC.ATTN_11DB)   #衰减设置范围:无衰减
Wind.width(ADC.WIDTH_12BIT) #读取的电压转为0-4096;ADC.WIDTH_9BIT:0-511
Wind.atten(ADC.ATTN_0DB)   #衰减设置范围:无衰减
#Wind_factor = 1.1 / (65535)
Resistor_factor = 3.3 / (65535)

#蓝牙部分
BLE_MSG = ""

class ESP32_BLE():
    def __init__(self, name):
        self.led = Pin(36,Pin.OUT)
        self.timer1 = Timer(0)
        self.name = name
        self.ble = bluetooth.BLE()
        self.ble.active(True)
        self.ble.config(gap_name=name)
        self.disconnected()
        self.ble.irq(self.ble_irq)
        self.register()
        self.advertiser()

    def connected(self):
        self.led.value(0)
        self.timer1.deinit()

    def disconnected(self):
#        self.timer1.init(period=100, mode=Timer.PERIODIC, callback=lambda t: self.led.duty(500))
        self.led.value(1)
    def ble_irq(self, event, data):
        global BLE_MSG
        if event == 1: #_IRQ_CENTRAL_CONNECT 手机链接了此设备
            self.connected()
        elif event == 2: #_IRQ_CENTRAL_DISCONNECT 手机断开此设备
            self.advertiser()
            self.disconnected()
        elif event == 3: #_IRQ_GATTS_WRITE 手机发送了数据 
            buffer = self.ble.gatts_read(self.rx)
            BLE_MSG = buffer.decode('UTF-8').strip()
            
    def register(self):        
        service_uuid = '6E400001-B5A3-F393-E0A9-E50E24DCCA9E'
        reader_uuid = '6E400002-B5A3-F393-E0A9-E50E24DCCA9E'
        sender_uuid = '6E400003-B5A3-F393-E0A9-E50E24DCCA9E'

        services = (
            (
                bluetooth.UUID(service_uuid), 
                (
                    (bluetooth.UUID(sender_uuid), bluetooth.FLAG_NOTIFY), 
                    (bluetooth.UUID(reader_uuid), bluetooth.FLAG_WRITE),
                )
            ), 
        )

        ((self.tx, self.rx,), ) = self.ble.gatts_register_services(services)

    def send(self, data):
        self.ble.gatts_notify(1, self.tx, data + '\n')

    def advertiser(self):
        name = bytes(self.name, 'UTF-8')
        adv_data = bytearray('\x02\x01\x02') + bytearray((len(name) + 1, 0x09)) + name
        self.ble.gap_advertise(100, adv_data)
        print(adv_data)
        print("\r\n")


def calculate_average(numbers):
    if len(numbers) < 3:
        return None  # 返回None表示无法计算平均值

#    numbers = [float(num) for num in numbers.split(",")]
    numbers.remove(max(numbers))
    numbers.remove(min(numbers))

    average = sum(numbers) / len(numbers)
    return average

def Get_list():
    values = []  # 创建一个空列表用于存储值
    for i in range(0,30,1):
        utime.sleep_ms(2)
        ValueWind = Wind.read_u16()  # 风速AD
        Wind_voltage = Wind.read_u16() * 1.1 / 65535
        
        value = float(Wind_voltage)
        values.append(value)
    return values #返回包含30个风速电压值的列表

def Wind_Speed():
    Number_List=Get_list()
    Vaverage=calculate_average(Number_List)
    if Vaverage >= 0.01 and  Vaverage <= 0.096:   #1
        WSpeed=37.02*Vaverage+0.3089
    elif Vaverage > 0.096 and Vaverage <= 0.166:  #2
        WSpeed=99.98*Vaverage-5.446
    elif Vaverage > 0.166 and Vaverage <= 0.175:  #3
        WSpeed=42.41*Vaverage+4.529
    elif Vaverage > 0.175 and Vaverage <= 0.208:  #4
        WSpeed=154.5*Vaverage-14.23
    elif Vaverage > 0.208 and Vaverage <= 0.255:  #5
        WSpeed=151.5*Vaverage-14.27
    elif Vaverage > 0.255:                        #6
        WSpeed=269.1*Vaverage-42.47
    else:
        WSpeed=0
    return WSpeed

ble = ESP32_BLE("ESP32S3_WindSpeed")
led = Pin(36)

warning_counter=0
while True:
    Number_List=Get_list()
    Vaverage=calculate_average(Number_List) #风速传感器输出平均电压
    VGet=Wind_Speed()
    for i in range(0,1000,1):
        utime.sleep_ms(1)
        ValueResistor=Uin.read_u16()    #读电位器
        PWMOut.duty_u16(ValueResistor)  #输出给风扇
        Ur=ValueResistor*Resistor_factor#电位器电压
        VDisplay=round(VGet,2)          
        if BLE_MSG == 'Getwindspeed': #手机蓝牙发送的信息
            BLE_MSG = ""              #Message清空
            ble.send(str(VDisplay))        #发送风速到手机蓝牙
        if i==999:
            if VDisplay == 0:    
                oled.text('0.000', 0, 5, 24)
                oled.text('m/s', 80, 5, 24)
                oled.show()
            else:
                if VDisplay >=30:    
                    warning_counter += 1
                    if warning_counter >= 5:
                        ble.send('Warning')
                        warning_counter = 0 
                else:
                    warning_counter = 0
                oled.text('{:.3f}'.format(VDisplay), 0, 5, 24)
                oled.text('m/s', 80, 5, 24)
                oled.show()
                print("电位器电压:{:.3f}V,传感器电压:{:.3f}V".format(Ur, Vaverage))  # Convert Ur and Vaverage to strings with 3 decimal places
                

OLED部分,用了大字体的程序,参考自oled屏自定义大小字体 micropython 使用 - 哔哩哔哩    

在此谢谢大佬。

### 使用 ESP8266 连接风速传感器进行数据采集 #### 1. 硬件准备与连接 为了实现 ESP8266 和风速传感器的集成,需完成以下硬件准备工作: - **ESP8266 模块**:用于无线通信和数据处理。 - **风速传感器**:提供风速测量信号。常见的风速传感器有模拟量输出型(电压或电流)和数字脉冲输出型。 - **电源管理**:确保两者供电稳定且匹配。 对于模拟量输出型传感器,通常将其输出端接到 ESP8266 的 ADC 输入引脚(如 A0)。如果是数字脉冲型,则可以接入 GPIO 引脚,并配置中断或定时器计数功能[^1]。 #### 2. 初始化与校验 在程序启动阶段,应初始化传感器接口并验证其工作状态。例如,如果使用的是模拟传感器,可以通过读取初始值判断是否存在异常情况: ```cpp int sensorPin = A0; // 定义传感器连接至A0引脚 void setup() { Serial.begin(9600); // 开启串口调试 } void loop() { int sensorValue = analogRead(sensorPin); // 读取ADC数值 float voltage = sensorValue * (5.0 / 1023.0); // 将ADC转换为实际电压 Serial.println(voltage, 2); // 打印电压值保留两位小数 delay(1000); } ``` 上述代码片段展示了如何利用 Arduino IDE 编程框架下的 `analogRead` 函数获取模拟输入值,并进一步计算对应的物理量。 #### 3. 数据有效性检查 由于外部干扰或其他原因可能导致错误读数,在正式应用前应对每次采样结果实施合理性检验。比如定上下限阈值过滤掉明显偏离正常范围的数据点。 #### 4. Wi-Fi 配置与联网 为了让 ESP8266 成功加入局域网并与云端服务器交互,必须先完成 WiFi 置过程。下面给出一段简单的WiFi连接示范代码: ```cpp #include <ESP8266WiFi.h> const char* ssid = "your_SSID"; // 替换为您自己的Wi-Fi SSID const char* password = "your_PASSWORD"; // 替换为您自己的Wi-Fi密码 void setup() { Serial.begin(115200); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("Connected to the WiFi network"); } void loop(){} ``` 此部分实现了基本的 WiFi 接入逻辑,持续尝试直到成功为止。 #### 5. 构造 JSON 并上传 当收集到有效的风速信息之后,下一步就是把这些数据打包成易于解析的形式传送给远程服务端。推荐采用轻量化结构化的表述方式—JSON格式来进行表达。借助第三方库简化操作流程如下所示: ```cpp #include <ArduinoJson.h> // 假已经定义好了变量 windSpeed 存储当前测得的风速值... StaticJsonDocument<200> doc; doc["sensor"] = "Wind Speed"; doc["value"] = windSpeed; doc["unit"] = "m/s"; String output; serializeJson(doc, output); Serial.println(output); ``` 以上实例创建了一个小型文档对象包含了三个字段分别代表传感类别、具体数值以及计量单位;最后一步把整个内容序列化成为字符串形式以便后续传输用途。 #### 6. Modbus 协议支持(可选) 针对某些工业级产品可能基于标准通讯协议运作的情况,像引用提到的例子那样涉及到 RS485 总线加上 MODBUS RTU 规范的情形下,则还需要额外学习掌握该类技术细节才能顺利完成对接任务[^2]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值