23.打點計時器頻率測量

此版程式使用霍爾磁效應感測器來計算打點計時器的頻率,

我是使用這個模組啦,其實還有很多選擇可以用

「霍爾感測 模組」的圖片搜尋結果

霍爾磁效應模組的工作電壓是5V,

無磁力時輸出電壓是2.5V,(電壓中點),類比腳位的讀取值約為532

使用時連接:GND(負極)、 Vcc(正極) 、 AO(類比輸出analog output)

因為霍爾效應感測器有分正反兩面,兩面效應恰好相反

測量時,先用感測器接近打點計時器的電磁鐵,

若通電後產生的電磁使銀幕上顯示的讀數變大,那就可以繼續測頻率

若通電後產生的電磁使銀幕上顯示的讀數變小,那就把感測器翻面,就可以正常測量頻率

第一版的程式原型

#include <Wire.h>  //載入I2C介面函式庫

#include <LiquidCrystal_I2C.h>     //載入I2C液晶控制函式庫

LiquidCrystal_I2C lcd(0x3f,16,2);  // 若LCD 無法啟用,請將0X3F 改為0X27

int a;                               //以下宣告全域變數

unsigned long t1,t2,dt;

int limit = 700;

float f;

 

void setup() {

Serial.begin(115200);  //啟用序列埠介面,可以從序列埠視窗抓到數據

pinMode(8,INPUT);

  lcd.init();        //LCD初始化             

  lcd.backlight();    //LCD 開啟背光

  lcd.clear();     // LCD清除畫面

}

 

void loop() {

do{                              //進入無磁力等待

a=analogRead(A0);          //讀取霍爾模組的讀數

}while(a<limit);

 

t1=micros();                //一產生磁力立刻記錄當下時間

 

do{                             //電磁鐵工作,等待磁力消失)

a=analogRead(A0);         //讀取霍爾模組的讀數

}while(a>=limit);

 

do{                            //進入無磁力等待

a=analogRead(A0); ;       //讀取霍爾模組的讀數 

}while(a<limit);

t2=micros();              //一產生磁力立刻記錄當下時間

 

dt=t2-t1;                    //計算兩次磁力出現的時間差(微秒)

if(dt>0){

f=1000000.000/dt;     //計算頻率,儲存成Hz

}

 

Serial.print("dt=");       //在序列埠監控視窗顯示

Serial.print(dt);

Serial.print(" ; f=");

Serial.println(f);

 

lcd.clear();

lcd.setCursor(0,0);  //設定LCD游標至第0行,第0列的位置

lcd.print("dt=");    //LCD在現在的游標開始顯示dt=

lcd.print(dt);        //LCD在現在的游標顯示變數dt的值 

lcd.setCursor(0,1);  //設定LCD游標至第0行,第1列的位置

lcd.print("f=");    //LCD在現在的游標開始顯示 f= 

lcd.print(f,3);        //LCD在現在的游標顯示變數f的值 

//delay(100);     //每0.5秒測量一次(太快眼睛無法讀取銀幕讀數)

}

第二版的程式原型

#include <Wire.h>  //載入I2C介面函式庫

#include <LiquidCrystal_I2C.h>     //載入I2C液晶控制函式庫

LiquidCrystal_I2C lcd(0x3f,16,2);  // 若LCD 無法啟用,請將0X3F 改為0X27

int a,p;                               //以下宣告全域變數

unsigned long t1,t2,dt;

int limit;

float f;

unsigned long i,test;

int up,down,sensor;

 

void setup() {

Serial.begin(115200);  //啟用序列埠介面,可以從序列埠視窗抓到數據

pinMode(8,INPUT);

  lcd.init();        //LCD初始化             

  lcd.backlight();    //LCD 開啟背光

  lcd.clear();     // LCD清除畫面

lcd.setCursor(0,0);

lcd.print("power-off value");

i=0;

test=0;

do{                         //找尋無通電狀態的磁力背景值

  p=analogRead(A7);              //讀取按鈕開關的讀數(此按鈕開關為長時高電位)

  sensor = analogRead(A0);        //讀取霍爾感測器

  test += sensor;                //累加感測器讀數

  i++;                          //累加測量次數

lcd.setCursor(12,1);

lcd.print(sensor);            //顯示霍爾感測器的即時讀數

  delay(20);

}while(p>512);    

down = test/i;                //計算背景值的平均值

lcd.clear();    

lcd.setCursor(0,1);

lcd.print("down=");

lcd.print(down);             //顯示或爾感測器讀到的方波的下限

lcd.setCursor(0,0);

lcd.print("power on value:");

delay(1000);

test=0;

do{

  p=analogRead(A7);               //讀取按鈕開關的讀數(此按鈕開關為長時高電位) 

  test=analogRead(A0);            //讀取霍爾感測器

  if(test>up){                   //找尋霍爾感測器讀到的最高磁力值

    up=test;

  }

lcd.setCursor(12,1);

lcd.print(test);                  //顯示霍爾感測器的即時讀數

  delay(20);

}while(p>512);

lcd.clear(); 

lcd.setCursor(0,0);

lcd.print("up=");

lcd.print(up);                     //顯示或爾感測器讀到的方波的上限

limit = (up + 2*down)/3 ;           //計算判斷時間的觸發值

lcd.setCursor(0,1);

lcd.print("limit=");

lcd.print(limit);                   //顯示判斷時間的觸發值

delay(1000); 

}

 

void loop() {

do{                              //進入無磁力等待

a=analogRead(A0);          //讀取霍爾模組的讀數

}while(a<limit);

 

t1=micros();                //一產生磁力立刻記錄當下時間

 

do{                             //電磁鐵工作,等待磁力消失)

a=analogRead(A0);         //讀取霍爾模組的讀數

}while(a>=limit);

 

do{                            //進入無磁力等待

a=analogRead(A0); ;       //讀取霍爾模組的讀數 

}while(a<limit);

t2=micros();              //一產生磁力立刻記錄當下時間

 

dt=t2-t1;                    //計算兩次磁力出現的時間差(微秒)

if(dt>0){

f=1000000.000/dt;     //計算頻率,儲存成Hz

}

 

Serial.print("dt=");       //在序列埠監控視窗顯示

Serial.print(dt);

Serial.print(" ; f=");

Serial.println(f);

 

lcd.clear();

lcd.setCursor(0,0);  //設定LCD游標至第0行,第0列的位置

lcd.print("dt=");    //LCD在現在的游標開始顯示dt=

lcd.print(dt);        //LCD在現在的游標顯示變數dt的值 

lcd.setCursor(0,1);  //設定LCD游標至第0行,第1列的位置

lcd.print("f=");    //LCD在現在的游標開始顯示 f= 

lcd.print(f,3);        //LCD在現在的游標顯示變數f的值 

delay(100);     //每0.5秒測量一次(太快眼睛無法讀取銀幕讀數)

}