【问题标题】:How do I discern 2 or more simultaneous IR inputs?如何辨别 2 个或更多同时的 IR 输入?
【发布时间】:2018-04-26 06:00:11
【问题描述】:

我正在尝试使用廉价的电视遥控器为类似 Jeopardy 的游戏创建学生响应系统。它们是红外线,NEC 协议。串行监视器显示学生按下的按钮,以便他们响应。

我正在使用一个 TSOP 4838 接收器,它通过一个电容器连接到一个 Arduino Uno,到目前为止只是 Arduino IDE 软件附带的串行监视器。我的代码如下所示。

只要 2 名或更多学生在彼此半秒内没有按下按钮,一切正常。如果发生这种情况,我在串行监视器上没有输出。我希望我可以对我的草图或 IRremote.h 或 IRremoteInt.h 文件进行一些更改,以更快地识别信号,以便我的显示列表首先单击。 IRremote.h:

 */
 * IRremote v1.1
 * By Chris Targett
 * November 2011
 *
 * Based on Ken Shirriff's Version 0.11 of his IR-Remote library August, 2009
 * https://github.com/shirriff/Arduino-IRremote
 */

#ifndef IRremote_h
#define IRremote_h

// The following are compile-time library options.
// If you change them, recompile the library.
// If DEBUG is defined, a lot of debugging output will be printed during decoding.
// TEST must be defined for the IRtest unittests to work.  It will make some
// methods virtual, which will be slightly slower, which is why it is optional.
// #define DEBUG
// #define TEST

// Results returned from the decoder
class decode_results {
public:
  int decode_type; // NEC, SONY, RC5, RC6, DISH, SHARP, SAMSUNG, JVC, UNKNOWN
  unsigned long value; // Decoded value
  unsigned long address; // address for panasonic codes
  int bits; // Number of bits in decoded value
  volatile unsigned int *rawbuf; // Raw intervals in .5 us ticks
  int rawlen; // Number of records in rawbuf.
};

// Values for decode_type
#define NEC 1
#define SONY 2
#define RC5 3
#define RC6 4
#define DISH 5
#define SHARP 6
#define SAMSUNG 7
#define JVC 8
#define PANASONIC 9
#define UNKNOWN -1

// Decoded value for NEC when a repeat code is received
#define REPEAT 0xffffffff 

// main class for receiving IR
class IRrecv
{
public:
  IRrecv(int recvpin);
  void blink13(int blinkflag);
  int decode(decode_results *results);
  void enableIRIn();
  void resume();
private:
  // These are called by decode
  int getRClevel(decode_results *results, int *offset, int *used, int t1);
  long decodeNEC(decode_results *results);
  long decodeSony(decode_results *results);
  long decodeSamsung(decode_results *results);
  long decodeRC5(decode_results *results);
  long decodeRC6(decode_results *results);
  long decodeJVC(decode_results *results);
  long decodeHash(decode_results *results);
  long decodePanasonic(decode_results *results);
  int compare(unsigned int oldval, unsigned int newval);
} 
;

// Only used for testing; can remove virtual for shorter code
#ifdef TEST
#define VIRTUAL virtual
#else
#define VIRTUAL
#endif

class IRsend
{
public:
  IRsend() {}
  void sendNEC(unsigned long data, int nbits);
  void sendSony(unsigned long data, int nbits);
  void sendSamsung(unsigned long data, int nbits);
  void sendRaw(unsigned int buf[], int len, int hz);
  void sendRC5(unsigned long data, int nbits);
  void sendRC6(unsigned long long data, int nbits);
  void sendDISH(unsigned long data, int nbits);
  void sendSharp(unsigned long data, int nbits);
  void sendJVC(unsigned long data, int nbits, int repeat);
  void sendPanasonic(unsigned long address, unsigned long data);
  // private:
  void enableIROut(int khz);
  VIRTUAL void mark(int usec);
  VIRTUAL void space(int usec);
}
;

// Some useful constants

#define USECPERTICK 50  
#define RAWBUF 76 

// Marks tend to be 100us too long, and spaces 100us too short
// when received due to sensor lag.
#define MARK_EXCESS 100  

#endif

这里是 IRremoteInt.h

/*
 * IRremote v1.1
 * By Chris Targett
 * November 2011
 *
 * Based on Ken Shirriff's Version 0.11 of his IR-Remote library August, 2009
 * https://github.com/shirriff/Arduino-IRremote
 */

#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 SAMSUNG_HDR_MARK 4500
#define SAMSUNG_BITS 32
#define SAMSUNG_HDR_SPACE 4500
#define SAMSUNG_BIT_MARK 560
#define SAMSUNG_ONE_SPACE 1600
#define SAMSUNG_ZERO_SPACE 600

#define SHARP_BIT_MARK 245
#define SHARP_ONE_SPACE 1805
#define SHARP_ZERO_SPACE 795
#define SHARP_GAP 600000
#define SHARP_TOGGLE_MASK 0x3FF
#define SHARP_RPT_SPACE 3000

#define DISH_HDR_MARK 400
#define DISH_HDR_SPACE 6100
#define DISH_BIT_MARK 400
#define DISH_ONE_SPACE 1700
#define DISH_ZERO_SPACE 2800
#define DISH_RPT_SPACE 6200
#define DISH_TOP_BIT 0x8000

#define SHARP_BITS 15
#define DISH_BITS 16

#define JVC_HDR_MARK 8000
#define JVC_HDR_SPACE 4000
#define JVC_BIT_MARK 600
#define JVC_ONE_SPACE 1600
#define JVC_ZERO_SPACE 550
#define JVC_RPT_LENGTH 60000

#define PANASONIC_HDR_MARK 3502
#define PANASONIC_HDR_SPACE 1750
#define PANASONIC_BIT_MARK 502
#define PANASONIC_ONE_SPACE 1244
#define PANASONIC_ZERO_SPACE 370

#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 JVC_BITS 32
#define MIN_RC5_SAMPLES 11
#define MIN_RC6_SAMPLES 1

#endif

这是我的草图:

#include <IRremote.h>
#include <IRremoteInt.h>
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}

void loop()
{
  if (irrecv.decode(&results))
    {
            if (results.value == 551520375) {  //1
      Serial.println("Team 1");
      }
            if (results.value == 551504055) {  //2
      Serial.println("Team 2");
      }
      if (results.value == 551536695) {  //3
      Serial.println("Team 3");
      }
      if (results.value == 551495895) {  //4
      Serial.println("Team 4");
      }
            if (results.value == 551528535) {  //5
      Serial.println("Team 5");
      }
            if (results.value == 551512215) {  //6
      Serial.println("Team 6");
      }
            if (results.value == 551544855) {  //7
      Serial.println("Team 7");
      }
            if (results.value == 551491815) {  //8
      Serial.println("Team 8");
      }
            if (results.value == 551524455) {  //9
      Serial.println("Team 9");
      }
            if (results.value == 551487735) {  //10
      Serial.println("Team 10");
      }
//     Serial.println(results.value);

     irrecv.resume(); // Receive the next value
    }
}

【问题讨论】:

    标签: c++ arduino infrared


    【解决方案1】:

    简而言之 - 不真实也不可靠。问题是您的系统实际上是多点的。接收器是看到两个发射器的总和。调制和编码信号相加并因此损坏的地方。

    我有 IR 玩具魔术棒,在决斗中,我有一个获胜者不断向 JAM 传输较松的后一个信号。

    您可以尝试使用两种不同的调制频率。一个遥控器为 36K,另一个为 60K。 38K 是典型的,并且有很大的重叠。我已经看到 36 和 40 被听到或损坏了 38K。所以我会到达可用解调器芯片的最远端;分别是 36K 和 60K。但是,我怀疑您使用的是提供的可能无法更改的发射器。所以你必须找到一些或建造一个。

    另外使用预建的,你会受到它的行为的支配。你说的是 1/2 秒。这可能是因为它们正在重新传输重试,并且启动延迟和暂停超出了正在发送的 NEC 帧的延迟。

    您还可以实现不同 IR 波长的 RX/TX 对。然而,大多数可购买的解调器 IC 都在标准波长上。我还建议尽可能不要构建离散 RX,因为它们集成的 RX/解调器具有 Auto GAIN 之类的功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-11
      • 1970-01-01
      • 1970-01-01
      • 2019-07-02
      • 2022-01-10
      • 2011-03-29
      • 1970-01-01
      相关资源
      最近更新 更多