狗趴(GodPub),开源硬件学习与实践
标题: 8个LED的音量表 的思考 [打印本页]
作者: 囧囧-科技大神粉 时间: 2015-2-26 19:10
标题: 8个LED的音量表 的思考
本帖最后由 囧囧-科技大神粉 于 2015-2-26 23:43 编辑
原帖:http://www.dianziaihaozhe.com/mulu/guowai/2627.html
下面的音量表电路采用两个四电压比较器(LM339),照亮了一系列的8个LED指示灯,指示音量。每个8比较器的偏置电压的增加由分压器设定为使右下LED点亮时,首先输入的是约400毫伏,或约22毫瓦的峰值在8欧姆系统。分压器的电压被设定为使得每个LED代表大约两倍的功率电平之前,当所有的LED被点亮时,这样的比例范围是从22毫瓦到大约2.5瓦特。灵敏度可与输入控制降低到读更高的水平。
我还没有建立或测试该电路,功率电平应该如下:
1个LED = 22MW
2个LED = 42MW
3个LED = 90mW的
4个LED =为175mW
5个LED =达320mW
6个LED =为650mW
7个LED = 1.2瓦
8个LED =2.5瓦特
————————————————————————————————————————————————
衍生,楼主想直接测3.5耳机音频孔出来的电压,就用这个电路,但根据其他论坛大神的描述,峰值电压最高不过1Vpp,均值不过700mVpp,显然不太适合则个阻值,目测原文作者的阻值是接在功放出口的,所以能达到这么大
现在,楼主想改成同相输入端为10mV、20mV、30mV、40mV、50mV、60mV、70mV、80mV,这种小电压的
那么问题来了,Vcc端5V,要分出80mV的,根据串联分压来说,如果R1为1200欧(8个150欧),那么R2需要73800欧
坑爹啊~~~楼主压根就没这么多的电阻(73800约要16个4.7k电阻)怎么办?
苦思冥想后,祭出一个神气,5.1V的稳压二极管,然后串联一个4.7K+1.57K(3个4.7K并联)+8个150欧
进而实现了,实测5.1V稳压管实际降压大概4.48V,剩下0.5V左右就比较好分了
http://www.tudou.com/listplay/NCZI5vbIFQE/IUKGSm4mutQ.html
——————————————————————————————————————————
另外,再附上1种单片机读音频的电路
作者: 囧囧-科技大神粉 时间: 2015-2-26 23:45
本帖最后由 囧囧-科技大神粉 于 2015-2-28 09:29 编辑
- /*
- 纯串口控制
- 加入脱机控制
- */
-
-
- //电机的高电平持续时间 us
- int maichongjiangeMax=357;
- int maichongjiangeMin=120;
-
- //电机的高电平持续时间的初始值 120us
- int maichongjiange=357;
-
- // EN+,脱机,高电平有效
- // CW+,方向
- // CLK+,频率(转速)
- int EN=10;
- int CW=11;
- int CLK=12;
-
-
- //脉冲的占空比为1/maichongzhankongbi
- int maichongzhankongbi=4;
-
- ////////////////////////////////////////////
-
- int tempint;
- int maichongjsq=0;//脉冲计数器
-
-
- unsigned long time2=micros();
-
-
- void setup(){
-
- Serial.begin(9600);
-
- pinMode(EN, OUTPUT);// EN+,脱机,高电平有效
- pinMode(CW, OUTPUT);// CW+,方向
- pinMode(CLK, OUTPUT);// CLK+,频率(转速)
-
- digitalWrite(EN, HIGH);//电机默认脱机
- digitalWrite(CW, LOW);//
- digitalWrite(CLK, LOW);
-
- for(int col=2;col<10;col++)pinMode(col, INPUT_PULLUP);
-
- }
-
-
- void loop(){
-
-
-
-
- while (Serial.available() > 0) {
-
- //丧心病狂的单字节控制,0延迟,纯ASCII分拆
- //定义1 0-9表示转速,每一个表示10%
- //定义2 A正转、B反转
- //定义3 C联机、D脱机
-
- tempint=Serial.read();
-
- //调速度
- if(tempint>47 && tempint< 58) maichongjiange = 625/(1.75+3.25*(tempint-48)/10);//0-1023
- //调方向
- else if(tempint==65)digitalWrite(CW, 0);
- else if(tempint==66)digitalWrite(CW, 1);
- //脱机
- else if(tempint==67)digitalWrite(EN, 0);
- else if(tempint==68)digitalWrite(EN, 1);
-
- //E jiansu F jiasu
- else if(tempint==69){
- maichongjiange=maichongjiange+3;
- if(maichongjiange>maichongjiangeMax)maichongjiange=maichongjiangeMax;
- }
- else if(tempint==70){
- maichongjiange=maichongjiange-3;
- if(maichongjiange<maichongjiangeMin)maichongjiange=maichongjiangeMin;
- }
-
-
- Serial.println(maichongjiange);
- tempint=0;
-
- }
-
-
-
- for(int col=10;col>1;col--){
-
- tempint= digitalRead(col);
- if(tempint==LOW){
- Serial.print("Max:");
- Serial.println(col);
- col=0;
-
- }
-
- }
-
- //在脉冲频率无变化的时候驱动电机正常运行
- maichongqudong();
-
-
- }
-
-
-
- void maichongqudong()//脉冲驱动
- {
-
- //步进电机控制脉冲
- if (micros()-time2 > maichongjiange){
-
- maichongjsq++;//每过一个“脉冲间隔”时间段,则“脉冲计数器”自增1
- maichongjsq=maichongjsq%maichongzhankongbi;//对“脉冲计数器”取模,这个取摸结果实质就是对占空比的调节(占空比为1/模),以4为例,则“脉冲计数器”的变化为:0——1——2——3——0
-
- if(maichongjsq==0)digitalWrite(CLK, HIGH);//输出控制步进电机的电平
- else digitalWrite(CLK, LOW);
-
- time2= micros();
- }
-
- }
复制代码
作者: 囧囧-科技大神粉 时间: 2015-2-28 20:18
本帖最后由 囧囧-科技大神粉 于 2015-2-28 20:26 编辑
音压、电机联动,最粗暴的一版
http://www.tudou.com/programs/view/PYSe20YSoy8/
- /*
- 纯串口控制
- 加入脱机控制
- */
-
-
- //电机的高电平持续时间 us
- int maichongjiangeMax=357;
- int maichongjiangeMin=120;
-
- //电机的高电平持续时间的初始值 120us
- int maichongjiange=357;
-
- // EN+,脱机,高电平有效
- // CW+,方向
- // CLK+,频率(转速)
- int EN=10;
- int CW=11;
- int CLK=12;
-
-
- //脉冲的占空比为1/maichongzhankongbi
- int maichongzhankongbi=4;
-
- ////////////////////////////////////////////
-
- int tempint;//打杂的中间数
- int shuaijianzhi;//衰减值
- int maichongjsq=0;//脉冲计数器
-
- boolean zusaiqu=0;//阻塞区
-
- unsigned long time1=micros();//电机CLK
- unsigned long time2=millis();//防止因音频变化而过快的改变电机的运行状态
-
-
- void setup(){
-
- Serial.begin(9600);
-
- pinMode(EN, OUTPUT);// EN+,脱机,高电平有效
- pinMode(CW, OUTPUT);// CW+,方向
- pinMode(CLK, OUTPUT);// CLK+,频率(转速)
-
- digitalWrite(EN, HIGH);//电机默认脱机
- digitalWrite(CW, LOW);//
- digitalWrite(CLK, LOW);
-
- for(int col=2;col<10;col++)pinMode(col, INPUT_PULLUP);
-
- }
-
-
- void loop(){
-
-
-
- //串口调速
- while (Serial.available() > 0) {
-
- //丧心病狂的单字节控制,0延迟,纯ASCII分拆
- //定义1 0-9表示转速,每一个表示10%
- //定义2 A正转、B反转
- //定义3 C联机、D脱机
-
- tempint=Serial.read();
-
- //调速度
- if(tempint>47 && tempint< 58) maichongjiange = 625/(1.75+3.25*(tempint-48)/10);//0-1023
- //调方向
- else if(tempint==65)digitalWrite(CW, 0);
- else if(tempint==66)digitalWrite(CW, 1);
- //脱机
- else if(tempint==67)digitalWrite(EN, 0);
- else if(tempint==68)digitalWrite(EN, 1);
-
- //E jiansu F jiasu
- else if(tempint==69){
- maichongjiange=maichongjiange+3;
- if(maichongjiange>maichongjiangeMax)maichongjiange=maichongjiangeMax;
- }
- else if(tempint==70){
- maichongjiange=maichongjiange-3;
- if(maichongjiange<maichongjiangeMin)maichongjiange=maichongjiangeMin;
- }
-
-
- Serial.println(maichongjiange);
- tempint=0;
-
- }
-
-
-
- //音频调速
-
- if(!zusaiqu){ //阻塞区内不做判断,最粗暴,完善的方法是,阻塞区内低值无效,高值有效
-
- for(int col=9;col>1;col--){
-
- tempint= digitalRead(col);
-
- if(!tempint){ //低电平有效
- zusaiqu=1;//进入阻塞期间
- // Serial.print("Max:"); //实际情况是其发送非常耗时,直接影响了步进电机的运行
- // Serial.println(col);
- //对于速度增加的定义,鉴于其返回值有9、8····2端口值,先粗暴一把吧,直接按声压,而非实际分贝分类
- maichongjiange = 625/(1.75+3.25*(col-1)/8);//
-
- //确定衰减值
- shuaijianzhi=(maichongjiangeMax-maichongjiange)/3;
-
-
- col=0;//跳出循环
- }
- }
-
-
- }else{
-
-
- //核心部分,转速的衰减,暂定为3秒,即声压带来的速度提升效果,会在3秒后消失
- //那么就意味,只有最慢的357才是常态,其他都是浮云
- //衰减暂定为3部曲,每秒衰减1/3,梯形衰减,不做平滑处理(平滑的效果反而很差,因为不是闭环)
- if (millis() - time2 > 1000 && shuaijianzhi>0){
- time2=millis();
-
- maichongjiange=maichongjiange+shuaijianzhi; //脉冲周期增加,频率下降,转速衰减
-
- if(maichongjiange>maichongjiangeMax){
- maichongjiange=maichongjiangeMax;//防止过度衰减
- zusaiqu=0;//退出阻塞期间
- shuaijianzhi=0;//衰减值归零
-
- }
- }
-
-
-
- }
-
-
- //在脉冲频率无变化的时候驱动电机正常运行
- maichongqudong();
-
-
-
-
-
- }
-
-
-
- void maichongqudong()//脉冲驱动
- {
-
- //步进电机控制脉冲
- if (micros()-time1 > maichongjiange){
-
- maichongjsq++;//每过一个“脉冲间隔”时间段,则“脉冲计数器”自增1
- maichongjsq=maichongjsq%maichongzhankongbi;//对“脉冲计数器”取模,这个取摸结果实质就是对占空比的调节(占空比为1/模),以4为例,则“脉冲计数器”的变化为:0——1——2——3——0
-
- if(maichongjsq==0)digitalWrite(CLK, HIGH);//输出控制步进电机的电平
- else digitalWrite(CLK, LOW);
-
- time1= micros();
- }
-
- }
复制代码
作者: 囧囧-科技大神粉 时间: 2015-3-1 11:47
本帖最后由 囧囧-科技大神粉 于 2015-3-1 13:15 编辑
http://www.tudou.com/programs/view/2P5KP6n270o/
音频电压控制电机精细版_修正音频电压与转速的关系
http://www.tudou.com/programs/view/KtN3iQ68DkY/
在16欧耳机内阻的情况下涵盖41-59db,共18db的音频变化,范围太窄,这个需要改进
作者: 囧囧-科技大神粉 时间: 2015-3-3 17:46
/*
纯串口控制
加入脱机控制
加入细分变量 xifen 用1250/xifen 取代625
单周期高电平US——圈/S := (1000000/(X*200))/xifen*0.25=xifen2/X=xifen2/X
*/
//电机的高电平持续时间 us
int maichongjiangeMax=357;
int maichongjiangeMin=120;
//电机的高电平持续时间的初始值 120us
int maichongjiange=357;
// EN+,脱机,高电平有效
// CW+,方向
// CLK+,频率(转速)
int EN=10;
int CW=11;
int CLK=12;
//步进电机控制器的细分数1、2、8、16(整、半、1/8、1/16)、
int xifen=8;
int xifen2;
//10步距角
int bujujiao=18;
//100度所需的色脉冲数,把度数放大,可以极大的提高控制精度,
int dumaichong100;
//脉冲的占空比为1/maichongzhankongbi
int maichongzhankongbi=4;
////////////////////////////////////////////
int tempint;//打杂的中间数
int yunxingmoshi;//运行模式
int moshijsq=0;//模式计数器
boolean fangxiang=0;//电机转动方向标识
int fanzhuanfazhi=0;
float quanshuzy;//圈数增益(量)每秒,作为感官等额衰减的依据
int tempint2;//打杂的中间数2,专注记录,maichongjiange的变化
int maichongjsq=0;//脉冲计数器
unsigned long time1=micros();//电机CLK
unsigned long time2=millis();//防止因音频变化而过快的改变电机的运行状态
void setup(){
Serial.begin(9600);
pinMode(EN, OUTPUT);// EN+,脱机,高电平有效
pinMode(CW, OUTPUT);// CW+,方向
pinMode(CLK, OUTPUT);// CLK+,频率(转速)
digitalWrite(EN, HIGH);//电机默认脱机
digitalWrite(CW, LOW);//
digitalWrite(CLK, LOW);
for(int col=2;col<10;col++)pinMode(col, INPUT_PULLUP);
xifen2=1250/xifen;
dumaichong100=xifen*10/bujujiao; //55(1) \ 111(2) \ 444(8) \ 888(16)
maichongjiangeMax=maichongjiangeMax*2/xifen;
maichongjiangeMin=maichongjiangeMin*2/xifen;
}
void loop(){
//串口调速
while (Serial.available() > 0) {
//丧心病狂的单字节控制,0延迟,纯ASCII分拆
//定义1 0-9表示转速,每一个表示10%
//定义2 A正转、B反转
//定义3 C联机、D脱机
tempint=Serial.read();
//调速度
if(tempint>47 && tempint< 58) maichongjiange = xifen2/(1.75+3.25*(tempint-48)/10);//0-1023
//调方向 A、B
else if(tempint==65){
digitalWrite(CW, 0);
fangxiang=0;
}
else if(tempint==66){
digitalWrite(CW, 1);
fangxiang=1;
}
//联机、脱机 C、D
else if(tempint==67)digitalWrite(EN, 0);
else if(tempint==68)digitalWrite(EN, 1);
//E 减速 F 加速
else if(tempint==69){
maichongjiange=maichongjiange+3;
if(maichongjiange>maichongjiangeMax)maichongjiange=maichongjiangeMax;
}
else if(tempint==70){
maichongjiange=maichongjiange-3;
if(maichongjiange<maichongjiangeMin)maichongjiange=maichongjiangeMin;
}
//模式G 转动
else if(tempint==71)yunxingmoshi=0;
//模式H 摇摆
else if(tempint==72)yunxingmoshi=1;
//模式J
//else if(tempint==73)yunxingmoshi=2;
Serial.println(maichongjiange);
tempint=0;
}
//音频调速
//阻塞区内不做判断,最粗暴,完善的方法是,阻塞区内低值无效,高值有效
for(int col=9;col>1;col--){
tempint= digitalRead(col);
if(!tempint){ //低电平有效
// Serial.print("Max:"); //实际情况是其发送非常耗时,直接影响了步进电机的运行
// Serial.println(col);
//对于速度增加的定义,鉴于其返回值有9、8····2端口值,先粗暴一把吧,直接按声压,而非实际分贝分类
// tempint2 = xifen2/(1.75+3.25*(col-1)/8);//在变化有效的情况下,maichongjiange的值得
//实际人耳的分类,与电压、耳机灵敏度有关
//现在以100db/mw灵敏度的耳机进行分类
//目前实测,2个LM339的,8个基准脚的电压与接口、分贝对于关系为
/*
IO 2 \ 3 \ 4 \ 5 \ 6 \ 7 \ 8 \ 9
基准mV 6.5 \ 12.9\ 19.5\ 26.1\ 33 \ 39.8\ 46.2\ 53.1
32欧对应db 41.2\ 47.1\ 50.7\ 53.2\ 55.3\ 56.9\ 58.2\ 59.4
16欧对应db 44.2\ 50.1\ 53.7\ 56.2\ 58.3\ 59.9\ 61.2\ 62.4
定义每个等级增加 0.40625圈,8个增量 =3.25圈
可见
1、耳机内阻减小虽然会导致功率翻倍,但分贝数不过变化3
2、坑爹啊,基准值取得太高,导致范围曲在了41-59db,所需音量太大(电脑音量输出50%以上),且范围窄(小于提速无效,大于衰减无效)
3、如果在32欧内阻下测量,需要细分到2mV(31db)、3mV(34db)、4mv(36.9db),328p分辨率不足,LM339的10mv分辨率更不足,需要放大
*/
tempint2 = xifen2/(1.75+0.40625*(col-1));//在变化有效的情况下,maichongjiange的值得
//仅当新值低于现值(周期短,频率高),此变化才是有效的
if(maichongjiange>tempint2){
maichongjiange=tempint2;
if(yunxingmoshi==1)fanzhuanfazhi=5*col;//反转阀值度数的确定,取端口值的5倍数
}
col=0;//跳出循环
}
}
//核心部分,转速的衰减,暂定为3秒,即声压带来的速度提升效果,会在3秒后消失
//那么就意味,只有最慢的357才是常态,其他都是浮云
//衰减暂定为3部曲,每秒衰减1/3,梯形衰减,不做平滑处理(平滑的效果反而很差,因为不是闭环)
if (millis() - time2 > 1000){
time2=millis();
//确定衰减值,这次是动态计算,理想中省资源的方式是直接分类
//先确定增益圈数
quanshuzy=xifen2/maichongjiange - 1.75;//等价 xifen2/maichongjiange - xifen2/maichongjiangeMax
//每次衰减增益数的20%
//等价xifen2/(1.75+quanshuzy*0.8)
//理论上,只要quanshuzy不为负,就速度下限就是1.75圈/秒,但328p的浮点不靠谱性得防
if(quanshuzy>0){
maichongjiange=xifen2/(1.75+quanshuzy*0.8); //脉冲周期增加,频率下降,转速衰减
if(yunxingmoshi==1 && fanzhuanfazhi>10)fanzhuanfazhi=fanzhuanfazhi*0.8;//H模式下,同转速,每次衰减20%
}else{
fanzhuanfazhi=5;
quanshuzy=0;
}
}
//在脉冲频率无变化的时候驱动电机正常运行
maichongqudong();
}
void maichongqudong()//脉冲驱动
{
//步进电机控制脉冲
if (micros()-time1 > maichongjiange){
maichongjsq++;//每过一个“脉冲间隔”时间段,则“脉冲计数器”自增1
maichongjsq=maichongjsq%maichongzhankongbi;//对“脉冲计数器”取模,这个取摸结果实质就是对占空比的调节(占空比为1/模),以4为例,则“脉冲计数器”的变化为:0——1——2——3——0
if(maichongjsq==0){
digitalWrite(CLK, HIGH);//输出控制步进电机的电平
///////////////////////////////////////////////////////////////////////////////////
//H模式
if(yunxingmoshi==1){
//对于脉冲数的计数
if(fangxiang)moshijsq++;
else moshijsq--;
//反转阀值折算为脉冲数进行反转
tempint=fanzhuanfazhi*dumaichong100/100; // 需要度数*100度所需周期数
if(moshijsq<-tempint || moshijsq>tempint){ //达到既定周期后反向
fangxiang=!fangxiang;
digitalWrite(CW, fangxiang);
}
}
/////////////////////////////////////////////////////////////////////////////////////
}else digitalWrite(CLK, LOW);
time1= micros();
}
}
作者: 囧囧-科技大神粉 时间: 2015-3-3 21:07
- /*
- 纯串口控制
- 加入脱机控制
- 加入细分变量 xifen 用1250/xifen 取代625
- 单周期高电平US——圈/S := (1000000/(X*200))/xifen*0.25=xifen2/X=xifen2/X
- */
- //电机的高电平持续时间 us
- int maichongjiangeMax=1563;
- int maichongjiangeMin=174;
- //电机的高电平持续时间的初始值 120us
- int maichongjiange=357;
- // EN+,脱机,高电平有效
- // CW+,方向
- // CLK+,频率(转速)
- int EN=10;
- int CW=11;
- int CLK=12;
- //步进电机控制器的细分数1、2、8、16(整、半、1/8、1/16)、
- int xifen=8;
- int xifen2;
- //10步距角
- int bujujiao=18;
- //100度所需的色脉冲数,把度数放大,可以极大的提高控制精度,
- int dumaichong100;
- //脉冲的占空比为1/maichongzhankongbi
- int maichongzhankongbi=4;
- ////////////////////////////////////////////
- int tempint;//打杂的中间数
- int yunxingmoshi;//运行模式
- int moshijsq=0;//模式计数器
- boolean fangxiang=0;//电机转动方向标识
- int fanzhuanfazhi=0;
- float quanshuzy;//圈数增益(量)每秒,作为感官等额衰减的依据
- int tempint2;//打杂的中间数2,专注记录,maichongjiange的变化
- int maichongjsq=0;//脉冲计数器
- unsigned long time1=micros();//电机CLK
- unsigned long time2=millis();//防止因音频变化而过快的改变电机的运行状态
- void setup(){
- Serial.begin(9600);
- pinMode(EN, OUTPUT);// EN+,脱机,高电平有效
- pinMode(CW, OUTPUT);// CW+,方向
- pinMode(CLK, OUTPUT);// CLK+,频率(转速)
- digitalWrite(EN, HIGH);//电机默认脱机
- digitalWrite(CW, LOW);//
- digitalWrite(CLK, LOW);
- for(int col=2;col<10;col++)pinMode(col, INPUT_PULLUP);
- xifen2=1250/xifen;
- dumaichong100=xifen*1000/bujujiao; //55(1) \ 111(2) \ 444(8) \ 888(16)
- }
- void loop(){
- //串口调速
- while (Serial.available() > 0) {
- //丧心病狂的单字节控制,0延迟,纯ASCII分拆
- //定义1 0-9表示转速,每一个表示10%
- //定义2 A正转、B反转
- //定义3 C联机、D脱机
- tempint=Serial.read();
- //调速度
- if(tempint>47 && tempint< 57) maichongjiange = xifen2/(0.1+0.1*(tempint-48));//0-1023
- //调方向 A、B
- else if(tempint==65){
- digitalWrite(CW, 0);
- fangxiang=0;
- }
- else if(tempint==66){
- digitalWrite(CW, 1);
- fangxiang=1;
- }
- //联机、脱机 C、D
- else if(tempint==67)digitalWrite(EN, 0);
- else if(tempint==68)digitalWrite(EN, 1);
- //E 减速 F 加速
- else if(tempint==69){
- maichongjiange=maichongjiange+3;
- if(maichongjiange>maichongjiangeMax)maichongjiange=maichongjiangeMax;
- }
- else if(tempint==70){
- maichongjiange=maichongjiange-3;
- if(maichongjiange<maichongjiangeMin)maichongjiange=maichongjiangeMin;
- }
- //模式G 转动
- else if(tempint==71)yunxingmoshi=0;
- //模式H 摇摆
- else if(tempint==72)yunxingmoshi=1;
- else tempint=0;
- Serial.println(maichongjiange);
- tempint=0;
- }
- //音频调速
- //阻塞区内不做判断,最粗暴,完善的方法是,阻塞区内低值无效,高值有效
- for(int col=9;col>1;col--){
- tempint= digitalRead(col);
- if(!tempint){ //低电平有效
- // Serial.print("Max:"); //实际情况是其发送非常耗时,直接影响了步进电机的运行
- // Serial.println(col);
- //对于速度增加的定义,鉴于其返回值有9、8····2端口值,先粗暴一把吧,直接按声压,而非实际分贝分类
- // tempint2 = xifen2/(1.75+3.25*(col-1)/8);//在变化有效的情况下,maichongjiange的值得
- //实际人耳的分类,与电压、耳机灵敏度有关
- //现在以100db/mw灵敏度的耳机进行分类
- //目前实测,2个LM339的,8个基准脚的电压与接口、分贝对于关系为
- /*
- IO 2 \ 3 \ 4 \ 5 \ 6 \ 7 \ 8 \ 9
- 基准mV 6.5 \ 12.9\ 19.5\ 26.1\ 33 \ 39.8\ 46.2\ 53.1
- 32欧对应db 41.2\ 47.1\ 50.7\ 53.2\ 55.3\ 56.9\ 58.2\ 59.4
- 16欧对应db 44.2\ 50.1\ 53.7\ 56.2\ 58.3\ 59.9\ 61.2\ 62.4
- 定义每个等级增加 0.1圈,8个增量 =0.8圈
- 可见
- 1、耳机内阻减小虽然会导致功率翻倍,但分贝数不过变化3
- 2、坑爹啊,基准值取得太高,导致范围曲在了41-59db,所需音量太大(电脑音量输出50%以上),且范围窄(小于提速无效,大于衰减无效)
- 3、如果在32欧内阻下测量,需要细分到2mV(31db)、3mV(34db)、4mv(36.9db),328p分辨率不足,LM339的10mv分辨率更不足,需要放大
- */
- tempint2 = xifen2/(0.1*col);//在变化有效的情况下,maichongjiange的值得
- //仅当新值低于现值(周期短,频率高),此变化才是有效的
- if(maichongjiange>tempint2){
- maichongjiange=tempint2;
- if(yunxingmoshi==1)fanzhuanfazhi=5*col;//反转阀值度数的确定,取端口值的5倍数
- }
- col=0;//跳出循环
- }
- }
- //核心部分,转速的衰减,暂定为3秒,即声压带来的速度提升效果,会在3秒后消失
- //那么就意味,只有最慢的357才是常态,其他都是浮云
- //衰减暂定为3部曲,每秒衰减1/3,梯形衰减,不做平滑处理(平滑的效果反而很差,因为不是闭环)
- if (millis() - time2 > 1000){
- //确定衰减值,这次是动态计算,理想中省资源的方式是直接分类
- //先确定增益圈数
- quanshuzy=xifen2/maichongjiange - 0.1;//等价 xifen2/maichongjiange - xifen2/maichongjiangeMax
- //每次衰减增益数的20%
- //理论上,只要quanshuzy不为负,就速度下限就是0.1圈/秒,但328p的浮点不靠谱性得防
- if(maichongjiangeMax>maichongjiange){
- maichongjiange=xifen2/(0.1+quanshuzy*0.8); //脉冲周期增加,频率下降,转速衰减
- if(yunxingmoshi==1 && fanzhuanfazhi>10)fanzhuanfazhi=fanzhuanfazhi*0.8;//H模式下,同转速,每次衰减20%
- }else{
- fanzhuanfazhi=5;
- maichongjiange=maichongjiangeMax;
- }
- time2=millis();
- }
- //在脉冲频率无变化的时候驱动电机正常运行
- maichongqudong();
- }
- void maichongqudong()//脉冲驱动
- {
- maichongjsq++;//每过一个“脉冲间隔”时间段,则“脉冲计数器”自增1
- maichongjsq=maichongjsq%maichongzhankongbi;//对“脉冲计数器”取模,这个取摸结果实质就是对占空比的调节(占空比为1/模),以4为例,则“脉冲计数器”的变化为:0——1——2——3——0
- if(maichongjsq==0){
- digitalWrite(CLK, HIGH);//输出控制步进电机的电平
- ///////////////////////////////////////////////////////////////////////////////////
- //H模式
- if(yunxingmoshi==1){
- //对于脉冲数的计数
- if(fangxiang)moshijsq++;
- else moshijsq--;
- //反转阀值折算为脉冲数进行反转
- tempint=fanzhuanfazhi*dumaichong100/100; // 需要度数*100度所需周期数
- if(moshijsq<-tempint || moshijsq>tempint){ //达到既定周期后反向
- fangxiang=!fangxiang;
- digitalWrite(CW, fangxiang);
- }
- }
- /////////////////////////////////////////////////////////////////////////////////////
- }else digitalWrite(CLK, LOW);
- }
复制代码
作者: 囧囧-科技大神粉 时间: 2015-3-4 12:06
待修改的半成品
- // EN+,脱机,高电平有效
- // CW+,方向
- // CLK+,频率(转速)
- int EN=10;
- int CW=11;
- int CLK=12;
-
- //步进电机控制器的细分数1、2、8、16(整、半、1/8、1/16)、整步用loop的方式是不行的,脉冲周期太短
- int xifen=2;
- //10步距角
- int bujujiao=18;
- //100度所需的色脉冲数,把度数放大,可以极大的提高控制精度,
- int dumaichong100;
-
- //脉冲的占空比为1/maichongzhankongbi
- int maichongzhankongbi=4;
-
- ////////////////////////////////////////////
-
- int tempint;//打杂的中间数
- int yunxingmoshi;//运行模式
- int moshijsq=0;//模式计数器
- boolean fangxiang=0;//电机转动方向标识
- int fanzhuanfazhi=0;//反转阀值
- float quanshuzy;//圈数增益(量)每秒,作为感官等额衰减的依据
- int tempint2;//打杂的中间数2,专注记录,maichongjiange的变化
- int maichongjsq=0;//脉冲计数器
-
- int loopjsq=0;
- unsigned long loopjsq2=0;
- float zhuansunow=0;
- float zhuansuWill=0;
- boolean suduok=0;
- boolean suduok2=0;
- int tuoshijian;//拖时间,每增加1,则周期增加 基数×占空比
- unsigned long time0=millis();
-
- unsigned long time1=micros();//电机CLK
- unsigned long time3=millis();//防止因音频变化而过快的改变电机的运行状态
-
-
- void setup(){
-
- Serial.begin(9600);
-
- pinMode(EN, OUTPUT);// EN+,脱机,高电平有效
- pinMode(CW, OUTPUT);// CW+,方向
- pinMode(CLK, OUTPUT);// CLK+,频率(转速)
-
- digitalWrite(EN, HIGH);//电机默认脱机
- digitalWrite(CW, LOW);//
- digitalWrite(CLK, LOW);
-
- for(int col=2;col<10;col++)pinMode(col, INPUT_PULLUP);
- dumaichong100=xifen*1000/bujujiao; //走100度所需脉冲数5555(1) \ 111(2) \ 444(8) \ 888(16)
-
- }
-
-
-
-
- void loop(){
-
-
- //获得可达到的最高理论转速,半步的情况下大概6转/秒,10ms测速一次
-
- loopjsq++;
- if (millis() - time0 > 10){
- //此刻的loopjsq本质就是loop的运行次数,因为电机控制脉冲是以一次loop为基础的
- //转速 转/s = 有效脉冲数/细分/200
-
- /*
- 表达方式无效 zhuansunow=loopjsq/(maichongzhankongbi*xifen*200);
-
- 328p扯淡的故事~~~
- 其中, zhuansunow为float,其他为int
- tempint=maichongzhankongbi*xifen*200;
- zhuansunow=loopjsq/tempint;
- 计算错误!!
- zhuansunow=maichongzhankongbi*xifen*200;
- zhuansunow=loopjsq/ zhuansunow;
- 计算正确
- */
-
- zhuansunow=maichongzhankongbi*xifen*2;
- zhuansunow=loopjsq/zhuansunow; //计算出每秒圈速
-
- //引入布尔量,证明这个速度是可用的
- suduok=1;
- suduok2=1;
-
-
- loopjsq=0;
-
- time0=millis();
- }
-
-
-
- //串口调速
- chuankoutiaosu();
-
-
-
- //音频调速
- yinpintiaosu();
-
-
- //速度衰减
- sudushuaijian();
-
-
- //速度的调节
-
-
- if(suduok){
- suduok=0;
-
- if(zhuansuWill<zhuansunow)tuoshijian++;
- else if(tuoshijian>1)tuoshijian--;
- }
-
-
-
-
- for(int col=1;col<tuoshijian;col++)delayMicroseconds(10);
-
-
- //在脉冲频率无变化的时候驱动电机正常运行
- maichongqudong();
-
-
-
-
-
- }
-
-
-
- void maichongqudong()//脉冲驱动
- {
-
- maichongjsq++;//每过一个“脉冲间隔”时间段,则“脉冲计数器”自增1
- maichongjsq=maichongjsq%maichongzhankongbi;//对“脉冲计数器”取模,这个取摸结果实质就是对占空比的调节(占空比为1/模),以4为例,则“脉冲计数器”的变化为:0——1——2——3——0
-
- if(maichongjsq==0){
-
- digitalWrite(CLK, HIGH);//输出控制步进电机的电平
-
- ///////////////////////////////////////////////////////////////////////////////////
- //H模式
- if(yunxingmoshi==1){
- //对于脉冲数的计数
- if(fangxiang)moshijsq++;
- else moshijsq--;
-
- //反转阀值折算为脉冲数进行反转
- tempint=fanzhuanfazhi*dumaichong100/100; // 需要度数*100度所需周期数
-
- if(moshijsq<-tempint || moshijsq>tempint){ //达到既定周期后反向
- fangxiang=!fangxiang;
- digitalWrite(CW, fangxiang);
- }
- }
-
-
- /////////////////////////////////////////////////////////////////////////////////////
-
- }else digitalWrite(CLK, LOW);
-
-
-
- }
- void sudushuaijian(){
-
-
- //核心部分,转速的衰减
- //此处用计数器代替时间
- //设每转2圈减速一次
- //理论上maichongzhankongbi*200*xifen =1圈 ,25%占空比、16细分,一圈为12800脉冲
- //换言之 loopjsq2 为int时,占空比应该大于10%,改为unsigned long后就比较随意了
- loopjsq2++;
- if (loopjsq2 > maichongzhankongbi*400*xifen){
-
- loopjsq2=0;
- Serial.print(zhuansuWill);
- Serial.print("zhuansuWill/zhuansunow=");
- Serial.println(zhuansunow);
-
-
- if(zhuansunow>0.5)zhuansuWill = zhuansuWill*0.95;
- else zhuansuWill=0.5;
-
- if(yunxingmoshi==1 && fanzhuanfazhi>10)fanzhuanfazhi=fanzhuanfazhi*0.8;//H模式下,同转速,每次衰减20%
-
- }
-
-
-
-
-
- }
- void yinpintiaosu(){
-
- //阻塞区内不做判断,最粗暴,完善的方法是,阻塞区内低值无效,高值有效
-
- for(int col=9;col>1;col--){
-
- tempint= digitalRead(col);
-
- if(!tempint){ //低电平有效
-
- // Serial.print("Max:"); //实际情况是其发送非常耗时,直接影响了步进电机的运行
- // Serial.println(col);
- //对于速度增加的定义,鉴于其返回值有9、8····2端口值,先粗暴一把吧,直接按声压,而非实际分贝分类
- // tempint2 = xifen2/(1.75+3.25*(col-1)/8);//在变化有效的情况下,maichongjiange的值得
- //实际人耳的分类,与电压、耳机灵敏度有关
- //现在以100db/mw灵敏度的耳机进行分类
- //目前实测,2个LM339的,8个基准脚的电压与接口、分贝对于关系为
- /*
- IO 2 \ 3 \ 4 \ 5 \ 6 \ 7 \ 8 \ 9
- 基准mV 6.5 \ 12.9\ 19.5\ 26.1\ 33 \ 39.8\ 46.2\ 53.1
- 32欧对应db 41.2\ 47.1\ 50.7\ 53.2\ 55.3\ 56.9\ 58.2\ 59.4
- 16欧对应db 44.2\ 50.1\ 53.7\ 56.2\ 58.3\ 59.9\ 61.2\ 62.4
-
- 可见
- 1、耳机内阻减小虽然会导致功率翻倍,但分贝数不过变化3
- 2、坑爹啊,基准值取得太高,导致范围曲在了41-59db,所需音量太大(电脑音量输出50%以上),且范围窄(小于提速无效,大于衰减无效)
- 3、如果在32欧内阻下测量,需要细分到2mV(31db)、3mV(34db)、4mv(36.9db),328p分辨率不足,LM339的10mv分辨率更不足,需要放大
-
- */
-
-
-
- //仅当新值低于现值(周期短,频率高),此变化才是有效的
-
- float zhuansuWill2 = 0.5*col+0.5;
-
- if(zhuansuWill2>zhuansuWill){
-
- zhuansuWill = zhuansuWill2;
-
- if(yunxingmoshi==1)fanzhuanfazhi=5*col;//反转阀值度数的确定,取端口值的5倍数
- }
-
-
-
-
- col=0;//跳出循环
- }
- }
-
-
- }
- void chuankoutiaosu(){
-
- //串口调速
- while (Serial.available() > 0) {
-
- //丧心病狂的单字节控制,0延迟,纯ASCII分拆
- //定义1 0-9表示转速,每一个表示10%
- //定义2 A正转、B反转
- //定义3 C联机、D脱机
-
- tempint=Serial.read();
-
- //调速度
- if(tempint>47 && tempint< 58) zhuansuWill = 0.5*(tempint-47);//48——58(0.5——5)
- //调方向 A、B
- else if(tempint==65){
- digitalWrite(CW, 0);
- fangxiang=0;
- }
- else if(tempint==66){
- digitalWrite(CW, 1);
- fangxiang=1;
- }
- //联机、脱机 C、D
- else if(tempint==67)digitalWrite(EN, 0);
- else if(tempint==68)digitalWrite(EN, 1);
-
- //E 减速 F 加速
- else if(tempint==69){
- zhuansuWill = zhuansuWill*0.95;
- }
- else if(tempint==70){
- zhuansuWill = zhuansuWill*1.05;
- }
-
- //模式G 转动
- else if(tempint==71)yunxingmoshi=0;
- //模式H 摇摆
- else if(tempint==72)yunxingmoshi=1;
- else tempint=0;
-
-
-
-
- Serial.println(zhuansunow);
-
- }
-
- }
复制代码
欢迎光临 狗趴(GodPub),开源硬件学习与实践 (http://forum.godpub.com/) |
Powered by Discuz! X3.2 |