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++; // 递增已发送的脉冲数}
}