Arduino硬件开发--红外遥控舵机

硬件:Arduino uno板、红外遥控器、红外接收三极管、舵机、杜绑线; 

端口:红外接收管VOUT脚接11,舵机信号接9;

效果:随机按红外遥控器1~9之间数字,对就舵机旋转20、40、60、80、100、120、140、160、180度; 

代码:

//接收红外信息,解码获取对应数字,控制舵机旋转对应角度。

#include <IRremote.h>//红外库
int RECV_PIN = 11; //红外接收VOUT引脚定义
int SERVOPIN = 9; //舵机驱动引脚定义
int myangle;//定义角度变量
int pulsewidth;//定义脉宽变量

//编码示例遥控数字1~9代表舵机20-180角度
long d20 = 0x00ff30CF;
long d40 = 0x00FF18E7;
long d60 = 0x00FF7A85;
long d80 = 0x00FF10EF;
long d100 = 0x00FF38C7;
long d120 = 0x00FF5AA5;
long d140 = 0x00FF42BD;
long d160 = 0x00FF4AB5;
long d180 = 0x00FF52AD;
IRrecv irrecv(RECV_PIN);
decode_results results;//结构声明

void setup() {
  // put your setup code here, to run once:
  pinMode(RECV_PIN, INPUT); //红外VOUT端口模式,输入
  pinMode(SERVOPIN, OUTPUT); //舵机端口模式,输出
  Serial.begin(9600);//波特率9600
  irrecv.enableIRIn();//开启红外接收
  Serial.println("system is read now!");
}

int on = 0;
unsigned long last = millis();

void loop() {
  // put your main code here, to run repeatedly:
  if (irrecv.decode(&results)) {
    if (millis() - last > 250) {
      on = !on;
      digitalWrite(13, on ? HIGH : LOW);
      dump(&results);
    }
    if (results.value == d20) {
      Serial.println("20 degree");
      startRun(20);
    }
    if (results.value == d40) {
      Serial.println("40 degree");
      startRun(40);
    }

    if (results.value == d60)
    {
      Serial.println("60 degree");
      startRun(60);
    }
    if (results.value == d80)
    {
      Serial.println("80 degree");
      startRun(80);
    }
    if (results.value == d100)
    {
      Serial.println("100 degree");
      startRun(100);
    }
    if (results.value == d120)
    {
      Serial.println("120 degree");
      startRun(120);
    }
    if (results.value == d140)
    {
      Serial.println("140 degree");
      startRun(140);
    }
    if (results.value == d160)
    {
      Serial.println("160 degree");
      startRun(160);
    }
    if (results.value == d180)
    {
      Serial.println("180 degree");
      startRun(180);
    }
    last = millis();
    irrecv.resume();
  }
}

void dump(decode_results *results)
{
  int count = results->rawlen;
  if (results->decode_type == UNKNOWN) {
    Serial.println("Could not decode message");
  }
  else
  {
    if (results->decode_type == NEC) {
      Serial.print("Decoded NEC: ");
    }
    else if (results->decode_type == SONY) {
      Serial.print("Decoded SONY: ");
    }
    else if (results->decode_type == RC5) {
      Serial.print("Decoded RC5: ");
    }
    else if (results->decode_type == RC6) {
      Serial.print("Decoded RC6: ");
    }
    Serial.print(results->value, HEX);
    Serial.print(" (");
    Serial.print(results->bits, DEC);
    Serial.println(" bits)");
  }
  Serial.print("Raw (");
  Serial.print(count, DEC);
  Serial.print("): ");

  for (int i = 0; i < count; i++)
  {
    if ((i % 2) == 1) {
      Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
    }
    else {
      Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
    }
    Serial.print(" ");
  }
  Serial.println("");
}

void servopulse(int servopin, int myangle) /*定义一个脉冲函数,用来模拟方式产生PWM值*/
{
  pulsewidth = (myangle * 11) + 500; //将角度转化为500-2480 的脉宽值
  digitalWrite(SERVOPIN, HIGH); //将舵机接口电平置高
  delayMicroseconds(pulsewidth);//延时脉宽值的微秒数
  digitalWrite(SERVOPIN, LOW); //将舵机接口电平置低
  delay(20 - pulsewidth / 1000); //延时周期内剩余时间
}

void startRun(int degree) {
  if (degree > 0 && degree <= 180) //判断收到数据值是否符合范围
  {
    //直接获取旋转角度
    Serial.print("moving servo to ");
    Serial.print(degree, DEC);
    Serial.println();
    for (int i = 0; i <= 50; i++) //产生PWM个数,等效延时以保证能转到响应角度
    {
      servopulse(SERVOPIN, degree); //模拟产生PWM
    }
  }
}

总结:基本实现预期效果,但遥控器必须对准接收管才能执行动作,如果非对准,虽然接收到信号,串口打印”Could not decode message“,还未发现原因。


你可能感兴趣的:(arduino,舵机,红外遥控)