极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

楼主: sunzewei

arduino 红外遥控小车的问题。

[复制链接]
发表于 2015-1-17 13:36:52 | 显示全部楼层 |阅读模式
本帖最后由 sunzewei 于 2015-1-17 22:36 编辑

大家好,本人arduino初学者,想利用红外遥控来控制小车,但是第一步就出现问题了。。
我用L298P电机扩展板来驱动小车的四个电机, 已经实现电机的控制。红外部分也已经基本测试完,但是将两部分加在一起时,出现电机只有一边转,另一边不转的情况。
后来反复测试了一下代码,发现是只要在 “void setup() ”里面加入“  irrecv.enableIRIn();  // 启动红外解码”这一句,电机就会出现这种一边转另一边不转的情况,但是这句又是红外遥控必须的。
有没有哪位知道这是怎么回事? 测了一下电压,发现不转的那边线路的电压基本为0,为什么启动红外解码会使一边电机无法供电? 求解救。。
下面是代码。。(就是只有一边转的情况下的, 只要将代码里面的那句 irrecv.enableIRIn(); 删掉,电机就两边都能转。。)

#include <IRremote.h>        // 使用IRRemote函数库
const int irReceiverPin = 2;   
IRrecv irrecv(irReceiverPin);   // 设置irReceiverPin定义的端口为红外信号接收端口
decode_results results;        // 定义results变量为红外结果存放位置

/**set control port**/
const int E1Pin = 10;   
const int M1Pin = 12;
const int E2Pin = 11;                        
const int M2Pin = 13;

/**inner definition**/
typedef struct
{
    byte enPin;
    byte directionPin;
}MotorContrl;

const int M1 = 0;
const int M2 = 1;
const int MotorNum = 2;

const MotorContrl MotorPin[] ={ {E1Pin,M1Pin}, {E2Pin,M2Pin} } ;

const int Forward = LOW;
const int Backward = HIGH;

/**program**/
void setup()
{
   initMotor();
   irrecv.enableIRIn();  // 启动红外解码
}
void loop()
{
   int value;
   setMotorDirection( M2, Forward );
   setMotorSpeed( M2, 50 );  
   setMotorDirection( M1, Forward );
   setMotorSpeed( M1, 50 );

}
/**functions**/
void initMotor( )
{
    int i;
    for ( i = 0; i < MotorNum; i++ )
    {
      digitalWrite(MotorPin.enPin, LOW);   
      
      pinMode(MotorPin.enPin, OUTPUT);   
      pinMode(MotorPin.directionPin, OUTPUT);   
    }
}

/**  motorNumber: M1, M2
        direction:          Forward, Backward **/
void setMotorDirection( int motorNumber, int direction )
{
     digitalWrite( MotorPin[motorNumber].directionPin, direction);   
}

/** speed:  0-100   * */
inline void setMotorSpeed( int motorNumber, int speed )
{     
     analogWrite(MotorPin[motorNumber].enPin, 255.0 * (speed/100.0) );   //PWM
}
回复

使用道具 举报

发表于 2015-1-17 14:56:32 | 显示全部楼层
没试过                           
回复 支持 反对

使用道具 举报

发表于 2015-1-17 15:09:55 | 显示全部楼层
是不是IO口冲突了,你把L298的驱动口换一下试试
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-1-17 22:35:20 | 显示全部楼层
xia0chun 发表于 2015-1-17 15:09
是不是IO口冲突了,你把L298的驱动口换一下试试

那个驱动板跟小车相关的四个串口是10-13,但是我红外部分只需要用到一个接收口,我连在2号口,按理说应该不会有冲突呀?  还是说启动红外解码会占用哪一些IO口?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-1-21 13:39:40 | 显示全部楼层
    经过一些资料的查阅后已经解了这个问题 ,所以贴出来 如果以后有人也遇到这个问题可以参考一下。
    事实结果是计时器的冲突。 红外跟PWM两部分都需要用到计时器。arduino有3个计时器(好像mega1280跟2560不止), timer0对应PIN5和6, timer1对应PIN9和10,timer2对应PIN11和3 。 而红外的库默认使用PIN9,所以跟我电机的10号使用了同一个计时器,冲突了。
    解决的方法是修改红外库文件的默认引脚。找到 “IRremoteInt.h” 进去修改就可以了...
回复 支持 反对

使用道具 举报

发表于 2015-1-21 17:18:49 | 显示全部楼层
学习了!!!!
回复 支持 反对

使用道具 举报

发表于 2015-2-2 22:42:26 | 显示全部楼层
lz是怎么发现是计数器的问题的?
回复 支持 反对

使用道具 举报

发表于 2015-2-12 13:04:01 | 显示全部楼层
也碰到了这个问题,谢了
回复 支持 反对

使用道具 举报

发表于 2015-2-27 20:11:35 | 显示全部楼层
/*
* IRremote
* Version 0.1 July, 2009
* Copyright 2009 Ken Shirriff
* For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
*
* Interrupt code based on NECIRrcv by Joe Knapp
* http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
* Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
*/

#ifndef IRremoteint_h
#define IRremoteint_h

#include <Arduino.h>

#define CLKFUDGE 5      // fudge factor for clock interrupt overhead
#define CLK 256      // max value for clock (timer 2)
#define PRESCALE 8      // timer2 clock prescale
#define SYSCLOCK 16000000  // main Arduino clock
#define CLKSPERUSEC (SYSCLOCK/PRESCALE/1000000)   // timer clocks per microsecond

#define ERR 0
#define DECODED 1

#define BLINKLED 13

// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

// clock timer reset value
#define INIT_TIMER_COUNT2 (CLK - USECPERTICK*CLKSPERUSEC + CLKFUDGE)
#define RESET_TIMER2 TCNT2 = INIT_TIMER_COUNT2

// pulse parameters in usec
#define NEC_HDR_MARK        9000
#define NEC_HDR_SPACE        4500
#define NEC_BIT_MARK        560
#define NEC_ONE_SPACE        1600
#define NEC_ZERO_SPACE        560
#define NEC_RPT_SPACE        2250

#define SONY_HDR_MARK        2400
#define SONY_HDR_SPACE        600
#define SONY_ONE_MARK        1200
#define SONY_ZERO_MARK        600
#define SONY_RPT_LENGTH 45000

#define RC5_T1                889
#define RC5_RPT_LENGTH        46000

#define RC6_HDR_MARK        2666
#define RC6_HDR_SPACE        889
#define RC6_T1                444
#define RC6_RPT_LENGTH        46000

#define TOLERANCE 25  // percent tolerance in measurements
#define LTOL (1.0 - TOLERANCE/100.)
#define UTOL (1.0 + TOLERANCE/100.)

#define _GAP 5000 // Minimum map between transmissions
#define GAP_TICKS (_GAP/USECPERTICK)

#define TICKS_LOW(us) (int) (((us)*LTOL/USECPERTICK))
#define TICKS_HIGH(us) (int) (((us)*UTOL/USECPERTICK + 1))

#ifndef DEBUG
#define MATCH(measured_ticks, desired_us) ((measured_ticks) >= TICKS_LOW(desired_us) && (measured_ticks) <= TICKS_HIGH(desired_us))
#define MATCH_MARK(measured_ticks, desired_us) MATCH(measured_ticks, (desired_us) + MARK_EXCESS)
#define MATCH_SPACE(measured_ticks, desired_us) MATCH((measured_ticks), (desired_us) - MARK_EXCESS)
// Debugging versions are in IRremote.cpp
#endif

// receiver states
#define STATE_IDLE     2
#define STATE_MARK     3
#define STATE_SPACE    4
#define STATE_STOP     5

// information for the interrupt handler
typedef struct {
  uint8_t recvpin;           // pin for IR data from detector
  uint8_t rcvstate;          // state machine
  uint8_t blinkflag;         // TRUE to enable blinking of pin 13 on IR processing
  unsigned int timer;     // state timer, counts 50uS ticks.
  unsigned int rawbuf[RAWBUF]; // raw data
  uint8_t rawlen;         // counter of entries in rawbuf
}
irparams_t;

// Defined in IRremote.cpp
extern volatile irparams_t irparams;

// IR detector output is active low
#define MARK  0
#define SPACE 1

#define TOPBIT 0x80000000

#define NEC_BITS 32
#define SONY_BITS 12
#define MIN_RC5_SAMPLES 11
#define MIN_RC6_SAMPLES 1

#endif



默认pin脚怎么改- -
回复 支持 反对

使用道具 举报

发表于 2016-5-9 22:42:50 | 显示全部楼层
同样问题 但是这个方法好像没有用
回复 支持 反对

使用道具 举报

发表于 2016-12-17 10:33:15 | 显示全部楼层
其实这个问题不止是修改IRremote解决,AFMotor.cpp中定义了4个pwm脚,分别是M1 M2 M3 M4 四个电机,一种解决方法是:把M1的pwm定义改为pin 9,也就是把11去掉。然后在IRremoteint.h中找到TMIER定义,可以看到UNO是可以使用TIMER1和TIMER2的,我们利用TIMER2,把针脚改为数字3#。这两个头文件同时修改后,问题解决了  保存头文件修改,重启ide试试吧
回复 支持 反对

使用道具 举报

发表于 2017-9-20 11:41:29 | 显示全部楼层
我也遇到相同的问题,看了你的贴子才知道怎么回事,但是我还没有解决问题。我把我的代码发下,看看能不能帮我解决下。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-3-29 22:56 , Processed in 0.055049 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表