Arduino 自动晾衣绳:我怎样才能满足不同的标准?

问题描述

所以我是编程新手,正在帮助我的朋友为一个项目编写自动晾衣绳。

每个组件单独工作正常,但是当我将所有代码放在一起时,电机会向哪个方向前进。任何人都可以看看它并给我们反馈吗?

我们有一个雨量传感器、光线传感器、2 个开关和一个电机。

下雨时天黑时电机将衣服拉入,当衣服到达末端时,它会接触开关 1 并停止电机。

当它停止下雨/晴天AND/OR当有光时,它会把衣服拉出来。

这是我提供的代码

**

#include <Stepper.h>
//motors
const int stepsPerRevolution = 400;
//motor speeds
Stepper myStepper = Stepper(stepsPerRevolution,2,4,3,5);//clockwise
Stepper myStepper2 = Stepper(stepsPerRevolution,5,2);//counterclockwise
//rain sensor
const int capture_D =4;
const int capture_A = A0;
int val_analogique;
int led = 8;
//switches
const int switch1 = A3;
const int switch2 =A4;
void setup() {
  // put your setup code here,to run once:
 // motors
myStepper.setSpeed(60);
myStepper2.setSpeed(60);
//rain sensor
pinMode(capture_D,INPUT);
pinMode(capture_A,INPUT);
pinMode(led,OUTPUT);
Serial.begin(9600);
}
void loop() {
// put your main code here,to run repeatedly:
//light sensors
unsigned int AnalogValueL;
AnalogValueL = analogRead(A5);
Serial.println(AnalogValueL);
delay(2000);
//rainsensor
if((digitalRead(capture_A) && digitalRead(capture_D)) ==LOW)
{
  digitalWrite(led,HIGH);
  
  myStepper2.step(stepsPerRevolution); // bringclothesout
  Serial.println("DRY");
  delay(1000); 
}
  
else
{
  //when it rains the clolthes re brought in 
  digitalWrite(led,LOW);
  Serial.println("WET");
  myStepper.step(stepsPerRevolution);//bring clothes in 
  delay(1000);
 
}
if(AnalogValueL < 1010)
{
  digitalWrite(led,HIGH);
  Serial.println("SUNNY");
    myStepper2.step(stepsPerRevolution);
  delay(1000);
}
else
{
  digitalWrite(led,LOW);
  Serial.println("Dark");
  myStepper.step(stepsPerRevolution);
    delay(1000);
}
//switches
unsigned int AnalogValueS;
AnalogValueS = analogRead(switch1);
Serial.println(AnalogValueS);
delay(2000);
if(AnalogValueS <= 1000)
{
  digitalWrite(led,HIGH);
  Serial.println("Off");
  myStepper.setSpeed(0);
}
else
{
  digitalWrite(led,LOW);
  Serial.println("on");
}
unsigned int AnalogValueSS;
AnalogValueSS = analogRead(switch2);
Serial.println(AnalogValueSS);
delay(2000);
if(AnalogValueSS <= 1000)
{
  digitalWrite(led,HIGH);
  Serial.println("ON");
 
}
else
{
  digitalWrite(led,LOW);
  Serial.println("Off");
   
}
*/
}//end of program

**

反馈?

解决方法

这是我的反馈:

  1. 为了清晰和可读性,您的代码需要稍微整理一下。
  2. 始终建议在 Serial.begin(); 函数的开头声明您的 setup()
  3. 您忘记将开关引脚声明为输入: pinMode(switchX,INPUT); // 其中 X = 1,2
  4. 为什么使用模拟引脚作为开关输入? (const int switch1 = A3)。如果您在这里连接 ON/OFF 开关,您应该使用数字引脚。如果您的开关是光传感器,那么它们很好(阅读下面的评论 9)。否则,这是:

AnalogValueS = analogRead(switch1);

是错误的,因为您无法读取带有 analogRead()

的数字开关

此外,您不会说您的开关是高电平有效还是低电平有效,即按下时它们脉冲低电平,释放时脉冲高电平,反之亦然。

  1. 一个重要的错误是您为不同的功能分配了两次引脚 4。首先作为电机销,然后作为 capture_D:

步进器 myStepper = Stepper(stepsPerRevolution,2,4,3,5);
Stepper myStepper2 = Stepper(stepsPerRevolution,5,2); const int capture_D = 4;

  1. 您读取了在 main() 循环内声明的变量中的模拟值,而您之前声明了 int val_analogique 而没有使用它。这是很差的一致性。
  2. 同样,您从模拟引脚 A5 读取数据,而无需事先将其声明为 INPUT

AnalogValueL = analogRead(A5);

  1. 您的循环流程可能会受到整个代码中那么多 delay() 的影响。
  2. 您表示拥有三个传感器:

我们有一个雨量传感器、光线传感器、2 个开关和一个电机。

使用相关传感器的代表名称标记这些传感器的引脚是一种很好的做法:例如:

const int lightSensor1 = 4;

  1. 在 C++ 中,思维定势是使用 enums 来定义来自特定事件或场景的状态的常见做法。例如:

    typedef 枚举 { 下雨, 黑暗的, NOT_RAINING, 阳光明媚 }WEATHER_CONDITIONS;

    WEATHER_CONDITIONS currentCondition = 晴天;

其中 typedef 表示您正在创建自己的数据类型 WEATHER_CONDITIONS 并且它们的分配值是 0,1,... 根据它们的顺序。

  1. 关于 Stepper.h 库,您声明了两个 Stepper 实例,希望通过这种方式反转电机的方向。这不是它的工作原理。根据库(Stepper.cpp)来反转电机,您需要发送一个负值作为参数来反转其方向。请阅读库中此文件的第 184 行。

  2. 在这一行:

if((digitalRead(capture_A) && digitalRead(capture_D)) ==LOW)

您正在尝试从模拟引脚读取数字值。如果该引脚上的电压处于逻辑电平可能会起作用,但不建议这样做。

  1. 最后,您应该将用于停止电机的开关连接到 INTERRUPT 引脚。这是检测何时按下开关并通过更改状态立即采取行动的更有效方法。您必须使用引脚 2 和 3(INT0 和 INT1)。

这是我对这段代码的看法。编译正确但未经测试!

#include <Arduino.h>
#include <Stepper.h>

/*Constants*/

//motor speeds
const int stepsPerRevolution = 400;

/*Pinout declarations*/
// Motor pins
const int motorPins[4] = {2,5};

//rain sensor
const int capture_D = 4;   // capture_D
const int capture_A = A0;  // A0

const int lightSensor = A5;

//switches
const int switch1 = 9;   // Previously: A3   So this is an analog switch?
const int switch2 = 10;  // Previously: A4    You should assing this to other two digital pins

//Led
const int led = 8;

/*Custom variables*/
typedef enum {
    DARK,SUNNY
} LIGHT_CONDITIONS;

LIGHT_CONDITIONS lightState = SUNNY;

const char* lightLabels[] = {"DARK","SUNNY"};

typedef enum {
    DRY,WET
} HUMIDITY_CONDITIONS;

HUMIDITY_CONDITIONS humidityState = DRY;

const char* humidityLabels[] = {"DRY","WET"};

typedef enum {
    CW,// Let's assume that this is bring them in
    CCW,// this is take them out
    STOP
} MOTOR_DIRECTION;

MOTOR_DIRECTION currentDirection = STOP;  // This declares a default state

const char* directionLabels[] = {"Clothes In","Clothes Out"};
/*General variables*/
int rawLightValue;

// Objects declaration
Stepper myStepper = Stepper(stepsPerRevolution,motorPins[0],motorPins[1],motorPins[2],motorPins[3]);

void activateMotor(int direction) {
    switch (direction) {
        case MOTOR_DIRECTION::CW:

            myStepper.step(-stepsPerRevolution);
            currentDirection = CW;

            break;

        case MOTOR_DIRECTION::CCW:

            myStepper.step(stepsPerRevolution);

            currentDirection = CCW;

            break;

        case MOTOR_DIRECTION::STOP:
            currentDirection = STOP;

            myStepper.step(0);

            break;

        default:

            // so much empty

            break;
    }
}

void setup() {
    Serial.begin(9600);
    // motors
    myStepper.setSpeed(60);

    //rain sensor
    pinMode(capture_D,INPUT);
    pinMode(capture_A,INPUT);

    pinMode(switch1,INPUT);
    pinMode(switch2,INPUT);

    pinMode(lightSensor,INPUT);

    pinMode(led,OUTPUT);
}

void loop() {
    // First,read light sensor

    rawLightValue = analogRead(lightSensor);
    Serial.println(rawLightValue);

    if (rawLightValue < 1010) {
        digitalWrite(led,HIGH);

        lightState = SUNNY;

        Serial.println(lightLabels[lightState]);

    } else {
        digitalWrite(led,LOW);

        lightState = DARK;

        Serial.println(lightLabels[lightState]);
    }

    // Then read rain sensor --> digital portion only,granted that you have calibrated
    // its pulsing voltage corectly. I am assuming that you are using one of these sensors:
    // https://circuitdigest.com/microcontroller-projects/rain-detector-using-arduino

    if (digitalRead(capture_D) == LOW) {
        digitalWrite(led,HIGH);

        humidityState = DRY;

        Serial.println(humidityLabels[humidityState]);

    }

    else {
        //when it rains the clolthes re brought in
        digitalWrite(led,LOW);
        humidityState = WET;
        Serial.println(humidityLabels[humidityState]);
    }

    // Based on these conditions,activate the motor accordingly

    /* When it rains OR when it is dark the motors pulls the clothes in and when 
   the the clothes reaches the end it touches switch 1 and stops the motors.
   */

    if ((humidityState == WET) || (lightState == DARK)) {
        // While the switch is released,meaning that the switch has NOT been pressed:
        while (digitalRead(switch1) == HIGH) {
            activateMotor(CCW);
            Serial.println(directionLabels[currentDirection]);
        }
        // Finally,let the motors go until the swithces tell the system to stop the motor
        activateMotor(STOP);
    }

    if ((humidityState == DRY) && (lightState == SUNNY)) {
        // While the switch is released,meaning that the switch has NOT been pressed:
        while (digitalRead(switch2) == HIGH) {
            activateMotor(CW);
            Serial.println(directionLabels[currentDirection]);
        }
        // Finally,let the motors go until the swithces tell the system to stop the motor
        activateMotor(STOP);
    }
}