|
数字出租车计价器的Arduino编程 在本文末尾处给出了完整的代码。在这里,我们介绍代码的一些重要部分。
在开始介绍代码之前,我们需要了解中断和Timer One库,因为它们会在代码中使用。
这里使用中断是因为我们需要不断检查速度传感器模块上检测到的输出是否为高优先级。所以在代码中使用了ISR。 ISR是中断服务程序,在中断引脚2和3发生中断时调用。
Arduino UNO有两个中断引脚2和3。 ● 在引脚2处,连接速度传感器的D0的输出。 ● 在引脚3处,连接带有下拉电阻的按钮。
代码中使用TimerOne库来检查一秒钟内检测到的旋转次数(多少个脉冲),然后我们可以计算每秒的速度并在输出端显示它们。此ISR函数每秒执行一次。
让我们详细看看代码: 1. 首先,包含函数的库将用于程序。 - #include "TimerOne.h"
- #include <LiquidCrystal.h>
复制代码2. 接下来声明全局变量,因为它们将在整个程序中使用。 - volatile unsigned int counter=0;
- volatile unsigned int rotation=0;
- float rotationinm=0;
- unsigned int speed=0;
复制代码3. 接下来定义并初始化连接到Arduino的LCD引脚。 - const int rs = 12, en = 13, d4 = 8, d5 = 9, d6 = 10, d7 = 11;
- LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
复制代码4. 接下来在void setup()函数中, 定义引脚模式,此处PIN A0用于从电位器获取模拟输入,引脚5用于写入连接到ULN2003 IC的IN1引脚的模拟输出。 - pinMode(A0,INPUT);
- pinMode(5,OUTPUT);
复制代码接下来显示一些欢迎消息,然后清除。 - lcd.begin(16,2); //Sets LCD as 16x2 type
- lcd.setCursor(0,0);
- lcd.print("CIRCUIT DIGEST");
- lcd.setCursor(0,1);
- lcd.print("WELCOME TO TAXI");
- delay(3000);
- lcd.clear();
- lcd.print("LETS START :)");
- delay(1000);
- lcd.clear();
复制代码
接下来重要的部分是设置中断引脚和中断发生时要调用的ISR。
首先,我们需要将timer1设置为1秒,然后为timer1附加一个ISR,以便每秒调用一次ISR。 ISR名称是timerIsr - Timer1.initialize(1000000);
- Timer1.attachInterrupt( timerIsr );
复制代码接下来关联两个外部中断。第一次中断使Arduino引脚2成为中断引脚,当引脚2检测到RISING(低电平到高电平)时,调用ISR(计数)。该引脚2连接到速度传感器模块的D0输出。 第二个将Arduino引脚3作为中断引脚,并在引脚3检测到高电平时调用ISR(生成)。该引脚通过下拉电阻连接到按钮。 - attachInterrupt(digitalPinToInterrupt(2), count, RISING);
- attachInterrupt(digitalPinToInterrupt(3), generatefare, HIGH);
复制代码
5. 接下来让我们看看我们在这里使用的ISR: 当引脚2(连接到速度传感器)发生上升沿中断(低到高)时,调用ISR1- count() ISR函数。 - void count() // ISR for counts from the speed sensor
- {
- counter++; // increase the counter value by one
- rotation++; //Increase the rotation value by one
- delay(10);
- }
复制代码ISR2- timerIsr() ISR每秒调用一次,并执行ISR中存在的那些代码。 - void timerIsr()
- {
- detachInterrupt(digitalPinToInterrupt(2));
- Timer1.detachInterrupt();
- lcd.clear();
- float speed = (counter / 20.0)* 60.0;
- float rotations = 230*( rotation / 20);
- rotationinm = rotations/100;
- lcd.setCursor(0,0);
- lcd.print("Dist(m):");
- lcd.print(rotationinm);
- lcd.setCursor(0,1);
- lcd.print("Speed(RPM):");
- lcd.print(speed);
- counter=0;
- int analogip = analogRead(A0);
- int motorspeed = map(analogip,0,1023,0,255);
- analogWrite(5,motorspeed);
- Timer1.attachInterrupt( timerIsr );
- attachInterrupt(digitalPinToInterrupt(2), count, RISING);
- }
复制代码
该函数包含实际首先分离Timer1和中断pin2的行,因为我们在ISR中有LCD打印语句。
为了以RPM计算SPEED,我们使用下面的代码,其中20.0是编码器轮中预设的槽数。 - float speed = (counter / 20.0) * 60.0;
复制代码并且为了计算距离,使用以下代码: - float rotations = 230*( rotation / 20);
复制代码这里车轮的周长假定为230厘米(这对于实时车来说是正常的) 接下来,通过将距离除以100来转换距离(m) - rotationinm = rotations/100;
复制代码之后,我们在LCD显示屏上显示SPEED和DISTANCE. - lcd.setCursor(0,0);
- lcd.print("Dist(m):");
- lcd.print(rotationinm);
- lcd.setCursor(0,1);
- lcd.print("Speed(RPM):");
- lcd.print(speed);
复制代码
重要提示:我们必须将计数器重置为0,因为我们需要获得每秒检测到的脉冲数,因此我们使用此代码 接下来读取模拟引脚A0并将其转换为数字值(0到1023)并进一步将这些值映射到0-255以进行PWM输出(设置电机速度),最后使用连接到ULN2003的analogWrite函数写入这些PWM值电机IC。 - int analogip = analogRead(A0);
- int motorspeed = map(analogip,0,1023,0,255);
- analogWrite(5,motorspeed);
复制代码
ISR3:generatefare() ISR用于根据行进距离生成票价金额。当检测到中断引脚3为高电平时(按下按钮时),将调用此ISR。该函数分离引脚2的中断和定时器中断,然后清除LCD。 - void generatefare()
- {
- detachInterrupt(digitalPinToInterrupt(2)); pin at 2
- Timer1.detachInterrupt();
- lcd.clear();
- lcd.setCursor(0,0);
- lcd.print("FARE Rs: ");
- float rupees = rotationinm*5;
- lcd.print(rupees);
- lcd.setCursor(0,1);
- lcd.print("Rs 5 per metre");
- }
复制代码之后行驶的距离乘以5。你可以根据自己的意愿改变。 - float rupees = rotationinm*5;
复制代码计算出数值后,将其显示在连接到Arduino的LCD显示屏上。 - lcd.setCursor(0,0);
- lcd.print("FARE Rs: ");
- lcd.print(rupees);
- lcd.setCursor(0,1);
- lcd.print("Rs 5 per metre");
复制代码
您可以通过提高准确性、稳健性并添加更多功能(如Android应用程序、数字支付等)并将其开发为产品来进一步改进此原型。
代码 完整的代码如下:
main.rar
(1.34 KB, 下载次数: 47)
|