狗趴(GodPub),开源硬件学习与实践

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 9720|回复: 6
打印 上一主题 下一主题

8个LED的音量表 的思考

[复制链接]

5

主题

36

帖子

141

积分

QQ群用户

积分
141
跳转到指定楼层
楼主
发表于 2015-2-26 19:10:37 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 囧囧-科技大神粉 于 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种单片机读音频的电路



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏

5

主题

36

帖子

141

积分

QQ群用户

积分
141
沙发
 楼主| 发表于 2015-2-26 23:45:18 | 只看该作者
本帖最后由 囧囧-科技大神粉 于 2015-2-28 09:29 编辑



  1. /*
  2. 纯串口控制
  3.   加入脱机控制
  4. */


  5. //电机的高电平持续时间 us
  6. int maichongjiangeMax=357;
  7. int maichongjiangeMin=120;

  8. //电机的高电平持续时间的初始值 120us
  9. int maichongjiange=357;

  10. // EN+,脱机,高电平有效
  11. // CW+,方向
  12. // CLK+,频率(转速)
  13. int EN=10;
  14. int CW=11;
  15. int CLK=12;


  16. //脉冲的占空比为1/maichongzhankongbi
  17. int maichongzhankongbi=4;

  18. ////////////////////////////////////////////

  19. int tempint;
  20. int maichongjsq=0;//脉冲计数器


  21. unsigned long time2=micros();


  22. void setup(){

  23. Serial.begin(9600);

  24. pinMode(EN, OUTPUT);// EN+,脱机,高电平有效
  25. pinMode(CW, OUTPUT);// CW+,方向
  26. pinMode(CLK, OUTPUT);// CLK+,频率(转速)

  27. digitalWrite(EN, HIGH);//电机默认脱机
  28. digitalWrite(CW, LOW);//
  29. digitalWrite(CLK, LOW);

  30. for(int col=2;col<10;col++)pinMode(col, INPUT_PULLUP);

  31. }


  32. void loop(){




  33.    while (Serial.available() > 0) {

  34.     //丧心病狂的单字节控制,0延迟,纯ASCII分拆
  35.         //定义1 0-9表示转速,每一个表示10%
  36.         //定义2 A正转、B反转
  37.         //定义3 C联机、D脱机

  38.    tempint=Serial.read();

  39.    //调速度
  40.    if(tempint>47 && tempint< 58) maichongjiange = 625/(1.75+3.25*(tempint-48)/10);//0-1023
  41.    //调方向
  42.    else if(tempint==65)digitalWrite(CW, 0);
  43.    else if(tempint==66)digitalWrite(CW, 1);
  44.     //脱机
  45.    else if(tempint==67)digitalWrite(EN, 0);
  46.    else if(tempint==68)digitalWrite(EN, 1);

  47. //E jiansu   F jiasu
  48.    else if(tempint==69){
  49.     maichongjiange=maichongjiange+3;
  50.     if(maichongjiange>maichongjiangeMax)maichongjiange=maichongjiangeMax;
  51.    }
  52.    else if(tempint==70){
  53.     maichongjiange=maichongjiange-3;
  54.     if(maichongjiange<maichongjiangeMin)maichongjiange=maichongjiangeMin;
  55.    }


  56.    Serial.println(maichongjiange);
  57.    tempint=0;

  58. }



  59. for(int col=10;col>1;col--){

  60.      tempint= digitalRead(col);
  61.          if(tempint==LOW){
  62.                  Serial.print("Max:");
  63.                  Serial.println(col);
  64.                  col=0;

  65.          }

  66. }

  67. //在脉冲频率无变化的时候驱动电机正常运行
  68. maichongqudong();


  69. }



  70. void maichongqudong()//脉冲驱动
  71. {

  72. //步进电机控制脉冲
  73. if (micros()-time2 > maichongjiange){

  74.         maichongjsq++;//每过一个“脉冲间隔”时间段,则“脉冲计数器”自增1
  75.         maichongjsq=maichongjsq%maichongzhankongbi;//对“脉冲计数器”取模,这个取摸结果实质就是对占空比的调节(占空比为1/模),以4为例,则“脉冲计数器”的变化为:0——1——2——3——0

  76.         if(maichongjsq==0)digitalWrite(CLK, HIGH);//输出控制步进电机的电平
  77.         else digitalWrite(CLK, LOW);

  78.      time2= micros();
  79. }

  80. }
复制代码


5

主题

36

帖子

141

积分

QQ群用户

积分
141
板凳
 楼主| 发表于 2015-2-28 20:18:25 | 只看该作者
本帖最后由 囧囧-科技大神粉 于 2015-2-28 20:26 编辑

音压、电机联动,最粗暴的一版


  1. /*
  2. 纯串口控制
  3.   加入脱机控制
  4. */


  5. //电机的高电平持续时间 us
  6. int maichongjiangeMax=357;
  7. int maichongjiangeMin=120;

  8. //电机的高电平持续时间的初始值 120us
  9. int maichongjiange=357;

  10. // EN+,脱机,高电平有效
  11. // CW+,方向
  12. // CLK+,频率(转速)
  13. int EN=10;
  14. int CW=11;
  15. int CLK=12;


  16. //脉冲的占空比为1/maichongzhankongbi
  17. int maichongzhankongbi=4;

  18. ////////////////////////////////////////////

  19. int tempint;//打杂的中间数


  20. int shuaijianzhi;//衰减值

  21. int maichongjsq=0;//脉冲计数器

  22. boolean zusaiqu=0;//阻塞区


  23. unsigned long time1=micros();//电机CLK

  24. unsigned long time2=millis();//防止因音频变化而过快的改变电机的运行状态


  25. void setup(){

  26. Serial.begin(9600);

  27. pinMode(EN, OUTPUT);// EN+,脱机,高电平有效
  28. pinMode(CW, OUTPUT);// CW+,方向
  29. pinMode(CLK, OUTPUT);// CLK+,频率(转速)

  30. digitalWrite(EN, HIGH);//电机默认脱机
  31. digitalWrite(CW, LOW);//
  32. digitalWrite(CLK, LOW);

  33. for(int col=2;col<10;col++)pinMode(col, INPUT_PULLUP);

  34. }


  35. void loop(){



  36. //串口调速
  37.    while (Serial.available() > 0) {

  38.     //丧心病狂的单字节控制,0延迟,纯ASCII分拆
  39.         //定义1 0-9表示转速,每一个表示10%
  40.         //定义2 A正转、B反转
  41.         //定义3 C联机、D脱机

  42.    tempint=Serial.read();

  43.    //调速度
  44.    if(tempint>47 && tempint< 58) maichongjiange = 625/(1.75+3.25*(tempint-48)/10);//0-1023
  45.    //调方向
  46.    else if(tempint==65)digitalWrite(CW, 0);
  47.    else if(tempint==66)digitalWrite(CW, 1);
  48.     //脱机
  49.    else if(tempint==67)digitalWrite(EN, 0);
  50.    else if(tempint==68)digitalWrite(EN, 1);

  51. //E jiansu   F jiasu
  52.    else if(tempint==69){
  53.     maichongjiange=maichongjiange+3;
  54.     if(maichongjiange>maichongjiangeMax)maichongjiange=maichongjiangeMax;
  55.    }
  56.    else if(tempint==70){
  57.     maichongjiange=maichongjiange-3;
  58.     if(maichongjiange<maichongjiangeMin)maichongjiange=maichongjiangeMin;
  59.    }


  60.    Serial.println(maichongjiange);
  61.    tempint=0;

  62. }



  63. //音频调速

  64. if(!zusaiqu){ //阻塞区内不做判断,最粗暴,完善的方法是,阻塞区内低值无效,高值有效

  65.         for(int col=9;col>1;col--){

  66.                 tempint= digitalRead(col);
  67.                
  68.          if(!tempint){ //低电平有效
  69.                                 zusaiqu=1;//进入阻塞期间
  70.                 // Serial.print("Max:"); //实际情况是其发送非常耗时,直接影响了步进电机的运行
  71.                 // Serial.println(col);
  72.                                 //对于速度增加的定义,鉴于其返回值有9、8····2端口值,先粗暴一把吧,直接按声压,而非实际分贝分类
  73.                                 maichongjiange = 625/(1.75+3.25*(col-1)/8);//
  74.                                 
  75.                                 //确定衰减值
  76.                                 shuaijianzhi=(maichongjiangeMax-maichongjiange)/3;
  77.         
  78.    
  79.                 col=0;//跳出循环
  80.          }
  81.         }


  82. }else{
  83.          
  84.          
  85. //核心部分,转速的衰减,暂定为3秒,即声压带来的速度提升效果,会在3秒后消失
  86. //那么就意味,只有最慢的357才是常态,其他都是浮云
  87. //衰减暂定为3部曲,每秒衰减1/3,梯形衰减,不做平滑处理(平滑的效果反而很差,因为不是闭环)
  88.         if (millis() - time2 > 1000 && shuaijianzhi>0){
  89.         time2=millis();
  90.         
  91.                         maichongjiange=maichongjiange+shuaijianzhi; //脉冲周期增加,频率下降,转速衰减
  92.                         
  93.                         if(maichongjiange>maichongjiangeMax){
  94.                                 maichongjiange=maichongjiangeMax;//防止过度衰减
  95.                                 zusaiqu=0;//退出阻塞期间
  96.                                 shuaijianzhi=0;//衰减值归零
  97.                                 
  98.                         }

  99.         }



  100. }



  101. //在脉冲频率无变化的时候驱动电机正常运行
  102. maichongqudong();






  103. }



  104. void maichongqudong()//脉冲驱动
  105. {

  106. //步进电机控制脉冲
  107. if (micros()-time1 > maichongjiange){

  108.         maichongjsq++;//每过一个“脉冲间隔”时间段,则“脉冲计数器”自增1
  109.         maichongjsq=maichongjsq%maichongzhankongbi;//对“脉冲计数器”取模,这个取摸结果实质就是对占空比的调节(占空比为1/模),以4为例,则“脉冲计数器”的变化为:0——1——2——3——0

  110.         if(maichongjsq==0)digitalWrite(CLK, HIGH);//输出控制步进电机的电平
  111.         else digitalWrite(CLK, LOW);

  112.      time1= micros();
  113. }

  114. }
复制代码


5

主题

36

帖子

141

积分

QQ群用户

积分
141
地板
 楼主| 发表于 2015-3-1 11:47:49 | 只看该作者
本帖最后由 囧囧-科技大神粉 于 2015-3-1 13:15 编辑




音频电压控制电机精细版_修正音频电压与转速的关系

在16欧耳机内阻的情况下涵盖41-59db,共18db的音频变化,范围太窄,这个需要改进

5

主题

36

帖子

141

积分

QQ群用户

积分
141
5#
 楼主| 发表于 2015-3-3 17:46:29 | 只看该作者
/*
纯串口控制
  加入脱机控制
  加入细分变量 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();
}



}


5

主题

36

帖子

141

积分

QQ群用户

积分
141
6#
 楼主| 发表于 2015-3-3 21:07:21 | 只看该作者
  1. /*
  2. 纯串口控制
  3.   加入脱机控制
  4.   加入细分变量 xifen 用1250/xifen 取代625
  5.   单周期高电平US——圈/S := (1000000/(X*200))/xifen*0.25=xifen2/X=xifen2/X

  6. */


  7. //电机的高电平持续时间 us
  8. int maichongjiangeMax=1563;
  9. int maichongjiangeMin=174;

  10. //电机的高电平持续时间的初始值 120us
  11. int maichongjiange=357;

  12. // EN+,脱机,高电平有效
  13. // CW+,方向
  14. // CLK+,频率(转速)
  15. int EN=10;
  16. int CW=11;
  17. int CLK=12;

  18. //步进电机控制器的细分数1、2、8、16(整、半、1/8、1/16)、
  19. int xifen=8;
  20. int xifen2;

  21. //10步距角
  22. int bujujiao=18;
  23. //100度所需的色脉冲数,把度数放大,可以极大的提高控制精度,
  24. int dumaichong100;

  25. //脉冲的占空比为1/maichongzhankongbi
  26. int maichongzhankongbi=4;

  27. ////////////////////////////////////////////

  28. int tempint;//打杂的中间数

  29. int yunxingmoshi;//运行模式
  30. int moshijsq=0;//模式计数器
  31. boolean fangxiang=0;//电机转动方向标识
  32. int fanzhuanfazhi=0;

  33. float quanshuzy;//圈数增益(量)每秒,作为感官等额衰减的依据
  34. int tempint2;//打杂的中间数2,专注记录,maichongjiange的变化

  35. int maichongjsq=0;//脉冲计数器




  36. unsigned long time1=micros();//电机CLK

  37. unsigned long time2=millis();//防止因音频变化而过快的改变电机的运行状态


  38. void setup(){

  39. Serial.begin(9600);

  40. pinMode(EN, OUTPUT);// EN+,脱机,高电平有效
  41. pinMode(CW, OUTPUT);// CW+,方向
  42. pinMode(CLK, OUTPUT);// CLK+,频率(转速)

  43. digitalWrite(EN, HIGH);//电机默认脱机
  44. digitalWrite(CW, LOW);//
  45. digitalWrite(CLK, LOW);

  46. for(int col=2;col<10;col++)pinMode(col, INPUT_PULLUP);

  47. xifen2=1250/xifen;
  48. dumaichong100=xifen*1000/bujujiao; //55(1)        \        111(2)        \        444(8)        \        888(16)

  49. }


  50. void loop(){



  51. //串口调速
  52.    while (Serial.available() > 0) {

  53.     //丧心病狂的单字节控制,0延迟,纯ASCII分拆
  54.         //定义1 0-9表示转速,每一个表示10%
  55.         //定义2 A正转、B反转
  56.         //定义3 C联机、D脱机

  57.    tempint=Serial.read();

  58.    //调速度
  59.    if(tempint>47 && tempint< 57) maichongjiange = xifen2/(0.1+0.1*(tempint-48));//0-1023
  60.    //调方向 A、B
  61.    else if(tempint==65){
  62.     digitalWrite(CW, 0);
  63.     fangxiang=0;
  64.    }
  65.    else if(tempint==66){
  66.     digitalWrite(CW, 1);
  67.     fangxiang=1;
  68.    }
  69.     //联机、脱机 C、D
  70.    else if(tempint==67)digitalWrite(EN, 0);
  71.    else if(tempint==68)digitalWrite(EN, 1);

  72. //E 减速   F 加速
  73.    else if(tempint==69){
  74.     maichongjiange=maichongjiange+3;
  75.     if(maichongjiange>maichongjiangeMax)maichongjiange=maichongjiangeMax;
  76.    }
  77.    else if(tempint==70){
  78.     maichongjiange=maichongjiange-3;
  79.     if(maichongjiange<maichongjiangeMin)maichongjiange=maichongjiangeMin;
  80.    }

  81.    //模式G 转动
  82.    else if(tempint==71)yunxingmoshi=0;
  83.    //模式H 摇摆
  84.    else if(tempint==72)yunxingmoshi=1;

  85.    else tempint=0;




  86.    Serial.println(maichongjiange);
  87.    tempint=0;

  88. }



  89. //音频调速

  90.   //阻塞区内不做判断,最粗暴,完善的方法是,阻塞区内低值无效,高值有效

  91.         for(int col=9;col>1;col--){

  92.                 tempint= digitalRead(col);

  93.          if(!tempint){ //低电平有效

  94.                 // Serial.print("Max:"); //实际情况是其发送非常耗时,直接影响了步进电机的运行
  95.                 // Serial.println(col);
  96.                                 //对于速度增加的定义,鉴于其返回值有9、8····2端口值,先粗暴一把吧,直接按声压,而非实际分贝分类
  97.                                // tempint2 = xifen2/(1.75+3.25*(col-1)/8);//在变化有效的情况下,maichongjiange的值得
  98.           //实际人耳的分类,与电压、耳机灵敏度有关
  99.           //现在以100db/mw灵敏度的耳机进行分类
  100.           //目前实测,2个LM339的,8个基准脚的电压与接口、分贝对于关系为
  101.           /*
  102.         IO        2        \        3        \        4        \        5        \        6        \        7        \        8        \        9
  103.         基准mV        6.5        \        12.9\        19.5\        26.1\        33        \        39.8\        46.2\        53.1
  104.       32欧对应db        41.2\        47.1\        50.7\        53.2\        55.3\        56.9\        58.2\        59.4
  105.       16欧对应db        44.2\        50.1\        53.7\        56.2\        58.3\        59.9\        61.2\        62.4
  106.       定义每个等级增加 0.1圈,8个增量 =0.8圈

  107.         可见
  108.         1、耳机内阻减小虽然会导致功率翻倍,但分贝数不过变化3
  109.         2、坑爹啊,基准值取得太高,导致范围曲在了41-59db,所需音量太大(电脑音量输出50%以上),且范围窄(小于提速无效,大于衰减无效)
  110.         3、如果在32欧内阻下测量,需要细分到2mV(31db)、3mV(34db)、4mv(36.9db),328p分辨率不足,LM339的10mv分辨率更不足,需要放大

  111.           */

  112.         tempint2 = xifen2/(0.1*col);//在变化有效的情况下,maichongjiange的值得

  113.                                 //仅当新值低于现值(周期短,频率高),此变化才是有效的
  114.         if(maichongjiange>tempint2){
  115.    maichongjiange=tempint2;

  116.    if(yunxingmoshi==1)fanzhuanfazhi=5*col;//反转阀值度数的确定,取端口值的5倍数
  117.   }




  118.                 col=0;//跳出循环
  119.          }
  120.         }





  121. //核心部分,转速的衰减,暂定为3秒,即声压带来的速度提升效果,会在3秒后消失
  122. //那么就意味,只有最慢的357才是常态,其他都是浮云
  123. //衰减暂定为3部曲,每秒衰减1/3,梯形衰减,不做平滑处理(平滑的效果反而很差,因为不是闭环)
  124.         if (millis() - time2 > 1000){


  125.                   //确定衰减值,这次是动态计算,理想中省资源的方式是直接分类
  126.       //先确定增益圈数
  127.                 quanshuzy=xifen2/maichongjiange - 0.1;//等价 xifen2/maichongjiange - xifen2/maichongjiangeMax

  128.                         //每次衰减增益数的20%

  129.       //理论上,只要quanshuzy不为负,就速度下限就是0.1圈/秒,但328p的浮点不靠谱性得防
  130.       if(maichongjiangeMax>maichongjiange){

  131.        maichongjiange=xifen2/(0.1+quanshuzy*0.8); //脉冲周期增加,频率下降,转速衰减

  132.     if(yunxingmoshi==1 && fanzhuanfazhi>10)fanzhuanfazhi=fanzhuanfazhi*0.8;//H模式下,同转速,每次衰减20%

  133.       }else{

  134.     fanzhuanfazhi=5;
  135.        maichongjiange=maichongjiangeMax;
  136.       }

  137.             time2=millis();

  138.         }






  139. //在脉冲频率无变化的时候驱动电机正常运行
  140. maichongqudong();



  141. }



  142. void maichongqudong()//脉冲驱动
  143. {



  144.         maichongjsq++;//每过一个“脉冲间隔”时间段,则“脉冲计数器”自增1
  145.         maichongjsq=maichongjsq%maichongzhankongbi;//对“脉冲计数器”取模,这个取摸结果实质就是对占空比的调节(占空比为1/模),以4为例,则“脉冲计数器”的变化为:0——1——2——3——0

  146.         if(maichongjsq==0){

  147.                         digitalWrite(CLK, HIGH);//输出控制步进电机的电平

  148. ///////////////////////////////////////////////////////////////////////////////////
  149.                                 //H模式
  150.                                     if(yunxingmoshi==1){
  151.                                      //对于脉冲数的计数
  152.                                     if(fangxiang)moshijsq++;
  153.                                     else moshijsq--;

  154.                                     //反转阀值折算为脉冲数进行反转
  155.                                     tempint=fanzhuanfazhi*dumaichong100/100; // 需要度数*100度所需周期数

  156.                                     if(moshijsq<-tempint || moshijsq>tempint){ //达到既定周期后反向
  157.                                      fangxiang=!fangxiang;
  158.                                      digitalWrite(CW, fangxiang);
  159.                                         }
  160.                                    }


  161. /////////////////////////////////////////////////////////////////////////////////////

  162.   }else digitalWrite(CLK, LOW);



  163. }


复制代码

5

主题

36

帖子

141

积分

QQ群用户

积分
141
7#
 楼主| 发表于 2015-3-4 12:06:21 | 只看该作者
待修改的半成品

  1. // EN+,脱机,高电平有效
  2. // CW+,方向
  3. // CLK+,频率(转速)
  4. int EN=10;
  5. int CW=11;
  6. int CLK=12;

  7. //步进电机控制器的细分数1、2、8、16(整、半、1/8、1/16)、整步用loop的方式是不行的,脉冲周期太短
  8. int xifen=2;

  9. //10步距角
  10. int bujujiao=18;
  11. //100度所需的色脉冲数,把度数放大,可以极大的提高控制精度,
  12. int dumaichong100;

  13. //脉冲的占空比为1/maichongzhankongbi
  14. int maichongzhankongbi=4;

  15. ////////////////////////////////////////////

  16. int tempint;//打杂的中间数

  17. int yunxingmoshi;//运行模式
  18. int moshijsq=0;//模式计数器
  19. boolean fangxiang=0;//电机转动方向标识
  20. int fanzhuanfazhi=0;//反转阀值

  21. float quanshuzy;//圈数增益(量)每秒,作为感官等额衰减的依据
  22. int tempint2;//打杂的中间数2,专注记录,maichongjiange的变化

  23. int maichongjsq=0;//脉冲计数器

  24. int loopjsq=0;
  25. unsigned long loopjsq2=0;


  26. float zhuansunow=0;
  27. float zhuansuWill=0;

  28. boolean suduok=0;
  29. boolean suduok2=0;

  30. int tuoshijian;//拖时间,每增加1,则周期增加 基数×占空比

  31. unsigned long time0=millis();

  32. unsigned long time1=micros();//电机CLK

  33. unsigned long time3=millis();//防止因音频变化而过快的改变电机的运行状态


  34. void setup(){

  35. Serial.begin(9600);

  36. pinMode(EN, OUTPUT);// EN+,脱机,高电平有效
  37. pinMode(CW, OUTPUT);// CW+,方向
  38. pinMode(CLK, OUTPUT);// CLK+,频率(转速)

  39. digitalWrite(EN, HIGH);//电机默认脱机
  40. digitalWrite(CW, LOW);//
  41. digitalWrite(CLK, LOW);

  42. for(int col=2;col<10;col++)pinMode(col, INPUT_PULLUP);

  43. dumaichong100=xifen*1000/bujujiao; //走100度所需脉冲数5555(1)        \        111(2)        \        444(8)        \        888(16)

  44. }




  45. void loop(){


  46.   //获得可达到的最高理论转速,半步的情况下大概6转/秒,10ms测速一次

  47. loopjsq++;

  48.   if (millis() - time0 > 10){
  49.    //此刻的loopjsq本质就是loop的运行次数,因为电机控制脉冲是以一次loop为基础的
  50.    //转速 转/s = 有效脉冲数/细分/200
  51.    
  52.    /*
  53.        表达方式无效 zhuansunow=loopjsq/(maichongzhankongbi*xifen*200);
  54.                
  55.                 328p扯淡的故事~~~
  56.                 其中, zhuansunow为float,其他为int

  57.                 tempint=maichongzhankongbi*xifen*200;
  58.                 zhuansunow=loopjsq/tempint;
  59.                 计算错误!!

  60.                 zhuansunow=maichongzhankongbi*xifen*200;
  61.                 zhuansunow=loopjsq/ zhuansunow;
  62.                 计算正确
  63.    */

  64. zhuansunow=maichongzhankongbi*xifen*2;
  65. zhuansunow=loopjsq/zhuansunow; //计算出每秒圈速

  66.    


  67. //引入布尔量,证明这个速度是可用的
  68.    suduok=1;
  69.    suduok2=1;
  70.    
  71.    
  72.    loopjsq=0;

  73.    
  74.    time0=millis();
  75.   }



  76. //串口调速
  77. chuankoutiaosu();



  78. //音频调速
  79. yinpintiaosu();
  80.          
  81.          
  82. //速度衰减
  83.   sudushuaijian();

  84.   
  85.   
  86.   //速度的调节
  87.    


  88. if(suduok){
  89.          suduok=0;

  90.         if(zhuansuWill<zhuansunow)tuoshijian++;
  91.         else if(tuoshijian>1)tuoshijian--;

  92. }


  93.   


  94.   for(int col=1;col<tuoshijian;col++)delayMicroseconds(10);

  95.   
  96.   
  97. //在脉冲频率无变化的时候驱动电机正常运行
  98. maichongqudong();






  99. }



  100. void maichongqudong()//脉冲驱动
  101. {

  102.    maichongjsq++;//每过一个“脉冲间隔”时间段,则“脉冲计数器”自增1
  103.         maichongjsq=maichongjsq%maichongzhankongbi;//对“脉冲计数器”取模,这个取摸结果实质就是对占空比的调节(占空比为1/模),以4为例,则“脉冲计数器”的变化为:0——1——2——3——0

  104.         if(maichongjsq==0){
  105.    
  106.    digitalWrite(CLK, HIGH);//输出控制步进电机的电平
  107.    
  108. ///////////////////////////////////////////////////////////////////////////////////
  109.     //H模式
  110.         if(yunxingmoshi==1){
  111.          //对于脉冲数的计数
  112.         if(fangxiang)moshijsq++;
  113.         else moshijsq--;

  114.         //反转阀值折算为脉冲数进行反转
  115.         tempint=fanzhuanfazhi*dumaichong100/100; // 需要度数*100度所需周期数
  116.    
  117.         if(moshijsq<-tempint || moshijsq>tempint){ //达到既定周期后反向
  118.          fangxiang=!fangxiang;
  119.          digitalWrite(CW, fangxiang);
  120.      }
  121.        }


  122. /////////////////////////////////////////////////////////////////////////////////////

  123.   }else digitalWrite(CLK, LOW);



  124. }


  125. void sudushuaijian(){
  126.        
  127.        
  128.         //核心部分,转速的衰减
  129. //此处用计数器代替时间
  130. //设每转2圈减速一次
  131. //理论上maichongzhankongbi*200*xifen =1圈 ,25%占空比、16细分,一圈为12800脉冲
  132. //换言之 loopjsq2 为int时,占空比应该大于10%,改为unsigned long后就比较随意了
  133. loopjsq2++;
  134.         if (loopjsq2 > maichongzhankongbi*400*xifen){

  135.                         loopjsq2=0;
  136.                         Serial.print(zhuansuWill);
  137.                         Serial.print("zhuansuWill/zhuansunow=");
  138.                         Serial.println(zhuansunow);
  139.          
  140.                  
  141.                         if(zhuansunow>0.5)zhuansuWill = zhuansuWill*0.95;
  142.                         else zhuansuWill=0.5;


  143.                         if(yunxingmoshi==1 && fanzhuanfazhi>10)fanzhuanfazhi=fanzhuanfazhi*0.8;//H模式下,同转速,每次衰减20%
  144.    
  145.       }
  146.           
  147.           
  148.           
  149.        
  150.        
  151. }


  152. void yinpintiaosu(){
  153.        
  154.   //阻塞区内不做判断,最粗暴,完善的方法是,阻塞区内低值无效,高值有效

  155.         for(int col=9;col>1;col--){

  156.                 tempint= digitalRead(col);
  157.                
  158.          if(!tempint){ //低电平有效
  159.                
  160.                 // Serial.print("Max:"); //实际情况是其发送非常耗时,直接影响了步进电机的运行
  161.                 // Serial.println(col);
  162.                                 //对于速度增加的定义,鉴于其返回值有9、8····2端口值,先粗暴一把吧,直接按声压,而非实际分贝分类
  163.                                // tempint2 = xifen2/(1.75+3.25*(col-1)/8);//在变化有效的情况下,maichongjiange的值得
  164.           //实际人耳的分类,与电压、耳机灵敏度有关
  165.           //现在以100db/mw灵敏度的耳机进行分类
  166.           //目前实测,2个LM339的,8个基准脚的电压与接口、分贝对于关系为
  167.           /*
  168.         IO        2        \        3        \        4        \        5        \        6        \        7        \        8        \        9
  169.         基准mV        6.5        \        12.9\        19.5\        26.1\        33        \        39.8\        46.2\        53.1
  170.       32欧对应db        41.2\        47.1\        50.7\        53.2\        55.3\        56.9\        58.2\        59.4
  171.       16欧对应db        44.2\        50.1\        53.7\        56.2\        58.3\        59.9\        61.2\        62.4

  172.      
  173.         可见
  174.         1、耳机内阻减小虽然会导致功率翻倍,但分贝数不过变化3
  175.         2、坑爹啊,基准值取得太高,导致范围曲在了41-59db,所需音量太大(电脑音量输出50%以上),且范围窄(小于提速无效,大于衰减无效)
  176.         3、如果在32欧内阻下测量,需要细分到2mV(31db)、3mV(34db)、4mv(36.9db),328p分辨率不足,LM339的10mv分辨率更不足,需要放大
  177.          
  178.           */
  179.       
  180.    
  181.       
  182.                                 //仅当新值低于现值(周期短,频率高),此变化才是有效的
  183.                                                                
  184.                 float zhuansuWill2 = 0.5*col+0.5;
  185.                  
  186.         if(zhuansuWill2>zhuansuWill){
  187.    
  188.                         zhuansuWill = zhuansuWill2;
  189.    
  190.                         if(yunxingmoshi==1)fanzhuanfazhi=5*col;//反转阀值度数的确定,取端口值的5倍数
  191.                 }



  192.       
  193.                 col=0;//跳出循环
  194.          }
  195.         }
  196.        
  197.        
  198. }


  199. void chuankoutiaosu(){
  200.        
  201.          //串口调速
  202.      while (Serial.available() > 0) {

  203.     //丧心病狂的单字节控制,0延迟,纯ASCII分拆
  204.         //定义1 0-9表示转速,每一个表示10%
  205.         //定义2 A正转、B反转
  206.         //定义3 C联机、D脱机

  207.    tempint=Serial.read();

  208.    //调速度
  209.    if(tempint>47 && tempint< 58) zhuansuWill = 0.5*(tempint-47);//48——58(0.5——5)
  210.    //调方向 A、B
  211.    else if(tempint==65){
  212.     digitalWrite(CW, 0);
  213.     fangxiang=0;
  214.    }
  215.    else if(tempint==66){
  216.     digitalWrite(CW, 1);
  217.     fangxiang=1;
  218.    }
  219.     //联机、脱机 C、D
  220.    else if(tempint==67)digitalWrite(EN, 0);
  221.    else if(tempint==68)digitalWrite(EN, 1);

  222. //E 减速   F 加速
  223.    else if(tempint==69){
  224.     zhuansuWill = zhuansuWill*0.95;

  225.    }
  226.    else if(tempint==70){
  227.     zhuansuWill = zhuansuWill*1.05;

  228.    }
  229.    
  230.    //模式G 转动
  231.    else if(tempint==71)yunxingmoshi=0;
  232.    //模式H 摇摆
  233.    else if(tempint==72)yunxingmoshi=1;

  234.    else tempint=0;
  235.    
  236.    


  237.   Serial.println(zhuansunow);


  238. }
  239.        
  240. }





复制代码


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

本版积分规则

QQ|Archiver|手机版|狗趴(GodPub) Arduino&Raspberry Pi开源硬件学习与实践[QQ群:20085629]  

GMT+8, 2024-4-26 05:03 , Processed in 0.146949 second(s), 43 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表