如何使用Arduino简单地构建模拟速度表

测量仪表

1495人已加入

描述

测量车辆或电机的速度/转速一直是一个值得尝试的迷人项目。在这个项目中,我们将使用 Arduino 构建一个模拟速度表。我们将使用红外传感器模块来测量速度。还有其他方法/传感器,例如霍尔传感器来测量速度,但使用红外传感器很容易,因为红外传感器模块是非常常见的设备,我们可以轻松地从市场上获得它,也可以用于任何类型的电机/车辆。

在这个项目中,我们将以模拟和数字形式展示速度。通过做这个项目,我们还将提高我们学习Arduino和步进电机的技能,因为这个项目涉及使用中断和定时器。在该项目结束时,您将能够计算任何旋转物体所覆盖的速度和距离,并将它们以数字格式显示在 16x2 LCD 屏幕上以及模拟仪表上。因此,让我们从带有Arduino的速度表和里程表电路开始

所需材料

阿杜伊诺

双极步进电机(4线)

步进电机驱动器(L298n模块)

红外传感器模块

16*2液晶显示屏

2.2k 电阻

连接线

面包板。

电源

车速表图片打印输出

双极步进电机

计算速度并将其显示在模拟速度表上

红外传感器是一种可以检测其前方物体存在的设备。我们使用了两个叶片转子(风扇),并将红外传感器放置在其附近,以便每次叶片旋转时,红外传感器都会检测到它。然后,我们使用Arduino中的计时器和中断的帮助来计算电机完全旋转所需的时间。

双极步进电机

在这个项目中,我们使用最高优先级的中断来检测rpm,并将其配置为上升模式。因此,每当传感器输出从低到高时,将执行函数 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 是上次执行的步骤。

电路图和连接

这个模拟车速表的电路图很简单,这里我们使用 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);

在此之后,我们采用一些变量和宏来执行计算。上一节中已经解释了计算。

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);

}

在此之后,我们读取循环函数中的rpm并执行计算以获得速度并将其转换为运行步进电机的步骤,以模拟形式显示速度。

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);

}

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分