用LCD1602显示小车每行驶一圈的圈数和此时的速度,写出代码并解释每一行代码的含义
时间: 2024-02-15 07:01:54 浏览: 59
好的,下面是用LCD1602显示小车每行驶一圈的圈数和此时的速度的代码,以及每一行代码的含义解释:
```c
#include <LiquidCrystal.h>
const int encoderPinA = 2; //编码器A相接在数字引脚2上
const int encoderPinB = 3; //编码器B相接在数字引脚3上
const int motorPin1 = 4; //电机控制引脚1相接在数字引脚4上
const int motorPin2 = 5; //电机控制引脚2相接在数字引脚5上
const int speedPin = A0; //速度传感器相接在模拟引脚A0上
const int rs = 12, en = 11, d4 = 7, d5 = 6, d6 = 5, d7 = 4; //LCD屏幕引脚连接
int count = 0; //计数器,用来记录小车已经行驶的圈数
float speed = 0; //速度变量,用来记录小车当前的速度
unsigned long lastTime = 0; //上一次计算速度的时间
unsigned long interval = 500; //计算速度的时间间隔
volatile int encoderPos = 0; //编码器计数器,用来记录小车行驶的圈数
volatile int lastEncoderA = 0;//上一次编码器A相的状态
LiquidCrystal lcd(rs, en, d4, d5, d6, d7); //声明一个LCD对象
void setup() {
pinMode(encoderPinA, INPUT_PULLUP); //将编码器A相的引脚设置为上拉输入
pinMode(encoderPinB, INPUT_PULLUP); //将编码器B相的引脚设置为上拉输入
pinMode(motorPin1, OUTPUT); //将电机控制引脚1设置为输出
pinMode(motorPin2, OUTPUT); //将电机控制引脚2设置为输出
pinMode(speedPin, INPUT); //将速度传感器的引脚设置为输入
attachInterrupt(digitalPinToInterrupt(encoderPinA), updateEncoder, CHANGE); //绑定编码器A相的中断函数
lcd.begin(16, 2); //初始化LCD屏幕
}
void loop() {
//计算速度
unsigned long currentTime = millis(); //获取当前时间
if(currentTime - lastTime >= interval){ //如果时间间隔大于等于计算速度的时间间隔
speed = (float)pulseIn(speedPin, HIGH) / 1000.0 * 0.5; //计算速度,pulseIn函数可以测量引脚上的高电平脉冲宽度
lastTime = currentTime; //更新上一次计算速度的时间
}
//显示圈数和速度
lcd.setCursor(0, 0);
lcd.print("Count:");
lcd.print(count);
lcd.setCursor(0, 1);
lcd.print("Speed:");
lcd.print(speed);
//小车行驶控制
if(count < 1){ //小车行驶圈数小于1时,继续行驶
int encoderDiff = encoderPos - lastEncoderA; //计算编码器A相状态的变化量
if(encoderDiff >= 2){ //当编码器A相由0变成1时,说明小车行驶了一圈
count++; //更新计数器的值
encoderPos = 0; //重置编码器计数器的值
}
lastEncoderA = encoderPos; //更新上一次编码器A相状态的值
//执行小车行驶的代码
digitalWrite(motorPin1, HIGH);
digitalWrite(motorPin2, LOW);
}
else{ //小车已经行驶一圈,停止行驶
//停止小车行驶的代码
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
}
}
void updateEncoder(){
int encoderA = digitalRead(encoderPinA); //读取编码器A相的状态
int encoderB = digitalRead(encoderPinB); //读取编码器B相的状态
if(encoderA != lastEncoderA){ //当编码器A相状态发生变化时
if(encoderB != encoderA){ //如果编码器B相与A相不同,说明小车向前行驶
encoderPos++; //编码器计数器加1
}
else{ //如果编码器B相与A相相同,说明小车向后行驶
encoderPos--; //编码器计数器减1
}
lastEncoderA = encoderA; //更新上一次编码器A相状态的值
}
}
```
代码解释:
第1行:引入LiquidCrystal库,该库可以用于控制LCD显示屏。
第3行到第7行:定义编码器A相、编码器B相、电机控制引脚和速度传感器的引脚。
第9行和第10行:定义计数器和速度变量,分别用来记录小车已经行驶的圈数和当前的速度。
第11行和第12行:定义上一次计算速度的时间和计算速度的时间间隔。
第14行和第15行:定义编码器计数器和上一次编码器A相的状态。
第17行:声明一个LiquidCrystal对象,并将LCD屏幕的引脚连接到Arduino开发板的数字引脚rs、en、d4、d5、d6、d7。
第19行到第26行:setup函数,初始化编码器引脚、电机引脚、速度传感器引脚和LCD屏幕。
第28行到第54行:loop函数,程序的主要逻辑都在这里实现。首先计算速度,使用millis函数计算时间间隔和pulseIn函数测量引脚上的高电平脉冲宽度。然后将当前圈数和速度显示在LCD屏幕上。接着执行小车行驶的代码,使用digitalWrite函数控制电机的转动。当小车行驶一圈时,更新计数器的值并重置编码器计数器的值。如果小车已经行驶一圈,则停止行驶。
第56行到第63行:updateEncoder函数,编码器A相的中断处理函数。当编码器A相状态发生变化时,根据编码器B相的状态来判断小车的行驶方向,然后更新编码器计数器的值。
第65行到第70行:在setup函数中将updateEncoder函数绑定到编码器A相的中断上。
希望这份代码和注释能够对你有所帮助。
阅读全文