155浏览
查看: 155|回复: 1

[M10项目] 行空板之物联网对-讲-机

[复制链接]
【项目背景】
        在当今的创客文化和教育环境中,培养学生的创新思维和实践能力成为了教育的重要目标。创客社团作为学校或社区中推广创客文化和项目的重要平台,一直在寻找能够激发学生兴趣、增强实践技能并促进团队合作的教学案例。物联网(IoT)作为一个充满创新潜力的领域,为创客社团提供了丰富的学习资源和项目实施机会。
        本项目旨在为创客社团提供一个基于物联网技术的对-讲-机功能的实践案例。通过这个项目,学生将有机会了解和掌握物联网的基本概念、音频处理技术和无线通信原理,同时提高他们的编程能力和问题解决能力。

        项目的核心是使用两个行空板,通过物联网技术实现对-讲-机功能。行空板作为一种多功能的开源硬件平台,非常适合用于教育和创新项目。它集成了麦克风和扬声器,可以通过编程实现音频的录制和播放,非常适合用来构建语音通信设备。
【项目目标】

  • 物联网技术理解:学生将学习物联网的基础知识,包括传感器、通信协议和云平台。

  • 编程实践:通过使用Mind+编程软件和Python语言,学生将练习编程技巧,实现音频数据的采集、处理和传输。

  • 音频处理技术:学生将了解音频信号的数字化过程,包括录音、文件格式转换和音频播放。

  • 无线通信原理:学生将探索蓝牙和物联网通信技术,了解它们在无线通信中的应用。

  • 团队合作与交流:项目需要学生分组合作,共同设计、编程和测试对-讲-机系统,培养团队协作和沟通能力。

  • 创新思维:鼓励学生在项目实施过程中发挥创意,探索物联网技术在其他领域的潜在应用。


【知识学习】
        成员们分组进行物联网和音频处理技术的基础知识学习,包括了解行空板的功能、Mind+编程软件的使用、Python语言基础、物联网通信协议以及音频信号的数字化处理。
【硬件准备】
       社团准备所需的硬件设备,包括两个行空板、两个蓝牙音箱、两个充电宝、必要的连接线和电脑设备。




行空板之物联网对-讲-机图1


行空板之物联网对-讲-机图2


行空板之物联网对-讲-机图3





【编程实践】
        1.在老师的指导下,成员们开始编写代码。他们使用Mind+编程软件中的Python编程环境,利用unihiker库的Audio模块来控制行空板上的麦克风进行声音采集,并通过wave库将声音文件转换为十六进制格式。成员们注册并配置物联网平台Easy IOT,创建设备ID和相应的话题,用于音频数据的传输。
  1. import wave,os
  2. import json
  3. import time
  4. from unihiker import GUI
  5. from unihiker import Audio
  6. import siot
  7. bs=1
  8. def send_wave(FILE_PATH):
  9. with wave.open(FILE_PATH, 'rb') as wav_file:
  10.    # 获取文件大小
  11.    file_size = os.path.getsize(FILE_PATH)
  12.    
  13.    
  14.    # 读取数据并发送
  15.    frame_count = 0
  16.    siot.publish(topic="z4ksqL6Ig", data="start")
  17.    while True:
  18.        frame = wav_file.readframes(1024)  # 读取1024字节
  19.        if not frame:
  20.            break
  21.        siot.publish(topic="z4ksqL6Ig", data=frame.hex())
  22.        frame_count += 1
  23.        显示.config(text="发送:"+str(frame_count)+"frame")
  24.    siot.publish(topic="z4ksqL6Ig", data="stop")
  25. # 事件回调函数
  26. def on_buttona_click_callback():
  27.    global bs
  28.    wave_path="record.wav"
  29.    if bs==1:
  30.       bs=0
  31.       显示.config(text="开始讲话")
  32.       u_audio.play("ding.wav")
  33.      
  34.       u_audio.start_record("record.wav")
  35.    else:
  36.       bs=1
  37.       显示.config(text="讲话结束")
  38.       u_audio.stop_record()
  39.       send_wave(wave_path)
  40.       u_audio.play("ding.wav")
  41.    
  42. u_gui=GUI()
  43. u_audio = Audio()
  44. u_gui.on_a_click(on_buttona_click_callback)
  45. 显示=u_gui.draw_text(text="行空板",x=0,y=0,font_size=20, color="#0000FF")
  46. siot.init(client_id="14603802900222362",server="iot.dfrobot.com.cn",port=1883,user="AVNLqL6SR",password="04HYqY6IRz")
  47. siot.connect()
  48. siot.loop()
  49. siot.getsubscribe(topic="z4ksqL6Ig")
  50. while True:
  51.    pass
复制代码

    2.编写代码,实现音频数据的接收。成员们测试音频数据是否能够成功通过物联网平台接收。
  1. import wave
  2. from unihiker import GUI
  3. import siot
  4. from unihiker import Audio
  5. # 接收到的消息存储在这里
  6. received_frames = []
  7. frame_count=0
  8. # 事件回调函数
  9. def on_message_callback(client, userdata, msg):
  10.    global bs2,received_frames,frame_count
  11.    re_msg=msg.payload.decode()
  12.    
  13.    if re_msg=="stop":
  14.       bs2=2
  15.    if bs2==1:
  16.       frame_data = bytes.fromhex(re_msg)
  17.       received_frames.append(frame_data)
  18.       frame_count+=1
  19.       显示.config(text="接收到:"+str(frame_count)+"frame")
  20.    if re_msg=="start":
  21.        bs2=1
  22.        received_frames = []  # 重置接收缓冲区
  23.        frame_count=0
  24.        u_audio.play("ding.wav")
  25. u_gui=GUI()
  26. 显示=u_gui.draw_text(text="行空板",x=0,y=0,font_size=20, color="#0000FF")
  27. siot.init(client_id="506958351015395",server="iot.dfrobot.com.cn",port=1883,user="AVNLqL6SR",password="04HYqY6IRz")
  28. u_audio = Audio()
  29. siot.connect()
  30. siot.loop()
  31. siot.set_callback(on_message_callback)
  32. siot.getsubscribe(topic="z4ksqL6Ig")
  33. bs2=0
  34. while True:
  35.    
  36.    if bs2==2:
  37.        js=0
  38.        bs2=0
  39.        # 重新组装WAV文件
  40.        FILE_NAME = "received.wav"
  41.        with wave.open(FILE_NAME, 'wb') as out_file:
  42.            out_file.setnchannels(1)  # 单声道
  43.            out_file.setsampwidth(2)  # 采样宽度2字节
  44.            out_file.setframerate(16000)  # 采样率44100Hz
  45.            for frame in received_frames:
  46.                out_file.writeframes(frame)
  47.                js+=1
  48.                print(js)
  49.       
  50.        u_audio.play(FILE_NAME)
  51.        print(f"Reassembly complete, saved to {FILE_NAME}")
复制代码
【蓝牙音箱连接】
        成员们学习如何通过蓝牙将行空板与音箱连接,并将接收到的音频数据播放出来。
  1. import subprocess
  2. import sys
  3. sys.path.append("/root/mindplus/.lib/thirdExtension/nick-pyttsx3-thirdex")
  4. import pyttsx3
  5. engine = pyttsx3.init()
  6. # 搜索附近的蓝牙设备
  7. def connect_bluetooth(address):
  8.    result = subprocess.run(['bluetoothctl', 'default-agent'], stdout=subprocess.PIPE)
  9.    result = subprocess.run(['bluetoothctl', 'power', 'on'], stdout=subprocess.PIPE)
  10.    result = subprocess.run(['bluetoothctl', 'pair', address], stdout=subprocess.PIPE)
  11.    result=subprocess.run(['bluetoothctl', 'connect', address], stdout=subprocess.PIPE)
  12.    print(result)
  13.    engine.say("蓝牙连接已完成")
  14.    engine.runAndWait()
  15. def is_connected(device_mac):
  16.    # 获取已配对的设备列表
  17.    result = subprocess.run(['bluetoothctl', 'paired-devices'], stdout=subprocess.PIPE)
  18.    paired_devices = result.stdout.decode().strip().split('\n')[1:]  # 跳过标题行
  19.    # 遍历已配对的设备,检查MAC地址
  20.    for device in paired_devices:
  21.        if device_mac in device:
  22.            # 如果设备已配对,检查是否已连接
  23.            result = subprocess.run(['bluetoothctl', 'info', device_mac], stdout=subprocess.PIPE)
  24.            info = result.stdout.decode().strip().split('\n')
  25.            for line in info:
  26.                if "Connected: yes" in line:
  27.                    return True
  28.    return False
  29. # 你的蓝牙音箱的MAC地址
  30. #speaker_mac = "08:D0:03:96:70:8D"#收音机音箱
  31. #speaker_mac ="41:42:BE:4A:B6:C1"#海螺音箱
  32. speaker_mac ="5A:5A:5A:A7:01:CA"#话筒音箱
  33. if not(is_connected(speaker_mac)):
  34.    connect_bluetooth(speaker_mac)
  35. else:
  36.    engine.say("蓝牙已连接")
  37.    engine.runAndWait()
  38. while True:
  39.    pass
  40. #先用手机搜索蓝牙音箱,查看蓝牙音箱名称。如X8
  41. #使用 PowerShell:
  42. #打开 PowerShell。可以在开始菜单中搜索 “PowerShell”,然后右键选择 “以管理员身份运行”。
  43. #输入以下命令:Get-PnpDevice -Class Bluetooth | Select-Object FriendlyName,InstanceId,Status,DeviceID。这个命令会列出系统中检测到的蓝牙设备的相关信息,包括设备名称、实例 ID、状态和设备 ID 等,你可以根据设备名称等信息来确定你想要获取 MAC 地址的蓝牙设备。
  44. #X8 Avrcp 传输                          BTHENUM\{0000110C-0000-1000-8000-00805F9B34FB}_LOCALMFG&0002\7&4000742&0&4142BE4AB6C1_C00000000
  45. #X8                                     BTHENUM\DEV_4142BE4AB6C1\7&4000742&0&BLUETOOTHDEVICE_4142BE4AB6C1
  46. #4142BE4AB6C1,这个就是蓝牙音箱的MAC地址。
复制代码
【系统集成】
        所有功能模块的代码集成到一个系统中,进行系统的全面测试,确保音频从采集到播放的整个流程顺畅无误。提示:两个行空板程序,物联网发送和接收主题要互相交换。
  1. import wave,os
  2. import json
  3. import time
  4. from unihiker import GUI
  5. from unihiker import Audio
  6. import siot
  7. import subprocess
  8. import sys
  9. sys.path.append("/root/mindplus/.lib/thirdExtension/nick-pyttsx3-thirdex")
  10. import pyttsx3
  11. engine = pyttsx3.init()
  12. # 搜索附近的蓝牙设备
  13. def connect_bluetooth(address):
  14.    result = subprocess.run(['bluetoothctl', 'default-agent'], stdout=subprocess.PIPE)
  15.    result = subprocess.run(['bluetoothctl', 'power', 'on'], stdout=subprocess.PIPE)
  16.    result = subprocess.run(['bluetoothctl', 'pair', address], stdout=subprocess.PIPE)
  17.    result=subprocess.run(['bluetoothctl', 'connect', address], stdout=subprocess.PIPE)
  18.    print(result)
  19.    engine.say("蓝牙连接已完成")
  20.    engine.runAndWait()
  21. def is_connected(device_mac):
  22.    # 获取已配对的设备列表
  23.    result = subprocess.run(['bluetoothctl', 'paired-devices'], stdout=subprocess.PIPE)
  24.    paired_devices = result.stdout.decode().strip().split('\n')[1:]  # 跳过标题行
  25.    # 遍历已配对的设备,检查MAC地址
  26.    for device in paired_devices:
  27.        if device_mac in device:
  28.            # 如果设备已配对,检查是否已连接
  29.            result = subprocess.run(['bluetoothctl', 'info', device_mac], stdout=subprocess.PIPE)
  30.            info = result.stdout.decode().strip().split('\n')
  31.            for line in info:
  32.                if "Connected: yes" in line:
  33.                    return True
  34.    return False
  35. # 你的蓝牙音箱的MAC地址
  36. speaker_mac = "08:D0:03:96:70:8D"#收音机音箱
  37. #speaker_mac ="41:42:BE:4A:B6:C1"#海螺音箱
  38. if not(is_connected(speaker_mac)):
  39.    connect_bluetooth(speaker_mac)
  40. else:
  41.    engine.say("蓝牙已连接")
  42.    engine.runAndWait()
  43. bs=1
  44. # 接收到的消息存储在这里
  45. received_frames = []
  46. frame_count=0
  47. # 事件回调函数
  48. def on_message_callback(client, userdata, msg):
  49.    global bs2,received_frames,frame_count
  50.    re_msg=msg.payload.decode()
  51.    
  52.    if re_msg=="stop":
  53.       bs2=2
  54.      
  55.    if bs2==1:
  56.       frame_data = bytes.fromhex(re_msg)
  57.       received_frames.append(frame_data)
  58.       frame_count+=1
  59.       显示.config(text="接收中:"+str(frame_count)+"frame")
  60.    if re_msg=="start":
  61.        bs2=1
  62.        received_frames = []  # 重置接收缓冲区
  63.        frame_count=0
  64.       
  65.       
  66. def send_wave(FILE_PATH):
  67. with wave.open(FILE_PATH, 'rb') as wav_file:
  68.    # 获取文件大小
  69.    
  70.    file_size = os.path.getsize(FILE_PATH)
  71.    
  72.    
  73.    # 读取数据并发送
  74.    frame_count = 0
  75.    siot.publish(topic="z4ksqL6Ig", data="start")
  76.    while True:
  77.        frame = wav_file.readframes(1024)  # 读取1024字节
  78.        if not frame:
  79.            break
  80.        siot.publish(topic="z4ksqL6Ig", data=frame.hex())
  81.        frame_count += 1
  82.        显示.config(text="正在发送:"+str(frame_count)+"frame")
  83.    siot.publish(topic="z28640zNg", data="stop")
  84. # 事件回调函数
  85. def on_buttona_click_callback():
  86.    global bs
  87.    wave_path="record.wav"
  88.    if bs==1:
  89.       bs=0
  90.       显示.config(text="开始讲话")
  91.       u_audio1.play("ding.wav")
  92.      
  93.       u_audio1.start_record("record.wav")
  94.    else:
  95.       bs=1
  96.       显示.config(text="讲话结束")
  97.       u_audio1.stop_record()
  98.       send_wave(wave_path)
  99.       u_audio1.play("ding.wav")
  100.    
  101. u_gui=GUI()
  102. u_audio1 = Audio()
  103. u_audio2 = Audio()
  104. u_gui.on_a_click(on_buttona_click_callback)
  105. 显示=u_gui.draw_text(text="行空板语音对讲",x=10,y=60,font_size=30, color="#0000FF")
  106. siot.init(client_id="14603802900222362",server="iot.dfrobot.com.cn",port=1883,user="AVNLqL6SR",password="04HYqY6IRz")
  107. siot.connect()
  108. siot.loop()
  109. siot.set_callback(on_message_callback)
  110. siot.getsubscribe(topic="z4ksqL6Ig")
  111. bs2=0
  112. while True:
  113.    
  114.    if bs2==2:
  115.        js=0
  116.        bs2=0
  117.        # 重新组装WAV文件
  118.        u_audio2.play("ding.wav")
  119.        显示.config(text="输出中……")
  120.        FILE_NAME = "received.wav"
  121.        with wave.open(FILE_NAME, 'wb') as out_file:
  122.            out_file.setnchannels(1)  # 单声道
  123.            out_file.setsampwidth(2)  # 采样宽度2字节
  124.            out_file.setframerate(16000)  # 采样率44100Hz
  125.            for frame in received_frames:
  126.                out_file.writeframes(frame)
  127.                js+=1
  128.                print(js)
  129.       
  130.        u_audio2.play(FILE_NAME)
  131.        显示.config(text="行空板语音对讲")
复制代码
【调试优化】
        在测试过程中,成员们可能会遇到各种问题,如音频质量不佳、传输延迟等,他们需要不断调试和优化代码,以提高系统的性能。
【项目展示】
        项目完成后,社团将组织一个展示活动,让成员们向同学、老师和其他社团展示他们的成果,分享他们在项目中学到的知识和经验。

        通过本项目的学习和实践,学生不仅能够获得宝贵的技术知识和实践经验,还能够体验到从零到一创造一个工作系统的过程,从而激发他们对科技和创新的热情。此外,项目的成功实施也将为创客社团增添一个展示其创新成果的亮点,吸引更多的学生参与到创客活动中来。

罗罗罗  中级技师

发表于 2024-10-10 22:38:18

厉害
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail