測量車輛或電機的速度/轉速一直是一個值得嘗試的迷人項目。在這個項目中,我們將使用 Arduino 構建一個模擬速度表。我們將使用紅外傳感器模塊來測量速度。還有其他方法/傳感器,例如霍爾傳感器來測量速度,但使用紅外傳感器很容易,因為紅外傳感器模塊是非常常見的設備,我們可以輕松地從市場上獲得它,也可以用于任何類型的電機/車輛。
在這個項目中,我們將以模擬和數字形式展示速度。通過做這個項目,我們還將提高我們學習Arduino和步進電機的技能,因為這個項目涉及使用中斷和定時器。在該項目結束時,您將能夠計算任何旋轉物體所覆蓋的速度和距離,并將它們以數字格式顯示在 16x2 LCD 屏幕上以及模擬儀表上。因此,讓我們從帶有Arduino的速度表和里程表電路開始
所需材料
阿杜伊諾
雙極步進電機(4線)
步進電機驅動器(L298n模塊)
紅外傳感器模塊
16*2液晶顯示屏
2.2k 電阻
連接線
面包板。
車速表圖片打印輸出
計算速度并將其顯示在模擬速度表上
紅外傳感器是一種可以檢測其前方物體存在的設備。我們使用了兩個葉片轉子(風扇),并將紅外傳感器放置在其附近,以便每次葉片旋轉時,紅外傳感器都會檢測到它。然后,我們使用Arduino中的計時器和中斷的幫助來計算電機完全旋轉所需的時間。
在這個項目中,我們使用最高優(yōu)先級的中斷來檢測rpm,并將其配置為上升模式。因此,每當傳感器輸出從低到高時,將執(zhí)行函數 RPMCount()。由于我們使用了兩個葉片轉子,這意味著該函數將在一圈內調用 4 次。
知道所花費的時間后,我們可以使用以下公式計算 RPM,其中 1000/時間將給我們 RPS(每秒轉數),進一步乘以 60 將得到 RPM(每分鐘轉數)
rpm = (60/2)*(1000/(millis() - time))*REV/bladesInFan;
獲得 RPM 后,可以通過給定的公式計算速度:
Speed = rpm * (2 * Pi * radius) / 1000
我們知道Pi = 3.14,半徑為4.7英寸
但首先我們需要將半徑從英寸轉換為米:
radius = ((radius * 2.54)/100.0) meters
Speed= rpm * 60.0 * (2.0 * 3.14 * radius)/ 1000.0) in kilometers per hour
在這里,我們將 rpm 乘以 60 將 rpm 轉換為 rph(每小時轉數),除以 1000 將米/小時轉換為公里/小時。
在以kmh為單位的速度之后,我們可以以數字形式直接在LCD上顯示這些值,但是要以模擬形式顯示速度,我們需要再進行一次計算才能找出否。步進電機應移動以在模擬儀表上顯示速度。
在這里,我們使用了一個用于模擬儀表的 4 線雙極步進電機,它具有 1.8 度意味著每轉 200 步。
現在我們必須在車速表上顯示 280 公里/小時。所以要顯示280 Kmh步進電機需要移動280度
所以我們有 maxSpeed = 280
最大步數將是
maxSteps = 280/1.8 = 155 steps
現在我們在 Arduino 代碼中有一個函數,即map函數,它在這里用于將速度映射到步驟中。
Steps = map(speed,0,maxSpeed,0,maxSteps);
所以現在我們有
steps=map(speed,0,280,0,155);
計算步長后,我們可以直接將這些步進電機功能應用于移動步進電機。我們還需要通過使用給定的計算來照顧步進電機的當前步長或角度
currSteps=Steps
steps= currSteps-preSteps
preSteps=currSteps?
這里的 currSteps 是來自上次計算的當前步驟,preSteps 是上次執(zhí)行的步驟。
電路圖和連接
這個模擬車速表的電路圖很簡單,這里我們使用 16x2 LCD 以數字形式顯示速度,并使用步進電機旋轉模擬車速表指針。
16x2 LCD連接在Arduino的以下模擬引腳上。
RS - A5 RW - GND
EN - A4 D4
- A3 D5
- A2 D6 - A1
D7 - A0
?
2.2k電阻用于設置LCD的亮度。紅外傳感器模塊,用于檢測風扇的葉片以計算轉速,連接到中斷 0 表示 Arduino 的 D2 引腳。
這里我們使用了步進電機驅動器,即L293N模塊。步進電機驅動器的IN1、IN2、IN3和IN4引腳直接連接到Arduino的D8、D9、D10和D11。其余連接在電路圖中給出。
編程說明
Arduino Speedomete r的完整代碼在最后給出,在這里我們解釋了其中的一些重要部分。
在編程部分,我們包含了所有必需的庫,如步進電機庫、液晶 LCD 庫和它們的聲明引腳。
#include
LiquidCrystal lcd(A5,A4,A3,A2,A1,A0);
#include
const int stepsPerRevolution = 200; ?// change this to fit the number of steps per revolution
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);
在此之后,我們采用一些變量和宏來執(zhí)行計算。上一節(jié)中已經解釋了計算。
volatile byte REV;
unsigned long int rpm,RPM;
unsigned long st=0;
unsigned long time;
int ledPin = 13;?
int led = 0,RPMlen , prevRPM;
int flag = 0; ? ?
int flag1=1;
#define bladesInFan 2
float radius=4.7; ? // inch
int preSteps=0;
float stepAngle= 360.0/(float)stepsPerRevolution;
float minSpeed=0;
float maxSpeed=280.0;
float minSteps=0;
float maxSteps=maxSpeed/stepAngle;
之后,我們在設置功能中初始化LCD,串行,中斷和步進電機
void setup()
{
myStepper.setSpeed(60);
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
lcd.begin(16,2);
lcd.print("Speedometer");
delay(2000);
attachInterrupt(0, RPMCount, RISING);
}
在此之后,我們讀取循環(huán)函數中的rpm并執(zhí)行計算以獲得速度并將其轉換為運行步進電機的步驟,以模擬形式顯示速度。
void loop()
{
readRPM();
radius=((radius * 2.54)/100.0); ?// convering in meter
int Speed= ((float)RPM * 60.0 * (2.0 * 3.14 * radius)/1000.0);
// RPM in 60 minute, diameter of tyre (2pi r) r is radius, 1000 to convert in km
int Steps=map(Speed, minSpeed,maxSpeed,minSteps,maxSteps);
if(flag1)
{
Serial.print(Speed);
Serial.println("Kmh");
lcd.setCursor(0,0);
lcd.print("RPM: ");
lcd.print(RPM);
lcd.print(" ? ? ? ? ? ");
lcd.setCursor(0,1);
lcd.print("Speed: ");
lcd.print(Speed);
lcd.print(" Km/h ? ? ? ");
flag1=0;
}
int currSteps=Steps;
int steps= currSteps-preSteps;
preSteps=currSteps;
myStepper.step(steps);
}
這里我們有 reapRPM() 函數來計算 RPM。
int readRPM()
{
if(REV >= 10 or millis()>=st+1000) ? ? ? ? ? ? ? ? ?// ?IT WILL UPDATE AFETR EVERY 10 READINGS or 1 second in idle
{ ? ? ? ? ?
if(flag==0) ? ? ? ? ? ? ? ?
flag=1; ? ? ? ? ? ? ? ? ? ??
rpm = (60/2)*(1000/(millis() - time))*REV/bladesInFan;?
time = millis(); ? ? ? ? ? ? ? ? ? ? ? ? ??
REV = 0;
int x= rpm; ? ? ? ? ? ? ? ?
while(x!=0)
{
x = x/10;
RPMlen++;
} ? ? ?
Serial.println(rpm,DEC);
RPM=rpm;
delay(500);
st=millis();
flag1=1;
}
}
Finally, we have interrupt routine which is responsible to measure revolution of object
void RPMCount() ? ? ? ? ? ? ? ? ? ? ??
{
REV++; ? ? ? ? ? ? ? ? ? ? ? ? ? ??
if (led == LOW)
{
led = HIGH; ? ? ? ? ? ? ? ? ? ? ? ?
}
else
{
led = LOW;
}
digitalWrite(ledPin, led);
}
評論
查看更多