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

news/2024/7/24 7:08:45 标签: 小程序, 数码碟盒, 无损改装

文章目录

    • 前言
    • 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.niftyadmin.cn/n/4991328.html

相关文章

求解整数规划问题的割平面法和分支定界法

文章目录 整数规划割平面法分支定界法代码实现 整数规划 整数规划问题是优化变量必须取整数值的线性或非线性规划问题&#xff0c;不过&#xff0c;在大多数情况下&#xff0c;整数规划问题指的是整数线性规划问题。 其数学模型为 m i n f ( x ) c T x s.t A x b x ≥ 0 x…

ASP.NET Core 的 Routing

ASP.NET Core 的 Routing ASP.NET Core 的 controllers 使用Routing 中间件匹配客户端的 url 请求&#xff0c;然后映射到对应的 controller 的处理方法&#xff08;Action&#xff09;上。 Actions 可以是 常规路由 或 属性路由 的映射。 MVC App一般使用常规路由。 REST API…

【视觉SLAM入门】6.1. (基于直接法的视觉里程计)LK光流法,代码解读, 直接法,特征点法对比,稀疏,半稠密,稠密地图

"刺卵掷地&#xff0c;逐蝇弃笔" 0. 数据集1. 光流法(Optical Flow)1.1. 光流1.2. LK光流法1.3 关键代码&#xff1a;1.4 特点 2. 直接法(Direct Methods)2.1 分类比较2.2 优缺点 前置事项&#xff1a; 特征点耗时&#xff0c;丢弃有用信息&#xff0c;特征缺失&…

我的创作纪念日 —— 一年之期

前言 大家好&#xff01;我是荔枝嘿~看到官方私信才发现原来时间又过去了一年&#xff0c;荔枝也在CSDN中创作满一年啦&#xff0c;虽然中间因为种种原因并没有经常输出博文哈哈&#xff0c;但荔枝一直在坚持创作嘿嘿。记得去年的同一时间我也同样写了一篇总结文哈哈哈&#x…

Cenos7安装小火车程序动画

一&#xff1a;替换安装源 #先安装一下 epel源,因为安装包在epel源中。 wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo [rootwww ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo --2023-09-01 18:5…

剑指 Offer 49. 丑数(C++实现)

剑指 Offer 49. 丑数https://leetcode.cn/problems/chou-shu-lcof/ 对每个丑数 分别乘2、乘3、乘5 即可得到后续丑数 其中只需要对计算出来的丑数结果进行去重即可 int nthUglyNumber(int n) {// base caseif (n < 1){return -1;}if (n 1){return 1;}vector<int> res…

使用远程桌面软件改善工作与生活的平衡

在当今高度互联的世界中&#xff0c;我们的工作和个人生活之间的界限变得越来越模糊。在本文中&#xff0c;我们将探讨像 Splashtop 这样的远程桌面工具如何成为实现和谐工作与生活平衡不可或缺的一部分。 在当今的背景下理解工作与生活的平衡 工作与生活的平衡不仅仅是一个时…

docker安装及使用-Linux

前提 确保docker支持当前系统版本&#xff0c;docker支持centos 7及以上版本&#xff0c;要求Linux内核版本不低于3.10 cat /etc/redhat-release #查看系统版本 查看内核版本三种方式 cat /proc/version uname -a uname -r 一、安装docker 0、卸载docker&#xff08;根…