使用ESP32C3自制简易潜水手表,可显示水深,温度,以及海拔高度

一、结构设计

       潜水手表结构分为上盖与底壳两部分如图一所示。潜水表整体结构如图二所示,蓝色的为触摸屏,白灰色的是电池,绿色的是PCB,黑灰色的是传感器,红色的是磁吸触点。

图一
图二

二、硬件设计   

1.核心部件

      1)主控:选用 ESP32C3H4 作为主控,自带4MB闪存,无需外加闪存,节省布局空间。需要外加40Mhz的晶振电路,

      2)电源:选用 AXP2101 作为PMU,可给电池充电,输出DCDC、LDO给主控以及外设供电,通过I2C可配置输出电压大小(调节屏幕亮度等)、读取电池电量以及重启电源和关掉电源。

      3)传感器:选用ST的压力传感器:LPS28DFWTR。可检测气压与温度,检测部位防水,最大量程4060 hPa,理论最大检测水深为310.6m。

      4)触摸屏:1.28寸圆屏,240*240屏幕,SPI接口,显示驱动GC9A01,触摸驱动CST816T。

      5)RTC:   选用 PCF8563MM/TR,封装较小,节省空间(MSOP-8)。

      6)电池:100mAh,21*11*4mm。

2.电路部分

1. 只使用一路I2C连接所有外设,包括触摸屏的触摸引脚(TP-SCL、TP-SDA)。两路I2C同时使用好像有问题。

2. RTC供电使用一颗LDO芯片供电,电池电压直接接到LDO的输入端。未找到AXP2101的RTCLDO输出电压的配置寄存器。

3.主控的GPIO9接按键接地。IO9拉低,主控上电进入Boot模式,通过串口烧录。

三、软件部分

1.安装对应的库

    使用Arduino IDE进行编程,在库管理栏搜索外设对应的库,如图三所示

图三

2.初始化代码

#define axp_ADDRESS 0x34

void setup()
{
    //初始化串口
    Serial.begin(115200);
    //指定I2C引脚进行初始化
    Wire.begin(1,0);
    //屏幕触控初始化
    touch.begin();
    //初始化PMU
    axp2101_init();
    //初始化屏幕
    tft.init();                               //初始化
    tft.fillScreen(TFT_BLACK); 
    tft.setSwapBytes(true);             //使图片颜色由RGB->BGR
    tft.setRotation(4);
    //初始化LPS28DFW
    while(pressureSensor.begin(i2cAddress) != LPS28DFW_OK)
    {
        Serial.println("Error: LPS28DFW not connected, check wiring and I2C address!");
        tft.drawString("LPS Err", 30, 90);
        delay(1000);
    }
    //配置为最大量程4060hPa
    pressureSensor.setModeConfig(&modeConfig2);
    //初始化Preferences,读取Flash里面的变量
    preferences.begin("my-app", false);
    max_long_time = preferences.getInt("mylongtime", 0); // 默认值为0
    max_depth = preferences.getFloat("mymaxdetpth", 0); 
    max_depth_time =preferences.getFloat("mymaxdetpthtime", 0); 
    preferences.end();

}

3.AXP2101的配置

//PMU初始化
void axp2101_init()
 {
  //set_axp2101_r(0x16,0);//输入电流限制100ma
  set_axp2101_r(0x20,0x04);//充电时开机  set_axp2101_r(0x20,0x06)
  set_axp2101_r(0x21,0x02);//使能软件关机
  set_axp2101_r(0x61,0x01);//预充电电流限制25ma
  set_axp2101_r(0x62,0x02);//恒流充电电流限制50ma
  set_axp2101_r(0x63,0x10);//终止电流限制0ma
  set_axp2101_r(0x80,0x01);//只使能DCDC1
  set_axp2101_r(0x92,0x1c);//配置aldo1输出为3.3v
  set_axp2101_r(0x94,0x17);//配置aldo3-LCD输出为2.8v
 }
//获取电池电量
void get_bat_power()
 {
   power_data=get_data_axp2101(0xA4);
   if(power_data>100)
        power_data=100;
 }
//往寄存器写入
void set_axp2101_r(uint8_t sub,uint8_t data)
 {
  Wire.beginTransmission(axp_ADDRESS); 		
  Wire.write(sub);        		
  Wire.write(data);              	
  Wire.endTransmission();
 }
//读取寄存器的值
uint8_t get_data_axp2101(uint8_t sub)
 {
 // 读取寄存器的当前值
  Wire.beginTransmission(axp_ADDRESS);
  Wire.write(sub);
  Wire.endTransmission();
  Wire.requestFrom(axp_ADDRESS, 1);
  uint8_t regValue = Wire.read();
  Wire.endTransmission();
  return regValue;
 }

4.传感器数据的读取与计算

1)海拔计算

计算海拔高度通常需要使用标准大气压公式或经验公式。一个常用的方法是使用国际标准大气层(ISA)模型中的公式,该公式假定温度随高度线性变化并给出了一种近似的计算方法。以下是一个常用的经验公式,用于根据海平面气压和实际测量的气压计算海拔高度:

                                       

其中:

  • h 是海拔高度(米)
  • T0是海平面标准温度(K),通常为 288.15 K
  • L 是对流层内的温度递减率(K/m),通常为 0.0065 K/m
  • P 是测量的气压(Pa)
  • P0​ 是海平面标准气压(Pa),通常为 101325 Pa
  • R是通用气体常数,8.3144598 J/(mol·K)
  • g是重力加速度,9.80665 m/s²
  • M 是空气的摩尔质量,0.0289644 kg/mo
 2)水深计算

要根据已知的压力计算海水的深度,可以使用类似的方法。假设海水的密度为常数(通常为1025 kg/m³,取决于温度和盐度),并且压力是绝对压力。

                                

其中:

  • d 是水深(米)
  • P 是测量的绝对压力(帕斯卡,Pa)
  • P0​ 是海平面上的大气压力(帕斯卡,Pa),通常为101325 Pa
  • ρ 是海水的密度(公斤/立方米,kg/m³),通常为1025 kg/m³
  • g 是重力加速度(米/秒²,m/s²),通常取9.80665 m/s²

3)代码 

//更新数据
pressureSensor.getSensorData();
Pressure = pressureSensor.data.pressure.hpa;

//计算水深
float  deph = (   (Pressure*100 - 101325) / (1025.0 * 9.8)    ); 

//计算海拔
float height =get_altitude(Pressure , pressureSensor.data.heat.deg_c); 
float get_altitude(float CurrentPressure,float CurrentTemperature)
     {   
         return (float)(1.0-pow((CurrentPressure / 1013.25), (1.0 / 5.255)) ) * (CurrentTemperature + 273.15) / 0.0065;  
     }

四、效果

                 

  • 22
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用ESP32C3驱动SPS30粉尘传感器,您需要连接传感器到ESP32C3微控制器上,并使用串行总线通信进行通信。以下是基本的步骤: 1. 连接SPS30到ESP32C3:将SPS30的VCC,GND,RX,TX引脚连接到ESP32C3的相应引脚上。 2. 安装串行通信库:在ESP32C3上安装支持Modbus RTU协议的串行通信库,例如Arduino的Modbus RTU库。 3. 配置SPS30参数:使用Modbus RTU协议向SPS30发送命令和参数,以配置其参数,例如测量周期、粉尘浓度单位和数据输出格式。 4. 读取SPS30数据:使用Modbus RTU协议从SPS30读取数据,并将其解析为可用的浓度值。 下面是一个示例代码,演示如何使用ESP32C3和Arduino的Modbus RTU库来驱动SPS30传感器: ```c++ #include <ModbusRTU.h> // Define SPS30 Modbus RTU address #define SPS30_ADDRESS 0x63 // Define SPS30 Modbus RTU function codes #define SPS30_START_MEASUREMENT 0x0010 #define SPS30_READ_MEASUREMENT 0x0300 #define SPS30_STOP_MEASUREMENT 0x0104 // Define SPS30 measurement data structure struct SPS30Measurement { uint16_t pm10; uint16_t pm25; uint16_t pm40; uint16_t pm100; }; // Create Modbus RTU instance ModbusRTU mb; void setup() { // Initialize serial communication Serial.begin(9600); // Initialize Modbus RTU communication mb.begin(9600, SERIAL_8N1, 16, 17); // Configure SPS30 measurement parameters mb.writeHoldingRegisters(SPS30_ADDRESS, 0x0006, 0x0001); // Set measurement mode to continuous mb.writeHoldingRegisters(SPS30_ADDRESS, 0x0008, 0x0000); // Set measurement interval to 1 second } void loop() { // Start SPS30 measurement mb.writeHoldingRegisters(SPS30_ADDRESS, SPS30_START_MEASUREMENT, 0x0001); // Wait for measurement to complete delay(1000); // Read SPS30 measurement data uint16_t data[10]; mb.readHoldingRegisters(SPS30_ADDRESS, SPS30_READ_MEASUREMENT, 10, data); // Stop SPS30 measurement mb.writeHoldingRegisters(SPS30_ADDRESS, SPS30_STOP_MEASUREMENT, 0x0001); // Parse SPS30 measurement data SPS30Measurement measurement; measurement.pm10 = data[0]; measurement.pm25 = data[1]; measurement.pm40 = data[2]; measurement.pm100 = data[3]; // Print SPS30 measurement data Serial.print("PM 1.0: "); Serial.print(measurement.pm10); Serial.print(" ug/m3, PM 2.5: "); Serial.print(measurement.pm25); Serial.print(" ug/m3, PM 4.0: "); Serial.print(measurement.pm40); Serial.print(" ug/m3, PM 10: "); Serial.print(measurement.pm100); Serial.println(" ug/m3"); // Wait for next measurement delay(9000); } ``` 请注意,此示例代码仅提供了基本的SPS30驱动程序。要实现更高级的功能,例如错误处理和数据校验,请参考SPS30数据手册和Modbus RTU协议规范。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值