控制程式修改-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 2001|回复: 1

[未解决] 控制程式修改

[复制链接]
发表于 2021-9-5 10:27 | 显示全部楼层 |阅读模式
大家好:
最近刚学Arduino Uno板子,我要控制类似铁路平交道,当按钮按下后1.先双闪红色警示灯,2.经过2秒后先Servo1下降,3.再经过2秒后Servo2再下降。按钮解除后同时警示灯灭,2颗servo回到原位。
程序如下测试:
#include <Servo.h>
Servo myservo1;
Servo myservo2;
#define Led1 2              // 定义Led1接脚
#define Led2 3              // 定义Led2接脚
#define POTPin A0           // 定义可变电阻读取接脚
#define servo1Pin 5         // 定义伺服马达1读取接脚
#define servo2Pin 6         // 定义伺服马达2读取接脚
#define buttonPin 7         // 定义按钮开关读取接脚

unsigned int dt1;           // 延迟时间
unsigned long tmin = 0;     // 周期最小值
unsigned long tmax = 800;   // 周期最大值
unsigned long startTime1;  
unsigned long currentTime1;
const unsigned long period1 = 2000; // 设定延迟秒数为 2秒
unsigned long startTime2;  
unsigned long currentTime2;
const unsigned long period2 = 3000; // 设定延迟秒数为 3 秒

int v1;                     // 可变电阻读取值
unsigned long tp1 = 0;      // 计算经过时间用的变量
unsigned long tc1 = 0;

bool LedState1 = LOW;       // Led1 状态
bool LedState2 = HIGH;      // Led2 状态

void setup() {
    pinMode(Led1, OUTPUT);       //定义Led1接脚为输出
    pinMode(Led2, OUTPUT);       //定义Led2接脚为输出
    pinMode(POTPin, INPUT);      //定义可变电阻接脚为输入, 可省略
    myservo1.attach(servo1Pin);  //定义伺服马达1接脚为输出
    myservo2.attach(servo2Pin);  //定义伺服马达2接脚为输出
    pinMode(buttonPin, INPUT);   //定义按钮开关接脚为输入
    startTime1 = millis();       //initial start time
    startTime2 = millis();       //initial start time
    Serial.begin(9600);

}

void loop() {
     v1 = analogRead(POTPin);
    dt1 = map(v1, 0, 1023, tmin, tmax) ;
    //Serial.println(dt1);
    tc1 = millis();
    // 当 millis() - tp1 >= dt1 时改变 Led 的状态
    if (digitalRead(buttonPin) == LOW) {
       if(millis() - tp1 >= dt1) {
          tp1 = tc1;
          LedState1 = !LedState1;
          digitalWrite(Led1, LedState1);
          LedState2 = !LedState2;
          digitalWrite(Led2, LedState2);
          }
        currentTime1 = millis();
        if (currentTime1 - startTime1 >= period1)     //test whether the period1 has elapsed

        {
           myservo1.write(0);
           //myservo2.write(180);
           startTime1 = currentTime1;
         }
        currentTime2 = millis();
        if (currentTime2 - startTime2 >= period2)     //test whether the period2 has elapsed

        {
           //myservo1.write(0);
           myservo2.write(180);
           startTime2 = currentTime2;
         }

      }
      else {  
          myservo1.write(90);
          myservo2.write(90);
          digitalWrite(Led1, LOW);
          digitalWrite(Led2, LOW);
        }

}
测试时第一次按钮按下运作正常,解除后马上再度按钮按下时,有时候正常有时候不正常,譬如警示灯servo同时动作,或者Servo2先动作再servo1动作。
请问:
1.        程序如何修正?才能达到我想要状态。
2.        Servo速度要再变慢如何修改?
谢谢各位解答


发表于 2021-9-6 01:12 | 显示全部楼层
本帖最后由 frankhan747 于 2021-9-6 01:17 编辑

1. 按钮按下时,你的软件计时器并没有及时重置。这导致按钮第二次按下时,各事件均满足触发条件。
你应该在if(digitalRead(buttonPin) == LOW){ 后面加这样几行:
  1. if(digitalRead(buttonPin) == LOW) {
  2.   tp1 = millis();
  3.   startTime1 = tp1;
  4.   startTime2 = tp1;
  5.   ···
复制代码

2. 舵机慢转可以通过“小碎步”法实现:
  1. for (step=90; step<=180; step++) {
  2.   m_servo.write(step);
  3.   delay(5);
  4. }
复制代码

3. 把setup里面的
  1. pinMode(POTPin, INPUT);      //定义可变电阻接脚为输入
复制代码
去掉
pinMode-INPUT是GPIO input,和analogRead用到的ADC输入根本不是一回事
此外,建议给按钮加个上拉电阻(如有请自行忽略此条)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 23:38 , Processed in 0.090346 second(s), 16 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表