官網後段也有改進之後的程式:
// 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;
接線圖同上一篇:
底下是我改寫後,將轉速輸出到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螢幕上。
此程式運動的十分穩定,我很喜歡。
留言列表