全网首发!大众宝来高尔夫polo领驭迈腾帕萨特奥迪A4A6B6B7等老车机增加带蓝牙控制的AUX解码模块,支持小程序原车按钮控制,支持外接高品质蓝牙模块

news2024/11/13 15:10:39

文章目录

    • 前言
    • 1、设计指标
    • 2、PCB设计
    • 3、程序设计
    • 4、调试
        • 4.1蓝牙控制AUX解码板
        • 4.2自定义车机按钮控制其他高品质蓝牙音频模块
        • 4.3小程序使用
    • 5、模块与车机连接方法
    • 6、结语

前言

​ 之前写过四篇关于车机增加音频输入的方法。

1、07宝来经典车机CD收音机(RC668)改装增加蓝牙播放音乐

2、全网首发!老大众奥迪碟盒通信协议破解,可以模拟数码碟盒,外接AUX蓝牙U盘等音频设备

3、全网首发!大众奥迪DIY数码碟盒增加USB和蓝牙播放音乐功能使用原车接口无损改装

4、全网首发,克莱斯勒大捷龙jeep道奇DIY数码碟盒增加USB和蓝牙播放音乐功能使用原车接口无损改装

​ 汽车使用寿命很长,而电子设备老化的速度很快,这就导致了10多年的老车还能在开10年,但是汽车上的电子设备基本都不能用了,比如听歌用的CD机,10年基本没有几个CD能正常工作了,为了解决老车不能听音乐,或者听音乐不方便的问题,所以设计了一款数码碟盒AUX解码模块,该模块能激活碟箱接口,通过碟箱接口接入自己喜欢的音源。保证原滋原味,音质的好坏取决于音源。

在这里插入图片描述
在这里插入图片描述

​ VWC-AB01 带蓝牙控制的AUX解码板

碟盒功能

产品型号碟箱解码开关机灯蓝牙指示灯蓝牙BLE原车按钮控制KEYIOOTA升级12V供电5V输出
VWC-AX01
VWC-AB01

1、设计指标

​ 模块规格如下:

输入电压12VDC
工作电流100mA
工作温度-40℃~+80℃
频率响应20HZ-20KHZ
长x宽x高如上图

2、PCB设计

​ AUX解码板碟箱音频接口直接引出,与控制端不共地,并且用模拟地对音频线进行包地处理,增加抗干扰能力。

在这里插入图片描述
带蓝牙控制的AUX解码板,红色部分为ble天线部分。

在这里插入图片描述

3、程序设计

贴上核心程序代码

/*捕捉中断*/
void ETM2_IRQHandler(void)
{


    uint32_t nextVal;
    uint32_t curVal = ETM2->CNT;
	
		if(ETM2->SC & ETM_SC_TOF_MASK)				//清除溢出标志位
	{
			 ETM2->SC &= ~ETM_SC_TOF_MASK;

	}
	

	if(ETM2->CONTROLS[0].CnSC & ETM_CnSC_CHF_MASK )//输入信号边沿变化
	{
		ETM2->CONTROLS[0].CnSC &= ~ETM_CnSC_CHF_MASK;

		
        if(RxInProgress == (VPW_RxStatus_t)Idle)													// 产生下降沿
        {
            RxInProgress = (VPW_RxStatus_t)SOF;
            VPW_RxBufPtr = 0;
//            ResetRx();
					
						if(VPW_TxBufPtr >1)
						{
							VPW_RxBufPtr = 0;
						}

						ETM2->CONTROLS[0].CnSC |= ETM_CnSC_ELSB_MASK; 								//切换到跳边沿检测

        }
        else if(RxInProgress == 1)
        {
            uint32_t width;
            uint8_t symIdx;
            width = GetPulseWidth(PrevCntrVal, curVal);
					
            if(width > RX_SOF_MIN && width <= RX_SOF_MAX)
            {
                symIdx = SOF_IDX;
            }
            else if(width > RX_LONG_MIN && width <= RX_LONG_MAX)
            {
                symIdx = LONG_IDX;
            }
            else if(width > RX_SHORT_MIN && width <= RX_SHORT_MAX)
            {
                symIdx = SHORT_IDX;
            }
            else
            {
                ResetRx();
                return;
            }
            VPW_RxBuf[VPW_RxBufPtr] = symIdx;
            if(TxInProgress == 1)										//正在发送
            {
                if(VPW_RxBuf[VPW_RxBufPtr] != VPW_TxBuf[VPW_RxBufPtr])
                {
                    FinalizeTx();
                }
            }
            if(VPW_RxBufPtr < sizeof(VPW_RxBuf) - 2)
            {
                VPW_RxBufPtr++;
            }
						SetTimerAlarm(239*48);
        }
        PrevCntrVal = curVal;
		
	}

	if(ETM2->CONTROLS[0].CnSC & ETM_CnSC_CHF_MASK )//输入信号上升沿
	{
		ETM2->CONTROLS[0].CnSC &= ~ETM_CnSC_CHF_MASK;

	}
}

发送程序使用定时器0产生波形

/*****************************************************************************//*!
*
* @brief ETM1 回调函数
*        
* @param  none
*
* @return none
*
*****************************************************************************/
void ETM0_IRQHandler(void)
{
	   uint32_t nextVal;



		ETM_ClrOverFlowFlag(ETM0); 				//清除溢出标志位
	
		ETM_ClockSet(ETM0, ETM_CLOCK_NOCLOCK, ETM_CLOCK_PS_DIV16); 		//停止计数

	    nextVal = VPW_Symbols[VPW_TxBuf[VPW_TxBufPtr]];
	
				
        if((VPW_TxBuf[VPW_TxBufPtr] == EOF_IDX)||(VPW_TxBufPtr>=(TX_BUFLEN*8)))
        {
            FinalizeTx();
        }
        else
        {
					
					  ETM_SetModValue(ETM0,nextVal);
						ETM0->CNT = 0;
						ETM_ClockSet(ETM0, ETM_CLOCK_SYSTEMCLOCK, ETM_CLOCK_PS_DIV16); 		//开始计数

						GPIO_Toggle(GPIOA,J1850_OUT_MASK);
					
        }
        VPW_TxBufPtr++;
	
	
}


定义结构体 用于保存车机播放音乐相关信息。

typedef struct
{

	
	uint8_t rnd;
	uint8_t scan;
	uint8_t playing;
	uint8_t cd_button;
	uint8_t cd_power;
	
	uint8_t cd_status;
	
	uint8_t disc;           
	uint8_t track;          
	uint8_t minute;         
	uint8_t second; 
	
	uint8_t workSta;					// 工作状态0  关机 1 待机 2工作 
	uint8_t BIDIstate;                       // pointer to the current state handler routine
	uint8_t BIDIcount;
	
	uint8_t staCount;
	
	
} CD_CHANFER_STRUCT;

自定义车机按钮程序

void  bt_exButtonMessage(void)
{

      if(mybtEx.fbutton_flag == 0)
      {
          if(mybtEx.frst == 1)
          {
              mybtEx.fbutton_flag = 1;
              mybtEx.fbutton_value = U_BUTTON_RST;


              tmos_start_task(userApp_task_id,USERAPP_EVENT,20 * TICK_PERIOD_MS);


          }else
          if(mybtEx.fpowerOn == 1)
          {
            mybtEx.fbutton_flag = 1;
            bt_exPowerOn();
            mybtEx.fbutton_value = U_BUTTON_POWER;

              tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT,  btMapPWMCfg.wmPowerOn.delayTime * TICK_PERIOD_MS);

          }else
          if(mybtEx.fpowerOff == 1)
          {
            mybtEx.fbutton_flag = 1;
            bt_exPowerOff();
            mybtEx.fbutton_value = U_BUTTON_POWER;

              tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT,  btMapPWMCfg.wmPowerOff.delayTime * TICK_PERIOD_MS);

          }else
          if(mybtEx.fPlay == 1)
          {
              mybtEx.fbutton_flag = 1;


              mybtEx.fbutton_value = U_BUTTON_PLAY;

              tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT, 500 * TICK_PERIOD_MS);

          }else
          if(mybtEx.fnext == 1)
          {
              mybtEx.fbutton_flag = 1;
              bt_exNext();
              mybtEx.fbutton_value = U_BUTTON_NEXT;
              tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT, btMapPWMCfg.wmNext.delayTime * TICK_PERIOD_MS);

          }else
          if(mybtEx.fpre == 1)
          {
              mybtEx.fbutton_flag = 1;
              bt_exPre();
              mybtEx.fbutton_value = U_BUTTON_PRE;

              tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT, btMapPWMCfg.wmPrev.delayTime  * TICK_PERIOD_MS);

          }else
          if(mybtEx.fmix == 1)
          {
              mybtEx.fbutton_flag = 1;
              bt_exMix();
              mybtEx.fbutton_value = U_BUTTON_MIX;

              tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT, btMapPWMCfg.wmMix.delayTime  * TICK_PERIOD_MS);

          }else
          if(mybtEx.fcd1 == 1)
          {
              mybtEx.fbutton_flag = 1;
              bt_exCd1();
              mybtEx.fbutton_value = U_BUTTON_CD1;

              tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT, btMapPWMCfg.wmCd1.delayTime  * TICK_PERIOD_MS);

          }else
          if(mybtEx.fcd2 == 1)
          {
              mybtEx.fbutton_flag = 1;
              bt_exCd2();
              mybtEx.fbutton_value = U_BUTTON_CD2;

              tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT, btMapPWMCfg.wmCd2.delayTime  * TICK_PERIOD_MS);

          }else
          if(mybtEx.fcd3 == 1)
          {
              mybtEx.fbutton_flag = 1;
              bt_exCd3();
              mybtEx.fbutton_value = U_BUTTON_CD3;

              tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT, btMapPWMCfg.wmCd3.delayTime  * TICK_PERIOD_MS);

          }else
          if(mybtEx.fcd4 == 1)
          {
              mybtEx.fbutton_flag = 1;
              bt_exCd4();
              mybtEx.fbutton_value = U_BUTTON_CD4;

              tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT, btMapPWMCfg.wmCd4.delayTime  * TICK_PERIOD_MS);

          }else
          if(mybtEx.fcd5 == 1)
          {
              mybtEx.fbutton_flag = 1;
              bt_exCd5();
              mybtEx.fbutton_value = U_BUTTON_CD5;

              tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT, btMapPWMCfg.wmCd5.delayTime  * TICK_PERIOD_MS);

          }else
          if(mybtEx.fcd6 == 1)
          {
              mybtEx.fbutton_flag = 1;
              bt_exCd6();
              mybtEx.fbutton_value = U_BUTTON_CD6;

              tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT, btMapPWMCfg.wmCd6.delayTime  * TICK_PERIOD_MS);

          }else
            if(mybtEx.btPause == 1)
            {

                #ifdef WDEBUG
                #endif
                mybtEx.fbutton_flag = 1;
                bt_exPlayPuse();
                mybtEx.fbutton_value = U_BUTTON_PAUSE;

                tmos_start_task(userApp_task_id, USERAPP_BUTTON_EVENT, btMapPWMCfg.wmPause.delayTime  * TICK_PERIOD_MS);

            }

      }


}

微信小程序程序

在这里插入图片描述

4、调试

​ AUX解码板插碟机上,搭铁开机,即可工作,这里不做详细论述。视频演示

带蓝牙控制的大众奥迪老车机AUX解码模块

下面主要讲解下,蓝牙控制AUX解码板。

4.1蓝牙控制AUX解码板

​ 现有AUX解码板只能解码不能用原车按钮控制,这样在开车的时候想要换歌曲,就需要操作手机或者其他设备,很不安全。为了解决这个问题,将解码板的主控换成带蓝牙5.3的单片机,既可以实现解码车机,又能实现原车按钮控制手机等数码产品上下一曲。

​ VWC-AB01 模组连接到车机上默认模式是AUX解码功能,当手机或其他电子设备连接蓝牙名称为:

VWCDC-SP-BLE蓝牙设备,如下图所示,手机端这时播放音乐,既可以通过车机原车按钮控制手机上下一曲播放蓝牙音乐了。
在这里插入图片描述

4.2自定义车机按钮控制其他高品质蓝牙音频模块

​ 市面上的公版蓝牙模组控制方式,大体上分为两类控制,一类是IO高低电平时间控制,另外一类是ADC按键控制。这里以ADC按键为控制方式的蓝牙模组为例,讲解如何自定义车机按键功能,控制蓝牙音频模块。
在这里插入图片描述
在这里插入图片描述

​ ADC按键原理如下图所示,核心原理就是电阻串联分压,不同按键按下,就是不同电阻与固定值的22k上拉电阻串联分压,因为每个按键对应的电阻值不同,所以可以区分不同按键按下。
在这里插入图片描述

蓝牙音频模块和解码板连接图
在这里插入图片描述

​ 根据上面原理,只要解码模块产生和按键按下相同的电压,和持续时间,就可以模拟对应按键功能了。比如下一曲对应的是0.96V,那么只要控制模块产生0.96v电压即可。那么怎么控制模块产生不同的电压呢?这里面要用到对应的微信小程序配置工具了。

4.3小程序使用

微信小程序搜索悦享行或者私聊博主发小程序
在这里插入图片描述

​ 搜索连接VWCDC-SP-BLE,连接成功后显示如下界面,默认参数为输出3.3V 持续0.5s
在这里插入图片描述
​ 根据上图可知上一曲、下一曲、暂停对应的电压值,根据实际情况设置即可,如下图所示,设置好按设置按钮,然后在读取设置参数,如果读回来的数据和写入的数据一致,那么设置成功。按对应的车机按键,模块就会输出设置的电压值和持续时间。

在这里插入图片描述

视频演示

支持小程序自定义大众奥迪车机按键功能的蓝牙控制AUX解码模块

5、模块与车机连接方法

AUX解码板连接方法
在这里插入图片描述
在这里插入图片描述

带蓝牙控制的AUX解码板连接方法
在这里插入图片描述

6、结语

有朋友反馈,找不到我,今打油诗一首

加流一壶真千金
微云澹日映寒流
信意麾毫无点误
KING_SONGING
唱奇腾怪可删修
歌咏康衢了此生
的然民仰如父母
国家涵养自建隆
王俭归来幕府非

有朋自远发来,不亦说乎!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/959735.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

11.Redis数据库管理命令

Redis数据库管理命令 数据库管理selectdbsizeflushall / flushdb 数据库管理 redis 中的 database 是现成的&#xff0c;咱们用户不能创建新的数据库&#xff0c;也不能删除已有的数据库~ 默认 redis 给我们提供了 16 个数据库&#xff0c;名字为 数字0 到数字15 这16个数据库…

【深度学习】ChatGPT

本文基于Andrej Karpathy(OpenAI 联合创始人&#xff0c;曾担任特斯拉的人工智能和自动驾驶视觉主管)在Microsoft Build 2023上的演讲整理而成&#xff08;完整的视频在文末&#xff0c;直接拖到文章底部&#xff09;&#xff0c;主要分为2大部分&#xff1a; 1.如何训练GPT(可…

实战系列(一)| Dubbo和Spring Cloud的区别,包含代码详解

目录 1. 概述2. 核心功能3. 代码示例4. 适用场景 Dubbo 和 Spring Cloud 都是微服务架构中的重要框架&#xff0c;但它们的定位和关注点不同。Dubbo 是阿里巴巴开源的一个高性能、轻量级的 RPC 框架&#xff0c;主要用于构建微服务之间的服务治理。而 Spring Cloud 是基于 Spri…

3D开发工具HOOPS Publish如何快速创建交互式3D PDF文档?

HOOPS Publish是一款功能强大的SDK&#xff0c;可以创作丰富的工程数据并将模型文件导出为各种行业标准格式&#xff0c;包括PDF、STEP、JT和3MF。HOOPS Publish核心的3D数据模型是经过ISO认证的PRC格式(ISO 14739-1:2014)&#xff0c;它为装配树、拓扑和几何、产品制造信息和视…

基于grpc从零开始搭建一个准生产分布式应用(6) - 02 - MapStruct数据转换

一、基础转换 1.1、基础类型 基本类型、包装类、BigDecimal转String默认使用DecimalFormat格式化&#xff0c;Mapping#numberFormat可以指定格式&#xff0c;Date转String默认使用SimpleDateFormat格式化&#xff0c;如默认格式不符要求&#xff0c;可以用&#xff0c;Mapping…

华为OD机试 - 字符串分割(Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路1、根据题意&#xff1a;2、例如&#xff1a;3、解题思路&#xff1a; 五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《…

温习下git同步本地代码至远程仓库

本地服务推远程git仓库&#xff1a; 1、远程git仓库或者云效服务创建服务名生产 ssh代码路径 2、进入本地项目文件夹git init 初始化git仓库 3、git remote add origin ssh(远程origin路径) 4、git add . 添加当前文件至暂存区 5、git commit -m "Initial commit"提交…

stable diffusion实践操作-安装

本文专门开一节写安装相关的内容&#xff0c;在看之前&#xff0c;可以同步关注&#xff1a; stable diffusion实践操作 正文 1、 秋葉一键安装包 github安装&#xff1a;https://github.com/AUTOMATIC1111/stable-diffusion-webui 秋叶安装&#xff1a;[b站教程和下载安装包…

按钮控件之1---QPushButton 标准按钮/普通按钮控件

1、父类QAbstractButton 2、QPushButton按钮&#xff0c;是Qt常用的控件之一&#xff0c;提供普通的按钮功能。 通过信号槽机制接收触发信号并执行对应动作。3、创建QPushButton 它有三个构造函数&#xff1a; // 空对象 QPushButton(QWidget *parent nullptr); // 指定QPus…

【Dots之008】TransformUsageFlags基础知识

一、基础介绍 在Baker中进行GetEntity对象的时候&#xff0c;需要填入TransformUsageFlags类型的参数&#xff1b;针对不同类型的参数&#xff0c;看看GameObject所转换后的IComponentData有什么差异&#xff1b; 演示代码&#xff1a; public class CubeAuthoring : MonoBe…

ITIL 4—创建、交付和支持—利用信息和技术创建、交付和支持服务

3.1 集成和数据共享 服务设计通常依赖于多个系统之间的集成&#xff08;integration&#xff09;&#xff0c;在这种情况下&#xff0c;理解集成建模的不同层次相当重要。例如&#xff1a; 应用程序级 应用程序之间是相互交互的。企业级 已集成的应用程序共同提供价值。业务…

计算机/嵌入式入门教材资料

背景 自学计算机&#xff0c;首先我们要找到好的教材、教程&#xff0c;可以事半功倍。 目前&#xff0c;互联网上计算机资源较多&#xff0c;难的不再是寻找资源&#xff0c;而是筛选出质量比较高的资源。 基于笔者经验&#xff0c;推荐以下资源。 书籍 传统的书籍是纸质版…

云存储:实现数据备份与恢复的创新方法

文章目录 云存储的基本概念数据备份的创新方法自动化备份策略增量备份和版本控制多地点备份 数据恢复的创新方法快速数据恢复弹性扩展性数据验证和一致性 案例分析&#xff1a;AWS S3自动化备份策略增量备份和版本控制多地点备份快速数据恢复数据验证和一致性 结论 &#x1f38…

不会还有人排长队吃饭吧?用这招,快速搞定!

随着现代企业对员工福利和工作环境的关注不断增加&#xff0c;企业智慧食堂已经成为了企业管理的重要组成部分。 智慧收银系统的出现不仅使员工用餐变得更加便捷和高效&#xff0c;还提供了一种强大的管理工具&#xff0c;有助于企业更好地理解员工消费行为、优化食堂运营&…

安卓10创建文件夹失败

最近在做拍照录像功能&#xff0c;已经有了文件读写权限&#xff0c;却发现在9.0手机上正常使用&#xff0c;但是在安卓12系统上根本没有创建文件夹。经过研究发现&#xff0c;创建名称为“DCIM”的文件夹可以&#xff0c;别的又都不行。而且是getExternalStorageDirectory和ge…

史上最细 B+Tree 解读

前言&#xff1a; BTree 经过几十年的发展已经成为 OLTP 数据库的首选索引结构&#xff0c;深入分析开始前先介绍一些书籍给大家&#xff0c;BTree 的演进非常的复杂&#xff0c;有很多的大牛论文都做出了很关键的指导性作用&#xff0c;就算当前还是在不断探索优化的可能&…

js实现图形验证码

图形验证码起什么作用&#xff1a; 可以防止&#xff1a;恶意破解密码、刷票、论坛灌水&#xff0c;有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登录尝试。 验证码一般是防止批量注册的&#xff0c;人眼看起来都费劲&#xff0c;何况是机器。不少…

让企业主们头疼的mkp勒索病毒,究竟有何来历,勒索病毒解密

mkp勒索病毒是一种比较常见的电脑病毒&#xff0c;它会对感染的电脑进行加密&#xff0c;并要求用户支付一定的赎金才能解锁。这种病毒已经引起了全球范围内的关注&#xff0c;因为它已经造成了严重的经济损失和电脑系统崩溃。 mkp勒索病毒是一种相对较新的病毒&#xff0c;但是…

【MySQL系列】索引的学习及理解

「前言」文章内容大致是MySQL索引的学习。 「归属专栏」MySQL 「主页链接」个人主页 「笔者」枫叶先生(fy) 目录 一、索引概念二、从硬件角度理解2.1 磁盘2.2 结论 三、从软件角度理解四、共识五、索引的理解5.1 一个现象和结论5.2 对Page进行建模5.3 索引可以采用的数据结构5.…

大数据组件Sqoop-安装与验证

&#x1f947;&#x1f947;【大数据学习记录篇】-持续更新中~&#x1f947;&#x1f947; 个人主页&#xff1a;beixi 本文章收录于专栏&#xff08;点击传送&#xff09;&#xff1a;【大数据学习】 &#x1f493;&#x1f493;持续更新中&#xff0c;感谢各位前辈朋友们支持…