sunzewei 发表于 2015-1-17 13:36:52

arduino 红外遥控小车的问题。

本帖最后由 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.directionPin, direction);   
}

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

flywat 发表于 2015-1-17 14:56:32

没试过                           

xia0chun 发表于 2015-1-17 15:09:55

是不是IO口冲突了,你把L298的驱动口换一下试试

sunzewei 发表于 2015-1-17 22:35:20

xia0chun 发表于 2015-1-17 15:09 static/image/common/back.gif
是不是IO口冲突了,你把L298的驱动口换一下试试

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

sunzewei 发表于 2015-1-21 13:39:40

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

kerr 发表于 2015-1-21 17:18:49

学习了!!!!

pumpitup 发表于 2015-2-2 22:42:26

lz是怎么发现是计数器的问题的?

quanpower 发表于 2015-2-12 13:04:01

也碰到了这个问题,谢了:lol

1012958620 发表于 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; // 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 MARK0
#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脚怎么改- -

flyeagle73 发表于 2016-5-9 22:42:50

同样问题 但是这个方法好像没有用

lafeng123 发表于 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试试吧:lol

okwp2005 发表于 2017-9-20 11:41:29

我也遇到相同的问题,看了你的贴子才知道怎么回事,但是我还没有解决问题。我把我的代码发下,看看能不能帮我解决下。
页: [1]
查看完整版本: arduino 红外遥控小车的问题。