激光轉速計,反射式。
須要用反光紙貼到轉軸上。
當被測零件完成一圈時,來自轉速計的持續發射的激光束會反射回來,
傳感器被其光觸發并向LGT8F328發送脈沖,
LGT8F328會保持這些脈沖發生的準確時間,
并以 RPM 為單位計算旋轉速度並運算顯示。
1. 激光二極管LED調制式發射頻率200hkz。
2. 激光接收傳感器調制式+消光座透鏡。
3. 128 x 32'' I2C OLED 顯示器。
4. arduino LGT8F328。
5. 電池3.7V400ma。
6. 反光紙。
制作出來的實物圖如下:
20220926_112507.jpg (1.22 MB, 下載次數: 52)
下載附件
2
2022-9-27 09:31 上傳
20220926_113044.jpg (913.38 KB, 下載次數: 48)
下載附件
3
2022-9-27 09:32 上傳
20220926_113124.jpg (1.19 MB, 下載次數: 59)
下載附件
4
2022-9-27 09:32 上傳
20220926_112507.jpg (1.22 MB, 下載次數: 62)
下載附件
2022-9-27 16:16 上傳
電路原理圖如下:
Schematic_laser_rpm_tachomater_2022-09-26.jpg (276.39 KB, 下載次數: 53)
下載附件
1
2022-9-27 09:31 上傳
Arduino源程序如下:
- //CPU Frequency "16MHz"
- #include <Wire.h>
- #include "U8glib.h"
- #include <SimpleKalmanFilter.h>
- SimpleKalmanFilter simpleKalmanFilter(1, 1, 0.1);
- //Nano: SDA (A4); SCL (A5);
- U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE); //0.96
- //U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);
- unsigned long rpmtime;
- unsigned long rpmtd[8]={};
- unsigned int rpm;
- unsigned int rpmcount=0;
- unsigned int rpm_tcnt=0;
- unsigned int MaxX;
- unsigned int MinX;
- unsigned int Sumrpm=0;
- unsigned int valmap;
- float rpmfloat=0.0;
- float K_rpmfloat=0.0;
- float rpmtime_dy=0.0;
- float kal_rpm=0.0;
- bool rpmslow = 1;
- //------------------------------------------------------
- //電壓表 voltage meter
- float vout = 0.0;
- float vin = 0.0;
- float R1 = 40000.0; // resistance of R1 (40K)
- float R2 = 10000.0; // resistance of R2 (10K)
- int value = 0;
- int analogInput = 1;
- unsigned int voltmap;
- //-------------------------------------------------------
- //顯示時間間隔 DisplayTime
- unsigned long previousBlinkTime;
- unsigned int TimeInterval = 500;
- bool toggleTime=0;
- bool DisplayTime=0;
- //------------------------------------------------
- //lgt328p
- //INTERNAL1V024 , uses a 1.024v reference voltage from inside the board.
- //--------------------------------------------------------------------
- void setup() {
- Serial.begin(115200);
- // pinMode(LED_BUILTIN, OUTPUT);
- analogReference(INTERNAL1V024);//INTERNAL lgt328p
- analogReadResolution(12);
- //----------------------------------------------------------
- //激光LED調制約200hkz輸出
- noInterrupts();
- TCCR2A =
- 1 << COM2B1 |
- 1 << COM2B0 |
- 1 << WGM21 |
- 1 << WGM20;
- TCCR2B =
- 1 << WGM22 |
- 1 << CS20;
- OCR2A = 80;
- OCR2B = 60;
- pinMode(3, OUTPUT);
- //-----------------------------------------------------------
- //RPM讀取時間
- TCCR1A = 0;
- TCCR1B = 0;
- TCCR1B |= (1 << CS12); //Prescaler 256
- TIMSK1 |= (1 << TOIE1); //enable timer overflow
- pinMode(2, INPUT);
- attachInterrupt(0, RPM2, RISING);//CHANGE
- //-----------------------------------------------------
- u8g.firstPage();
- do {
- display_rpm_stop();
- } while (u8g.nextPage());
- interrupts();
- }
- //-----------------------------------------------------------------
- void loop() {
-
- voltmeter();
- millisTime();
-
- if(DisplayTime){
- if (rpmslow) {
- if(vin<3.3){
- u8g.firstPage();
- do {
- display_Volmeter();
- } while (u8g.nextPage());
- }
- else{
- u8g.firstPage();
- do {
- display_rpm_stop();
- } while (u8g.nextPage());
- }
- }
- else {
- kalman_rpm();
- u8g.firstPage();
- do {
- display_rpm();
- } while (u8g.nextPage() );
- }
- DisplayTime=0;
- }
- //----------------------------------------------------------
- // Serial.print(vout);
- // Serial.print("\t");
- // Serial.print( kal_rpm );
- // Serial.print("\t");
- // Serial.print(K_rpmfloat);
- // Serial.print("\t");
- // Serial.println();
-
- }
- //---------------------------------------------------------
- void kalman_rpm(){
- kal_rpm = simpleKalmanFilter.updateEstimate(rpmtime);
- K_rpmfloat = 120/(kal_rpm/31250.00);
- rpmtime_dy=K_rpmfloat;
- }
- //----------------------------------------------------------
- void voltmeter(){
- // read the value at analog input
- value = analogRead(VCCM);
- vout = (value * 5.0)/4096.0; //lgt328p
- vin = vout;
- unsigned int val = vin*10;
- voltmap = map(val, 30, 40, 0, 50);
- }
- //--------------------------------------------------------
- ISR(TIMER1_OVF_vect) {
- rpmslow = 1;
- }
- //------------------------------------------------------
- void RPM2 () {
- rpmtd[7]=TCNT1;
- TCNT1 = 0;
- rpmslow = 0;
- rpmtd[0]=rpmtd[1];
- rpmtd[1]=rpmtd[2];
- rpmtd[2]=rpmtd[3];
- rpmtd[3]=rpmtd[4];
- rpmtd[4]=rpmtd[5];
- rpmtd[5]=rpmtd[6];
- rpmtd[6]=rpmtd[7];
- rpmtime = (rpmtd[0]+rpmtd[1]+rpmtd[2]+rpmtd[3]+rpmtd[4]+rpmtd[5]+rpmtd[6]+rpmtd[7])/8;
- }
- //----------------------------------------------------------------------------------
- void millisTime() {
- unsigned long currentTime = millis(); // 獲取當前時間
- if (currentTime - previousBlinkTime >= TimeInterval) { //如果時間間隔達到了
- previousBlinkTime = currentTime; // 將檢查時間復位
- toggleTime = (toggleTime == 1) ? 0 : 1;
- DisplayTime = toggleTime;
- }
- else if (currentTime - previousBlinkTime <= 0) { // 如果millis時間溢出
- previousBlinkTime = currentTime;
- }
- }
- //-----------------------------------------------------------------------------------
- void display_rpm(void) {
- u8g.setFont(u8g_font_ncenR08);
- u8g.drawBox(100,4,2,4);
- u8g.drawFrame(103,0,25,12);
- u8g.setPrintPos(108, 10);
- u8g.println((voltmap*2));
- // u8g.println("%");
- u8g.setPrintPos(104, 32);
- u8g.print("RPM");
- u8g.setFont(u8g_font_ncenR24);
- u8g.setPrintPos(0, 32);
- if(rpmtime_dy>=10000) {u8g.print(rpmtime_dy,0);}
- else{u8g.print(rpmtime_dy,1);}
- }
- //-----------------------------------------------------------
- void display_rpm_stop(void) {
- u8g.setFont(u8g_font_ncenR08);
- u8g.drawBox(100,4,2,4);
- u8g.drawFrame(103,0,25,12);
- u8g.setPrintPos(107, 10);
- // u8g.println((voltmap*2));
- u8g.println(vout,2);
- u8g.setPrintPos(104, 32);
- u8g.print("RPM");
- u8g.setFont(u8g_font_ncenR24);
- u8g.setPrintPos(0, 32);
- if(rpmtime_dy>=10000) {u8g.print(rpmtime_dy,0);}
- else{u8g.print(rpmtime_dy,1);}
- }
- //-----------------------------------------------------------
- //display the voltage
- void display_Volmeter(void) {
- u8g.setFont(u8g_font_ncenR08);
- u8g.drawBox(3,11,5,10);
- u8g.drawBox(10,6,voltmap,20);
- u8g.drawFrame(10,6,50,20);
- u8g.setPrintPos(103, 16);
- u8g.println(vin);
- u8g.println("v");
- if(vin<3.3){
- u8g.setPrintPos(32, 20);
- u8g.println((voltmap*2));
- u8g.println("%");
- u8g.setPrintPos(103,32);
- u8g.print("LOW");
- }
- }
- //------------------------------------------------
復制代碼
|