电赛__失真度检测-手机App的制作

Android:11.0

IDE:Android Studio

        应2021年信号失真度测量检查装置的题目要求,需要在手机上显示波形,因此需要开发一个手机App来完成。开发方式有多种,出于性能考量这里选择原生开发,同时需具备一点点Android开发的常识。工程代码都放在最后

 BluetoothSend

        开发前由于是初次接触蓝牙模块和使用手机权限,为避免可能的后续问题先开发一个简单的蓝牙收发App,测试一下蓝牙通信。原理很简单,如图

        需注意HC-05模块的VCC最好要接5V,直接使用USB转TTL的3.3V可能未必能驱动。

创建

        选择Empty Activity创建,创建后会有一个简单的Hello模板

        想要开发蓝牙应用,需要申请权限,在AndroidMainfest.xml里需要添加下面这几条权限语句

    <!-- 基础蓝牙权限 -->
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

    <!-- 定位权限(Android 10+ 需要) -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE"/>

    <!-- Android 12+ 需要额外权限 -->
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN"
        android:usesPermissionFlags="neverForLocation"
        tools:targetApi="s" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>

    <!-- 针对Android 13的附近设备权限 -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

        接下来是界面和逻辑代码,以现在大语言模型的智能程度,可以很轻易地让它生成。要求是让它仅在MainActivity里生成界面和逻辑代码,便于我们观察学习。

调试

        蓝牙是手机的底层硬件资源,Android Studio自带的模拟器是基于qemu的,对于蓝牙的支持有限。若想达到理想效果,须真机调试,即在手机上启用USB调试,并连接至电脑。配对成功后,一般会自动选择真机(上方会显示手机型号)

        效果如下:

实测

        蓝牙连接后,在电脑上通过串口助手发送数据(波特率要正确),手机上也能正确接收数据,手机上发送的数据,电脑上也能接收到

查看

        对于使用蓝牙的操作,前面需要做权限检查,用以申请权限

        如果未做权限检查或者不需要做不想做,那么在函数前面需要加个注解

        界面开发使用的是Jetpack Compose,像这种仅使用语言来描述的声明式开发,使用AI可以快速生成相当不错的界面,不符合要求可以短时间内随时改进

        稍微了解一下回调、线程和协程之类的语法,就可以很方便地进行修改了。

        学习过程比较清晰,让AI生成一个简单的案例,然后理解、手动修改,有了新的需求后让AI改进,再尝试理解,形成闭环。

 DistortionMeter

创建

        同理,创建一个Empty Activity工程,这次采用的是MVVM模式。不过处于时间考虑,并没有完全遵循,代码可能写得一坨,能用就行

        基本目录组织如下,主要分成domain(业务逻辑)、ui(界面)和viewmodel(视图模型)三个部分。ui里有三个部分,分别是components(组件)、home(主界面)和theme(主题,但这里没用到)

       

        这里的代码开发不像前面那样,可以用AI直接生成所有代码,而是需要自己对代码框架有个初步认识,知道哪个地方该放哪些代码,需要完成什么样的功能,模块与模块之间如何协同工作。

        划分为不同部分后,再针对某一部分让AI生成代码就具有针对性,更加方便且高效。

代码

        可以安装一个通义灵码的插件,安装后一般在右边的侧边栏。这里面有两种模式,一种是普通的AI对话,另一种则是下面这种AI程序员,添加上下文之后,它会根据要求更改代码,点击更改后的文件即可查看它更改了哪些。如果符合预期点击Accept即可自动应用更改,省去了复制粘贴

        对话框的左下角可以切换不同模型,目前里面只有qwq-plus是推理模型

发送

        开发这个应用的目的是接收单片机发来的数据,我们需要考虑数据的格式。最朴素的办法就是单片机重定向printf函数到串口,使用printf发送数据。

        只不过蓝牙速率有限(此处或者应该说串口速率有限),使用printf发送数据实际上发送的是字符串,既耗时也耗费容量,且是完全暴露的。更好的方式是发送一个数据包(十六进制),单片机这里方便操作,手机App这里也容易解析

        以我这里的情况,我可以发送失真度、采样率、信号频率、增益、波形数据和谐波成分这些信息,那么需要把这些信息打包(共计155字节,可根据自己情况更改)。同时在这个包的前面添加两个字节作为包头,第一个一般是0xA5,后面是版本号可加可不加。包的尾部可以添加一个字节作为校验和,以确保数据包接收的安全和稳定

        

#pragma pack(push, 1)
typedef struct {
    uint8_t header;     // 0xA5
    uint8_t version;    // 0x01
    float thd;          // 失真度
    float freq;         // 频率
    float rate;         // 采样率
    float gain;         // 增益
    float wave[24];     // 波形数据
    float harmonics[10];// 新增的10次谐波
    uint8_t checksum;   // 校验和
} SensorDataPacket;
#pragma pack(pop)

        波形数据为24点,因为采样率固定为输入信号频率的23倍,多加一个点避免波形不完整。

        接下来就是把数据正确打包发送,除了前面的初始化包头和后面的校验和计算,中间的可根据自己的情况改,其实就是把获得的数据填充到包里面

void send_bluetooth_data() {
    SensorDataPacket packet;
    // 初始化包头
    packet.header = 0xA5;
    packet.version = 0x01;
    
    // 填充基础参数
    packet.thd = read_thd_sensor();
    packet.freq = read_frequency();
    packet.rate = SAMPLING_RATE;
    packet.gain = current_gain;
    
    // 填充波形和谐波数据
    read_waveform(packet.wave);
    read_harmonics(packet.harmonics);  // 新增谐波读取函数

    // 计算校验和(需包含所有数据)
    uint8_t* p = (uint8_t*)&packet;
    packet.checksum = 0;
    for(int i=0; i<sizeof(packet)-1; i++) { // 排除checksum自身
        packet.checksum ^= p[i];
    }

    // 发送完整数据包
    bluetooth_send((uint8_t*)&packet, sizeof(packet));
}

        手机App这里只需要验证包和解包即可(在BluetoothManager.kt里),需要配合前面的打包逻辑

仿真

        App开发完成后,单片机部分未必做好,可以写个python脚本来验证一下。与前面一样,蓝牙模块通过USB转TTL接到电脑上,由电脑发送模拟出的数据。脚本如下,波特率和串口需自行设置

import math

import serial
import struct
import time
import random

# 配置串口参数
PORT = 'COM7'  # 修改为实际端口
BAUDRATE = 115200

# 生成一个完整周期的正弦波数据(24个采样点)
n_samples = 24
amplitude = 2047.5  # 确保峰峰值覆盖 0-4095 范围
offset = 2047.5  # 直流偏置居中


def create_packet():
    # 全局变量
    global amplitude
    """生成符合协议的数据包"""
    header = bytes([0xA5, 0x01])  # 包头和版本

    # 生成随机测试数据
    thd = random.uniform(0.5, 12)  # 失真度 0.5%~5%
    freq = random.uniform(1000, 20000)  # 频率 50Hz-20kHz
    rate = 44100.0+random.uniform(-100, 100)  # 采样率
    gain = float(random.randint(0, 3))

    # 生成24个正弦波采样点
    amplitude -= 60
    if amplitude < 50:
        amplitude = 2047.5
    phase_offset = random.uniform(-math.pi / 12, math.pi / 12)  # ±15度随机相位偏移
    wave = []
    for i in range(n_samples):
        phase = 2 * math.pi * i / n_samples + phase_offset  # 计算当前相位
        value = amplitude * math.sin(phase) + offset  # 原始正弦波值
        noisy_value = value + random.gauss(0, 5)  # 添加噪声(标准差可调)
        clamped_value = int(round(max(0, min(noisy_value, 4095))))  # 限幅+取整
        wave.append(float(clamped_value))

    # 新增的10次谐波成分(0-1之间的归一化幅值)
    harmonics = [random.uniform(0, 1) for _ in range(10)]  # 10次谐波

    # 打包二进制数据
    data = struct.pack('<4f', thd, freq, rate, gain)
    wave_data = struct.pack('<24f', *wave)
    harmonic_data = struct.pack('<10f', *harmonics)  # 新增谐波数据

    # 计算校验和(需要包含新增的谐波数据)
    checksum = 0
    full_packet = header + data + wave_data + harmonic_data  # 更新完整数据包
    for b in full_packet:
        checksum ^= b

    return full_packet + bytes([checksum])


def main():
    with serial.Serial(PORT, BAUDRATE, timeout=1) as ser:
        print(f"开始模拟数据发送到 {PORT}...")
        try:
            while True:
                packet = create_packet()
                ser.write(packet)
                print(f"发送数据包: {len(packet)}字节")
                time.sleep(0.4)  # 100ms间隔
        except KeyboardInterrupt:
            print("\n停止发送")


if __name__ == "__main__":
    main()

测试如下:

        

失真度检测App演示

 工程

gitcode

        BluetoothSend:项目首页 - Bluetooth - GitCode

        DistortionMeter:项目首页 - DistortionMeter:2021年电赛题失真度检测App - GitCode

github

        算了,没流量了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值