1.接线介绍
注意:NPN和PNP型光电开关的接线方式不同
首先,得在arduino上设置一个数字量接口,例如:
#define PHOTO_SWITCH_PIN 53 // 假设光电开关连接到数字引脚53
然后根据你的情况把白色的或者黑色的线接到该引脚上,我这里接的是黑线,白色线不用管。如果如果你希望在物体未被遮挡时无需关注输出信号,而在物体遮挡时发送一个信号并在遮挡持续期间保持这个信号状态,那么您应该使用常开输出线(NO,Normally Open)。然后5v和0v都可以使用arduino自带的接口。
下面是完整的实现代码:
#define RX_PIN 19
#define TX_PIN 18 // 定义电机控制引脚
#define DIRECTION_PIN 46
#define PULSE_PIN 47
#define MOTOR_PIN 9 // 定义光电开关连接的引脚(根据实际情况修改)
#define PHOTO_SWITCH_PIN 53 // 假设光电开关连接到数字引脚53 //#define MAX_PULSES_TO_REVERSE 100 // 定义需要反转的最大脉冲数unsigned long pulsesReversed = 0; // 记录已经反转的脉冲数
bool reverseMotorOnce = false; // 标志位,表示电机是否需要反转一次// 定义位移传感器的最小和最大位移值
const int minDisplacement = 200; // 最小位移(mm)
const int maxDisplacement = 4000; // 最大位移(mm) char command = '0'; // 初始值设为 '0'
bool isMotorRunning = false; // 标志位,表示电机是否正在运行
bool isReversed = false; // 标志位,表示电机是否处于反转状态 void setup() { pinMode(DIRECTION_PIN, OUTPUT); pinMode(PULSE_PIN, OUTPUT); pinMode(MOTOR_PIN, OUTPUT); digitalWrite(MOTOR_PIN, LOW); // 初始时电机停止 digitalWrite(DIRECTION_PIN, LOW); // 初始方向设置,假设正转对应低电平 // 初始化串口通信 Serial.begin(9600); pinMode(RX_PIN, INPUT); pinMode(TX_PIN, OUTPUT); // 初始化光电开关引脚为输入,并启用内部上拉电阻 pinMode(PHOTO_SWITCH_PIN, INPUT_PULLUP); // 添加一个初始状态检查,确保电机在启动时处于正确的状态 checkPhotoSwitch();
} void loop() { // 检查串口命令 if (Serial.available() > 0) { command = Serial.read(); if (command == '1') { startMotor(false); // 开始正转电机 } else if (command == '2') { startMotor(true); // 开始反转电机 } else if (command == '0') { stopMotor(); // 停止电机 } } // 检查光电开关状态 checkPhotoSwitch(); // 发送脉冲信号(当电机开启时) if (isMotorRunning) { if (!isReversed) {// 正转时持续发送脉冲信号sendPulseForward();} else {// 反转时发送脉冲信号,直到完成100个脉冲sendPulseReverse();}}
} void checkPhotoSwitch() { bool currentSwitchState = digitalRead(PHOTO_SWITCH_PIN) == LOW; // 假设低电平表示触发 if (currentSwitchState && isMotorRunning && !isReversed && !reverseMotorOnce) { // 如果光电开关被触发,电机正在运行,且当前不是反转状态,并且还未进行过反转,则反转电机 reverseMotorOnce = true; // 设置为已经反转过reverseMotor(); }
} void startMotor(bool reverse) { digitalWrite(MOTOR_PIN, HIGH); // 开启电机 setDirection(reverse); // 设置电机方向 isMotorRunning = true; isReversed = reverse; // 更新反转状态标志
} void stopMotor() { digitalWrite(MOTOR_PIN, LOW); // 停止电机 isMotorRunning = false;reverseMotorOnce = false; // 重置反转标志
} void setDirection(bool reverse) { digitalWrite(DIRECTION_PIN, reverse ? HIGH : LOW); // 设置电机方向
} void reverseMotor() { isReversed = !isReversed; // 反转状态取反 setDirection(isReversed); // 根据新的反转状态设置电机方向
} void sendPulseForward() { if (isMotorRunning && !isReversed) {// 只有在电机正转时才发送脉冲信号digitalWrite(PULSE_PIN, HIGH); delayMicroseconds(300); // 脉冲持续时间 digitalWrite(PULSE_PIN, LOW); delayMicroseconds(300); // 脉冲间隔时间 }
}void sendPulseReverse() { if (isMotorRunning && isReversed && pulsesReversed < 36000) {// 仅在电机反转且未达到100个脉冲时发送脉冲信号digitalWrite(PULSE_PIN, HIGH); delayMicroseconds(300); // 脉冲持续时间 digitalWrite(PULSE_PIN, LOW); delayMicroseconds(300); // 脉冲间隔时间 pulsesReversed++; // 递增已发送的脉冲数}
}