数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 1522|回复: 28

[工仪] 制作激光反射式转速仪与红外遥控器解码

[复制链接]
发表于 2025-3-23 11:10:24 | 显示全部楼层 |阅读模式
这是去年的diy,当时鼓捣无刷电机改造风扇,转速标定没有仪器,这就成了配套工程。

特点:
1、超低成本,10元。
2、激光反射式测速,转盘粘贴白纸或者烟盒锡纸,激光照射到纸上就反射回来获得信号,因为射出是点光源,用锡纸的话控制好角度5米距离测转速都可以,转速测量范围6转/分钟-9万转/分钟(没实际验证)。
3、红外遥控器解码是白送的功能,测转速做好后试验能接受红外信号,索性加上红外解码程序,解码红外遥控器键值。




演示,电磁炉风扇


NEC格式解码


5104格式解码


激光接收管用的是这个





激光发射管是从退役的PPT翻页笔拆下来的激光头,网购约3元,开始加了透镜,距离远了机关点会散焦,后来把透镜去掉了。


自制PCB,stc8g1k08a芯片,5v转3.3v供激光头,IO控制激光头工作,8秒没有反射信号关闭激光头。


外壳用20的pvc水管,没有内置电池,设置一按钮作为功能切换。


拆除透镜后直接一片有机玻璃做发射窗。




0.91寸OLED显示屏,单片机硬件I2C控制。


显示屏左侧的 〉符号实时显示是否收到反射信号。





80厘米距离测试可有效接收反射信号。


制作过程没画原理图,方便大家参考,现在我的pcb图上加上硬件连接示意图。
如果你使用的激光头是两线的,就不用接那个PD点,同样如果激光头是5v供电的,就接到+5端。



楼下更新代码文件:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x

打赏

参与人数 4家元 +93 收起 理由
just56 + 18 謝謝分享
飞向狙沙 + 30 謝謝分享
IlovePLC + 30 原創內容
jf201006 + 15 謝謝分享

查看全部打赏

发表于 2025-3-23 17:29:33 | 显示全部楼层
这个真是厉害
回复 支持 反对

使用道具 举报

发表于 2025-3-23 17:58:57 | 显示全部楼层
楼主做的六啊
   
不开源一下吗
回复 支持 反对

使用道具 举报

发表于 2025-3-23 18:22:16 来自手机浏览器 | 显示全部楼层
好奇的是单片机里面的代码
回复 支持 反对

使用道具 举报

发表于 2025-3-23 18:32:28 来自手机浏览器 | 显示全部楼层
很强,会单片机编程就是玩得花
回复 支持 反对

使用道具 举报

发表于 2025-3-23 20:18:56 | 显示全部楼层
这个好玩哈,可惜没有开源
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-3-23 21:11:16 | 显示全部楼层
开源... 欢迎大家讨论交流。
  1. /*激光转速测量*/
  2. /*设定内部晶振24M 时钟周期0.041666us 1T机器周期0.041666us
  3. 使用stc8g1k08a,pcb文件名leise6.lay6,红点光笔拆激光管,工作电压3v,激光调制接收管180k-200kHz(入光1,遮光0) */
  4. #include "intrins.h"
  5. #include "stc8g.h"
  6. #include "codetab.h"
  7. #include "iic.h"
  8. #include "oled12832.h"
  9. #include "NECir.h"
  10. //#include "BA5104ir.h"
  11. //sbit p54=P5^4;    //iic-scl
  12. //sbit p55=P5^5;    //iic-sda
  13. sbit ir=P3^2; //int0
  14. sbit p33=P3^3;
  15. sbit key=P3^0;
  16. unsigned char mun;
  17. unsigned int tes,ird0,ird1;
  18. unsigned char irdat,kx,ok5104;
  19. //在单片机中,CCP是英文单词Capture(捕获),Compare(比较),PWM(脉宽调制)的缩写。
  20. //这个模块可配置为工作在输入捕捉、定时器比较或 PWM 输出方式下。
  21. //可工作在捕捉输入、比较输出和脉宽调制输出三种状态,三种状态各自独立工作。
  22. //PCA 计数器
  23. //激光发射调制180-200kHz
  24. void stcIO_Init(void)
  25. {
  26.     P3M0=0x00;  //设置P3.0-P3.7为双向口模式
  27.     P3M1=0x00;
  28.     P5M0=0x00;  //设置P5.0-P5.7为双向口模式
  29.     P5M1=0x00;
  30.     P0M0 = 0x00;
  31.     P0M1 = 0x00;
  32.     P1M0 = 0x00;
  33.     P1M1 = 0x00;
  34.     P2M0 = 0x00;
  35.     P2M1 = 0x00;
  36.     // P3M0 = 0x00;
  37.     // P3M1 = 0x00;
  38.     P4M0 = 0x00;
  39.     P4M1 = 0x00;
  40.     // P5M0 = 0x00;
  41.     // P5M1 = 0x00;
  42.     P3=0xff;  //芯片内部没有打线到外部管脚的IO是悬空的,设置成准双向模式,并固定输出高电平
  43.     P5=0xff;
  44. }
  45. //调制190k  2.63us高/2.63us低
  46. //*************定时器0初始化*********************//
  47. void laser_Timer0_Init(void)        //2.625微秒@24.000MHz  190kHz  laser
  48. {
  49.     AUXR |= 0x80;           //定时器时钟1T模式
  50.     TMOD &= 0xF0;           //设置定时器模式 16位自动重装
  51.     TL0 = 0xc1;             //设置定时初始值
  52.     TH0 = 0xFF;             //设置定时初始值
  53.     TF0 = 0;                //清除TF0标志
  54.     TR0 = 1;                //定时器0开始计时
  55.     ET0 = 1;                //使能定时器中断
  56. }
  57. void ir_Timer0_Init(void)       //32毫秒@24.000MHz  定时器0/12T模式/16位不自动重载/最大32毫秒溢出
  58. {
  59.     AUXR &= 0x7F;           //定时器时钟12T模式
  60.     TMOD &= 0xF0;           //设置定时器模式
  61.     TMOD |= 0x01;           //设置定时器模式 16位不自动重载
  62.     TL0 = 0x00;             //设置定时初始值
  63.     TH0 = 0x00;             //设置定时初始值
  64.     TF0 = 0;                //清除TF0标志
  65.     TR0 = 1;                //定时器0开始计时
  66.     ET0 = 0;                //关闭定时器0中断
  67. }
  68. /************************************************
  69. BA5104的编码格式:
  70. 每一帧遥控码的长度为12位,高位在前,包括3位起始码位(110)、2位用户码位、7位指令码位。
  71. 每一帧遥控码的时间间隔为4T(6.7516ms),其中T=1.6879ms为每一位遥控码的周期。
  72. 遥控码“0”用1/4T的高电平(0.395ms)、3/4T(1.284ms)的低电平表示,遥控码“1”用3/4T的高电平、1/4T的低电平表示。
  73.     关-0x01  摇头-0x10  定时-0x08  风类-0x04  开/风速-0x02  彩灯-0x43
  74.     110 11 1000011=0x0dc3=67 彩灯
  75. *************************************************/
  76. void do_ir5104()
  77. {
  78. //uchar k;
  79.     if(ird0<<4==ird1<<4)
  80.     {
  81.         show[7]=(ird0>>9&0x07)>>4;  //0x00
  82.         show[6]=(ird0>>9&0x07)&0x0f;  //0x06
  83.         show[3]=(ird0>>7&0x03)>>4;
  84.         show[2]=(ird0>>7&0x03)&0x0f;
  85.         show[1]=(ird0&0x7f)>>4;
  86.         show[0]=(ird0&0x7f)&0x0f;
  87.         //_nop_();
  88.         //_nop_();
  89.         OLED_WrCmd(0x81);//--set contrast control register  设置对比度 0x00-0xff  值增加对比度增加
  90.         OLED_WrCmd(0xff);//0xff);
  91.         t1k=0;
  92.     }
  93.     else
  94.     {
  95.         ird1=ird0;
  96.     }
  97.     irdat=kx=ok5104=0;
  98.     TR0=0;
  99.     ET0=0;
  100. }
  101. void TM0_Isr() interrupt 1
  102. {
  103.     switch (mun)
  104.     {
  105.     case 0:
  106.         p33 = !p33;
  107.         break;
  108.     case 2:
  109.         TR0=0;
  110.         ird0=(ird0<<1)|ir;
  111.         irdat++;
  112.         if(irdat>11)
  113.         {
  114.             ok5104=1;
  115.         }
  116.         break;
  117.     default:
  118.         break;
  119.     }
  120. }
  121. /**********************以下转速测量************************/
  122. //1w转  每转脉冲间隔6000us
  123. //200转  每转脉冲间隔300000us=300ms
  124. //24M晶振 定时器12T模式 机器周期0.5us 最小可测每分钟10转 最大可测每分钟100万转 显示只有5位数最高10万转
  125. void Timer1_Init(void)      //25毫秒@24.000MHz  16位不自动重装  机器周期0.5us
  126. {
  127.     AUXR &= 0xBF;           //定时器时钟12T模式
  128.     TMOD &= 0x0F;           //设置定时器模式
  129.     TMOD |= 0x10;           //设置定时器模式
  130.     TL1 = 0xB0;             //设置定时初始值
  131.     TH1 = 0x3C;             //设置定时初始值
  132.     TF1 = 0;                //清除TF1标志
  133.     TR1 = 1;                //定时器1开始计时
  134.     ET1 = 1;                //使能定时器中断
  135. }
  136. unsigned int t1k;
  137. unsigned long speedT;
  138. void TM1_Isr() interrupt 3     //定时器1中断
  139. {


  140.     TL1 = 0xB0;             //设置定时初始值
  141.     TH1 = 0x3C;             //设置定时初始值
  142.     //TR1 = 1;              //定时器1开始计时
  143.     t1k++;
  144. }
  145. void int0_Init(void)
  146. {
  147.     IT0=0;      //IT0 = 1; //使能INT0下降沿中断
  148.     EX0 = 1;    //使能INT0中断
  149.     //EA = 1;
  150. }
  151. void INT0_Isr() interrupt 0  //ir接收中断0
  152. {
  153.     if(ir)
  154.     {
  155.         switch (mun)
  156.         {
  157.         case 0:  //转速
  158.             speedT=((TH1-0x3c)*256+(TL1-0xb0))/2+(t1k*25000UL); //us  "UL"指定"25000"为unsigned long,否证keil会导致溢出
  159.             TL1 = 0xB0;             //设置定时初始值
  160.             TH1 = 0x3C;             //设置定时初始值
  161.             //TR1 = 1;              //定时器1开始计时
  162.             t1k=0;
  163.             //ET1 = 1;                //使能定时器中断
  164.             break;
  165.         case 1:  //NEC解码
  166.             Tc=TH0*256+TL0;   //提取中断时间间隔时长
  167.             TH0=0;
  168.             TL0=0;         //定时中断重新置零
  169.             if((Tc>Imin)&&(Tc<Imax))
  170.             {
  171.                 m=0;
  172.                 f=1;
  173.                 return;
  174.             }       //找到启始码
  175.             if(f==1)
  176.             {
  177.                 if(Tc>Inum1&&Tc<Inum3)
  178.                 {
  179.                     Im[m/8]=Im[m/8]>>1;
  180.                     m++; //取码//Im[m/8]=Im[m/8]>>1|0x80; m++;
  181.                 }
  182.                 if(Tc>Inum2&&Tc<Inum1)
  183.                 {
  184.                     Im[m/8]=Im[m/8]>>1|0x80;
  185.                     m++;//Im[m/8]=Im[m/8]>>1; m++; //取码
  186.                 }
  187.                 if(m==32)
  188.                 {
  189.                     m=0;
  190.                     f=0;
  191.                     if(Im[2]==~Im[3])
  192.                     {
  193.                         IrOK=1;
  194.                     }
  195.                     else
  196.                     {
  197.                         IrOK=0;    //取码完成后判断读码是否正确
  198.                     }
  199.                 }
  200.                 //准备读下一码
  201.             }
  202.             break;
  203.         case 2:  //BA5104解码
  204.             if(!kx)
  205.             {
  206.                 tes=TH0*256+TL0;   //提取中断时间间隔时长
  207.                 TH0=0;
  208.                 TL0=0;
  209.                 ET0=0;
  210.                 TR0=1;        //定时中断重新置零
  211.                 if((tes>16492)&&(tes<17794))//11.0592_if((tes>7600)&&(tes<8200)) //8246us-8897us
  212.                 {
  213.                     //24M _if((tes>16492)&&(tes<17794)) //8246us-8897us
  214.                     kx=1;
  215.                 }
  216.             }
  217.             if(!ok5104&&kx)  //11.0592_ TH0=0xfc;TL0=0xf1;
  218.             {
  219.                 TL0=0x68;  //溢出时间844us,取遥控码“0”或“1”的一个T的一半(0.84395ms),根据此时的高低电平判断是0还是1//
  220.                 TH0=0xf9;
  221.                 TR0=1;
  222.                 ET0=1;
  223.             }
  224.             break;
  225.         default:
  226.             break;
  227.         }
  228.     }
  229. }
  230. unsigned dis[5]= {0x0a,0x0a,0x0a,0x0a,0x0a};
  231. unsigned dis_tmp[5]= {0,0,0,0,0};
  232. unsigned irdis[8]= {1,1,1,1,1,1,1,1};
  233. unsigned long rpm;
  234. void do_rpm (void)
  235. {
  236.     rpm=60000000/speedT;//t1k;//60000/speedT;
  237.     if(!speedT)
  238.     {
  239.         rpm=0;
  240.     }
  241.     //rpm=mun;
  242.     dis_tmp[4]=rpm%100000/10000;
  243.     dis_tmp[3]=rpm%10000/1000;
  244.     dis_tmp[2]=rpm%1000/100;
  245.     dis_tmp[1]=rpm%100/10;
  246.     dis_tmp[0]=rpm%10;
  247. }
  248. void scan_key(void)
  249. {
  250.     static unsigned int k;
  251.     if(t1k==600)
  252.     {
  253.         if(mun==0)
  254.         {
  255.             TR0=0;
  256.             p33=0;
  257.         }
  258.     }
  259.     if(t1k==800)
  260.     {
  261.         OLED_WrCmd(0x81);   //--set contrast control register   设置对比度 0x00-0xff  值增加对比度增加
  262.         OLED_WrCmd(0x00);//0xff);
  263.     }
  264.     if(!key)
  265.     {
  266.         OLED_WrCmd(0x81);   //--set contrast control register   设置对比度 0x00-0xff  值增加对比度增加
  267.         OLED_WrCmd(0xff);//0xff);
  268.         TR0=1;
  269.         t1k=0;
  270.         k++;
  271.         if(k==1500)  //开关长按约3秒,改变状态
  272.         {
  273.             mun++;
  274.             if(mun>2)
  275.             {
  276.                 mun=0;
  277.             }
  278.             OLED_CLS();
  279.             dis[0]=dis[1]=dis[2]=dis[3]=dis[4]=0x0b;
  280.             irdis[7]=irdis[6]=irdis[5]=irdis[4]=irdis[3]=irdis[2]=irdis[1]=irdis[0]=0x10;
  281.             switch (mun)
  282.             {
  283.             case 0:  //测转速
  284.                 laser_Timer0_Init();
  285.                 break;
  286.             case 1:  //红外NRC格式解码
  287.                 ir_Timer0_Init();
  288.                 p33=0;
  289.                 OLED_P8x16Str(30,0,"NEC  KEY:");
  290.                 break;
  291.             case 2:  //红外BA5104格式解码
  292.                 ir_Timer0_Init();
  293.                 p33=0;
  294.                 OLED_P8x16Str(30,0,"5104 KEY:");
  295.                 break;
  296.             default:
  297.                 break;
  298.             }
  299.         }
  300.     }
  301.     else
  302.     {
  303.         k=0;
  304.     }
  305.     if((mun==1)&&IrOK)
  306.     {
  307.         irshow();
  308.     }
  309. }
  310. //**********************将P0.5,P0.7,P3.6,和P3.7片内上拉电阻使能************************//
  311. // P_SW2 |= 0X80; //将EAXFR位置1,以访问在XDATA区域的扩展SFR
  312. // P0PU |= 0XA0; //设置P0.5,P0.7口有上拉电阻
  313. // P3PU |= 0XC0; //设置P3.6,P3.7口有上拉电阻
  314. // P_SW2 &= 0X7E; //将EAXFR位置0,恢复访问XRAM
  315. //****************************************************************************************//
  316. void main(void)
  317. {
  318.     stcIO_Init(); //STC IO 模式设置
  319.     iicInit();
  320.     laser_Timer0_Init();
  321. //stc8g_pwm_init    ();
  322.     Timer1_Init();
  323.     OLED_Init(); //OLED初始化
  324.     int0_Init(); //int0初始化
  325.     m=0;
  326.     f=0;
  327.     TR1=1;
  328.     EA=1;
  329.     while(1)
  330.     {
  331.         //p33=0;
  332.         //OLED_P6x8Str(0,1,"www.taobao.com");
  333.         //OLED_P8x16Str(0,0,"Hello");//第一行 -- 8x16的显示单元显示ASCII码
  334.         //OLED_z8x16    (14,2,6);
  335.         //OLED_P16x16Ch(24,0,1);    /**功能描述:显示16*16点阵  显示的坐标(x,y),y为页范围0~7** void OLED_P16x16Ch(unsigned char x, y, N)**/
  336.         //OLED_z17x32 (6,0,k);
  337.         scan_key();
  338.         if(!mun)
  339.         {
  340.             do_rpm();
  341.         }
  342.         if((mun==2)&&ok5104)
  343.         {
  344.             do_ir5104();
  345.         }
  346.         switch (mun)
  347.         {
  348.         case 0:
  349.             if(dis[4]!=dis_tmp[4])
  350.             {
  351.                 dis[4]=dis_tmp[4];
  352.                 OLED_z17x32 (18,0,dis[4]);
  353.             }
  354.             if(dis[3]!=dis_tmp[3])
  355.             {
  356.                 dis[3]=dis_tmp[3];
  357.                 OLED_z17x32 (40,0,dis[3]);
  358.             }
  359.             if(dis[2]!=dis_tmp[2])
  360.             {
  361.                 dis[2]=dis_tmp[2];
  362.                 OLED_z17x32 (62,0,dis[2]);
  363.             }
  364.             if(dis[1]!=dis_tmp[1])
  365.             {
  366.                 dis[1]=dis_tmp[1];
  367.                 OLED_z17x32 (84,0,dis[1]);
  368.             }
  369.             if(dis[0]!=dis_tmp[0])
  370.             {
  371.                 dis[0]=dis_tmp[0];
  372.                 OLED_z17x32 (106,0,dis[0]);
  373.             }
  374.             break;
  375.         case 1:
  376.             if(irdis[7]!=show[7])
  377.             {
  378.                 irdis[7]=show[7];
  379.                 OLED_F8x16(30,2,irdis[7]);
  380.             }
  381.             if(irdis[6]!=show[6])
  382.             {
  383.                 irdis[6]=show[6];
  384.                 OLED_F8x16(38,2,irdis[6]);
  385.             }
  386.             if(irdis[5]!=show[5])
  387.             {
  388.                 irdis[5]=show[5];
  389.                 OLED_F8x16(54,2,irdis[5]);
  390.             }
  391.             if(irdis[4]!=show[4])
  392.             {
  393.                 irdis[4]=show[4];
  394.                 OLED_F8x16(62,2,irdis[4]);
  395.             }
  396.             if(irdis[3]!=show[3])
  397.             {
  398.                 irdis[3]=show[3];
  399.                 OLED_F8x16(78,2,irdis[3]);
  400.                 OLED_F8x16(102,0,irdis[3]);
  401.             }
  402.             if(irdis[2]!=show[2])
  403.             {
  404.                 irdis[2]=show[2];
  405.                 OLED_F8x16(86,2,irdis[2]);
  406.                 OLED_F8x16(110,0,irdis[2]);
  407.             }
  408.             if(irdis[1]!=show[1])
  409.             {
  410.                 irdis[1]=show[1];
  411.                 OLED_F8x16(102,2,irdis[1]);
  412.             }
  413.             if(irdis[0]!=show[0])
  414.             {
  415.                 irdis[0]=show[0];
  416.                 OLED_F8x16(110,2,irdis[0]);
  417.             }
  418.             break;
  419.         case 2:
  420.             if(irdis[7]!=show[7])
  421.             {
  422.                 irdis[7]=show[7];
  423.                 OLED_F8x16(30,2,irdis[7]);
  424.             }
  425.             if(irdis[6]!=show[6])
  426.             {
  427.                 irdis[6]=show[6];
  428.                 OLED_F8x16(38,2,irdis[6]);
  429.             }
  430.             //if(irdis[5]!=show[5]){irdis[5]=show[5];OLED_F8x16(54,2,irdis[5]);}
  431.             //if(irdis[4]!=show[4]){irdis[4]=show[4];OLED_F8x16(62,2,irdis[4]);}
  432.             if(irdis[3]!=show[3])
  433.             {
  434.                 irdis[3]=show[3];
  435.                 OLED_F8x16(66,2,irdis[3]);
  436.             }
  437.             if(irdis[2]!=show[2])
  438.             {
  439.                 irdis[2]=show[2];
  440.                 OLED_F8x16(74,2,irdis[2]);
  441.             }
  442.             if(irdis[1]!=show[1])
  443.             {
  444.                 irdis[1]=show[1];
  445.                 OLED_F8x16(102,2,irdis[1]);
  446.                 OLED_F8x16(102,0,irdis[1]);
  447.             }
  448.             if(irdis[0]!=show[0])
  449.             {
  450.                 irdis[0]=show[0];
  451.                 OLED_F8x16(110,2,irdis[0]);
  452.                 OLED_F8x16(110,0,irdis[0]);
  453.             }
  454.             break;
  455.         default:
  456.             break;
  457.         }
  458.         if(ir)
  459.         {
  460.             OLED_F8x16(2,0,36);
  461.         }
  462.         else
  463.         {
  464.             OLED_F8x16(2,0,37);
  465.         }
  466.         //_nop_();
  467.         //_nop_();
  468.     }
  469. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x

打赏

参与人数 2家元 +40 收起 理由
梅花一党 + 10 優秀文章
IlovePLC + 30 熱心助人

查看全部打赏

回复 支持 反对

使用道具 举报

发表于 2025-3-23 22:14:39 | 显示全部楼层
万用表带频率测试的是不是可以不用解码,直接接激光管测试?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-3-23 22:21:52 | 显示全部楼层
lookball 发表于 2025-3-23 22:14
万用表带频率测试的是不是可以不用解码,直接接激光管测试?

测转速不用解码,测键值才要。你用万用表测转速那还是要搭建接收反射信号的东西。
回复 支持 反对

使用道具 举报

发表于 2025-3-23 22:38:50 | 显示全部楼层
高手的作品!



DIY低成本激光+霍尔转速计:https://www.mydigit.cn/thread-526971-1-1.html


回复 支持 反对

使用道具 举报

发表于 2025-3-24 00:32:55 | 显示全部楼层
理论上可以测到多少转/分钟?实际估计是多少?
回复 支持 反对

使用道具 举报

发表于 2025-3-24 08:16:22 | 显示全部楼层
这种标称激光接收管的,实际上就是光敏管。
回复 支持 反对

使用道具 举报

发表于 2025-3-24 08:30:18 | 显示全部楼层
本帖最后由 纯今 于 2025-3-24 08:35 编辑




楼主这单片机实验板,都是插拔,透露了楼主玩单片机是老资格了

还同时利用红外接收管来解码红外遥控器

解码红外遥控器,我都是利用现有的库

硬件我是面包板与Breakout Board结合

而楼主这么多条代码,楼主这是从源头解码

我们是有代差的,致敬楼主,因为您资格老

我会参考你的代码,寻找现成的库去解决测速
回复 支持 反对

使用道具 举报

发表于 2025-3-24 08:39:09 | 显示全部楼层
做的很好,很实用。
回复 支持 反对

使用道具 举报

发表于 2025-3-24 08:52:35 | 显示全部楼层
典型CPU风扇转速范围:
普通风扇:800~2,000 RPM
高性能风扇:2,000~6,000 RPM
服务器/涡轮风扇:最高约 ​12,000 RPM​(如戴尔服务器风扇)
楼主是否通过CPU风扇自身的霍尔测速对比过准确性
回复 支持 反对

使用道具 举报

发表于 2025-3-24 09:01:21 | 显示全部楼层
谢谢分享,详细diy帖,有干货
回复 支持 反对

使用道具 举报

发表于 2025-3-24 09:03:06 | 显示全部楼层
本帖最后由 纯今 于 2025-3-24 09:12 编辑




楼主采用定时器中断生成 ​190kHz方波​(占空比50%),调制激光发射频率
我手头有这种2.5元/个的激光头,也可以拿来调制吗,我是控制端高电平发射激光
有时间我也做一个,届时开源代码,评估了一下,代码比您少多了

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
回复 支持 反对

使用道具 举报

发表于 2025-3-24 11:07:53 | 显示全部楼层
完出花活了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-3-24 13:32:45 | 显示全部楼层
纯今 发表于 2025-3-24 09:03
楼主采用定时器中断生成 ​190kHz方波​(占空比50%),调制激光发射频率
我手头有这种2.5元/个的激光头 ...

    实际测量误差不知道,没有标准件来比对,做好转速仪后我测量了风扇交流电机的转速是400-1200转,改无刷电机档位设置成180-1200转,在我看来这就可以了,如果有人做出来了有条件可以看看误差。
    关于激光头,我做的时候试验过不调制(就是红光常亮)也可以用,感官对比觉得调制效果好点。
    如果用的两线激光头也是可以通过单片机IO调制的,本质上就是受控闪烁。
    测量范围理论上是10转/分钟-20万转/分钟,但是单片机除了中断还要做计算和显示,我觉得5万转以下没问题,如果要测量高转速就用更高的晶振频率,程序核心就是一个微秒级的秒表,测量两个反射脉冲的时间间隔。
回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-7-19 06:49 , Processed in 0.109200 second(s), 10 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

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