Как определить 2 или более одновременных ИК входа?

Я пытаюсь создать систему ответов учеников для игры, подобной 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
}
}

0

Решение

Короче говоря — не совсем и не надежно. Проблема заключается в том, что ваша система эффективно поддерживает несколько каналов. Приемник видит сумму обоих передатчиков. Где модуляция и кодированный сигнал суммируются и, таким образом, искажаются.

У меня есть ИК игрушечные волшебные палочки, для дуэли у меня есть победитель, продолжающий передавать относительно JAM более слабый последний сигнал.

Вы можете попробовать использовать две разные частоты модуляции. Один пульт на 36К, а другой на 60К. 38K является типичным и имеет значительное совпадение. Я видел, как 36 и 40 услышали или испортили 38K. Так что я бы добрался до самых дальних концов доступных чипов демодулятора; быть 36K и 60K. Тем не менее, я подозреваю, что вы используете предоставленные передатчики, которые не могут быть изменены. Таким образом, вам придется найти или построить один.

Кроме того, используя готовые, вы зависите от его поведения. Вы заявили 1/2 секунды. Это вероятно, потому что они повторно передают повторные попытки и имеют задержки запуска и паузы, превышающие время отправки кадра NEC.

Вы также можете реализовать пары RX / TX с различной длиной волны ИК. Тем не менее, большинство приобретаемых ИС демодулятора находятся на стандартной длине волны. Я также рекомендую не создавать дискретный RX, когда это возможно, поскольку в них интегрированы RX / демодуляторы с функцией Auto GAIN, и тому подобное.

0

Другие решения


По вопросам рекламы [email protected]