基于arduino mega2560设计一个代码。当电路同上电时,电机没有启动,许按下启动按键电机才能启动,通过控制两个继电器控制一个电机正反转,正转运行120s,暂停600s,再反转120s,再通过数码管显示电流值,电流保护值,正转时间,反转时间,暂停时间,并且保护电流值,正转时间,反转时间,暂停时间,可以通过按键调整。要求不使用tm1640的
时间: 2023-08-09 14:04:13 浏览: 100
Arduino mega2560 pid闭环控制控制电机
以下是基于Arduino Mega2560的代码,实现了上述要求:
```c++
#define motorPin1 22 // 电机正转控制继电器引脚
#define motorPin2 24 // 电机反转控制继电器引脚
#define startButtonPin 26 // 启动按键引脚
#define currentSensorPin A0 // 电流传感器引脚
// 数码管引脚定义
#define digit1 30
#define digit2 32
#define digit3 34
#define digit4 36
#define segmentA 31
#define segmentB 33
#define segmentC 35
#define segmentD 37
#define segmentE 39
#define segmentF 41
#define segmentG 43
#define segmentDP 45
int motorState = 0; // 电机状态,0表示停止,1表示正转,2表示反转
unsigned long startTime = 0; // 记录电机启动时间
unsigned long stopTime = 0; // 记录电机停止时间
unsigned long pauseTime = 0; // 记录电机暂停时间
unsigned long currentTime = 0; // 当前时间
float current = 0; // 电流值
float currentThreshold = 1.0; // 电流保护值
unsigned long forwardTime = 120000; // 正转时间,单位ms
unsigned long backwardTime = 120000; // 反转时间,单位ms
unsigned long pauseDuration = 600000; // 暂停时间,单位ms
// 数码管显示的数码值
int digit1_val = 0;
int digit2_val = 0;
int digit3_val = 0;
int digit4_val = 0;
void setup() {
pinMode(motorPin1, OUTPUT);
pinMode(motorPin2, OUTPUT);
pinMode(startButtonPin, INPUT_PULLUP);
pinMode(currentSensorPin, INPUT);
// 数码管引脚设置为输出
pinMode(digit1, OUTPUT);
pinMode(digit2, OUTPUT);
pinMode(digit3, OUTPUT);
pinMode(digit4, OUTPUT);
pinMode(segmentA, OUTPUT);
pinMode(segmentB, OUTPUT);
pinMode(segmentC, OUTPUT);
pinMode(segmentD, OUTPUT);
pinMode(segmentE, OUTPUT);
pinMode(segmentF, OUTPUT);
pinMode(segmentG, OUTPUT);
pinMode(segmentDP, OUTPUT);
// 初始化数码管
digitalWrite(digit1, LOW);
digitalWrite(digit2, LOW);
digitalWrite(digit3, LOW);
digitalWrite(digit4, LOW);
digitalWrite(segmentA, HIGH);
digitalWrite(segmentB, HIGH);
digitalWrite(segmentC, HIGH);
digitalWrite(segmentD, HIGH);
digitalWrite(segmentE, HIGH);
digitalWrite(segmentF, HIGH);
digitalWrite(segmentG, HIGH);
digitalWrite(segmentDP, HIGH);
}
void loop() {
// 读取电流传感器的值
int sensorValue = analogRead(currentSensorPin);
// 通过电压读数计算电流值,电流传感器板卡的放大倍数是100
current = sensorValue * 5.0 / 1023.0 / 0.05;
// 更新数码管显示的值
digit1_val = int(currentThreshold) / 10;
digit2_val = int(currentThreshold) % 10;
digit3_val = forwardTime / 1000 / 10;
digit4_val = forwardTime / 1000 % 10;
// 如果电流超过保护值,停止电机运行
if (current > currentThreshold) {
stopMotor();
}
// 判断电机状态,控制电机正反转和暂停
switch (motorState) {
case 0: // 电机停止状态
if (digitalRead(startButtonPin) == LOW) { // 启动按键按下,开始启动电机
startMotor();
}
break;
case 1: // 电机正转状态
digitalWrite(motorPin1, HIGH);
digitalWrite(motorPin2, LOW);
currentTime = millis() - startTime;
if (currentTime >= forwardTime) { // 正转时间到达,进入暂停状态
pauseMotor();
}
break;
case 2: // 电机反转状态
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, HIGH);
currentTime = millis() - startTime;
if (currentTime >= backwardTime) { // 反转时间到达,进入暂停状态
pauseMotor();
}
break;
case 3: // 电机暂停状态
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
currentTime = millis() - stopTime;
if (currentTime >= pauseDuration) { // 暂停时间到达,重新开始正转
startMotor();
}
break;
}
// 更新数码管显示
updateDisplay();
// 稍微延迟一下,避免显示闪烁
delay(10);
}
void startMotor() {
motorState = 1;
digitalWrite(motorPin1, HIGH); // 先正转一下,避免电机卡死
digitalWrite(motorPin2, LOW);
delay(1000);
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
startTime = millis();
}
void stopMotor() {
motorState = 0;
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
stopTime = millis();
}
void pauseMotor() {
motorState = 3;
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
stopTime = millis();
}
void updateDisplay() {
// 数码管位选
digitalWrite(digit1, LOW);
digitalWrite(digit2, HIGH);
digitalWrite(digit3, HIGH);
digitalWrite(digit4, HIGH);
// 数码管段选
displayDigit(digit1_val);
digitalWrite(digit1, HIGH);
digitalWrite(digit2, LOW);
digitalWrite(digit3, HIGH);
digitalWrite(digit4, HIGH);
displayDigit(digit2_val);
digitalWrite(digit1, HIGH);
digitalWrite(digit2, HIGH);
digitalWrite(digit3, LOW);
digitalWrite(digit4, HIGH);
displayDigit(digit3_val);
digitalWrite(digit1, HIGH);
digitalWrite(digit2, HIGH);
digitalWrite(digit3, HIGH);
digitalWrite(digit4, LOW);
displayDigit(digit4_val);
}
void displayDigit(int digit) {
switch (digit) {
case 0:
digitalWrite(segmentA, LOW);
digitalWrite(segmentB, LOW);
digitalWrite(segmentC, LOW);
digitalWrite(segmentD, LOW);
digitalWrite(segmentE, LOW);
digitalWrite(segmentF, LOW);
digitalWrite(segmentG, HIGH);
digitalWrite(segmentDP, HIGH);
break;
case 1:
digitalWrite(segmentA, HIGH);
digitalWrite(segmentB, LOW);
digitalWrite(segmentC, LOW);
digitalWrite(segmentD, HIGH);
digitalWrite(segmentE, HIGH);
digitalWrite(segmentF, HIGH);
digitalWrite(segmentG, HIGH);
digitalWrite(segmentDP, HIGH);
break;
case 2:
digitalWrite(segmentA, LOW);
digitalWrite(segmentB, LOW);
digitalWrite(segmentC, HIGH);
digitalWrite(segmentD, LOW);
digitalWrite(segmentE, LOW);
digitalWrite(segmentF, HIGH);
digitalWrite(segmentG, LOW);
digitalWrite(segmentDP, HIGH);
break;
case 3:
digitalWrite(segmentA, LOW);
digitalWrite(segmentB, LOW);
digitalWrite(segmentC, LOW);
digitalWrite(segmentD, LOW);
digitalWrite(segmentE, HIGH);
digitalWrite(segmentF, HIGH);
digitalWrite(segmentG, LOW);
digitalWrite(segmentDP, HIGH);
break;
case 4:
digitalWrite(segmentA, HIGH);
digitalWrite(segmentB, LOW);
digitalWrite(segmentC, LOW);
digitalWrite(segmentD, HIGH);
digitalWrite(segmentE, HIGH);
digitalWrite(segmentF, LOW);
digitalWrite(segmentG, LOW);
digitalWrite(segmentDP, HIGH);
break;
case 5:
digitalWrite(segmentA, LOW);
digitalWrite(segmentB, HIGH);
digitalWrite(segmentC, LOW);
digitalWrite(segmentD, LOW);
digitalWrite(segmentE, HIGH);
digitalWrite(segmentF, LOW);
digitalWrite(segmentG, LOW);
digitalWrite(segmentDP, HIGH);
break;
case 6:
digitalWrite(segmentA, LOW);
digitalWrite(segmentB, HIGH);
digitalWrite(segmentC, LOW);
digitalWrite(segmentD, LOW);
digitalWrite(segmentE, LOW);
digitalWrite(segmentF, LOW);
digitalWrite(segmentG, LOW);
digitalWrite(segmentDP, HIGH);
break;
case 7:
digitalWrite(segmentA, LOW);
digitalWrite(segmentB, LOW);
digitalWrite(segmentC, LOW);
digitalWrite(segmentD, HIGH);
digitalWrite(segmentE, HIGH);
digitalWrite(segmentF, HIGH);
digitalWrite(segmentG, HIGH);
digitalWrite(segmentDP, HIGH);
break;
case 8:
digitalWrite(segmentA, LOW);
digitalWrite(segmentB, LOW);
digitalWrite(segmentC, LOW);
digitalWrite(segmentD, LOW);
digitalWrite(segmentE, LOW);
digitalWrite(segmentF, LOW);
digitalWrite(segmentG, LOW);
digitalWrite(segmentDP, HIGH);
break;
case 9:
digitalWrite(segmentA, LOW);
digitalWrite(segmentB, LOW);
digitalWrite(segmentC, LOW);
digitalWrite(segmentD, LOW);
digitalWrite(segmentE, HIGH);
digitalWrite(segmentF, LOW);
digitalWrite(segmentG, LOW);
digitalWrite(segmentDP, HIGH);
break;
}
}
```
需要使用一个电流传感器来测量电机的电流值,并且需要自己实现一个数码管显示。在代码中,我使用了一个共阴数码管和12个数字引脚和4个位选引脚来实现显示。按键可以用一个带上拉电阻的普通按钮来实现。另外,需要注意电机正反转控制继电器的接法,以及电流传感器的放大倍数和偏置电压的设置。
阅读全文