找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1329|回复: 2
收起左侧

Arduino LGT8F328激光转速计制作 附程序

[复制链接]
ID:330820 发表于 2022-9-27 09:33 | 显示全部楼层 |阅读模式
激光转速计,反射式。
須要用反光纸贴到转轴上。
当被测零件完成一圈时,来自转速计的持续发射的激光束会反射回来,
传感器被其光触发并向LGT8F328发送脉冲,
LGT8F328会保持这些脉冲发生的准确时间,
并以 RPM 为单位计算旋转速度並运算显示。

1. 激光二极管LED调制式发射频率200hkz。
2. 激光接收传感器调制式+消光座透镜。
3. 128 x 32'' I2C OLED 显示器。
4. arduino LGT8F328。
5. 电池3.7V400ma。
6. 反光纸。

制作出来的实物图如下:

2

2

3

3

4

4
20220926_112507.jpg

电路原理图如下:

1

1


Arduino源程序如下:
  1. //CPU Frequency "16MHz"
  2. #include <Wire.h>
  3. #include "U8glib.h"
  4. #include <SimpleKalmanFilter.h>
  5. SimpleKalmanFilter simpleKalmanFilter(1, 1, 0.1);
  6. //Nano: SDA (A4); SCL (A5);
  7. U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE); //0.96
  8. //U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);
  9. unsigned long rpmtime;
  10. unsigned long rpmtd[8]={};
  11. unsigned int rpm;
  12. unsigned int rpmcount=0;
  13. unsigned int rpm_tcnt=0;
  14. unsigned int MaxX;   
  15. unsigned int MinX;  
  16. unsigned int Sumrpm=0;
  17. unsigned int valmap;
  18. float rpmfloat=0.0;
  19. float K_rpmfloat=0.0;
  20. float rpmtime_dy=0.0;
  21. float kal_rpm=0.0;
  22. bool  rpmslow = 1;
  23. //------------------------------------------------------
  24. //电压表 voltage meter
  25. float vout = 0.0;
  26. float vin = 0.0;
  27. float R1 = 40000.0; // resistance of R1 (40K)
  28. float R2 = 10000.0; // resistance of R2 (10K)
  29. int value = 0;
  30. int analogInput = 1;
  31. unsigned int voltmap;
  32. //-------------------------------------------------------
  33. //显示时间间隔 DisplayTime
  34. unsigned long previousBlinkTime;
  35. unsigned int TimeInterval = 500;
  36. bool toggleTime=0;
  37. bool DisplayTime=0;
  38. //------------------------------------------------
  39. //lgt328p
  40. //INTERNAL1V024 , uses a 1.024v reference voltage from inside the board.
  41. //--------------------------------------------------------------------
  42. void setup() {
  43.     Serial.begin(115200);
  44.    // pinMode(LED_BUILTIN, OUTPUT);
  45.     analogReference(INTERNAL1V024);//INTERNAL lgt328p
  46.     analogReadResolution(12);
  47. //----------------------------------------------------------
  48. //激光LED调制约200hkz输出
  49.    noInterrupts();
  50.    TCCR2A =
  51.     1 << COM2B1 |
  52.     1 << COM2B0 |
  53.     1 << WGM21 |
  54.     1 << WGM20;
  55.   TCCR2B =
  56.     1 << WGM22 |
  57.     1 << CS20;
  58.   OCR2A = 80;
  59.   OCR2B = 60;
  60.   pinMode(3, OUTPUT);
  61. //-----------------------------------------------------------
  62. //RPM读取时间
  63.   TCCR1A = 0;
  64.   TCCR1B = 0;
  65.   TCCR1B |= (1 << CS12); //Prescaler 256
  66.   TIMSK1 |= (1 << TOIE1); //enable timer overflow  
  67.   pinMode(2, INPUT);
  68.   attachInterrupt(0, RPM2, RISING);//CHANGE
  69. //-----------------------------------------------------  
  70.   u8g.firstPage();
  71.      do {
  72.      display_rpm_stop();
  73.      } while (u8g.nextPage());

  74.   interrupts();   
  75. }
  76. //-----------------------------------------------------------------
  77. void loop() {
  78.   
  79.     voltmeter();
  80.    millisTime();
  81.    
  82. if(DisplayTime){     
  83.     if (rpmslow) {      
  84.       if(vin<3.3){
  85.         u8g.firstPage();
  86.       do {
  87.        display_Volmeter();
  88.         } while (u8g.nextPage());  
  89.       }   
  90.      else{  
  91.       u8g.firstPage();
  92.      do {
  93.       display_rpm_stop();
  94.       } while (u8g.nextPage());
  95.     }
  96. }   
  97.   else {  
  98.     kalman_rpm();   
  99.     u8g.firstPage();
  100.   do {
  101.     display_rpm();
  102.      } while (u8g.nextPage() );
  103.   }
  104.   DisplayTime=0;
  105. }

  106. //----------------------------------------------------------   
  107.    // Serial.print(vout);
  108.    // Serial.print("\t");
  109.    // Serial.print( kal_rpm );
  110.    // Serial.print("\t");
  111.    // Serial.print(K_rpmfloat);
  112.    // Serial.print("\t");
  113.    // Serial.println();
  114.    
  115. }
  116. //---------------------------------------------------------
  117. void kalman_rpm(){
  118.          kal_rpm = simpleKalmanFilter.updateEstimate(rpmtime);
  119.          K_rpmfloat = 120/(kal_rpm/31250.00);
  120.          rpmtime_dy=K_rpmfloat;   
  121. }
  122. //----------------------------------------------------------
  123. void voltmeter(){
  124. // read the value at analog input
  125.     value = analogRead(VCCM);
  126.      vout = (value * 5.0)/4096.0;    //lgt328p
  127.       vin = vout;   
  128.     unsigned int val = vin*10;
  129.     voltmap = map(val, 30, 40, 0, 50);
  130. }
  131. //--------------------------------------------------------
  132. ISR(TIMER1_OVF_vect) {
  133.   rpmslow = 1;
  134. }
  135. //------------------------------------------------------
  136. void RPM2 () {
  137.    rpmtd[7]=TCNT1;
  138.    TCNT1 = 0;
  139.    rpmslow = 0;
  140.    rpmtd[0]=rpmtd[1];
  141.    rpmtd[1]=rpmtd[2];
  142.    rpmtd[2]=rpmtd[3];
  143.    rpmtd[3]=rpmtd[4];
  144.    rpmtd[4]=rpmtd[5];
  145.    rpmtd[5]=rpmtd[6];
  146.    rpmtd[6]=rpmtd[7];
  147.    rpmtime = (rpmtd[0]+rpmtd[1]+rpmtd[2]+rpmtd[3]+rpmtd[4]+rpmtd[5]+rpmtd[6]+rpmtd[7])/8;   
  148. }
  149. //----------------------------------------------------------------------------------
  150. void millisTime() {
  151.    unsigned long currentTime = millis();                         // 获取当前时间                                                           
  152.   if (currentTime - previousBlinkTime >= TimeInterval) {         //如果时间间隔达到了
  153.       previousBlinkTime = currentTime;                           // 将检查时间复位
  154.       toggleTime = (toggleTime == 1) ? 0 : 1;  
  155.       DisplayTime =  toggleTime;
  156.   }   
  157. else if (currentTime - previousBlinkTime <= 0) {                 // 如果millis时间溢出
  158.   previousBlinkTime = currentTime;
  159.   }
  160. }
  161. //-----------------------------------------------------------------------------------
  162.   void display_rpm(void) {
  163.    u8g.setFont(u8g_font_ncenR08);
  164.    u8g.drawBox(100,4,2,4);
  165.    u8g.drawFrame(103,0,25,12);
  166.    u8g.setPrintPos(108, 10);
  167.    u8g.println((voltmap*2));
  168.   // u8g.println("%");
  169.    u8g.setPrintPos(104, 32);
  170.    u8g.print("RPM");
  171.    u8g.setFont(u8g_font_ncenR24);
  172.    u8g.setPrintPos(0, 32);
  173.    if(rpmtime_dy>=10000) {u8g.print(rpmtime_dy,0);}  
  174.    else{u8g.print(rpmtime_dy,1);}  
  175. }
  176. //-----------------------------------------------------------
  177. void display_rpm_stop(void) {
  178.   u8g.setFont(u8g_font_ncenR08);
  179.   u8g.drawBox(100,4,2,4);
  180.   u8g.drawFrame(103,0,25,12);
  181.   u8g.setPrintPos(107, 10);
  182. // u8g.println((voltmap*2));
  183.   u8g.println(vout,2);  
  184.   u8g.setPrintPos(104, 32);
  185.   u8g.print("RPM");
  186.   u8g.setFont(u8g_font_ncenR24);
  187.   u8g.setPrintPos(0, 32);
  188.   if(rpmtime_dy>=10000) {u8g.print(rpmtime_dy,0);}  
  189.   else{u8g.print(rpmtime_dy,1);}
  190. }
  191. //-----------------------------------------------------------
  192. //display the voltage
  193. void display_Volmeter(void) {
  194.   u8g.setFont(u8g_font_ncenR08);  
  195.   u8g.drawBox(3,11,5,10);
  196.   u8g.drawBox(10,6,voltmap,20);
  197.   u8g.drawFrame(10,6,50,20);
  198.   u8g.setPrintPos(103, 16);
  199.   u8g.println(vin);
  200.   u8g.println("v");
  201.   if(vin<3.3){
  202.   u8g.setPrintPos(32, 20);
  203.   u8g.println((voltmap*2));
  204.   u8g.println("%");  
  205.   u8g.setPrintPos(103,32);
  206.   u8g.print("LOW");
  207.   }
  208. }
  209. //------------------------------------------------
复制代码

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:430492 发表于 2022-9-29 10:45 | 显示全部楼层
需要反光贴纸的话,使用场合就会受限不少啊,很多地方无法贴纸,况且贴了也可能容易掉。
回复

使用道具 举报

ID:367080 发表于 2022-12-18 15:52 | 显示全部楼层
这个很好,正好有配件有空做一个试试。先收藏
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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