close

官網後段也有改進之後的程式:

  // read RPM
 int half_revolutions = 0;
 int rpm = 0;
 unsigned long lastmillis = 0;
 void setup(){
 Serial.begin(9600); 
 attachInterrupt(0, rpm_fan, FALLING);
 }
 void loop(){
 if (millis() - lastmillis == 1000){ //Uptade every one second, this will be equal to reading frecuency (Hz).
 detachInterrupt(0);//Disable interrupt when calculating
 rpm = half_revolutions * 60; // Convert frecuency to RPM, note: this works for one interruption per full rotation. For two interrups per full rotation use half_revolutions * 30.
 Serial.print("RPM =\t"); //print the word "RPM" and tab.
 Serial.print(rpm); // print the rpm value.
 Serial.print("\t Hz=\t"); //print the word "Hz".
 Serial.println(half_revolutions); //print revolutions per second or Hz. And print new line or enter.
 half_revolutions = 0; // Restart the RPM counter
 lastmillis = millis(); // Uptade lasmillis
 attachInterrupt(0, rpm_fan, FALLING); //enable interrupt
  }
 }
 // this code will be executed every time the interrupt 0 (pin2) gets low.
 void rpm_fan(){
  half_revolutions++;
 }

這個程式改進了上一個程式時基不固定的缺點,改用等待1000mS也就是一秒鐘之後統計

中斷次數並乘以60,也就是一分鐘的換算RPM值輸出到com port。

不過這樣的算法會造成RPM數值為兩倍,因為每轉一次會輸出兩個pluse,所以算式要調整除以二:

 rpm = (half_revolutions * 60)/2; 

 

接線圖同上一篇:

「arduino FAN speed meter」的圖片搜尋結果

 

底下是我改寫後,將轉速輸出到1602A液晶螢幕上的程式:

/*
使用1602A I2C LCD模組及函式庫
使用Interrupt 0 讀取風扇轉速並顯示在1602A LCD螢幕上
LCD I2C Library,從這裡可以下載:
https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads
本程式使用Newliquidcrystal_1.3.5版函式庫
作者:Lu yaku
日期:2018.04.25
*/

#include <Wire.h>               
#include <LiquidCrystal_I2C.h>  

// 初始化 I2C 1602A LCD,I2C預設地址為0x27
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);


 int half_revolutions;
 int rpm;
 unsigned long lastmillis;

 void setup(){
 
 lcd.begin(16, 2);
 lcd.backlight();
 delay(250);
 lcd.clear();
 lcd.setCursor(0, 0); 
 lcd.print("FAN Speed");

 half_revolutions = 0;
 rpm = 0;
 lastmillis = 0;
  
 attachInterrupt(0, rpm_fan, FALLING);
 }

  void rpm_fan(){
  half_revolutions++;
 }
 
 void loop(){
  
 if (millis() - lastmillis == 1000){
 detachInterrupt(0);
 rpm = (half_revolutions * 30);
 
 lcd.setCursor(0, 1); 
 lcd.print("RPM = ");
 lcd.print(rpm); 
 lcd.print("   ");
 half_revolutions = 0; // Restart the RPM counter
 lastmillis = millis(); // Uptade lasmillis
 attachInterrupt(0, rpm_fan, FALLING); //enable interrupt
  }
 }
 // this code will be executed every time the interrupt 0 (pin2) gets low.
 

底下是我依據同樣原理改寫後的程式:

/*
使用1602A I2C LCD模組及函式庫
使用Interrupt 0 讀取風扇轉速並顯示在1602A LCD螢幕上
LCD I2C Library,從這裡可以下載:
https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads
本程式使用Newliquidcrystal_1.3.5版函式庫
作者:Lu yaku
日期:2018.04.26
*/

#include <Wire.h>               
#include <LiquidCrystal_I2C.h>  

// 初始化 I2C 1602A LCD,I2C預設地址為0x27
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
 
//設定變數作為計算使用
int count; 
int Calc;
 
//接轉速sensor的pin腳
int hallsensor = 2; typedef struct{
 
//Defines the structure for multiple fans and 
//their dividers 
char fantype;
unsigned int fandiv; }fanspec;
 
//Definitions of the fans
//This is the varible used to select the fan and it's divider,
//set 1 for unipole hall effect sensor
//and 2 for bipole hall effect sensor
fanspec fanspace[3]={{0,1},{1,2},{2,8}}; char fan = 1;
 
//This is the setup function where the serial port is initialised,
//and the interrupt is attached

void setup()

pinMode(hallsensor, INPUT);

attachInterrupt(0, rpm, RISING); 
 
 lcd.begin(16, 2);

//背光閃爍三次,間隔0.25秒
for(int i = 0; i < 3; i++) {
lcd.backlight();
delay(250);
lcd.noBacklight();
delay(250);
}

lcd.backlight();

// 輸出初始化文字
  lcd.setCursor(0, 0); // 設定游標位置在第一行行首
  lcd.print("Hello, world!");
  delay(1000);
  lcd.setCursor(0, 1); // 設定游標位置在第二行行首
  lcd.print("LCD is Working!");
  delay(2000);
 
 lcd.clear();
 lcd.setCursor(0, 0); 
 lcd.print("DC FAN Speed");
 delay(250);

}

void rpm ()
//This is the function that the interupt calls
{ count++; }


void loop ()
//Set NbTops to 0 ready for calculations

//計數器歸零
count = 0;

//開啟中斷interrupt0
attachInterrupt(0, rpm, RISING);  

delay (1000);

//關閉中斷interrupt0
detachInterrupt(0);

//計算每分鐘轉速RPM
Calc = ((count * 60)/fanspace[fan].fandiv);

//將轉速計算後輸出到1602A LCD上
 lcd.setCursor(0, 1); 
 lcd.print("RPM = ");
 lcd.print(Calc); 
 lcd.print("   ");

 

開機後先讓LCD螢幕背光亮三次

然後顯示開機字串

開啟中斷後等待一秒,然後計算轉速

最後顯示在LCD螢幕上。

此程式運動的十分穩定,我很喜歡。

 

 

arrow
arrow

    呂阿谷 發表在 痞客邦 留言(0) 人氣()