大三课程设计,两个传感器隔一点距离,打孔纸带在上面移动,要求纸带移动方向和丝杠螺母方向一致。
用到一个arduino板子,一个驱动电路模块,两个红外传感器,一个丝杠螺母连着步进电机的,一个打孔纸带。
关于用到的驱动电路,原因是arduinoI/O口直接驱动的话电流电压太小,电机可能不转或者太慢,所以要加一个驱动电路。
红外线传感器:二极管是阳极接+5V。当检测到有覆盖则输出为0,二极管亮。这种传感器有很大缺点:灵敏性难控制,两个相同传感器都可能会不一样。白天可能会受光线的影响。
步进电机是二相四拍的。四拍是+A+B—>-A+B->-A-B ->+A-B -A,-B就是反接的意思。
步进电机的知识:步进电机是给一个脉冲走一个步距角的。电机转速和脉冲频率有关,f=1/T。
arduino怎么产生脉冲,简单的可以通过延时,难一点通过定时器。
以下是示例程序
#include <Arduino.h>
#include <IRremote.h>
int RECV_PIN1 = 11;//传感器的引脚命名
int RECV_PIN2 = 12;
IRrecv irrecv1(RECV_PIN1);//定义IRrecv对象来接受传感器信号
IRrecv irrecv2(RECV_PIN2);
decode_results results;//存放解码器的值
#define A1 3 //步进电机驱动引脚命名
#define A2 4
#define B1 5
#define B2 6
int LEFT_flag = 0; //设置左传感器标志位
int RIGHT_flag = 0;
int time=7; //全局变量,改变延时可改变旋转速度
void setup()
{
Serial.begin(9600);
pinMode(RECV_PIN1,INPUT_PULLUP);// 配置11号针脚为输入状态,并设置使用内部上拉电阻。
pinMode(RECV_PIN2,INPUT_PULLUP);
pinMode(A1,OUTPUT); //设置3号引脚为输出引脚
pinMode(A2,OUTPUT);
pinMode(B1,OUTPUT);
pinMode(B2,OUTPUT);
}
void Scan() //扫描两个传感器,并设置传感器标志位值
{
LEFT_flag = 0; //清空变量
RIGHT_flag = 0;
int Left = digitalRead(RECV_PIN1);// 读取11号针脚上的输入信号的数值
int Right = digitalRead(RECV_PIN2);
Serial.println(Left); // 将获取到的数值打印到串行调试窗口,方便调试。
Serial.println(Right);
if(Left == LOW) //左边的传感器检测到低电平
{
LEFT_flag = 1; //左传感器标志位设置为1
}
if(Right == LOW) //右边传感器检测到低电平
{
RIGHT_flag = 1; //右传感器标志位设置为1
}
}
void orientations_right()//正转
{
Phase_A(); //设置A相位
delay(time); //改变延时可改变旋转速度
Phase_B(); //设置B相位
delay(time);
Phase_C(); //设置C相位
delay(time);
Phase_D(); //设置D相位
delay(time);
}
void orientations_left()//反转
{
Phase_D(); //设置D相位
delay(time); //改变延时可改变旋转速度
Phase_C(); //设置C相位
delay(time);
Phase_B(); //设置B相位
delay(time);
Phase_A(); //设置A相位
delay(time);
}
void Phase_A()
{
digitalWrite(A1,HIGH); //A1引脚高电平
digitalWrite(A2,LOW);
digitalWrite(B1,HIGH);
digitalWrite(B2,LOW);
}
void Phase_B()
{
digitalWrite(A1,LOW);
digitalWrite(A2,HIGH); //B1引脚高电平
digitalWrite(B1,HIGH);
digitalWrite(B2,LOW);
}
void Phase_C()
{
digitalWrite(A1,LOW);
digitalWrite(A2,HIGH);
digitalWrite(B1,LOW); //C1引脚高电平
digitalWrite(B2,HIGH);
}
void Phase_D()
{
digitalWrite(A1,HIGH);
digitalWrite(A2,LOW);
digitalWrite(B1,LOW);
digitalWrite(B2,HIGH); //D1引脚高电平
}
void loop()
{
int i;
Scan();
if(LEFT_flag == 0 && RIGHT_flag == 1)
{
for(i = 0 ; i < 40; i++){
orientations_right(); //电机正转,螺母纸带向左边移动
}
}
else if(LEFT_flag == 1 && RIGHT_flag == 0)
{
for(i = 0 ; i < 40; i++){
orientations_left(); //反转,螺母纸带向右边移动
}
}
delay(5);
}
上面程序还有问题,我觉得相位超前滞后的条件下,不能只单单去判断高低电平,应该要有判断上升和沿下降沿。这样程序运行以后的效果会更加好
以下是简单判断上升沿的程序
//定义全局变量
int flag = 0; //设置左传感器标志位
static int number=0
//检测左边红外传感器上升沿
boolean ScanLeft_up()
{
int Left = digitalRead(RECV_PIN1);// 读取11号针脚上的输入信号的数值
int Right = digitalRead(RECV_PIN2);
Serial.println(Left);
Serial.println(Right);
boolean Left_up = false;
if(Left == LOW){
flag = 1;
number++;//实现脉冲的计数
}
if((Left == HIGH) && (flag == 1))
{
Left_up = true; flag= 0;
}
return Left_up;
}
以下是带有上升沿或者下降沿判断的程序
#include <Arduino.h>
#include <IRremote.h>
int RECV_PIN1 = 11;//传感器的引脚命名
int RECV_PIN2 = 12;
IRrecv irrecv1(RECV_PIN1);//定义IRrecv对象来接受传感器信号
IRrecv irrecv2(RECV_PIN2);
decode_results results;//存放解码器的值
#define A1 3 //步进电机驱动引脚命名
#define A2 4
#define B1 5
#define B2 6
//定义全局变量
int flagLeft_up= 0;//设置左传感器上升沿标志位
int flagLeft_down= 0;
int flagRight_up= 0;
int flagRight_down= 0;
//static int number = 0;//记录多少个周期
int time=8;//全局变量,改变延时可改变旋转速度
void setup() {
// put your setup code here, to run once:
pinMode(RECV_PIN1,INPUT_PULLUP);// 配置11号针脚为输入状态,并设置使用内部上拉电阻。
pinMode(RECV_PIN2,INPUT_PULLUP);
Serial.begin(9600);
pinMode(A1,OUTPUT); //设置引脚为输出引脚
pinMode(A2,OUTPUT);
pinMode(B1,OUTPUT);
pinMode(B2,OUTPUT);
}
//检测左边红外传感器上升沿
boolean ScanLeft_up()
{
int Left = digitalRead(RECV_PIN1);//从11引脚读取值,HIGH或者LOW
int Right = digitalRead(RECV_PIN2);
Serial.println(Left);
Serial.println(Right);
boolean Left_up = false;
if(Left == LOW){
flagLeft_up = 1;
//number++;
}
if((Left == HIGH) && (flagLeft_up == 1))
{
Left_up = true; flagLeft_up = 0;
}
return Left_up;
}
boolean ScanLeft_down()//检测左边红外传感器下降沿
{
int Left = digitalRead(RECV_PIN1);//从11引脚读取值,HIGH或者LOW
int Right = digitalRead(RECV_PIN2);
Serial.println(Left);
Serial.println(Right);
boolean Left_down = false;
if(Left == HIGH){
flagLeft_down = 1;
}
if((Left == LOW) && (flagLeft_down == 1))
{
Left_down = true; flagLeft_down = 0;
}
return Left_down;
}
//检测右边红外传感器上升沿
boolean ScanRight_up()
{
int Left = digitalRead(RECV_PIN1);//从11引脚读取值,HIGH或者LOW
int Right = digitalRead(RECV_PIN2);
Serial.println(Left);
Serial.println(Right);
boolean Right_up = false;
if(Right == LOW){
flagRight_up = 1;
}
if((Right == HIGH) && (flagRight_up == 1))
{
Right_up = true; flagRight_up = 0;
}
return Right_up;
}
boolean ScanRight_down()//检测右边红外传感器下降沿
{
int Left = digitalRead(RECV_PIN1);//从11引脚读取值,HIGH或者LOW
int Right = digitalRead(RECV_PIN2);
Serial.println(Left);
Serial.println(Right);
boolean Right_down = false;
if(Right == HIGH){
flagRight_down = 1;
}
if((Right == LOW) && (flagRight_down == 1))
{
Right_down = true; flagRight_down = 0;
}
return Right_down;
}
void orientations_right()
{
Phase_A(); //设置A相位(A->B->C->D是左边移动)
delay(time);
Phase_B(); //设置B相位
delay(time);
Phase_C(); //设置C相位
delay(time);
Phase_D(); //设置D相位
delay(time);
}
void orientations_left()
{
Phase_D();
delay(time);
Phase_C();
delay(time);
Phase_B();
delay(time);
Phase_A();
delay(time);
}
void Phase_A()
{
digitalWrite(A1,HIGH); //A1引脚高电平
digitalWrite(A2,LOW);
digitalWrite(B1,HIGH);
digitalWrite(B2,LOW);
}
void Phase_B()
{
digitalWrite(A1,LOW);
digitalWrite(A2,HIGH); //B1引脚高电平
digitalWrite(B1,HIGH);
digitalWrite(B2,LOW);
}
void Phase_C()
{
digitalWrite(A1,LOW);
digitalWrite(A2,HIGH);
digitalWrite(B1,LOW); //C1引脚高电平
digitalWrite(B2,HIGH);
}
void Phase_D()
{
digitalWrite(A1,HIGH);
digitalWrite(A2,LOW);
digitalWrite(B1,LOW);
digitalWrite(B2,HIGH); //D1引脚高电平
}
void loop() {
int Left = digitalRead(RECV_PIN1);//从11引脚读取值,HIGH或者LOW
int Right = digitalRead(RECV_PIN2);
Serial.println(Left);
Serial.println(Right);
//判断条件左边的传感器的上升沿或下降沿和右边的传感器的电平的关系,或者右边的传感器的上升沿或下降沿和左边传感器的电平的关系
if(((ScanLeft_up()&&Right==HIGH)||(ScanLeft_down()&&Right==LOW))||((ScanRight_up()&&Left==LOW)||(ScanRight_down()&&Left==HIGH)))//正转,向左移动
{
int i=40;
while(i>0){
i--;
orientations_right();
}
}
else if((((ScanLeft_up()&&Right==LOW)||(ScanLeft_down()&&Right==HIGH))||((ScanRight_up()&&Left==HIGH)||(ScanRight_down()&&Left==LOW))))//反转、螺母往右,纸带右运动
{
int i=40;
while(i>0){
i--;
orientations_left();
}
}
}