mirror of
https://github.com/Theaninova/Arduino-IRremote.git
synced 2026-01-17 23:02:48 +00:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2dbfee0c2e | ||
|
|
49855488d5 | ||
|
|
e04e7d31b7 | ||
|
|
0096727887 | ||
|
|
74622ec776 | ||
|
|
9a5d40a74c | ||
|
|
1cf65bbcde | ||
|
|
2926b33526 | ||
|
|
ccc7ad9627 | ||
|
|
50530b6519 | ||
|
|
095d8241f1 | ||
|
|
93c6e4af55 | ||
|
|
3722d6a0cb | ||
|
|
14f4c7af77 | ||
|
|
3dd4ff6f5f | ||
|
|
32e3bf780f | ||
|
|
806d3246f9 | ||
|
|
f0670efe86 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
*.un~
|
|
||||||
@@ -10,8 +10,6 @@ These are the active contributors of this project that you may contact if there
|
|||||||
- [PaulStoffregen](https://github.com/paulstroffregen) : Active contributor
|
- [PaulStoffregen](https://github.com/paulstroffregen) : Active contributor
|
||||||
- [crash7](https://github.com/crash7) : Active contributor
|
- [crash7](https://github.com/crash7) : Active contributor
|
||||||
- [Neco777](https://github.com/neco777) : Active contributor
|
- [Neco777](https://github.com/neco777) : Active contributor
|
||||||
- [Lauszus](https://github.com/lauszus) : Active contributor
|
|
||||||
- [csBlueChip](https://github.com/csbluechip) : Active contributor
|
|
||||||
|
|
||||||
Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed.
|
Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed.
|
||||||
|
|
||||||
|
|||||||
1434
IRremote.cpp
1434
IRremote.cpp
File diff suppressed because it is too large
Load Diff
429
IRremote.h
429
IRremote.h
@@ -1,329 +1,144 @@
|
|||||||
|
/*
|
||||||
//******************************************************************************
|
* IRremote
|
||||||
// IRremote
|
* Version 0.1 July, 2009
|
||||||
// Version 0.1 July, 2009
|
* Copyright 2009 Ken Shirriff
|
||||||
// Copyright 2009 Ken Shirriff
|
* For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.htm http://arcfn.com
|
||||||
// For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
|
* Edited by Mitra to add new controller SANYO
|
||||||
// Edited by Mitra to add new controller SANYO
|
*
|
||||||
//
|
* Interrupt code based on NECIRrcv by Joe Knapp
|
||||||
// Interrupt code based on NECIRrcv by Joe Knapp
|
* http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
|
||||||
// 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/
|
||||||
// Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
|
*
|
||||||
//
|
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
|
||||||
// JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
|
* LG added by Darryl Smith (based on the JVC protocol)
|
||||||
// LG added by Darryl Smith (based on the JVC protocol)
|
* Whynter A/C ARC-110WD added by Francesco Meschia
|
||||||
// Whynter A/C ARC-110WD added by Francesco Meschia
|
*/
|
||||||
//******************************************************************************
|
|
||||||
|
|
||||||
#ifndef IRremote_h
|
#ifndef IRremote_h
|
||||||
#define IRremote_h
|
#define IRremote_h
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
#if defined(ARDUINO) && ARDUINO >= 100
|
||||||
// The ISR header contains several useful macros the user may wish to use
|
#include <Arduino.h>
|
||||||
//
|
|
||||||
#include "IRremoteInt.h"
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Supported IR protocols
|
|
||||||
// Each protocol you include costs memory and, during decode, costs time
|
|
||||||
// Disable (set to 0) all the protocols you do not need/want!
|
|
||||||
//
|
|
||||||
#define DECODE_RC5 1
|
|
||||||
#define SEND_RC5 1
|
|
||||||
|
|
||||||
#define DECODE_RC6 1
|
|
||||||
#define SEND_RC6 1
|
|
||||||
|
|
||||||
#define DECODE_NEC 1
|
|
||||||
#define SEND_NEC 1
|
|
||||||
|
|
||||||
#define DECODE_SONY 1
|
|
||||||
#define SEND_SONY 1
|
|
||||||
|
|
||||||
#define DECODE_PANASONIC 1
|
|
||||||
#define SEND_PANASONIC 1
|
|
||||||
|
|
||||||
#define DECODE_JVC 1
|
|
||||||
#define SEND_JVC 1
|
|
||||||
|
|
||||||
#define DECODE_SAMSUNG 1
|
|
||||||
#define SEND_SAMSUNG 1
|
|
||||||
|
|
||||||
#define DECODE_WHYNTER 1
|
|
||||||
#define SEND_WHYNTER 1
|
|
||||||
|
|
||||||
#define DECODE_AIWA_RC_T501 1
|
|
||||||
#define SEND_AIWA_RC_T501 1
|
|
||||||
|
|
||||||
#define DECODE_LG 1
|
|
||||||
#define SEND_LG 0 // NOT WRITTEN
|
|
||||||
|
|
||||||
#define DECODE_SANYO 1
|
|
||||||
#define SEND_SANYO 0 // NOT WRITTEN
|
|
||||||
|
|
||||||
#define DECODE_MITSUBISHI 1
|
|
||||||
#define SEND_MITSUBISHI 0 // NOT WRITTEN
|
|
||||||
|
|
||||||
#define DECODE_DISH 0 // NOT WRITTEN
|
|
||||||
#define SEND_DISH 1
|
|
||||||
|
|
||||||
#define DECODE_SHARP 0 // NOT WRITTEN
|
|
||||||
#define SEND_SHARP 1
|
|
||||||
|
|
||||||
#define DECODE_DENON 1
|
|
||||||
#define SEND_DENON 1
|
|
||||||
|
|
||||||
#define DECODE_PRONTO 0 // This function doe not logically make sense
|
|
||||||
#define SEND_PRONTO 1
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// When sending a Pronto code we request to send either the "once" code
|
|
||||||
// or the "repeat" code
|
|
||||||
// If the code requested does not exist we can request to fallback on the
|
|
||||||
// other code (the one we did not explicitly request)
|
|
||||||
//
|
|
||||||
// I would suggest that "fallback" will be the standard calling method
|
|
||||||
// The last paragraph on this page discusses the rationale of this idea:
|
|
||||||
// http://www.remotecentral.com/features/irdisp2.htm
|
|
||||||
//
|
|
||||||
#define PRONTO_ONCE false
|
|
||||||
#define PRONTO_REPEAT true
|
|
||||||
#define PRONTO_FALLBACK true
|
|
||||||
#define PRONTO_NOFALLBACK false
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// An enumerated list of all supported formats
|
|
||||||
// You do NOT need to remove entries from this list when disabling protocols!
|
|
||||||
//
|
|
||||||
typedef
|
|
||||||
enum {
|
|
||||||
UNKNOWN = -1,
|
|
||||||
UNUSED = 0,
|
|
||||||
RC5,
|
|
||||||
RC6,
|
|
||||||
NEC,
|
|
||||||
SONY,
|
|
||||||
PANASONIC,
|
|
||||||
JVC,
|
|
||||||
SAMSUNG,
|
|
||||||
WHYNTER,
|
|
||||||
AIWA_RC_T501,
|
|
||||||
LG,
|
|
||||||
SANYO,
|
|
||||||
MITSUBISHI,
|
|
||||||
DISH,
|
|
||||||
SHARP,
|
|
||||||
DENON,
|
|
||||||
PRONTO,
|
|
||||||
}
|
|
||||||
decode_type_t;
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Set DEBUG to 1 for lots of lovely debug output
|
|
||||||
//
|
|
||||||
#define DEBUG 0
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Debug directives
|
|
||||||
//
|
|
||||||
#if DEBUG
|
|
||||||
# define DBG_PRINT(...) Serial.print(__VA_ARGS__)
|
|
||||||
# define DBG_PRINTLN(...) Serial.println(__VA_ARGS__)
|
|
||||||
#else
|
#else
|
||||||
# define DBG_PRINT(...)
|
#include <WProgram.h>
|
||||||
# define DBG_PRINTLN(...)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Mark & Space matching functions
|
|
||||||
//
|
|
||||||
int MATCH (int measured, int desired) ;
|
|
||||||
int MATCH_MARK (int measured_ticks, int desired_us) ;
|
|
||||||
int MATCH_SPACE (int measured_ticks, int desired_us) ;
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
// 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
|
// Results returned from the decoder
|
||||||
//
|
class decode_results {
|
||||||
class decode_results
|
public:
|
||||||
{
|
int8_t decode_type; // NEC, SONY, RC5, UNKNOWN
|
||||||
public:
|
int8_t bits; // Number of bits in decoded value
|
||||||
decode_type_t decode_type; // UNKNOWN, NEC, SONY, RC5, ...
|
unsigned long value; // Decoded value
|
||||||
unsigned int address; // Used by Panasonic & Sharp [16-bits]
|
|
||||||
unsigned long value; // Decoded value [max 32-bits]
|
union { // This is used for decoding Panasonic and Sharp data
|
||||||
int bits; // Number of bits in decoded value
|
unsigned int panasonicAddress;
|
||||||
volatile unsigned int *rawbuf; // Raw intervals in 50uS ticks
|
unsigned int sharpAddress;
|
||||||
int rawlen; // Number of records in rawbuf
|
};
|
||||||
int overflow; // true iff IR raw code too long
|
|
||||||
|
volatile unsigned int *rawbuf; // Raw intervals in .5 us ticks
|
||||||
|
int rawlen; // Number of records in rawbuf.
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
// Values for decode_type
|
||||||
// Decoded value for NEC when a repeat code is received
|
#define NEC 1
|
||||||
//
|
#define SONY 2
|
||||||
#define REPEAT 0xFFFFFFFF
|
#define RC5 3
|
||||||
|
#define RC6 4
|
||||||
|
#define DISH 5
|
||||||
|
#define SHARP 6
|
||||||
|
#define PANASONIC 7
|
||||||
|
#define JVC 8
|
||||||
|
#define SANYO 9
|
||||||
|
#define MITSUBISHI 10
|
||||||
|
#define SAMSUNG 11
|
||||||
|
#define LG 12
|
||||||
|
#define WHYNTER 13
|
||||||
|
#define Sharp 14
|
||||||
|
#define AIWA_RC_T501 15
|
||||||
|
#define UNKNOWN -1
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
// Decoded value for NEC when a repeat code is received
|
||||||
// Main class for receiving IR
|
#define REPEAT 0xffffffff
|
||||||
//
|
|
||||||
|
// main class for receiving IR
|
||||||
class IRrecv
|
class IRrecv
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IRrecv (int recvpin) ;
|
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 decodeSharp(decode_results *results);
|
||||||
|
long decodeSanyo(decode_results *results);
|
||||||
|
long decodeMitsubishi(decode_results *results);
|
||||||
|
long decodeRC5(decode_results *results);
|
||||||
|
long decodeRC6(decode_results *results);
|
||||||
|
long decodePanasonic(decode_results *results);
|
||||||
|
long decodeLG(decode_results *results);
|
||||||
|
long decodeJVC(decode_results *results);
|
||||||
|
long decodeSAMSUNG(decode_results *results);
|
||||||
|
long decodeWhynter(decode_results *results);
|
||||||
|
long decodeAiwaRCT501(decode_results *results);
|
||||||
|
long decodeHash(decode_results *results);
|
||||||
|
int compare(unsigned int oldval, unsigned int newval);
|
||||||
|
|
||||||
void blink13 (int blinkflag) ;
|
|
||||||
int decode (decode_results *results) ;
|
|
||||||
void enableIRIn ( ) ;
|
|
||||||
void resume ( ) ;
|
|
||||||
|
|
||||||
private:
|
|
||||||
long decodeHash (decode_results *results) ;
|
|
||||||
int compare (unsigned int oldval, unsigned int newval) ;
|
|
||||||
|
|
||||||
//......................................................................
|
|
||||||
# if (DECODE_RC5 || DECODE_RC6)
|
|
||||||
// This helper function is shared by RC5 and RC6
|
|
||||||
int getRClevel (decode_results *results, int *offset, int *used, int t1) ;
|
|
||||||
# endif
|
|
||||||
# if DECODE_RC5
|
|
||||||
bool decodeRC5 (decode_results *results) ;
|
|
||||||
# endif
|
|
||||||
# if DECODE_RC6
|
|
||||||
bool decodeRC6 (decode_results *results) ;
|
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if DECODE_NEC
|
|
||||||
bool decodeNEC (decode_results *results) ;
|
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if DECODE_SONY
|
|
||||||
bool decodeSony (decode_results *results) ;
|
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if DECODE_PANASONIC
|
|
||||||
bool decodePanasonic (decode_results *results) ;
|
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if DECODE_JVC
|
|
||||||
bool decodeJVC (decode_results *results) ;
|
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if DECODE_SAMSUNG
|
|
||||||
bool decodeSAMSUNG (decode_results *results) ;
|
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if DECODE_WHYNTER
|
|
||||||
bool decodeWhynter (decode_results *results) ;
|
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if DECODE_AIWA_RC_T501
|
|
||||||
bool decodeAiwaRCT501 (decode_results *results) ;
|
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if DECODE_LG
|
|
||||||
bool decodeLG (decode_results *results) ;
|
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if DECODE_SANYO
|
|
||||||
bool decodeSanyo (decode_results *results) ;
|
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if DECODE_MITSUBISHI
|
|
||||||
bool decodeMitsubishi (decode_results *results) ;
|
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if DECODE_DISH
|
|
||||||
bool decodeDish (decode_results *results) ; // NOT WRITTEN
|
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if DECODE_SHARP
|
|
||||||
bool decodeSharp (decode_results *results) ; // NOT WRITTEN
|
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if DECODE_DENON
|
|
||||||
bool decodeDenon (decode_results *results) ;
|
|
||||||
# endif
|
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
// Only used for testing; can remove virtual for shorter code
|
||||||
// Main class for sending IR
|
#ifdef TEST
|
||||||
//
|
#define VIRTUAL virtual
|
||||||
|
#else
|
||||||
|
#define VIRTUAL
|
||||||
|
#endif
|
||||||
|
|
||||||
class IRsend
|
class IRsend
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IRsend () { }
|
IRsend() {}
|
||||||
|
void sendWhynter(unsigned long data, int nbits);
|
||||||
void enableIROut (int khz) ;
|
void sendNEC(unsigned long data, int nbits);
|
||||||
void mark (int usec) ;
|
void sendSony(unsigned long data, int nbits);
|
||||||
void space (int usec) ;
|
// Neither Sanyo nor Mitsubishi send is implemented yet
|
||||||
void sendRaw (unsigned int buf[], int len, int hz) ;
|
// void sendSanyo(unsigned long data, int nbits);
|
||||||
|
// void sendMitsubishi(unsigned long data, int nbits);
|
||||||
//......................................................................
|
void sendRaw(unsigned int buf[], int len, int hz);
|
||||||
# if SEND_RC5
|
void sendRC5(unsigned long data, int nbits);
|
||||||
void sendRC5 (unsigned long data, int nbits) ;
|
void sendRC6(unsigned long data, int nbits);
|
||||||
# endif
|
void sendDISH(unsigned long data, int nbits);
|
||||||
# if SEND_RC6
|
void sendSharp(unsigned int address, unsigned int command);
|
||||||
void sendRC6 (unsigned long data, int nbits) ;
|
void sendSharpRaw(unsigned long data, int nbits);
|
||||||
# endif
|
void sendPanasonic(unsigned int address, unsigned long data);
|
||||||
//......................................................................
|
void sendJVC(unsigned long data, int nbits, int repeat); // *Note instead of sending the REPEAT constant if you want the JVC repeat signal sent, send the original code value and change the repeat argument from 0 to 1. JVC protocol repeats by skipping the header NOT by sending a separate code value like NEC does.
|
||||||
# if SEND_NEC
|
void sendAiwaRCT501(int code);
|
||||||
void sendNEC (unsigned long data, int nbits) ;
|
// private:
|
||||||
# endif
|
void sendSAMSUNG(unsigned long data, int nbits);
|
||||||
//......................................................................
|
void enableIROut(int khz);
|
||||||
# if SEND_SONY
|
VIRTUAL void mark(int usec);
|
||||||
void sendSony (unsigned long data, int nbits) ;
|
VIRTUAL void space(int usec);
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if SEND_PANASONIC
|
|
||||||
void sendPanasonic (unsigned int address, unsigned long data) ;
|
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if SEND_JVC
|
|
||||||
// JVC does NOT repeat by sending a separate code (like NEC does).
|
|
||||||
// The JVC protocol repeats by skipping the header.
|
|
||||||
// To send a JVC repeat signal, send the original code value
|
|
||||||
// and set 'repeat' to true
|
|
||||||
void sendJVC (unsigned long data, int nbits, bool repeat) ;
|
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if SEND_SAMSUNG
|
|
||||||
void sendSAMSUNG (unsigned long data, int nbits) ;
|
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if SEND_WHYNTER
|
|
||||||
void sendWhynter (unsigned long data, int nbits) ;
|
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if SEND_AIWA_RC_T501
|
|
||||||
void sendAiwaRCT501 (int code) ;
|
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if SEND_LG
|
|
||||||
void sendLG ( ) ; // NOT WRITTEN
|
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if SEND_SANYO
|
|
||||||
void sendSanyo ( ) ; // NOT WRITTEN
|
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if SEND_MISUBISHI
|
|
||||||
void sendMitsubishi ( ) ; // NOT WRITTEN
|
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if SEND_DISH
|
|
||||||
void sendDISH (unsigned long data, int nbits) ;
|
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if SEND_SHARP
|
|
||||||
void sendSharpRaw (unsigned long data, int nbits) ;
|
|
||||||
void sendSharp (unsigned int address, unsigned int command) ;
|
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if SEND_DENON
|
|
||||||
void sendDenon (unsigned long data, int nbits) ;
|
|
||||||
# endif
|
|
||||||
//......................................................................
|
|
||||||
# if SEND_Pronto
|
|
||||||
void sendPronto (char* code, bool repeat, bool fallback) ;
|
|
||||||
# endif
|
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
// Some useful constants
|
||||||
|
|
||||||
|
#define USECPERTICK 50 // microseconds per clock interrupt tick
|
||||||
|
#define RAWBUF 100 // Length of raw duration buffer
|
||||||
|
|
||||||
|
// Marks tend to be 100us too long, and spaces 100us too short
|
||||||
|
// when received due to sensor lag.
|
||||||
|
#define MARK_EXCESS 100
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
841
IRremoteInt.h
841
IRremoteInt.h
@@ -1,315 +1,347 @@
|
|||||||
//******************************************************************************
|
/*
|
||||||
// IRremote
|
* IRremote
|
||||||
// Version 0.1 July, 2009
|
* Version 0.1 July, 2009
|
||||||
// Copyright 2009 Ken Shirriff
|
* Copyright 2009 Ken Shirriff
|
||||||
// For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
|
* For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
|
||||||
//
|
*
|
||||||
// Modified by Paul Stoffregen <paul@pjrc.com> to support other boards and timers
|
* Modified by Paul Stoffregen <paul@pjrc.com> to support other boards and timers
|
||||||
//
|
*
|
||||||
// Interrupt code based on NECIRrcv by Joe Knapp
|
* Interrupt code based on NECIRrcv by Joe Knapp
|
||||||
// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
|
* 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/
|
* Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
|
||||||
//
|
*
|
||||||
// JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
|
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
|
||||||
// Whynter A/C ARC-110WD added by Francesco Meschia
|
* Whynter A/C ARC-110WD added by Francesco Meschia
|
||||||
//******************************************************************************
|
*/
|
||||||
|
|
||||||
#ifndef IRremoteint_h
|
#ifndef IRremoteint_h
|
||||||
#define IRremoteint_h
|
#define IRremoteint_h
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
#if defined(ARDUINO) && ARDUINO >= 100
|
||||||
// Include the right Arduino header
|
#include <Arduino.h>
|
||||||
//
|
|
||||||
#if defined(ARDUINO) && (ARDUINO >= 100)
|
|
||||||
# include <Arduino.h>
|
|
||||||
#else
|
#else
|
||||||
# if !defined(IRPRONTO)
|
#include <WProgram.h>
|
||||||
# include <WProgram.h>
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
// define which timer to use
|
||||||
// This handles definition and access to global variables
|
|
||||||
//
|
|
||||||
#ifdef IR_GLOBAL
|
|
||||||
# define EXTERN
|
|
||||||
#else
|
|
||||||
# define EXTERN extern
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Information for the Interrupt Service Routine
|
|
||||||
//
|
|
||||||
#define RAWBUF 101 // Maximum length of raw duration buffer
|
|
||||||
|
|
||||||
typedef
|
|
||||||
struct {
|
|
||||||
// The fields are ordered to reduce memory over caused by struct-padding
|
|
||||||
uint8_t rcvstate; // State Machine state
|
|
||||||
uint8_t recvpin; // Pin connected to IR data from detector
|
|
||||||
uint8_t blinkflag; // true -> enable blinking of pin 13 on IR processing
|
|
||||||
uint8_t rawlen; // counter of entries in rawbuf
|
|
||||||
unsigned int timer; // State timer, counts 50uS ticks.
|
|
||||||
unsigned int rawbuf[RAWBUF]; // raw data
|
|
||||||
uint8_t overflow; // Raw buffer overflow occurred
|
|
||||||
}
|
|
||||||
irparams_t;
|
|
||||||
|
|
||||||
// ISR State-Machine : Receiver States
|
|
||||||
#define STATE_IDLE 2
|
|
||||||
#define STATE_MARK 3
|
|
||||||
#define STATE_SPACE 4
|
|
||||||
#define STATE_STOP 5
|
|
||||||
#define STATE_OVERFLOW 6
|
|
||||||
|
|
||||||
// Allow all parts of the code access to the ISR data
|
|
||||||
// NB. The data can be changed by the ISR at any time, even mid-function
|
|
||||||
// Therefore we declare it as "volatile" to stop the compiler/CPU caching it
|
|
||||||
EXTERN volatile irparams_t irparams;
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Defines for blinking the LED
|
|
||||||
//
|
|
||||||
#if defined(CORE_LED0_PIN)
|
|
||||||
# define BLINKLED CORE_LED0_PIN
|
|
||||||
# define BLINKLED_ON() (digitalWrite(CORE_LED0_PIN, HIGH))
|
|
||||||
# define BLINKLED_OFF() (digitalWrite(CORE_LED0_PIN, LOW))
|
|
||||||
|
|
||||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
|
||||||
# define BLINKLED 13
|
|
||||||
# define BLINKLED_ON() (PORTB |= B10000000)
|
|
||||||
# define BLINKLED_OFF() (PORTB &= B01111111)
|
|
||||||
|
|
||||||
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
|
||||||
# define BLINKLED 0
|
|
||||||
# define BLINKLED_ON() (PORTD |= B00000001)
|
|
||||||
# define BLINKLED_OFF() (PORTD &= B11111110)
|
|
||||||
|
|
||||||
#else
|
|
||||||
# define BLINKLED 13
|
|
||||||
#define BLINKLED_ON() (PORTB |= B00100000)
|
|
||||||
# define BLINKLED_OFF() (PORTB &= B11011111)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// CPU Frequency
|
|
||||||
//
|
|
||||||
#ifdef F_CPU
|
|
||||||
# define SYSCLOCK F_CPU // main Arduino clock
|
|
||||||
#else
|
|
||||||
# define SYSCLOCK 16000000 // main Arduino clock
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// 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
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Pulse parms are ((X*50)-100) for the Mark and ((X*50)+100) for the Space.
|
|
||||||
// First MARK is the one after the long gap
|
|
||||||
// Pulse parameters in uSec
|
|
||||||
//
|
|
||||||
|
|
||||||
// Due to sensor lag, when received, Marks tend to be 100us too long and
|
|
||||||
// Spaces tend to be 100us too short
|
|
||||||
#define MARK_EXCESS 100
|
|
||||||
|
|
||||||
// microseconds per clock interrupt tick
|
|
||||||
#define USECPERTICK 50
|
|
||||||
|
|
||||||
// Upper and Lower percentage tolerances in measurements
|
|
||||||
#define TOLERANCE 25
|
|
||||||
#define LTOL (1.0 - (TOLERANCE/100.))
|
|
||||||
#define UTOL (1.0 + (TOLERANCE/100.))
|
|
||||||
|
|
||||||
// Minimum gap between IR transmissions
|
|
||||||
#define _GAP 5000
|
|
||||||
#define GAP_TICKS (_GAP/USECPERTICK)
|
|
||||||
|
|
||||||
#define TICKS_LOW(us) ((int)(((us)*LTOL/USECPERTICK)))
|
|
||||||
#define TICKS_HIGH(us) ((int)(((us)*UTOL/USECPERTICK + 1)))
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// IR detector output is active low
|
|
||||||
//
|
|
||||||
#define MARK 0
|
|
||||||
#define SPACE 1
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Define which timer to use
|
|
||||||
//
|
|
||||||
// Uncomment the timer you wish to use on your board.
|
|
||||||
// If you are using another library which uses timer2, you have options to
|
|
||||||
// switch IRremote to use a different timer.
|
|
||||||
//
|
//
|
||||||
|
// Uncomment the timer you wish to use on your board. If you
|
||||||
|
// are using another library which uses timer2, you have options
|
||||||
|
// to switch IRremote to use a different timer.
|
||||||
|
|
||||||
// Arduino Mega
|
// Arduino Mega
|
||||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||||
//#define IR_USE_TIMER1 // tx = pin 11
|
//#define IR_USE_TIMER1 // tx = pin 11
|
||||||
#define IR_USE_TIMER2 // tx = pin 9
|
#define IR_USE_TIMER2 // tx = pin 9
|
||||||
//#define IR_USE_TIMER3 // tx = pin 5
|
//#define IR_USE_TIMER3 // tx = pin 5
|
||||||
//#define IR_USE_TIMER4 // tx = pin 6
|
//#define IR_USE_TIMER4 // tx = pin 6
|
||||||
//#define IR_USE_TIMER5 // tx = pin 46
|
//#define IR_USE_TIMER5 // tx = pin 46
|
||||||
|
|
||||||
// Teensy 1.0
|
// Teensy 1.0
|
||||||
#elif defined(__AVR_AT90USB162__)
|
#elif defined(__AVR_AT90USB162__)
|
||||||
#define IR_USE_TIMER1 // tx = pin 17
|
#define IR_USE_TIMER1 // tx = pin 17
|
||||||
|
|
||||||
// Teensy 2.0
|
// Teensy 2.0
|
||||||
#elif defined(__AVR_ATmega32U4__)
|
#elif defined(__AVR_ATmega32U4__)
|
||||||
//#define IR_USE_TIMER1 // tx = pin 14
|
//#define IR_USE_TIMER1 // tx = pin 14
|
||||||
//#define IR_USE_TIMER3 // tx = pin 9
|
//#define IR_USE_TIMER3 // tx = pin 9
|
||||||
#define IR_USE_TIMER4_HS // tx = pin 10
|
#define IR_USE_TIMER4_HS // tx = pin 10
|
||||||
|
|
||||||
// Teensy 3.0
|
// Teensy 3.0
|
||||||
#elif defined(__MK20DX128__) || defined(__MK20DX256__)
|
#elif defined(__MK20DX128__)
|
||||||
#define IR_USE_TIMER_CMT // tx = pin 5
|
#define IR_USE_TIMER_CMT // tx = pin 5
|
||||||
|
|
||||||
// Teensy-LC
|
|
||||||
#elif defined(__MKL26Z64__)
|
|
||||||
#define IR_USE_TIMER_TPM1 // tx = pin 16
|
|
||||||
|
|
||||||
// Teensy++ 1.0 & 2.0
|
// Teensy++ 1.0 & 2.0
|
||||||
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
|
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
|
||||||
//#define IR_USE_TIMER1 // tx = pin 25
|
//#define IR_USE_TIMER1 // tx = pin 25
|
||||||
#define IR_USE_TIMER2 // tx = pin 1
|
#define IR_USE_TIMER2 // tx = pin 1
|
||||||
//#define IR_USE_TIMER3 // tx = pin 16
|
//#define IR_USE_TIMER3 // tx = pin 16
|
||||||
|
|
||||||
// Sanguino
|
// Sanguino
|
||||||
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||||
//#define IR_USE_TIMER1 // tx = pin 13
|
//#define IR_USE_TIMER1 // tx = pin 13
|
||||||
#define IR_USE_TIMER2 // tx = pin 14
|
#define IR_USE_TIMER2 // tx = pin 14
|
||||||
|
|
||||||
// Atmega8
|
// Atmega8
|
||||||
#elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__)
|
#elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__)
|
||||||
#define IR_USE_TIMER1 // tx = pin 9
|
#define IR_USE_TIMER1 // tx = pin 9
|
||||||
|
|
||||||
// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc
|
// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, etc
|
||||||
#else
|
#else
|
||||||
//#define IR_USE_TIMER1 // tx = pin 9
|
//#define IR_USE_TIMER1 // tx = pin 9
|
||||||
#define IR_USE_TIMER2 // tx = pin 3
|
#define IR_USE_TIMER2 // tx = pin 3
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Defines for Timer
|
|
||||||
|
|
||||||
//---------------------------------------------------------
|
|
||||||
// Timer2 (8 bits)
|
#ifdef F_CPU
|
||||||
//
|
#define SYSCLOCK F_CPU // main Arduino clock
|
||||||
|
#else
|
||||||
|
#define SYSCLOCK 16000000 // main Arduino clock
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ERR 0
|
||||||
|
#define DECODED 1
|
||||||
|
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// Pulse parms are *50-100 for the Mark and *50+100 for the space
|
||||||
|
// First MARK is the one after the long gap
|
||||||
|
// pulse parameters in usec
|
||||||
|
#define WHYNTER_HDR_MARK 2850
|
||||||
|
#define WHYNTER_HDR_SPACE 2850
|
||||||
|
#define WHYNTER_BIT_MARK 750
|
||||||
|
#define WHYNTER_ONE_MARK 750
|
||||||
|
#define WHYNTER_ONE_SPACE 2150
|
||||||
|
#define WHYNTER_ZERO_MARK 750
|
||||||
|
#define WHYNTER_ZERO_SPACE 750
|
||||||
|
|
||||||
|
#define NEC_HDR_MARK 9000
|
||||||
|
#define NEC_HDR_SPACE 4500
|
||||||
|
#define NEC_BIT_MARK 560
|
||||||
|
#define NEC_ONE_SPACE 1690
|
||||||
|
#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 SONY_DOUBLE_SPACE_USECS 500 // usually ssee 713 - not using ticks as get number wrapround
|
||||||
|
|
||||||
|
// SA 8650B
|
||||||
|
#define SANYO_HDR_MARK 3500 // seen range 3500
|
||||||
|
#define SANYO_HDR_SPACE 950 // seen 950
|
||||||
|
#define SANYO_ONE_MARK 2400 // seen 2400
|
||||||
|
#define SANYO_ZERO_MARK 700 // seen 700
|
||||||
|
#define SANYO_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround
|
||||||
|
#define SANYO_RPT_LENGTH 45000
|
||||||
|
|
||||||
|
// Mitsubishi RM 75501
|
||||||
|
// 14200 7 41 7 42 7 42 7 17 7 17 7 18 7 41 7 18 7 17 7 17 7 18 7 41 8 17 7 17 7 18 7 17 7
|
||||||
|
|
||||||
|
// #define MITSUBISHI_HDR_MARK 250 // seen range 3500
|
||||||
|
#define MITSUBISHI_HDR_SPACE 350 // 7*50+100
|
||||||
|
#define MITSUBISHI_ONE_MARK 1950 // 41*50-100
|
||||||
|
#define MITSUBISHI_ZERO_MARK 750 // 17*50-100
|
||||||
|
// #define MITSUBISHI_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround
|
||||||
|
// #define MITSUBISHI_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 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 950 // 40ms
|
||||||
|
|
||||||
|
#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 PANASONIC_HDR_MARK 3502
|
||||||
|
#define PANASONIC_HDR_SPACE 1750
|
||||||
|
#define PANASONIC_BIT_MARK 502
|
||||||
|
#define PANASONIC_ONE_SPACE 1244
|
||||||
|
#define PANASONIC_ZERO_SPACE 400
|
||||||
|
|
||||||
|
#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 LG_HDR_MARK 8000
|
||||||
|
#define LG_HDR_SPACE 4000
|
||||||
|
#define LG_BIT_MARK 600
|
||||||
|
#define LG_ONE_SPACE 1600
|
||||||
|
#define LG_ZERO_SPACE 550
|
||||||
|
#define LG_RPT_LENGTH 60000
|
||||||
|
|
||||||
|
#define SAMSUNG_HDR_MARK 5000
|
||||||
|
#define SAMSUNG_HDR_SPACE 5000
|
||||||
|
#define SAMSUNG_BIT_MARK 560
|
||||||
|
#define SAMSUNG_ONE_SPACE 1600
|
||||||
|
#define SAMSUNG_ZERO_SPACE 560
|
||||||
|
#define SAMSUNG_RPT_SPACE 2250
|
||||||
|
|
||||||
|
|
||||||
|
#define SHARP_BITS 15
|
||||||
|
#define DISH_BITS 16
|
||||||
|
|
||||||
|
// AIWA RC T501
|
||||||
|
// Lirc file http://lirc.sourceforge.net/remotes/aiwa/RC-T501
|
||||||
|
#define AIWA_RC_T501_HZ 38
|
||||||
|
#define AIWA_RC_T501_BITS 15
|
||||||
|
#define AIWA_RC_T501_PRE_BITS 26
|
||||||
|
#define AIWA_RC_T501_POST_BITS 1
|
||||||
|
#define AIWA_RC_T501_SUM_BITS AIWA_RC_T501_PRE_BITS+AIWA_RC_T501_BITS+AIWA_RC_T501_POST_BITS
|
||||||
|
#define AIWA_RC_T501_HDR_MARK 8800
|
||||||
|
#define AIWA_RC_T501_HDR_SPACE 4500
|
||||||
|
#define AIWA_RC_T501_BIT_MARK 500
|
||||||
|
#define AIWA_RC_T501_ONE_SPACE 600
|
||||||
|
#define AIWA_RC_T501_ZERO_SPACE 1700
|
||||||
|
|
||||||
|
|
||||||
|
#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))
|
||||||
|
|
||||||
|
// 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 SANYO_BITS 12
|
||||||
|
#define MITSUBISHI_BITS 16
|
||||||
|
#define MIN_RC5_SAMPLES 11
|
||||||
|
#define MIN_RC6_SAMPLES 1
|
||||||
|
#define PANASONIC_BITS 48
|
||||||
|
#define JVC_BITS 16
|
||||||
|
#define LG_BITS 28
|
||||||
|
#define SAMSUNG_BITS 32
|
||||||
|
#define WHYNTER_BITS 32
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// defines for timer2 (8 bits)
|
||||||
#if defined(IR_USE_TIMER2)
|
#if defined(IR_USE_TIMER2)
|
||||||
|
|
||||||
#define TIMER_RESET
|
#define TIMER_RESET
|
||||||
#define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1))
|
#define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1))
|
||||||
#define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1)))
|
#define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1)))
|
||||||
#define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A))
|
#define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A))
|
||||||
#define TIMER_DISABLE_INTR (TIMSK2 = 0)
|
#define TIMER_DISABLE_INTR (TIMSK2 = 0)
|
||||||
#define TIMER_INTR_NAME TIMER2_COMPA_vect
|
#define TIMER_INTR_NAME TIMER2_COMPA_vect
|
||||||
|
|
||||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||||
const uint8_t pwmval = SYSCLOCK / 2000 / (val); \
|
const uint8_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||||
TCCR2A = _BV(WGM20); \
|
TCCR2A = _BV(WGM20); \
|
||||||
TCCR2B = _BV(WGM22) | _BV(CS20); \
|
TCCR2B = _BV(WGM22) | _BV(CS20); \
|
||||||
OCR2A = pwmval; \
|
OCR2A = pwmval; \
|
||||||
OCR2B = pwmval / 3; \
|
OCR2B = pwmval / 3; \
|
||||||
})
|
})
|
||||||
|
#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000)
|
||||||
#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000)
|
|
||||||
|
|
||||||
//-----------------
|
|
||||||
#if (TIMER_COUNT_TOP < 256)
|
#if (TIMER_COUNT_TOP < 256)
|
||||||
# define TIMER_CONFIG_NORMAL() ({ \
|
|
||||||
TCCR2A = _BV(WGM21); \
|
|
||||||
TCCR2B = _BV(CS20); \
|
|
||||||
OCR2A = TIMER_COUNT_TOP; \
|
|
||||||
TCNT2 = 0; \
|
|
||||||
})
|
|
||||||
#else
|
|
||||||
# define TIMER_CONFIG_NORMAL() ({ \
|
|
||||||
TCCR2A = _BV(WGM21); \
|
|
||||||
TCCR2B = _BV(CS21); \
|
|
||||||
OCR2A = TIMER_COUNT_TOP / 8; \
|
|
||||||
TCNT2 = 0; \
|
|
||||||
})
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//-----------------
|
|
||||||
#if defined(CORE_OC2B_PIN)
|
|
||||||
# define TIMER_PWM_PIN CORE_OC2B_PIN // Teensy
|
|
||||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
|
||||||
# define TIMER_PWM_PIN 9 // Arduino Mega
|
|
||||||
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
|
||||||
# define TIMER_PWM_PIN 14 // Sanguino
|
|
||||||
#else
|
|
||||||
# define TIMER_PWM_PIN 3 // Arduino Duemilanove, Diecimila, LilyPad, etc
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//---------------------------------------------------------
|
|
||||||
// Timer1 (16 bits)
|
|
||||||
//
|
|
||||||
#elif defined(IR_USE_TIMER1)
|
|
||||||
|
|
||||||
#define TIMER_RESET
|
|
||||||
#define TIMER_ENABLE_PWM (TCCR1A |= _BV(COM1A1))
|
|
||||||
#define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1)))
|
|
||||||
|
|
||||||
//-----------------
|
|
||||||
#if defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__)
|
|
||||||
# define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE1A))
|
|
||||||
# define TIMER_DISABLE_INTR (TIMSK &= ~_BV(OCIE1A))
|
|
||||||
#else
|
|
||||||
# define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A))
|
|
||||||
# define TIMER_DISABLE_INTR (TIMSK1 = 0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//-----------------
|
|
||||||
#define TIMER_INTR_NAME TIMER1_COMPA_vect
|
|
||||||
|
|
||||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
|
||||||
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
|
||||||
TCCR1A = _BV(WGM11); \
|
|
||||||
TCCR1B = _BV(WGM13) | _BV(CS10); \
|
|
||||||
ICR1 = pwmval; \
|
|
||||||
OCR1A = pwmval / 3; \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define TIMER_CONFIG_NORMAL() ({ \
|
#define TIMER_CONFIG_NORMAL() ({ \
|
||||||
TCCR1A = 0; \
|
TCCR2A = _BV(WGM21); \
|
||||||
TCCR1B = _BV(WGM12) | _BV(CS10); \
|
TCCR2B = _BV(CS20); \
|
||||||
OCR1A = SYSCLOCK * USECPERTICK / 1000000; \
|
OCR2A = TIMER_COUNT_TOP; \
|
||||||
TCNT1 = 0; \
|
TCNT2 = 0; \
|
||||||
})
|
})
|
||||||
|
|
||||||
//-----------------
|
|
||||||
#if defined(CORE_OC1A_PIN)
|
|
||||||
# define TIMER_PWM_PIN CORE_OC1A_PIN // Teensy
|
|
||||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
|
||||||
# define TIMER_PWM_PIN 11 // Arduino Mega
|
|
||||||
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
|
||||||
# define TIMER_PWM_PIN 13 // Sanguino
|
|
||||||
#else
|
#else
|
||||||
# define TIMER_PWM_PIN 9 // Arduino Duemilanove, Diecimila, LilyPad, etc
|
#define TIMER_CONFIG_NORMAL() ({ \
|
||||||
|
TCCR2A = _BV(WGM21); \
|
||||||
|
TCCR2B = _BV(CS21); \
|
||||||
|
OCR2A = TIMER_COUNT_TOP / 8; \
|
||||||
|
TCNT2 = 0; \
|
||||||
|
})
|
||||||
|
#endif
|
||||||
|
#if defined(CORE_OC2B_PIN)
|
||||||
|
#define TIMER_PWM_PIN CORE_OC2B_PIN /* Teensy */
|
||||||
|
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||||
|
#define TIMER_PWM_PIN 9 /* Arduino Mega */
|
||||||
|
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||||
|
#define TIMER_PWM_PIN 14 /* Sanguino */
|
||||||
|
#else
|
||||||
|
#define TIMER_PWM_PIN 3 /* Arduino Duemilanove, Diecimila, LilyPad, etc */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//---------------------------------------------------------
|
|
||||||
// Timer3 (16 bits)
|
|
||||||
//
|
|
||||||
#elif defined(IR_USE_TIMER3)
|
|
||||||
|
|
||||||
|
// defines for timer1 (16 bits)
|
||||||
|
#elif defined(IR_USE_TIMER1)
|
||||||
|
#define TIMER_RESET
|
||||||
|
#define TIMER_ENABLE_PWM (TCCR1A |= _BV(COM1A1))
|
||||||
|
#define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1)))
|
||||||
|
#if defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__)
|
||||||
|
#define TIMER_ENABLE_INTR (TIMSK = _BV(OCIE1A))
|
||||||
|
#define TIMER_DISABLE_INTR (TIMSK = 0)
|
||||||
|
#else
|
||||||
|
#define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A))
|
||||||
|
#define TIMER_DISABLE_INTR (TIMSK1 = 0)
|
||||||
|
#endif
|
||||||
|
#define TIMER_INTR_NAME TIMER1_COMPA_vect
|
||||||
|
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||||
|
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||||
|
TCCR1A = _BV(WGM11); \
|
||||||
|
TCCR1B = _BV(WGM13) | _BV(CS10); \
|
||||||
|
ICR1 = pwmval; \
|
||||||
|
OCR1A = pwmval / 3; \
|
||||||
|
})
|
||||||
|
#define TIMER_CONFIG_NORMAL() ({ \
|
||||||
|
TCCR1A = 0; \
|
||||||
|
TCCR1B = _BV(WGM12) | _BV(CS10); \
|
||||||
|
OCR1A = SYSCLOCK * USECPERTICK / 1000000; \
|
||||||
|
TCNT1 = 0; \
|
||||||
|
})
|
||||||
|
#if defined(CORE_OC1A_PIN)
|
||||||
|
#define TIMER_PWM_PIN CORE_OC1A_PIN /* Teensy */
|
||||||
|
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||||
|
#define TIMER_PWM_PIN 11 /* Arduino Mega */
|
||||||
|
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||||
|
#define TIMER_PWM_PIN 13 /* Sanguino */
|
||||||
|
#else
|
||||||
|
#define TIMER_PWM_PIN 9 /* Arduino Duemilanove, Diecimila, LilyPad, etc */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// defines for timer3 (16 bits)
|
||||||
|
#elif defined(IR_USE_TIMER3)
|
||||||
#define TIMER_RESET
|
#define TIMER_RESET
|
||||||
#define TIMER_ENABLE_PWM (TCCR3A |= _BV(COM3A1))
|
#define TIMER_ENABLE_PWM (TCCR3A |= _BV(COM3A1))
|
||||||
#define TIMER_DISABLE_PWM (TCCR3A &= ~(_BV(COM3A1)))
|
#define TIMER_DISABLE_PWM (TCCR3A &= ~(_BV(COM3A1)))
|
||||||
#define TIMER_ENABLE_INTR (TIMSK3 = _BV(OCIE3A))
|
#define TIMER_ENABLE_INTR (TIMSK3 = _BV(OCIE3A))
|
||||||
#define TIMER_DISABLE_INTR (TIMSK3 = 0)
|
#define TIMER_DISABLE_INTR (TIMSK3 = 0)
|
||||||
#define TIMER_INTR_NAME TIMER3_COMPA_vect
|
#define TIMER_INTR_NAME TIMER3_COMPA_vect
|
||||||
|
|
||||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||||
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||||
TCCR3A = _BV(WGM31); \
|
TCCR3A = _BV(WGM31); \
|
||||||
@@ -317,81 +349,69 @@ EXTERN volatile irparams_t irparams;
|
|||||||
ICR3 = pwmval; \
|
ICR3 = pwmval; \
|
||||||
OCR3A = pwmval / 3; \
|
OCR3A = pwmval / 3; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define TIMER_CONFIG_NORMAL() ({ \
|
#define TIMER_CONFIG_NORMAL() ({ \
|
||||||
TCCR3A = 0; \
|
TCCR3A = 0; \
|
||||||
TCCR3B = _BV(WGM32) | _BV(CS30); \
|
TCCR3B = _BV(WGM32) | _BV(CS30); \
|
||||||
OCR3A = SYSCLOCK * USECPERTICK / 1000000; \
|
OCR3A = SYSCLOCK * USECPERTICK / 1000000; \
|
||||||
TCNT3 = 0; \
|
TCNT3 = 0; \
|
||||||
})
|
})
|
||||||
|
|
||||||
//-----------------
|
|
||||||
#if defined(CORE_OC3A_PIN)
|
#if defined(CORE_OC3A_PIN)
|
||||||
# define TIMER_PWM_PIN CORE_OC3A_PIN // Teensy
|
#define TIMER_PWM_PIN CORE_OC3A_PIN /* Teensy */
|
||||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||||
# define TIMER_PWM_PIN 5 // Arduino Mega
|
#define TIMER_PWM_PIN 5 /* Arduino Mega */
|
||||||
#else
|
#else
|
||||||
# error "Please add OC3A pin number here\n"
|
#error "Please add OC3A pin number here\n"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//---------------------------------------------------------
|
|
||||||
// Timer4 (10 bits, high speed option)
|
// defines for timer4 (10 bits, high speed option)
|
||||||
//
|
|
||||||
#elif defined(IR_USE_TIMER4_HS)
|
#elif defined(IR_USE_TIMER4_HS)
|
||||||
|
|
||||||
#define TIMER_RESET
|
#define TIMER_RESET
|
||||||
#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1))
|
#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1))
|
||||||
#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1)))
|
#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1)))
|
||||||
#define TIMER_ENABLE_INTR (TIMSK4 = _BV(TOIE4))
|
#define TIMER_ENABLE_INTR (TIMSK4 = _BV(TOIE4))
|
||||||
#define TIMER_DISABLE_INTR (TIMSK4 = 0)
|
#define TIMER_DISABLE_INTR (TIMSK4 = 0)
|
||||||
#define TIMER_INTR_NAME TIMER4_OVF_vect
|
#define TIMER_INTR_NAME TIMER4_OVF_vect
|
||||||
|
|
||||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||||
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||||
TCCR4A = (1<<PWM4A); \
|
TCCR4A = (1<<PWM4A); \
|
||||||
TCCR4B = _BV(CS40); \
|
TCCR4B = _BV(CS40); \
|
||||||
TCCR4C = 0; \
|
TCCR4C = 0; \
|
||||||
TCCR4D = (1<<WGM40); \
|
TCCR4D = (1<<WGM40); \
|
||||||
TCCR4E = 0; \
|
TCCR4E = 0; \
|
||||||
TC4H = pwmval >> 8; \
|
TC4H = pwmval >> 8; \
|
||||||
OCR4C = pwmval; \
|
OCR4C = pwmval; \
|
||||||
TC4H = (pwmval / 3) >> 8; \
|
TC4H = (pwmval / 3) >> 8; \
|
||||||
OCR4A = (pwmval / 3) & 255; \
|
OCR4A = (pwmval / 3) & 255; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define TIMER_CONFIG_NORMAL() ({ \
|
#define TIMER_CONFIG_NORMAL() ({ \
|
||||||
TCCR4A = 0; \
|
TCCR4A = 0; \
|
||||||
TCCR4B = _BV(CS40); \
|
TCCR4B = _BV(CS40); \
|
||||||
TCCR4C = 0; \
|
TCCR4C = 0; \
|
||||||
TCCR4D = 0; \
|
TCCR4D = 0; \
|
||||||
TCCR4E = 0; \
|
TCCR4E = 0; \
|
||||||
TC4H = (SYSCLOCK * USECPERTICK / 1000000) >> 8; \
|
TC4H = (SYSCLOCK * USECPERTICK / 1000000) >> 8; \
|
||||||
OCR4C = (SYSCLOCK * USECPERTICK / 1000000) & 255; \
|
OCR4C = (SYSCLOCK * USECPERTICK / 1000000) & 255; \
|
||||||
TC4H = 0; \
|
TC4H = 0; \
|
||||||
TCNT4 = 0; \
|
TCNT4 = 0; \
|
||||||
})
|
})
|
||||||
|
|
||||||
//-----------------
|
|
||||||
#if defined(CORE_OC4A_PIN)
|
#if defined(CORE_OC4A_PIN)
|
||||||
# define TIMER_PWM_PIN CORE_OC4A_PIN // Teensy
|
#define TIMER_PWM_PIN CORE_OC4A_PIN /* Teensy */
|
||||||
#elif defined(__AVR_ATmega32U4__)
|
#elif defined(__AVR_ATmega32U4__)
|
||||||
# define TIMER_PWM_PIN 13 // Leonardo
|
#define TIMER_PWM_PIN 13 /* Leonardo */
|
||||||
#else
|
#else
|
||||||
# error "Please add OC4A pin number here\n"
|
#error "Please add OC4A pin number here\n"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//---------------------------------------------------------
|
|
||||||
// Timer4 (16 bits)
|
// defines for timer4 (16 bits)
|
||||||
//
|
|
||||||
#elif defined(IR_USE_TIMER4)
|
#elif defined(IR_USE_TIMER4)
|
||||||
|
|
||||||
#define TIMER_RESET
|
#define TIMER_RESET
|
||||||
#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1))
|
#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1))
|
||||||
#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1)))
|
#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1)))
|
||||||
#define TIMER_ENABLE_INTR (TIMSK4 = _BV(OCIE4A))
|
#define TIMER_ENABLE_INTR (TIMSK4 = _BV(OCIE4A))
|
||||||
#define TIMER_DISABLE_INTR (TIMSK4 = 0)
|
#define TIMER_DISABLE_INTR (TIMSK4 = 0)
|
||||||
#define TIMER_INTR_NAME TIMER4_COMPA_vect
|
#define TIMER_INTR_NAME TIMER4_COMPA_vect
|
||||||
|
|
||||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||||
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||||
TCCR4A = _BV(WGM41); \
|
TCCR4A = _BV(WGM41); \
|
||||||
@@ -399,35 +419,29 @@ EXTERN volatile irparams_t irparams;
|
|||||||
ICR4 = pwmval; \
|
ICR4 = pwmval; \
|
||||||
OCR4A = pwmval / 3; \
|
OCR4A = pwmval / 3; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define TIMER_CONFIG_NORMAL() ({ \
|
#define TIMER_CONFIG_NORMAL() ({ \
|
||||||
TCCR4A = 0; \
|
TCCR4A = 0; \
|
||||||
TCCR4B = _BV(WGM42) | _BV(CS40); \
|
TCCR4B = _BV(WGM42) | _BV(CS40); \
|
||||||
OCR4A = SYSCLOCK * USECPERTICK / 1000000; \
|
OCR4A = SYSCLOCK * USECPERTICK / 1000000; \
|
||||||
TCNT4 = 0; \
|
TCNT4 = 0; \
|
||||||
})
|
})
|
||||||
|
|
||||||
//-----------------
|
|
||||||
#if defined(CORE_OC4A_PIN)
|
#if defined(CORE_OC4A_PIN)
|
||||||
# define TIMER_PWM_PIN CORE_OC4A_PIN
|
#define TIMER_PWM_PIN CORE_OC4A_PIN
|
||||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||||
# define TIMER_PWM_PIN 6 // Arduino Mega
|
#define TIMER_PWM_PIN 6 /* Arduino Mega */
|
||||||
#else
|
#else
|
||||||
# error "Please add OC4A pin number here\n"
|
#error "Please add OC4A pin number here\n"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//---------------------------------------------------------
|
|
||||||
// Timer5 (16 bits)
|
// defines for timer5 (16 bits)
|
||||||
//
|
|
||||||
#elif defined(IR_USE_TIMER5)
|
#elif defined(IR_USE_TIMER5)
|
||||||
|
|
||||||
#define TIMER_RESET
|
#define TIMER_RESET
|
||||||
#define TIMER_ENABLE_PWM (TCCR5A |= _BV(COM5A1))
|
#define TIMER_ENABLE_PWM (TCCR5A |= _BV(COM5A1))
|
||||||
#define TIMER_DISABLE_PWM (TCCR5A &= ~(_BV(COM5A1)))
|
#define TIMER_DISABLE_PWM (TCCR5A &= ~(_BV(COM5A1)))
|
||||||
#define TIMER_ENABLE_INTR (TIMSK5 = _BV(OCIE5A))
|
#define TIMER_ENABLE_INTR (TIMSK5 = _BV(OCIE5A))
|
||||||
#define TIMER_DISABLE_INTR (TIMSK5 = 0)
|
#define TIMER_DISABLE_INTR (TIMSK5 = 0)
|
||||||
#define TIMER_INTR_NAME TIMER5_COMPA_vect
|
#define TIMER_INTR_NAME TIMER5_COMPA_vect
|
||||||
|
|
||||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||||
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||||
TCCR5A = _BV(WGM51); \
|
TCCR5A = _BV(WGM51); \
|
||||||
@@ -435,124 +449,91 @@ EXTERN volatile irparams_t irparams;
|
|||||||
ICR5 = pwmval; \
|
ICR5 = pwmval; \
|
||||||
OCR5A = pwmval / 3; \
|
OCR5A = pwmval / 3; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define TIMER_CONFIG_NORMAL() ({ \
|
#define TIMER_CONFIG_NORMAL() ({ \
|
||||||
TCCR5A = 0; \
|
TCCR5A = 0; \
|
||||||
TCCR5B = _BV(WGM52) | _BV(CS50); \
|
TCCR5B = _BV(WGM52) | _BV(CS50); \
|
||||||
OCR5A = SYSCLOCK * USECPERTICK / 1000000; \
|
OCR5A = SYSCLOCK * USECPERTICK / 1000000; \
|
||||||
TCNT5 = 0; \
|
TCNT5 = 0; \
|
||||||
})
|
})
|
||||||
|
|
||||||
//-----------------
|
|
||||||
#if defined(CORE_OC5A_PIN)
|
#if defined(CORE_OC5A_PIN)
|
||||||
# define TIMER_PWM_PIN CORE_OC5A_PIN
|
#define TIMER_PWM_PIN CORE_OC5A_PIN
|
||||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||||
# define TIMER_PWM_PIN 46 // Arduino Mega
|
#define TIMER_PWM_PIN 46 /* Arduino Mega */
|
||||||
#else
|
#else
|
||||||
# error "Please add OC5A pin number here\n"
|
#error "Please add OC5A pin number here\n"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//---------------------------------------------------------
|
|
||||||
// Special carrier modulator timer
|
// defines for special carrier modulator timer
|
||||||
//
|
|
||||||
#elif defined(IR_USE_TIMER_CMT)
|
#elif defined(IR_USE_TIMER_CMT)
|
||||||
|
#define TIMER_RESET ({ \
|
||||||
#define TIMER_RESET ({ \
|
uint8_t tmp = CMT_MSC; \
|
||||||
uint8_t tmp = CMT_MSC; \
|
CMT_CMD2 = 30; \
|
||||||
CMT_CMD2 = 30; \
|
|
||||||
})
|
})
|
||||||
|
#define TIMER_ENABLE_PWM CORE_PIN5_CONFIG = PORT_PCR_MUX(2)|PORT_PCR_DSE|PORT_PCR_SRE
|
||||||
#define TIMER_ENABLE_PWM do { \
|
#define TIMER_DISABLE_PWM CORE_PIN5_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_DSE|PORT_PCR_SRE
|
||||||
CORE_PIN5_CONFIG = PORT_PCR_MUX(2) | PORT_PCR_DSE | PORT_PCR_SRE; \
|
#define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_CMT)
|
||||||
} while(0)
|
#define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_CMT)
|
||||||
|
#define TIMER_INTR_NAME cmt_isr
|
||||||
#define TIMER_DISABLE_PWM do { \
|
|
||||||
CORE_PIN5_CONFIG = PORT_PCR_MUX(1) | PORT_PCR_DSE | PORT_PCR_SRE; \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_CMT)
|
|
||||||
#define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_CMT)
|
|
||||||
#define TIMER_INTR_NAME cmt_isr
|
|
||||||
|
|
||||||
//-----------------
|
|
||||||
#ifdef ISR
|
|
||||||
# undef ISR
|
|
||||||
#endif
|
|
||||||
#define ISR(f) void f(void)
|
|
||||||
|
|
||||||
//-----------------
|
|
||||||
#if (F_BUS == 48000000)
|
|
||||||
# define CMT_PPS_VAL 5
|
|
||||||
#else
|
|
||||||
# define CMT_PPS_VAL 2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//-----------------
|
|
||||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
|
||||||
SIM_SCGC4 |= SIM_SCGC4_CMT; \
|
|
||||||
SIM_SOPT2 |= SIM_SOPT2_PTD7PAD; \
|
|
||||||
CMT_PPS = CMT_PPS_VAL; \
|
|
||||||
CMT_CGH1 = 2667 / val; \
|
|
||||||
CMT_CGL1 = 5333 / val; \
|
|
||||||
CMT_CMD1 = 0; \
|
|
||||||
CMT_CMD2 = 30; \
|
|
||||||
CMT_CMD3 = 0; \
|
|
||||||
CMT_CMD4 = 0; \
|
|
||||||
CMT_OC = 0x60; \
|
|
||||||
CMT_MSC = 0x01; \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define TIMER_CONFIG_NORMAL() ({ \
|
|
||||||
SIM_SCGC4 |= SIM_SCGC4_CMT; \
|
|
||||||
CMT_PPS = CMT_PPS_VAL; \
|
|
||||||
CMT_CGH1 = 1; \
|
|
||||||
CMT_CGL1 = 1; \
|
|
||||||
CMT_CMD1 = 0; \
|
|
||||||
CMT_CMD2 = 30 \
|
|
||||||
CMT_CMD3 = 0; \
|
|
||||||
CMT_CMD4 = 19; \
|
|
||||||
CMT_OC = 0; \
|
|
||||||
CMT_MSC = 0x03; \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define TIMER_PWM_PIN 5
|
|
||||||
|
|
||||||
// defines for TPM1 timer on Teensy-LC
|
|
||||||
#elif defined(IR_USE_TIMER_TPM1)
|
|
||||||
#define TIMER_RESET FTM1_SC |= FTM_SC_TOF;
|
|
||||||
#define TIMER_ENABLE_PWM CORE_PIN16_CONFIG = PORT_PCR_MUX(3)|PORT_PCR_DSE|PORT_PCR_SRE
|
|
||||||
#define TIMER_DISABLE_PWM CORE_PIN16_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_SRE
|
|
||||||
#define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_FTM1)
|
|
||||||
#define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_FTM1)
|
|
||||||
#define TIMER_INTR_NAME ftm1_isr
|
|
||||||
#ifdef ISR
|
#ifdef ISR
|
||||||
#undef ISR
|
#undef ISR
|
||||||
#endif
|
#endif
|
||||||
#define ISR(f) void f(void)
|
#define ISR(f) void f(void)
|
||||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
#if F_BUS == 48000000
|
||||||
SIM_SCGC6 |= SIM_SCGC6_TPM1; \
|
#define CMT_PPS_VAL 5
|
||||||
FTM1_SC = 0; \
|
|
||||||
FTM1_CNT = 0; \
|
|
||||||
FTM1_MOD = (F_PLL/2000) / val - 1; \
|
|
||||||
FTM1_C0V = (F_PLL/6000) / val - 1; \
|
|
||||||
FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); \
|
|
||||||
})
|
|
||||||
#define TIMER_CONFIG_NORMAL() ({ \
|
|
||||||
SIM_SCGC6 |= SIM_SCGC6_TPM1; \
|
|
||||||
FTM1_SC = 0; \
|
|
||||||
FTM1_CNT = 0; \
|
|
||||||
FTM1_MOD = (F_PLL/40000) - 1; \
|
|
||||||
FTM1_C0V = 0; \
|
|
||||||
FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0) | FTM_SC_TOF | FTM_SC_TOIE; \
|
|
||||||
})
|
|
||||||
#define TIMER_PWM_PIN 16
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------
|
|
||||||
// Unknown Timer
|
|
||||||
//
|
|
||||||
#else
|
#else
|
||||||
# error "Internal code configuration error, no known IR_USE_TIMER# defined\n"
|
#define CMT_PPS_VAL 2
|
||||||
#endif
|
#endif
|
||||||
|
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||||
|
SIM_SCGC4 |= SIM_SCGC4_CMT; \
|
||||||
|
SIM_SOPT2 |= SIM_SOPT2_PTD7PAD; \
|
||||||
|
CMT_PPS = CMT_PPS_VAL; \
|
||||||
|
CMT_CGH1 = 2667 / val; \
|
||||||
|
CMT_CGL1 = 5333 / val; \
|
||||||
|
CMT_CMD1 = 0; \
|
||||||
|
CMT_CMD2 = 30; \
|
||||||
|
CMT_CMD3 = 0; \
|
||||||
|
CMT_CMD4 = 0; \
|
||||||
|
CMT_OC = 0x60; \
|
||||||
|
CMT_MSC = 0x01; \
|
||||||
|
})
|
||||||
|
#define TIMER_CONFIG_NORMAL() ({ \
|
||||||
|
SIM_SCGC4 |= SIM_SCGC4_CMT; \
|
||||||
|
CMT_PPS = CMT_PPS_VAL; \
|
||||||
|
CMT_CGH1 = 1; \
|
||||||
|
CMT_CGL1 = 1; \
|
||||||
|
CMT_CMD1 = 0; \
|
||||||
|
CMT_CMD2 = 30; \
|
||||||
|
CMT_CMD3 = 0; \
|
||||||
|
CMT_CMD4 = 19; \
|
||||||
|
CMT_OC = 0; \
|
||||||
|
CMT_MSC = 0x03; \
|
||||||
|
})
|
||||||
|
#define TIMER_PWM_PIN 5
|
||||||
|
|
||||||
|
|
||||||
|
#else // unknown timer
|
||||||
|
#error "Internal code configuration error, no known IR_USE_TIMER# defined\n"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// defines for blinking the LED
|
||||||
|
#if defined(CORE_LED0_PIN)
|
||||||
|
#define BLINKLED CORE_LED0_PIN
|
||||||
|
#define BLINKLED_ON() (digitalWrite(CORE_LED0_PIN, HIGH))
|
||||||
|
#define BLINKLED_OFF() (digitalWrite(CORE_LED0_PIN, LOW))
|
||||||
|
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||||
|
#define BLINKLED 13
|
||||||
|
#define BLINKLED_ON() (PORTB |= B10000000)
|
||||||
|
#define BLINKLED_OFF() (PORTB &= B01111111)
|
||||||
|
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||||
|
#define BLINKLED 0
|
||||||
|
#define BLINKLED_ON() (PORTD |= B00000001)
|
||||||
|
#define BLINKLED_OFF() (PORTD &= B11111110)
|
||||||
|
#else
|
||||||
|
#define BLINKLED 13
|
||||||
|
#define BLINKLED_ON() (PORTB |= B00100000)
|
||||||
|
#define BLINKLED_OFF() (PORTB &= B11011111)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
# IRremote Arduino Library
|
# IRremote Arduino Library
|
||||||
|
|
||||||
[](https://gitter.im/shirriff/Arduino-IRremote?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
|
||||||
|
|
||||||
This library enables you to send and receive using infra-red signals on an arduino.
|
This library enables you to send and receive using infra-red signals on an arduino.
|
||||||
|
|
||||||
Check [here](http://shirriff.github.io/Arduino-IRremote/) for tutorials and more information.
|
Check [here](http://shirriff.github.io/Arduino-IRremote/) for tutorials and more information.
|
||||||
|
|
||||||
## Version - 22.00
|
## Version - 1.01
|
||||||
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
1. Navigate to the [Releases](https://github.com/shirriff/Arduino-IRremote/releases) page.
|
1. Navigate to the [Releases](https://github.com/shirriff/Arduino-IRremote/releases) page.
|
||||||
@@ -14,9 +12,6 @@ Check [here](http://shirriff.github.io/Arduino-IRremote/) for tutorials and more
|
|||||||
3. Extract the zip file
|
3. Extract the zip file
|
||||||
4. Move the "IRremote" folder that has been extracted to your libraries directory.
|
4. Move the "IRremote" folder that has been extracted to your libraries directory.
|
||||||
|
|
||||||
## Usage
|
|
||||||
- TODO (Check examples for now)
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
If you want to contribute to this project:
|
If you want to contribute to this project:
|
||||||
- Report bugs and errors
|
- Report bugs and errors
|
||||||
|
|||||||
16
changelog.md
16
changelog.md
@@ -1,5 +1,13 @@
|
|||||||
## 2.0.1 - 2015/06/26 - [Release](https://github.com/shirriff/Arduino-IRremote/releases/tag/BETA)
|
# Change Log
|
||||||
- Separated protocols into individual files
|
All notable changes to this project will be documented in this file.
|
||||||
- Lots of code clean up
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
- Possible bug fixes
|
|
||||||
|
|
||||||
|
## [1.0.1] - 2015-03-08
|
||||||
|
### Added
|
||||||
|
- Support for Sharp Decoding
|
||||||
|
- Support for Aiwa Decoding
|
||||||
|
- Changelog documentation
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Improved memory management in debugging
|
||||||
|
- Use of F() macro saves RAM
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
#include "IRremote.h"
|
#include "IRremote.h"
|
||||||
|
|
||||||
#define POWER 0x7F80
|
#define POWER 0x7F80
|
||||||
#define AIWA_RC_T501
|
|
||||||
|
|
||||||
IRsend irsend;
|
IRsend irsend;
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,12 @@ void dump(decode_results *results) {
|
|||||||
}
|
}
|
||||||
else if (results->decode_type == PANASONIC) {
|
else if (results->decode_type == PANASONIC) {
|
||||||
Serial.print("Decoded PANASONIC - Address: ");
|
Serial.print("Decoded PANASONIC - Address: ");
|
||||||
Serial.print(results->address,HEX);
|
Serial.print(results->panasonicAddress,HEX);
|
||||||
|
Serial.print(" Value: ");
|
||||||
|
}
|
||||||
|
else if (results->decode_type == SHARP) {
|
||||||
|
Serial.print("Decoded SHARP - Address: ");
|
||||||
|
Serial.print(results->sharpAddress,HEX);
|
||||||
Serial.print(" Value: ");
|
Serial.print(" Value: ");
|
||||||
}
|
}
|
||||||
else if (results->decode_type == LG) {
|
else if (results->decode_type == LG) {
|
||||||
|
|||||||
@@ -1,179 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
// Include the IRremote library header
|
|
||||||
//
|
|
||||||
#include <IRremote.h>
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Tell IRremote which Arduino pin is connected to the IR Receiver (TSOP4838)
|
|
||||||
//
|
|
||||||
int recvPin = 6;
|
|
||||||
IRrecv irrecv(recvPin);
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// Configure the Arduino
|
|
||||||
//
|
|
||||||
void setup ( )
|
|
||||||
{
|
|
||||||
Serial.begin(9600); // Status message will be sent to PC at 9600 baud
|
|
||||||
irrecv.enableIRIn(); // Start the receiver
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// Display IR code
|
|
||||||
//
|
|
||||||
void ircode (decode_results *results)
|
|
||||||
{
|
|
||||||
// Panasonic has an Address
|
|
||||||
if (results->decode_type == PANASONIC) {
|
|
||||||
Serial.print(results->address, HEX);
|
|
||||||
Serial.print(":");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print Code
|
|
||||||
Serial.print(results->value, HEX);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// Display encoding type
|
|
||||||
//
|
|
||||||
void encoding (decode_results *results)
|
|
||||||
{
|
|
||||||
switch (results->decode_type) {
|
|
||||||
default:
|
|
||||||
case UNKNOWN: Serial.print("UNKNOWN"); break ;
|
|
||||||
case NEC: Serial.print("NEC"); break ;
|
|
||||||
case SONY: Serial.print("SONY"); break ;
|
|
||||||
case RC5: Serial.print("RC5"); break ;
|
|
||||||
case RC6: Serial.print("RC6"); break ;
|
|
||||||
case DISH: Serial.print("DISH"); break ;
|
|
||||||
case SHARP: Serial.print("SHARP"); break ;
|
|
||||||
case JVC: Serial.print("JVC"); break ;
|
|
||||||
case SANYO: Serial.print("SANYO"); break ;
|
|
||||||
case MITSUBISHI: Serial.print("MITSUBISHI"); break ;
|
|
||||||
case SAMSUNG: Serial.print("SAMSUNG"); break ;
|
|
||||||
case LG: Serial.print("LG"); break ;
|
|
||||||
case WHYNTER: Serial.print("WHYNTER"); break ;
|
|
||||||
case AIWA_RC_T501: Serial.print("AIWA_RC_T501"); break ;
|
|
||||||
case PANASONIC: Serial.print("PANASONIC"); break ;
|
|
||||||
case DENON: Serial.print("Denon"); break ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// Dump out the decode_results structure.
|
|
||||||
//
|
|
||||||
void dumpInfo (decode_results *results)
|
|
||||||
{
|
|
||||||
// Check if the buffer overflowed
|
|
||||||
if (results->overflow) {
|
|
||||||
Serial.println("IR code too long. Edit IRremoteInt.h and increase RAWLEN");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show Encoding standard
|
|
||||||
Serial.print("Encoding : ");
|
|
||||||
encoding(results);
|
|
||||||
Serial.println("");
|
|
||||||
|
|
||||||
// Show Code & length
|
|
||||||
Serial.print("Code : ");
|
|
||||||
ircode(results);
|
|
||||||
Serial.print(" (");
|
|
||||||
Serial.print(results->bits, DEC);
|
|
||||||
Serial.println(" bits)");
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// Dump out the decode_results structure.
|
|
||||||
//
|
|
||||||
void dumpRaw (decode_results *results)
|
|
||||||
{
|
|
||||||
// Print Raw data
|
|
||||||
Serial.print("Timing[");
|
|
||||||
Serial.print(results->rawlen, DEC);
|
|
||||||
Serial.println("]: ");
|
|
||||||
Serial.print(" -");
|
|
||||||
Serial.println(results->rawbuf[0] * USECPERTICK, DEC);
|
|
||||||
for (int i = 1; i < results->rawlen; i++) {
|
|
||||||
int x = results->rawbuf[i] * USECPERTICK;
|
|
||||||
if (!(i & 1)) { // even
|
|
||||||
Serial.print("-");
|
|
||||||
if (x < 1000) Serial.print(" ") ;
|
|
||||||
if (x < 100) Serial.print(" ") ;
|
|
||||||
Serial.print(x, DEC);
|
|
||||||
} else { // odd
|
|
||||||
Serial.print(" ");
|
|
||||||
Serial.print("+");
|
|
||||||
if (x < 1000) Serial.print(" ") ;
|
|
||||||
if (x < 100) Serial.print(" ") ;
|
|
||||||
Serial.print(x, DEC);
|
|
||||||
Serial.print(", ");
|
|
||||||
}
|
|
||||||
if (!(i%8)) Serial.println("");
|
|
||||||
}
|
|
||||||
Serial.println(""); // Newline
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// Dump out the decode_results structure.
|
|
||||||
//
|
|
||||||
void dumpCode (decode_results *results)
|
|
||||||
{
|
|
||||||
// Start declaration
|
|
||||||
Serial.print("unsigned int "); // variable type
|
|
||||||
Serial.print("rawData["); // array name
|
|
||||||
Serial.print(results->rawlen + 1, DEC); // array size
|
|
||||||
Serial.print("] = {"); // Start declaration
|
|
||||||
|
|
||||||
// Dump data
|
|
||||||
for (int i = 0; i < results->rawlen; i++) {
|
|
||||||
Serial.print(results->rawbuf[i], DEC);
|
|
||||||
Serial.print(",");
|
|
||||||
if (!(i&1)) Serial.print(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
// End declaration
|
|
||||||
Serial.print("0};"); // Turn LED off at the end
|
|
||||||
|
|
||||||
// Comment
|
|
||||||
Serial.print(" // ");
|
|
||||||
encoding(results);
|
|
||||||
Serial.print(" ");
|
|
||||||
ircode(results);
|
|
||||||
|
|
||||||
// Newline
|
|
||||||
Serial.println("");
|
|
||||||
|
|
||||||
// Now dump "known" codes
|
|
||||||
if (results->decode_type != UNKNOWN) {
|
|
||||||
|
|
||||||
// Some protocols have an address
|
|
||||||
if (results->decode_type == PANASONIC) {
|
|
||||||
Serial.print("unsigned int addr = 0x");
|
|
||||||
Serial.print(results->address, HEX);
|
|
||||||
Serial.println(";");
|
|
||||||
}
|
|
||||||
|
|
||||||
// All protocols have data
|
|
||||||
Serial.print("unsigned int data = 0x");
|
|
||||||
Serial.print(results->value, HEX);
|
|
||||||
Serial.println(";");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// The repeating section of the code
|
|
||||||
//
|
|
||||||
void loop ( )
|
|
||||||
{
|
|
||||||
decode_results results; // Somewhere to store the results
|
|
||||||
|
|
||||||
if (irrecv.decode(&results)) { // Grab an IR code
|
|
||||||
dumpInfo(&results); // Output the results
|
|
||||||
dumpRaw(&results); // Output the results in RAW format
|
|
||||||
dumpCode(&results); // Output the results as source code
|
|
||||||
Serial.println(""); // Blank line between entries
|
|
||||||
irrecv.resume(); // Prepare for the next value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
85
irISR.cpp
85
irISR.cpp
@@ -1,85 +0,0 @@
|
|||||||
#include <avr/interrupt.h>
|
|
||||||
|
|
||||||
#include "IRremote.h"
|
|
||||||
#include "IRremoteInt.h"
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// Interrupt Service Routine - Fires every 50uS
|
|
||||||
// TIMER2 interrupt code to collect raw data.
|
|
||||||
// Widths of alternating SPACE, MARK are recorded in rawbuf.
|
|
||||||
// Recorded in ticks of 50uS [microseconds, 0.000050 seconds]
|
|
||||||
// 'rawlen' counts the number of entries recorded so far.
|
|
||||||
// First entry is the SPACE between transmissions.
|
|
||||||
// As soon as a the first [SPACE] entry gets long:
|
|
||||||
// Ready is set; State switches to IDLE; Timing of SPACE continues.
|
|
||||||
// As soon as first MARK arrives:
|
|
||||||
// Gap width is recorded; Ready is cleared; New logging starts
|
|
||||||
//
|
|
||||||
ISR (TIMER_INTR_NAME)
|
|
||||||
{
|
|
||||||
TIMER_RESET;
|
|
||||||
|
|
||||||
// Read if IR Receiver -> SPACE [xmt LED off] or a MARK [xmt LED on]
|
|
||||||
// digitalRead() is very slow. Optimisation is possible, but makes the code unportable
|
|
||||||
uint8_t irdata = (uint8_t)digitalRead(irparams.recvpin);
|
|
||||||
|
|
||||||
irparams.timer++; // One more 50uS tick
|
|
||||||
if (irparams.rawlen >= RAWBUF) irparams.rcvstate = STATE_OVERFLOW ; // Buffer overflow
|
|
||||||
|
|
||||||
switch(irparams.rcvstate) {
|
|
||||||
//......................................................................
|
|
||||||
case STATE_IDLE: // In the middle of a gap
|
|
||||||
if (irdata == MARK) {
|
|
||||||
if (irparams.timer < GAP_TICKS) { // Not big enough to be a gap.
|
|
||||||
irparams.timer = 0;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Gap just ended; Record duration; Start recording transmission
|
|
||||||
irparams.overflow = false;
|
|
||||||
irparams.rawlen = 0;
|
|
||||||
irparams.rawbuf[irparams.rawlen++] = irparams.timer;
|
|
||||||
irparams.timer = 0;
|
|
||||||
irparams.rcvstate = STATE_MARK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
//......................................................................
|
|
||||||
case STATE_MARK: // Timing Mark
|
|
||||||
if (irdata == SPACE) { // Mark ended; Record time
|
|
||||||
irparams.rawbuf[irparams.rawlen++] = irparams.timer;
|
|
||||||
irparams.timer = 0;
|
|
||||||
irparams.rcvstate = STATE_SPACE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
//......................................................................
|
|
||||||
case STATE_SPACE: // Timing Space
|
|
||||||
if (irdata == MARK) { // Space just ended; Record time
|
|
||||||
irparams.rawbuf[irparams.rawlen++] = irparams.timer;
|
|
||||||
irparams.timer = 0;
|
|
||||||
irparams.rcvstate = STATE_MARK;
|
|
||||||
|
|
||||||
} else if (irparams.timer > GAP_TICKS) { // Space
|
|
||||||
// A long Space, indicates gap between codes
|
|
||||||
// Flag the current code as ready for processing
|
|
||||||
// Switch to STOP
|
|
||||||
// Don't reset timer; keep counting Space width
|
|
||||||
irparams.rcvstate = STATE_STOP;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
//......................................................................
|
|
||||||
case STATE_STOP: // Waiting; Measuring Gap
|
|
||||||
if (irdata == MARK) irparams.timer = 0 ; // Reset gap timer
|
|
||||||
break;
|
|
||||||
//......................................................................
|
|
||||||
case STATE_OVERFLOW: // Flag up a read overflow; Stop the State Machine
|
|
||||||
irparams.overflow = true;
|
|
||||||
irparams.rcvstate = STATE_STOP;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If requested, flash LED L (D13) while receiving IR data
|
|
||||||
if (irparams.blinkflag) {
|
|
||||||
if (irdata == MARK) BLINKLED_ON() ; // turn pin 13 LED on
|
|
||||||
else BLINKLED_OFF() ; // turn pin 13 LED off
|
|
||||||
}
|
|
||||||
}
|
|
||||||
513
irPronto.cpp
513
irPronto.cpp
@@ -1,513 +0,0 @@
|
|||||||
#define TEST 0
|
|
||||||
|
|
||||||
#if TEST
|
|
||||||
# define SEND_PRONTO 1
|
|
||||||
# define PRONTO_ONCE false
|
|
||||||
# define PRONTO_REPEAT true
|
|
||||||
# define PRONTO_FALLBACK true
|
|
||||||
# define PRONTO_NOFALLBACK false
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SEND_PRONTO
|
|
||||||
|
|
||||||
//******************************************************************************
|
|
||||||
#if TEST
|
|
||||||
# include <stdio.h>
|
|
||||||
void enableIROut (int freq) { printf("\nFreq = %d KHz\n", freq); }
|
|
||||||
void mark (int t) { printf("+%d," , t); }
|
|
||||||
void space (int t) { printf("-%d, ", t); }
|
|
||||||
#else
|
|
||||||
# include "IRremote.h"
|
|
||||||
#endif // TEST
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// Check for a valid hex digit
|
|
||||||
//
|
|
||||||
bool ishex (char ch)
|
|
||||||
{
|
|
||||||
return ( ((ch >= '0') && (ch <= '9')) ||
|
|
||||||
((ch >= 'A') && (ch <= 'F')) ||
|
|
||||||
((ch >= 'a') && (ch <= 'f')) ) ? true : false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// Check for a valid "blank" ... '\0' is a valid "blank"
|
|
||||||
//
|
|
||||||
bool isblank (char ch)
|
|
||||||
{
|
|
||||||
return ((ch == ' ') || (ch == '\t') || (ch == '\0')) ? true : false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// Bypass spaces
|
|
||||||
//
|
|
||||||
bool byp (char** pcp)
|
|
||||||
{
|
|
||||||
while (isblank(**pcp)) (*pcp)++ ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// Hex-to-Byte : Decode a hex digit
|
|
||||||
// We assume the character has already been validated
|
|
||||||
//
|
|
||||||
uint8_t htob (char ch)
|
|
||||||
{
|
|
||||||
if ((ch >= '0') && (ch <= '9')) return ch - '0' ;
|
|
||||||
if ((ch >= 'A') && (ch <= 'F')) return ch - 'A' + 10 ;
|
|
||||||
if ((ch >= 'a') && (ch <= 'f')) return ch - 'a' + 10 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// Hex-to-Word : Decode a block of 4 hex digits
|
|
||||||
// We assume the string has already been validated
|
|
||||||
// and the pointer being passed points at the start of a block of 4 hex digits
|
|
||||||
//
|
|
||||||
uint16_t htow (char* cp)
|
|
||||||
{
|
|
||||||
return ( (htob(cp[0]) << 12) | (htob(cp[1]) << 8) |
|
|
||||||
(htob(cp[2]) << 4) | (htob(cp[3]) ) ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
//
|
|
||||||
bool sendPronto (char* s, bool repeat, bool fallback)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int len;
|
|
||||||
int skip;
|
|
||||||
char* cp;
|
|
||||||
uint16_t freq; // Frequency in KHz
|
|
||||||
uint8_t usec; // pronto uSec/tick
|
|
||||||
uint8_t once;
|
|
||||||
uint8_t rpt;
|
|
||||||
|
|
||||||
// Validate the string
|
|
||||||
for (cp = s; *cp; cp += 4) {
|
|
||||||
byp(&cp);
|
|
||||||
if ( !ishex(cp[0]) || !ishex(cp[1]) ||
|
|
||||||
!ishex(cp[2]) || !ishex(cp[3]) || !isblank(cp[4]) ) return false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We will use cp to traverse the string
|
|
||||||
cp = s;
|
|
||||||
|
|
||||||
// Check mode = Oscillated/Learned
|
|
||||||
byp(&cp);
|
|
||||||
if (htow(cp) != 0000) return false;
|
|
||||||
cp += 4;
|
|
||||||
|
|
||||||
// Extract & set frequency
|
|
||||||
byp(&cp);
|
|
||||||
freq = (int)(1000000 / (htow(cp) * 0.241246)); // Rounding errors will occur, tolerance is +/- 10%
|
|
||||||
usec = (int)(((1.0 / freq) * 1000000) + 0.5); // Another rounding error, thank Cod for analogue electronics
|
|
||||||
freq /= 1000; // This will introduce a(nother) rounding error which we do not want in the usec calcualtion
|
|
||||||
cp += 4;
|
|
||||||
|
|
||||||
// Get length of "once" code
|
|
||||||
byp(&cp);
|
|
||||||
once = htow(cp);
|
|
||||||
cp += 4;
|
|
||||||
|
|
||||||
// Get length of "repeat" code
|
|
||||||
byp(&cp);
|
|
||||||
rpt = htow(cp);
|
|
||||||
cp += 4;
|
|
||||||
|
|
||||||
// Which code are we sending?
|
|
||||||
if (fallback) { // fallback on the "other" code if "this" code is not present
|
|
||||||
if (!repeat) { // requested 'once'
|
|
||||||
if (once) len = once * 2, skip = 0 ; // if once exists send it
|
|
||||||
else len = rpt * 2, skip = 0 ; // else send repeat code
|
|
||||||
} else { // requested 'repeat'
|
|
||||||
if (rpt) len = rpt * 2, skip = 0 ; // if rpt exists send it
|
|
||||||
else len = once * 2, skip = 0 ; // else send once code
|
|
||||||
}
|
|
||||||
} else { // Send what we asked for, do not fallback if the code is empty!
|
|
||||||
if (!repeat) len = once * 2, skip = 0 ; // 'once' starts at 0
|
|
||||||
else len = rpt * 2, skip = once ; // 'repeat' starts where 'once' ends
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip to start of code
|
|
||||||
for (i = 0; i < skip; i++, cp += 4) byp(&cp) ;
|
|
||||||
|
|
||||||
// Send code
|
|
||||||
enableIROut(freq);
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
byp(&cp);
|
|
||||||
if (i & 1) space(htow(cp) * usec);
|
|
||||||
else mark (htow(cp) * usec);
|
|
||||||
cp += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
#if TEST
|
|
||||||
|
|
||||||
int main ( )
|
|
||||||
{
|
|
||||||
char prontoTest[] =
|
|
||||||
"0000 0070 0000 0032 0080 0040 0010 0010 0010 0030 " // 10
|
|
||||||
"0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 20
|
|
||||||
"0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 30
|
|
||||||
"0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 40
|
|
||||||
"0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 50
|
|
||||||
"0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 60
|
|
||||||
"0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 70
|
|
||||||
"0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 " // 80
|
|
||||||
"0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 90
|
|
||||||
"0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 100
|
|
||||||
"0010 0030 0010 0aa6"; // 104
|
|
||||||
|
|
||||||
sendPronto(prontoTest, PRONTO_ONCE, PRONTO_FALLBACK); // once code
|
|
||||||
sendPronto(prontoTest, PRONTO_REPEAT, PRONTO_FALLBACK); // repeat code
|
|
||||||
sendPronto(prontoTest, PRONTO_ONCE, PRONTO_NOFALLBACK); // once code
|
|
||||||
sendPronto(prontoTest, PRONTO_REPEAT, PRONTO_NOFALLBACK); // repeat code
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // TEST
|
|
||||||
|
|
||||||
#endif // SEND_PRONTO
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
//******************************************************************************
|
|
||||||
// Sources:
|
|
||||||
// http://www.remotecentral.com/features/irdisp2.htm
|
|
||||||
// http://www.hifi-remote.com/wiki/index.php?title=Working_With_Pronto_Hex
|
|
||||||
//******************************************************************************
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#define IRPRONTO
|
|
||||||
#include "IRremoteInt.h" // The Arduino IRremote library defines USECPERTICK
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Source: https://www.google.co.uk/search?q=DENON+MASTER+IR+Hex+Command+Sheet
|
|
||||||
// -> http://assets.denon.com/documentmaster/us/denon%20master%20ir%20hex.xls
|
|
||||||
//
|
|
||||||
char prontoTest[] =
|
|
||||||
"0000 0070 0000 0032 0080 0040 0010 0010 0010 0030 " // 10
|
|
||||||
"0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 20
|
|
||||||
"0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 30
|
|
||||||
"0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 40
|
|
||||||
"0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 50
|
|
||||||
"0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 60
|
|
||||||
"0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 70
|
|
||||||
"0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 " // 80
|
|
||||||
"0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 90
|
|
||||||
"0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 100
|
|
||||||
"0010 0030 0010 0aa6"; // 104
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// This is the longest code we can support
|
|
||||||
#define CODEMAX 200
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// This is the data we pull out of the pronto code
|
|
||||||
typedef
|
|
||||||
struct {
|
|
||||||
int freq; // Carrier frequency (in Hz)
|
|
||||||
int usec; // uSec per tick (based on freq)
|
|
||||||
|
|
||||||
int codeLen; // Length of code
|
|
||||||
uint16_t code[CODEMAX]; // Code in hex
|
|
||||||
|
|
||||||
int onceLen; // Length of "once" transmit
|
|
||||||
uint16_t* once; // Pointer to start within 'code'
|
|
||||||
|
|
||||||
int rptLen; // Length of "repeat" transmit
|
|
||||||
uint16_t* rpt; // Pointer to start within 'code'
|
|
||||||
}
|
|
||||||
pronto_t;
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// From what I have seen, the only time we go over 8-bits is the 'space'
|
|
||||||
// on the end which creates the lead-out/inter-code gap. Assuming I'm right,
|
|
||||||
// we can code this up as a special case and otherwise halve the size of our
|
|
||||||
// data!
|
|
||||||
// Ignoring the first four values (the config data) and the last value
|
|
||||||
// (the lead-out), if you find a protocol that uses values greater than 00fe
|
|
||||||
// we are going to have to revisit this code!
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// So, the 0th byte will be the carrier frequency in Khz (NOT Hz)
|
|
||||||
// " 1st " " " " length of the "once" code
|
|
||||||
// " 2nd " " " " length of the "repeat" code
|
|
||||||
//
|
|
||||||
// Thereafter, odd bytes will be Mark lengths as a multiple of USECPERTICK uS
|
|
||||||
// even " " " Space " " " " " " "
|
|
||||||
//
|
|
||||||
// Any occurence of "FF" in either a Mark or a Space will indicate
|
|
||||||
// "Use the 16-bit FF value" which will also be a multiple of USECPERTICK uS
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// As a point of comparison, the test code (prontoTest[]) is 520 bytes
|
|
||||||
// (yes, more than 0.5KB of our Arduino's precious 32KB) ... after conversion
|
|
||||||
// to pronto hex that goes down to ((520/5)*2) = 208 bytes ... once converted to
|
|
||||||
// our format we are down to ((208/2) -1 -1 +2) = 104 bytes
|
|
||||||
//
|
|
||||||
// In fariness this is still very memory-hungry
|
|
||||||
// ...As a rough guide:
|
|
||||||
// 10 codes cost 1K of memory (this will vary depending on the protocol).
|
|
||||||
//
|
|
||||||
// So if you're building a complex remote control, you will probably need to
|
|
||||||
// keep the codes on an external memory device (not in the Arduino sketch) and
|
|
||||||
// load them as you need them. Hmmm.
|
|
||||||
//
|
|
||||||
// This dictates that "Oscillated Pronto Codes" are probably NOT the way forward
|
|
||||||
//
|
|
||||||
// For example, prontoTest[] happens to be: A 48-bit IR code in Denon format
|
|
||||||
// So we know it starts with 80/40 (Denon header)
|
|
||||||
// and ends with 10/aa6 (Denon leadout)
|
|
||||||
// and all (48) bits in between are either 10/10 (Denon 0)
|
|
||||||
// or 10/30 (Denon 1)
|
|
||||||
// So we could easily store this data in 1-byte ("Denon")
|
|
||||||
// + 1-byte (Length=48)
|
|
||||||
// + 6-bytes (IR code)
|
|
||||||
// At 8-bytes per code, we can store 128 codes in 1KB or memory - that's a lot
|
|
||||||
// better than the 2 (two) we started off with!
|
|
||||||
//
|
|
||||||
// And serendipitously, by reducing the amount of data, our program will run
|
|
||||||
// a LOT faster!
|
|
||||||
//
|
|
||||||
// Again, I repeat, even after you have spent time converting the "Oscillated
|
|
||||||
// Pronto Codes" in to IRremote format, it will be a LOT more memory-hungry
|
|
||||||
// than using sendDenon() (or whichever) ...BUT these codes are easily
|
|
||||||
// available on the internet, so we'll support them!
|
|
||||||
//
|
|
||||||
typedef
|
|
||||||
struct {
|
|
||||||
uint16_t FF;
|
|
||||||
uint8_t code[CODEMAX];
|
|
||||||
}
|
|
||||||
irCode_t;
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
#define DEBUGF(...) printf(__VA_ARGS__)
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// String must be block of 4 hex digits separated with blanks
|
|
||||||
//
|
|
||||||
bool validate (char* cp, int* len)
|
|
||||||
{
|
|
||||||
for (*len = 0; *cp; (*len)++, cp += 4) {
|
|
||||||
byp(&cp);
|
|
||||||
if ( !ishex(cp[0]) || !ishex(cp[1]) ||
|
|
||||||
!ishex(cp[2]) || !ishex(cp[3]) || !isblank(cp[4]) ) return false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// Hex-to-Byte : Decode a hex digit
|
|
||||||
// We assume the character has already been validated
|
|
||||||
//
|
|
||||||
uint8_t htob (char ch)
|
|
||||||
{
|
|
||||||
if ((ch >= '0') && (ch <= '9')) return ch - '0' ;
|
|
||||||
if ((ch >= 'A') && (ch <= 'F')) return ch - 'A' + 10 ;
|
|
||||||
if ((ch >= 'a') && (ch <= 'f')) return ch - 'a' + 10 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// Hex-to-Word : Decode a block of 4 hex digits
|
|
||||||
// We assume the string has already been validated
|
|
||||||
// and the pointer being passed points at the start of a block of 4 hex digits
|
|
||||||
//
|
|
||||||
uint16_t htow (char* cp)
|
|
||||||
{
|
|
||||||
return ( (htob(cp[0]) << 12) | (htob(cp[1]) << 8) |
|
|
||||||
(htob(cp[2]) << 4) | (htob(cp[3]) ) ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// Convert the pronto string in to data
|
|
||||||
//
|
|
||||||
bool decode (char* s, pronto_t* p, irCode_t* ir)
|
|
||||||
{
|
|
||||||
int i, len;
|
|
||||||
char* cp;
|
|
||||||
|
|
||||||
// Validate the Pronto string
|
|
||||||
if (!validate(s, &p->codeLen)) {
|
|
||||||
DEBUGF("Invalid pronto string\n");
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
DEBUGF("Found %d hex codes\n", p->codeLen);
|
|
||||||
|
|
||||||
// Allocate memory to store the decoded string
|
|
||||||
//if (!(p->code = malloc(p->len))) {
|
|
||||||
// DEBUGF("Memory allocation failed\n");
|
|
||||||
// return false ;
|
|
||||||
//}
|
|
||||||
|
|
||||||
// Check in case our code is too long
|
|
||||||
if (p->codeLen > CODEMAX) {
|
|
||||||
DEBUGF("Code too long, edit CODEMAX and recompile\n");
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decode the string
|
|
||||||
cp = s;
|
|
||||||
for (i = 0; i < p->codeLen; i++, cp += 4) {
|
|
||||||
byp(&cp);
|
|
||||||
p->code[i] = htow(cp);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Announce our findings
|
|
||||||
DEBUGF("Input: |%s|\n", s);
|
|
||||||
DEBUGF("Found: |");
|
|
||||||
for (i = 0; i < p->codeLen; i++) DEBUGF("%04x ", p->code[i]) ;
|
|
||||||
DEBUGF("|\n");
|
|
||||||
|
|
||||||
DEBUGF("Form [%04X] : ", p->code[0]);
|
|
||||||
if (p->code[0] == 0x0000) DEBUGF("Oscillated (Learned)\n");
|
|
||||||
else if (p->code[0] == 0x0100) DEBUGF("Unmodulated\n");
|
|
||||||
else DEBUGF("Unknown\n");
|
|
||||||
if (p->code[0] != 0x0000) return false ; // Can only handle Oscillated
|
|
||||||
|
|
||||||
// Calculate the carrier frequency (+/- 10%) & uSecs per pulse
|
|
||||||
// Pronto uses a crystal which generates a timeabse of 0.241246
|
|
||||||
p->freq = (int)(1000000 / (p->code[1] * 0.241246));
|
|
||||||
p->usec = (int)(((1.0 / p->freq) * 1000000) + 0.5);
|
|
||||||
ir->code[0] = p->freq / 1000;
|
|
||||||
DEBUGF("Freq [%04X] : %d Hz (%d uS/pluse) -> %d KHz\n",
|
|
||||||
p->code[1], p->freq, p->usec, ir->code[0]);
|
|
||||||
|
|
||||||
// Set the length & start pointer for the "once" code
|
|
||||||
p->onceLen = p->code[2];
|
|
||||||
p->once = &p->code[4];
|
|
||||||
ir->code[1] = p->onceLen;
|
|
||||||
DEBUGF("Once [%04X] : %d\n", p->code[2], p->onceLen);
|
|
||||||
|
|
||||||
// Set the length & start pointer for the "repeat" code
|
|
||||||
p->rptLen = p->code[3];
|
|
||||||
p->rpt = &p->code[4 + p->onceLen];
|
|
||||||
ir->code[2] = p->rptLen;
|
|
||||||
DEBUGF("Rpt [%04X] : %d\n", p->code[3], p->rptLen);
|
|
||||||
|
|
||||||
// Check everything tallies
|
|
||||||
if (1 + 1 + 1 + 1 + (p->onceLen * 2) + (p->rptLen * 2) != p->codeLen) {
|
|
||||||
DEBUGF("Bad code length\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert the IR data to our new format
|
|
||||||
ir->FF = p->code[p->codeLen - 1];
|
|
||||||
|
|
||||||
len = (p->onceLen * 2) + (p->rptLen * 2);
|
|
||||||
DEBUGF("Encoded: |");
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
if (p->code[i+4] == ir->FF) {
|
|
||||||
ir->code[i+3] = 0xFF;
|
|
||||||
} else if (p->code[i+4] > 0xFE) {
|
|
||||||
DEBUGF("\n%04X : Mark/Space overflow\n", p->code[i+4]);
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
ir->code[i+3] = (p->code[i+4] * p->usec) / USECPERTICK;
|
|
||||||
}
|
|
||||||
DEBUGF("%s%d", !i ? "" : (i&1 ? "," : ", "), ir->code[i+3]);
|
|
||||||
}
|
|
||||||
DEBUGF("|\n");
|
|
||||||
|
|
||||||
ir->FF = (ir->FF * p->usec) / USECPERTICK;
|
|
||||||
DEBUGF("FF -> %d\n", ir->FF);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
//
|
|
||||||
void irDump (irCode_t* ir)
|
|
||||||
{
|
|
||||||
int i, len;
|
|
||||||
|
|
||||||
printf("uint8_t buttonName[%d] = {", len);
|
|
||||||
|
|
||||||
printf("%d,%d, ", (ir->FF >> 8), ir->FF & 0xFF);
|
|
||||||
printf("%d,%d,%d, ", ir->code[0], ir->code[1], ir->code[2]);
|
|
||||||
|
|
||||||
len = (ir->code[1] * 2) + (ir->code[2] * 2);
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
printf("%s%d", !i ? "" : (i&1 ? "," : ", "), ir->code[i+3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("};\n");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
//
|
|
||||||
int main ( )
|
|
||||||
{
|
|
||||||
pronto_t pCode;
|
|
||||||
irCode_t irCode;
|
|
||||||
|
|
||||||
decode(prontoTest, &pCode, &irCode);
|
|
||||||
|
|
||||||
irDump(&irCode);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //0
|
|
||||||
196
irRecv.cpp
196
irRecv.cpp
@@ -1,196 +0,0 @@
|
|||||||
#include "IRremote.h"
|
|
||||||
#include "IRremoteInt.h"
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// Decodes the received IR message
|
|
||||||
// Returns 0 if no data ready, 1 if data ready.
|
|
||||||
// Results of decoding are stored in results
|
|
||||||
//
|
|
||||||
int IRrecv::decode (decode_results *results)
|
|
||||||
{
|
|
||||||
results->rawbuf = irparams.rawbuf;
|
|
||||||
results->rawlen = irparams.rawlen;
|
|
||||||
|
|
||||||
results->overflow = irparams.overflow;
|
|
||||||
|
|
||||||
if (irparams.rcvstate != STATE_STOP) return false ;
|
|
||||||
|
|
||||||
#ifdef DECODE_NEC
|
|
||||||
DBG_PRINTLN("Attempting NEC decode");
|
|
||||||
if (decodeNEC(results)) return true ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DECODE_SONY
|
|
||||||
DBG_PRINTLN("Attempting Sony decode");
|
|
||||||
if (decodeSony(results)) return true ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DECODE_SANYO
|
|
||||||
DBG_PRINTLN("Attempting Sanyo decode");
|
|
||||||
if (decodeSanyo(results)) return true ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DECODE_MITSUBISHI
|
|
||||||
DBG_PRINTLN("Attempting Mitsubishi decode");
|
|
||||||
if (decodeMitsubishi(results)) return true ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DECODE_RC5
|
|
||||||
DBG_PRINTLN("Attempting RC5 decode");
|
|
||||||
if (decodeRC5(results)) return true ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DECODE_RC6
|
|
||||||
DBG_PRINTLN("Attempting RC6 decode");
|
|
||||||
if (decodeRC6(results)) return true ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DECODE_PANASONIC
|
|
||||||
DBG_PRINTLN("Attempting Panasonic decode");
|
|
||||||
if (decodePanasonic(results)) return true ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DECODE_LG
|
|
||||||
DBG_PRINTLN("Attempting LG decode");
|
|
||||||
if (decodeLG(results)) return true ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DECODE_JVC
|
|
||||||
DBG_PRINTLN("Attempting JVC decode");
|
|
||||||
if (decodeJVC(results)) return true ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DECODE_SAMSUNG
|
|
||||||
DBG_PRINTLN("Attempting SAMSUNG decode");
|
|
||||||
if (decodeSAMSUNG(results)) return true ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DECODE_WHYNTER
|
|
||||||
DBG_PRINTLN("Attempting Whynter decode");
|
|
||||||
if (decodeWhynter(results)) return true ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DECODE_AIWA_RC_T501
|
|
||||||
DBG_PRINTLN("Attempting Aiwa RC-T501 decode");
|
|
||||||
if (decodeAiwaRCT501(results)) return true ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DECODE_DENON
|
|
||||||
DBG_PRINTLN("Attempting Denon decode");
|
|
||||||
if (decodeDenon(results)) return true ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// decodeHash returns a hash on any input.
|
|
||||||
// Thus, it needs to be last in the list.
|
|
||||||
// If you add any decodes, add them before this.
|
|
||||||
if (decodeHash(results)) return true ;
|
|
||||||
|
|
||||||
// Throw away and start over
|
|
||||||
resume();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
IRrecv::IRrecv (int recvpin)
|
|
||||||
{
|
|
||||||
irparams.recvpin = recvpin;
|
|
||||||
irparams.blinkflag = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// initialization
|
|
||||||
//
|
|
||||||
void IRrecv::enableIRIn ( )
|
|
||||||
{
|
|
||||||
cli();
|
|
||||||
// Setup pulse clock timer interrupt
|
|
||||||
// Prescale /8 (16M/8 = 0.5 microseconds per tick)
|
|
||||||
// Therefore, the timer interval can range from 0.5 to 128 microseconds
|
|
||||||
// Depending on the reset value (255 to 0)
|
|
||||||
TIMER_CONFIG_NORMAL();
|
|
||||||
|
|
||||||
// Timer2 Overflow Interrupt Enable
|
|
||||||
TIMER_ENABLE_INTR;
|
|
||||||
|
|
||||||
TIMER_RESET;
|
|
||||||
|
|
||||||
sei(); // enable interrupts
|
|
||||||
|
|
||||||
// Initialize state machine variables
|
|
||||||
irparams.rcvstate = STATE_IDLE;
|
|
||||||
irparams.rawlen = 0;
|
|
||||||
|
|
||||||
// Set pin modes
|
|
||||||
pinMode(irparams.recvpin, INPUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// Enable/disable blinking of pin 13 on IR processing
|
|
||||||
//
|
|
||||||
void IRrecv::blink13 (int blinkflag)
|
|
||||||
{
|
|
||||||
irparams.blinkflag = blinkflag;
|
|
||||||
if (blinkflag) pinMode(BLINKLED, OUTPUT) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// Restart the ISR state machine
|
|
||||||
//
|
|
||||||
void IRrecv::resume ( )
|
|
||||||
{
|
|
||||||
irparams.rcvstate = STATE_IDLE;
|
|
||||||
irparams.rawlen = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// hashdecode - decode an arbitrary IR code.
|
|
||||||
// Instead of decoding using a standard encoding scheme
|
|
||||||
// (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value.
|
|
||||||
//
|
|
||||||
// The algorithm: look at the sequence of MARK signals, and see if each one
|
|
||||||
// is shorter (0), the same length (1), or longer (2) than the previous.
|
|
||||||
// Do the same with the SPACE signals. Hash the resulting sequence of 0's,
|
|
||||||
// 1's, and 2's to a 32-bit value. This will give a unique value for each
|
|
||||||
// different code (probably), for most code systems.
|
|
||||||
//
|
|
||||||
// http://arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html
|
|
||||||
//
|
|
||||||
// Compare two tick values, returning 0 if newval is shorter,
|
|
||||||
// 1 if newval is equal, and 2 if newval is longer
|
|
||||||
// Use a tolerance of 20%
|
|
||||||
//
|
|
||||||
int IRrecv::compare (unsigned int oldval, unsigned int newval)
|
|
||||||
{
|
|
||||||
if (newval < oldval * .8) return 0 ;
|
|
||||||
else if (oldval < newval * .8) return 2 ;
|
|
||||||
else return 1 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param
|
|
||||||
// Converts the raw code values into a 32-bit hash code.
|
|
||||||
// Hopefully this code is unique for each button.
|
|
||||||
// This isn't a "real" decoding, just an arbitrary value.
|
|
||||||
//
|
|
||||||
#define FNV_PRIME_32 16777619
|
|
||||||
#define FNV_BASIS_32 2166136261
|
|
||||||
|
|
||||||
long IRrecv::decodeHash (decode_results *results)
|
|
||||||
{
|
|
||||||
long hash = FNV_BASIS_32;
|
|
||||||
|
|
||||||
// Require at least 6 samples to prevent triggering on noise
|
|
||||||
if (results->rawlen < 6) return false ;
|
|
||||||
|
|
||||||
for (int i = 1; (i + 2) < results->rawlen; i++) {
|
|
||||||
int value = compare(results->rawbuf[i], results->rawbuf[i+2]);
|
|
||||||
// Add value into the hash
|
|
||||||
hash = (hash * FNV_PRIME_32) ^ value;
|
|
||||||
}
|
|
||||||
|
|
||||||
results->value = hash;
|
|
||||||
results->bits = 32;
|
|
||||||
results->decode_type = UNKNOWN;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
66
irSend.cpp
66
irSend.cpp
@@ -1,66 +0,0 @@
|
|||||||
#include "IRremote.h"
|
|
||||||
#include "IRremoteInt.h"
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
void IRsend::sendRaw (unsigned int buf[], int len, int hz)
|
|
||||||
{
|
|
||||||
// Set IR carrier frequency
|
|
||||||
enableIROut(hz);
|
|
||||||
|
|
||||||
for (int i = 0; i < len; i++) {
|
|
||||||
if (i & 1) space(buf[i]) ;
|
|
||||||
else mark (buf[i]) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
space(0); // Always end with the LED off
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// Sends an IR mark for the specified number of microseconds.
|
|
||||||
// The mark output is modulated at the PWM frequency.
|
|
||||||
//
|
|
||||||
void IRsend::mark (int time)
|
|
||||||
{
|
|
||||||
TIMER_ENABLE_PWM; // Enable pin 3 PWM output
|
|
||||||
if (time > 0) delayMicroseconds(time);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// Leave pin off for time (given in microseconds)
|
|
||||||
// Sends an IR space for the specified number of microseconds.
|
|
||||||
// A space is no output, so the PWM output is disabled.
|
|
||||||
//
|
|
||||||
void IRsend::space (int time)
|
|
||||||
{
|
|
||||||
TIMER_DISABLE_PWM; // Disable pin 3 PWM output
|
|
||||||
if (time > 0) delayMicroseconds(time);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// Enables IR output. The khz value controls the modulation frequency in kilohertz.
|
|
||||||
// The IR output will be on pin 3 (OC2B).
|
|
||||||
// This routine is designed for 36-40KHz; if you use it for other values, it's up to you
|
|
||||||
// to make sure it gives reasonable results. (Watch out for overflow / underflow / rounding.)
|
|
||||||
// TIMER2 is used in phase-correct PWM mode, with OCR2A controlling the frequency and OCR2B
|
|
||||||
// controlling the duty cycle.
|
|
||||||
// There is no prescaling, so the output frequency is 16MHz / (2 * OCR2A)
|
|
||||||
// To turn the output on and off, we leave the PWM running, but connect and disconnect the output pin.
|
|
||||||
// A few hours staring at the ATmega documentation and this will all make sense.
|
|
||||||
// See my Secrets of Arduino PWM at http://arcfn.com/2009/07/secrets-of-arduino-pwm.html for details.
|
|
||||||
//
|
|
||||||
void IRsend::enableIROut (int khz)
|
|
||||||
{
|
|
||||||
// Disable the Timer2 Interrupt (which is used for receiving IR)
|
|
||||||
TIMER_DISABLE_INTR; //Timer2 Overflow Interrupt
|
|
||||||
|
|
||||||
pinMode(TIMER_PWM_PIN, OUTPUT);
|
|
||||||
digitalWrite(TIMER_PWM_PIN, LOW); // When not sending PWM, we want it low
|
|
||||||
|
|
||||||
// COM2A = 00: disconnect OC2A
|
|
||||||
// COM2B = 00: disconnect OC2B; to send signal set to 10: OC2B non-inverted
|
|
||||||
// WGM2 = 101: phase-correct PWM with OCRA as top
|
|
||||||
// CS2 = 000: no prescaling
|
|
||||||
// The top value for the timer. The modulation frequency will be SYSCLOCK / 2 / OCR2A.
|
|
||||||
TIMER_CONFIG_KHZ(khz);
|
|
||||||
}
|
|
||||||
|
|
||||||
106
ir_Aiwa.cpp
106
ir_Aiwa.cpp
@@ -1,106 +0,0 @@
|
|||||||
#include "IRremote.h"
|
|
||||||
#include "IRremoteInt.h"
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
// AAA IIIII W W AAA
|
|
||||||
// A A I W W A A
|
|
||||||
// AAAAA I W W W AAAAA
|
|
||||||
// A A I W W W A A
|
|
||||||
// A A IIIII WWW A A
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
// Baszed off the RC-T501 RCU
|
|
||||||
// Lirc file http://lirc.sourceforge.net/remotes/aiwa/RC-T501
|
|
||||||
|
|
||||||
#define AIWA_RC_T501_HZ 38
|
|
||||||
#define AIWA_RC_T501_BITS 15
|
|
||||||
#define AIWA_RC_T501_PRE_BITS 26
|
|
||||||
#define AIWA_RC_T501_POST_BITS 1
|
|
||||||
#define AIWA_RC_T501_SUM_BITS (AIWA_RC_T501_PRE_BITS + AIWA_RC_T501_BITS + AIWA_RC_T501_POST_BITS)
|
|
||||||
#define AIWA_RC_T501_HDR_MARK 8800
|
|
||||||
#define AIWA_RC_T501_HDR_SPACE 4500
|
|
||||||
#define AIWA_RC_T501_BIT_MARK 500
|
|
||||||
#define AIWA_RC_T501_ONE_SPACE 600
|
|
||||||
#define AIWA_RC_T501_ZERO_SPACE 1700
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
#if SEND_AIWA_RC_T501
|
|
||||||
void IRsend::sendAiwaRCT501 (int code)
|
|
||||||
{
|
|
||||||
unsigned long pre = 0x0227EEC0; // 26-bits
|
|
||||||
int mask;
|
|
||||||
|
|
||||||
// Set IR carrier frequency
|
|
||||||
enableIROut(AIWA_RC_T501_HZ);
|
|
||||||
|
|
||||||
// Header
|
|
||||||
mark(AIWA_RC_T501_HDR_MARK);
|
|
||||||
space(AIWA_RC_T501_HDR_SPACE);
|
|
||||||
|
|
||||||
// Send "pre" data
|
|
||||||
for (unsigned long mask = 1UL << (26 - 1); mask; mask >>= 1) {
|
|
||||||
mark(AIWA_RC_T501_BIT_MARK);
|
|
||||||
if (pre & mask) space(AIWA_RC_T501_ONE_SPACE) ;
|
|
||||||
else space(AIWA_RC_T501_ZERO_SPACE) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-v- THIS CODE LOOKS LIKE IT MIGHT BE WRONG - CHECK!
|
|
||||||
// it only send 15bits and ignores the top bit
|
|
||||||
// then uses TOPBIT which is 0x80000000 to check the bit code
|
|
||||||
// I suspect TOPBIT should be changed to 0x00008000
|
|
||||||
|
|
||||||
// Skip first code bit
|
|
||||||
code <<= 1;
|
|
||||||
// Send code
|
|
||||||
for (int i = 0; i < 15; i++) {
|
|
||||||
mark(AIWA_RC_T501_BIT_MARK);
|
|
||||||
if (code & 0x80000000) space(AIWA_RC_T501_ONE_SPACE) ;
|
|
||||||
else space(AIWA_RC_T501_ZERO_SPACE) ;
|
|
||||||
code <<= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-^- THIS CODE LOOKS LIKE IT MIGHT BE WRONG - CHECK!
|
|
||||||
|
|
||||||
// POST-DATA, 1 bit, 0x0
|
|
||||||
mark(AIWA_RC_T501_BIT_MARK);
|
|
||||||
space(AIWA_RC_T501_ZERO_SPACE);
|
|
||||||
|
|
||||||
mark(AIWA_RC_T501_BIT_MARK);
|
|
||||||
space(0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
#if DECODE_AIWA_RC_T501
|
|
||||||
bool IRrecv::decodeAiwaRCT501 (decode_results *results)
|
|
||||||
{
|
|
||||||
int data = 0;
|
|
||||||
int offset = 1;
|
|
||||||
|
|
||||||
// Check SIZE
|
|
||||||
if (irparams.rawlen < 2 * (AIWA_RC_T501_SUM_BITS) + 4) return false ;
|
|
||||||
|
|
||||||
// Check HDR Mark/Space
|
|
||||||
if (!MATCH_MARK (results->rawbuf[offset++], AIWA_RC_T501_HDR_MARK )) return false ;
|
|
||||||
if (!MATCH_SPACE(results->rawbuf[offset++], AIWA_RC_T501_HDR_SPACE)) return false ;
|
|
||||||
|
|
||||||
offset += 26; // skip pre-data - optional
|
|
||||||
while(offset < irparams.rawlen - 4) {
|
|
||||||
if (MATCH_MARK(results->rawbuf[offset], AIWA_RC_T501_BIT_MARK)) offset++ ;
|
|
||||||
else return false ;
|
|
||||||
|
|
||||||
// ONE & ZERO
|
|
||||||
if (MATCH_SPACE(results->rawbuf[offset], AIWA_RC_T501_ONE_SPACE)) data = (data << 1) | 1 ;
|
|
||||||
else if (MATCH_SPACE(results->rawbuf[offset], AIWA_RC_T501_ZERO_SPACE)) data = (data << 1) | 0 ;
|
|
||||||
else break ; // End of one & zero detected
|
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
|
|
||||||
results->bits = (offset - 1) / 2;
|
|
||||||
if (results->bits < 42) return false ;
|
|
||||||
|
|
||||||
results->value = data;
|
|
||||||
results->decode_type = AIWA_RC_T501;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
94
ir_Denon.cpp
94
ir_Denon.cpp
@@ -1,94 +0,0 @@
|
|||||||
#include "IRremote.h"
|
|
||||||
#include "IRremoteInt.h"
|
|
||||||
|
|
||||||
// Reverse Engineered by looking at RAW dumps generated by IRremote
|
|
||||||
|
|
||||||
// I have since discovered that Denon publish all their IR codes:
|
|
||||||
// https://www.google.co.uk/search?q=DENON+MASTER+IR+Hex+Command+Sheet
|
|
||||||
// -> http://assets.denon.com/documentmaster/us/denon%20master%20ir%20hex.xls
|
|
||||||
|
|
||||||
// Having looked at the official Denon Pronto sheet and reverse engineered
|
|
||||||
// the timing values from it, it is obvious that Denon have a range of
|
|
||||||
// different timings and protocols ...the values here work for my AVR-3801 Amp!
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
// DDDD EEEEE N N OOO N N
|
|
||||||
// D D E NN N O O NN N
|
|
||||||
// D D EEE N N N O O N N N
|
|
||||||
// D D E N NN O O N NN
|
|
||||||
// DDDD EEEEE N N OOO N N
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#define BITS 14 // The number of bits in the command
|
|
||||||
|
|
||||||
#define HDR_MARK 300 // The length of the Header:Mark
|
|
||||||
#define HDR_SPACE 750 // The lenght of the Header:Space
|
|
||||||
|
|
||||||
#define BIT_MARK 300 // The length of a Bit:Mark
|
|
||||||
#define ONE_SPACE 1800 // The length of a Bit:Space for 1's
|
|
||||||
#define ZERO_SPACE 750 // The length of a Bit:Space for 0's
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
//
|
|
||||||
#if SEND_DENON
|
|
||||||
void IRsend::sendDenon (unsigned long data, int nbits)
|
|
||||||
{
|
|
||||||
// Set IR carrier frequency
|
|
||||||
enableIROut(38);
|
|
||||||
|
|
||||||
// Header
|
|
||||||
mark (HDR_MARK);
|
|
||||||
space(HDR_SPACE);
|
|
||||||
|
|
||||||
// Data
|
|
||||||
for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) {
|
|
||||||
if (data & mask) {
|
|
||||||
mark (BIT_MARK);
|
|
||||||
space(ONE_SPACE);
|
|
||||||
} else {
|
|
||||||
mark (BIT_MARK);
|
|
||||||
space(ZERO_SPACE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Footer
|
|
||||||
mark(BIT_MARK);
|
|
||||||
space(0); // Always end with the LED off
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
//
|
|
||||||
#if DECODE_DENON
|
|
||||||
bool IRrecv::decodeDenon (decode_results *results)
|
|
||||||
{
|
|
||||||
unsigned long data = 0; // Somewhere to build our code
|
|
||||||
int offset = 1; // Skip the Gap reading
|
|
||||||
|
|
||||||
// Check we have the right amount of data
|
|
||||||
if (irparams.rawlen != 1 + 2 + (2 * BITS) + 1) return false ;
|
|
||||||
|
|
||||||
// Check initial Mark+Space match
|
|
||||||
if (!MATCH_MARK (results->rawbuf[offset++], HDR_MARK )) return false ;
|
|
||||||
if (!MATCH_SPACE(results->rawbuf[offset++], HDR_SPACE)) return false ;
|
|
||||||
|
|
||||||
// Read the bits in
|
|
||||||
for (int i = 0; i < BITS; i++) {
|
|
||||||
// Each bit looks like: MARK + SPACE_1 -> 1
|
|
||||||
// or : MARK + SPACE_0 -> 0
|
|
||||||
if (!MATCH_MARK(results->rawbuf[offset++], BIT_MARK)) return false ;
|
|
||||||
|
|
||||||
// IR data is big-endian, so we shuffle it in from the right:
|
|
||||||
if (MATCH_SPACE(results->rawbuf[offset], ONE_SPACE)) data = (data << 1) | 1 ;
|
|
||||||
else if (MATCH_SPACE(results->rawbuf[offset], ZERO_SPACE)) data = (data << 1) | 0 ;
|
|
||||||
else return false ;
|
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Success
|
|
||||||
results->bits = BITS;
|
|
||||||
results->value = data;
|
|
||||||
results->decode_type = DENON;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
53
ir_Dish.cpp
53
ir_Dish.cpp
@@ -1,53 +0,0 @@
|
|||||||
#include "IRremote.h"
|
|
||||||
#include "IRremoteInt.h"
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
// DDDD IIIII SSSS H H
|
|
||||||
// D D I S H H
|
|
||||||
// D D I SSS HHHHH
|
|
||||||
// D D I S H H
|
|
||||||
// DDDD IIIII SSSS H H
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
// Sharp and DISH support by Todd Treece ( http://unionbridge.org/design/ircommand )
|
|
||||||
//
|
|
||||||
// The sned function needs to be repeated 4 times
|
|
||||||
//
|
|
||||||
// Only send the last for characters of the hex.
|
|
||||||
// I.E. Use 0x1C10 instead of 0x0000000000001C10 as listed in the LIRC file.
|
|
||||||
//
|
|
||||||
// Here is the LIRC file I found that seems to match the remote codes from the
|
|
||||||
// oscilloscope:
|
|
||||||
// DISH NETWORK (echostar 301):
|
|
||||||
// http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx
|
|
||||||
|
|
||||||
#define DISH_BITS 16
|
|
||||||
#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
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
#if SEND_DISH
|
|
||||||
void IRsend::sendDISH (unsigned long data, int nbits)
|
|
||||||
{
|
|
||||||
// Set IR carrier frequency
|
|
||||||
enableIROut(56);
|
|
||||||
|
|
||||||
mark(DISH_HDR_MARK);
|
|
||||||
space(DISH_HDR_SPACE);
|
|
||||||
|
|
||||||
for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) {
|
|
||||||
if (data & mask) {
|
|
||||||
mark(DISH_BIT_MARK);
|
|
||||||
space(DISH_ONE_SPACE);
|
|
||||||
} else {
|
|
||||||
mark(DISH_BIT_MARK);
|
|
||||||
space(DISH_ZERO_SPACE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
101
ir_JVC.cpp
101
ir_JVC.cpp
@@ -1,101 +0,0 @@
|
|||||||
#include "IRremote.h"
|
|
||||||
#include "IRremoteInt.h"
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
// JJJJJ V V CCCC
|
|
||||||
// J V V C
|
|
||||||
// J V V C
|
|
||||||
// J J V V C
|
|
||||||
// J V CCCC
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#define JVC_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
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// JVC does NOT repeat by sending a separate code (like NEC does).
|
|
||||||
// The JVC protocol repeats by skipping the header.
|
|
||||||
// To send a JVC repeat signal, send the original code value
|
|
||||||
// and set 'repeat' to true
|
|
||||||
//
|
|
||||||
#if SEND_JVC
|
|
||||||
void IRsend::sendJVC (unsigned long data, int nbits, bool repeat)
|
|
||||||
{
|
|
||||||
// Set IR carrier frequency
|
|
||||||
enableIROut(38);
|
|
||||||
|
|
||||||
// Only send the Header if this is NOT a repeat command
|
|
||||||
if (!repeat){
|
|
||||||
mark(JVC_HDR_MARK);
|
|
||||||
space(JVC_HDR_SPACE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Data
|
|
||||||
for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) {
|
|
||||||
if (data & mask) {
|
|
||||||
mark(JVC_BIT_MARK);
|
|
||||||
space(JVC_ONE_SPACE);
|
|
||||||
} else {
|
|
||||||
mark(JVC_BIT_MARK);
|
|
||||||
space(JVC_ZERO_SPACE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Footer
|
|
||||||
mark(JVC_BIT_MARK);
|
|
||||||
space(0); // Always end with the LED off
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
#if DECODE_JVC
|
|
||||||
bool IRrecv::decodeJVC (decode_results *results)
|
|
||||||
{
|
|
||||||
long data = 0;
|
|
||||||
int offset = 1; // Skip first space
|
|
||||||
|
|
||||||
// Check for repeat
|
|
||||||
if ( (irparams.rawlen - 1 == 33)
|
|
||||||
&& MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK)
|
|
||||||
&& MATCH_MARK(results->rawbuf[irparams.rawlen-1], JVC_BIT_MARK)
|
|
||||||
) {
|
|
||||||
results->bits = 0;
|
|
||||||
results->value = REPEAT;
|
|
||||||
results->decode_type = JVC;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initial mark
|
|
||||||
if (!MATCH_MARK(results->rawbuf[offset++], JVC_HDR_MARK)) return false ;
|
|
||||||
|
|
||||||
if (irparams.rawlen < (2 * JVC_BITS) + 1 ) return false ;
|
|
||||||
|
|
||||||
// Initial space
|
|
||||||
if (!MATCH_SPACE(results->rawbuf[offset++], JVC_HDR_SPACE)) return false ;
|
|
||||||
|
|
||||||
for (int i = 0; i < JVC_BITS; i++) {
|
|
||||||
if (!MATCH_MARK(results->rawbuf[offset++], JVC_BIT_MARK)) return false ;
|
|
||||||
|
|
||||||
if (MATCH_SPACE(results->rawbuf[offset], JVC_ONE_SPACE)) data = (data << 1) | 1 ;
|
|
||||||
else if (MATCH_SPACE(results->rawbuf[offset], JVC_ZERO_SPACE)) data = (data << 1) | 0 ;
|
|
||||||
else return false ;
|
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop bit
|
|
||||||
if (!MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK)) return false ;
|
|
||||||
|
|
||||||
// Success
|
|
||||||
results->bits = JVC_BITS;
|
|
||||||
results->value = data;
|
|
||||||
results->decode_type = JVC;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
54
ir_LG.cpp
54
ir_LG.cpp
@@ -1,54 +0,0 @@
|
|||||||
#include "IRremote.h"
|
|
||||||
#include "IRremoteInt.h"
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
// L GGGG
|
|
||||||
// L G
|
|
||||||
// L G GG
|
|
||||||
// L G G
|
|
||||||
// LLLLL GGG
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#define LG_BITS 28
|
|
||||||
|
|
||||||
#define LG_HDR_MARK 8000
|
|
||||||
#define LG_HDR_SPACE 4000
|
|
||||||
#define LG_BIT_MARK 600
|
|
||||||
#define LG_ONE_SPACE 1600
|
|
||||||
#define LG_ZERO_SPACE 550
|
|
||||||
#define LG_RPT_LENGTH 60000
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
#if DECODE_LG
|
|
||||||
bool IRrecv::decodeLG (decode_results *results)
|
|
||||||
{
|
|
||||||
long data = 0;
|
|
||||||
int offset = 1; // Skip first space
|
|
||||||
|
|
||||||
// Check we have the right amount of data
|
|
||||||
if (irparams.rawlen < (2 * LG_BITS) + 1 ) return false ;
|
|
||||||
|
|
||||||
// Initial mark/space
|
|
||||||
if (!MATCH_MARK(results->rawbuf[offset++], LG_HDR_MARK)) return false ;
|
|
||||||
if (!MATCH_SPACE(results->rawbuf[offset++], LG_HDR_SPACE)) return false ;
|
|
||||||
|
|
||||||
for (int i = 0; i < LG_BITS; i++) {
|
|
||||||
if (!MATCH_MARK(results->rawbuf[offset++], LG_BIT_MARK)) return false ;
|
|
||||||
|
|
||||||
if (MATCH_SPACE(results->rawbuf[offset], LG_ONE_SPACE)) data = (data << 1) | 1 ;
|
|
||||||
else if (MATCH_SPACE(results->rawbuf[offset], LG_ZERO_SPACE)) data = (data << 1) | 0 ;
|
|
||||||
else return false ;
|
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop bit
|
|
||||||
if (!MATCH_MARK(results->rawbuf[offset], LG_BIT_MARK)) return false ;
|
|
||||||
|
|
||||||
// Success
|
|
||||||
results->bits = LG_BITS;
|
|
||||||
results->value = data;
|
|
||||||
results->decode_type = LG;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
#include "IRremote.h"
|
|
||||||
#include "IRremoteInt.h"
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
// MMMMM IIIII TTTTT SSSS U U BBBB IIIII SSSS H H IIIII
|
|
||||||
// M M M I T S U U B B I S H H I
|
|
||||||
// M M M I T SSS U U BBBB I SSS HHHHH I
|
|
||||||
// M M I T S U U B B I S H H I
|
|
||||||
// M M IIIII T SSSS UUU BBBBB IIIII SSSS H H IIIII
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
// Looks like Sony except for timings, 48 chars of data and time/space different
|
|
||||||
|
|
||||||
#define MITSUBISHI_BITS 16
|
|
||||||
|
|
||||||
// Mitsubishi RM 75501
|
|
||||||
// 14200 7 41 7 42 7 42 7 17 7 17 7 18 7 41 7 18 7 17 7 17 7 18 7 41 8 17 7 17 7 18 7 17 7
|
|
||||||
// #define MITSUBISHI_HDR_MARK 250 // seen range 3500
|
|
||||||
#define MITSUBISHI_HDR_SPACE 350 // 7*50+100
|
|
||||||
#define MITSUBISHI_ONE_MARK 1950 // 41*50-100
|
|
||||||
#define MITSUBISHI_ZERO_MARK 750 // 17*50-100
|
|
||||||
// #define MITSUBISHI_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround
|
|
||||||
// #define MITSUBISHI_RPT_LENGTH 45000
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
#if DECODE_MITSUBISHI
|
|
||||||
bool IRrecv::decodeMitsubishi (decode_results *results)
|
|
||||||
{
|
|
||||||
// Serial.print("?!? decoding Mitsubishi:");Serial.print(irparams.rawlen); Serial.print(" want "); Serial.println( 2 * MITSUBISHI_BITS + 2);
|
|
||||||
long data = 0;
|
|
||||||
if (irparams.rawlen < 2 * MITSUBISHI_BITS + 2) return false ;
|
|
||||||
int offset = 0; // Skip first space
|
|
||||||
// Initial space
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// Put this back in for debugging - note can't use #DEBUG as if Debug on we don't see the repeat cos of the delay
|
|
||||||
Serial.print("IR Gap: ");
|
|
||||||
Serial.println( results->rawbuf[offset]);
|
|
||||||
Serial.println( "test against:");
|
|
||||||
Serial.println(results->rawbuf[offset]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// Not seeing double keys from Mitsubishi
|
|
||||||
if (results->rawbuf[offset] < MITSUBISHI_DOUBLE_SPACE_USECS) {
|
|
||||||
// Serial.print("IR Gap found: ");
|
|
||||||
results->bits = 0;
|
|
||||||
results->value = REPEAT;
|
|
||||||
results->decode_type = MITSUBISHI;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
offset++;
|
|
||||||
|
|
||||||
// Typical
|
|
||||||
// 14200 7 41 7 42 7 42 7 17 7 17 7 18 7 41 7 18 7 17 7 17 7 18 7 41 8 17 7 17 7 18 7 17 7
|
|
||||||
|
|
||||||
// Initial Space
|
|
||||||
if (!MATCH_MARK(results->rawbuf[offset], MITSUBISHI_HDR_SPACE)) return false ;
|
|
||||||
offset++;
|
|
||||||
|
|
||||||
while (offset + 1 < irparams.rawlen) {
|
|
||||||
if (MATCH_MARK(results->rawbuf[offset], MITSUBISHI_ONE_MARK)) data = (data << 1) | 1 ;
|
|
||||||
else if (MATCH_MARK(results->rawbuf[offset], MITSUBISHI_ZERO_MARK)) data <<= 1 ;
|
|
||||||
else return false ;
|
|
||||||
offset++;
|
|
||||||
|
|
||||||
if (!MATCH_SPACE(results->rawbuf[offset], MITSUBISHI_HDR_SPACE)) break ;
|
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Success
|
|
||||||
results->bits = (offset - 1) / 2;
|
|
||||||
if (results->bits < MITSUBISHI_BITS) {
|
|
||||||
results->bits = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
results->value = data;
|
|
||||||
results->decode_type = MITSUBISHI;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
98
ir_NEC.cpp
98
ir_NEC.cpp
@@ -1,98 +0,0 @@
|
|||||||
#include "IRremote.h"
|
|
||||||
#include "IRremoteInt.h"
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
// N N EEEEE CCCC
|
|
||||||
// NN N E C
|
|
||||||
// N N N EEE C
|
|
||||||
// N NN E C
|
|
||||||
// N N EEEEE CCCC
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#define NEC_BITS 32
|
|
||||||
#define NEC_HDR_MARK 9000
|
|
||||||
#define NEC_HDR_SPACE 4500
|
|
||||||
#define NEC_BIT_MARK 560
|
|
||||||
#define NEC_ONE_SPACE 1690
|
|
||||||
#define NEC_ZERO_SPACE 560
|
|
||||||
#define NEC_RPT_SPACE 2250
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
#if SEND_NEC
|
|
||||||
void IRsend::sendNEC (unsigned long data, int nbits)
|
|
||||||
{
|
|
||||||
// Set IR carrier frequency
|
|
||||||
enableIROut(38);
|
|
||||||
|
|
||||||
// Header
|
|
||||||
mark(NEC_HDR_MARK);
|
|
||||||
space(NEC_HDR_SPACE);
|
|
||||||
|
|
||||||
// Data
|
|
||||||
for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) {
|
|
||||||
if (data & mask) {
|
|
||||||
mark(NEC_BIT_MARK);
|
|
||||||
space(NEC_ONE_SPACE);
|
|
||||||
} else {
|
|
||||||
mark(NEC_BIT_MARK);
|
|
||||||
space(NEC_ZERO_SPACE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Footer
|
|
||||||
mark(NEC_BIT_MARK);
|
|
||||||
space(0); // Always end with the LED off
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// NECs have a repeat only 4 items long
|
|
||||||
//
|
|
||||||
#if DECODE_NEC
|
|
||||||
bool IRrecv::decodeNEC (decode_results *results)
|
|
||||||
{
|
|
||||||
long data = 0; // We decode in to here; Start with nothing
|
|
||||||
int offset = 1; // Index in to results; Skip first entry!?
|
|
||||||
|
|
||||||
// Check header "mark"
|
|
||||||
if (!MATCH_MARK(results->rawbuf[offset], NEC_HDR_MARK)) return false ;
|
|
||||||
offset++;
|
|
||||||
|
|
||||||
// Check for repeat
|
|
||||||
if ( (irparams.rawlen == 4)
|
|
||||||
&& MATCH_SPACE(results->rawbuf[offset ], NEC_RPT_SPACE)
|
|
||||||
&& MATCH_MARK (results->rawbuf[offset+1], NEC_BIT_MARK )
|
|
||||||
) {
|
|
||||||
results->bits = 0;
|
|
||||||
results->value = REPEAT;
|
|
||||||
results->decode_type = NEC;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check we have enough data
|
|
||||||
if (irparams.rawlen < (2 * NEC_BITS) + 4) return false ;
|
|
||||||
|
|
||||||
// Check header "space"
|
|
||||||
if (!MATCH_SPACE(results->rawbuf[offset], NEC_HDR_SPACE)) return false ;
|
|
||||||
offset++;
|
|
||||||
|
|
||||||
// Build the data
|
|
||||||
for (int i = 0; i < NEC_BITS; i++) {
|
|
||||||
// Check data "mark"
|
|
||||||
if (!MATCH_MARK(results->rawbuf[offset], NEC_BIT_MARK)) return false ;
|
|
||||||
offset++;
|
|
||||||
// Suppend this bit
|
|
||||||
if (MATCH_SPACE(results->rawbuf[offset], NEC_ONE_SPACE )) data = (data << 1) | 1 ;
|
|
||||||
else if (MATCH_SPACE(results->rawbuf[offset], NEC_ZERO_SPACE)) data = (data << 1) | 0 ;
|
|
||||||
else return false ;
|
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Success
|
|
||||||
results->bits = NEC_BITS;
|
|
||||||
results->value = data;
|
|
||||||
results->decode_type = NEC;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
#include "IRremote.h"
|
|
||||||
#include "IRremoteInt.h"
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
// PPPP AAA N N AAA SSSS OOO N N IIIII CCCC
|
|
||||||
// P P A A NN N A A S O O NN N I C
|
|
||||||
// PPPP AAAAA N N N AAAAA SSS O O N N N I C
|
|
||||||
// P A A N NN A A S O O N NN I C
|
|
||||||
// P A A N N A A SSSS OOO N N IIIII CCCC
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#define PANASONIC_BITS 48
|
|
||||||
#define PANASONIC_HDR_MARK 3502
|
|
||||||
#define PANASONIC_HDR_SPACE 1750
|
|
||||||
#define PANASONIC_BIT_MARK 502
|
|
||||||
#define PANASONIC_ONE_SPACE 1244
|
|
||||||
#define PANASONIC_ZERO_SPACE 400
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
#if SEND_PANASONIC
|
|
||||||
void IRsend::sendPanasonic (unsigned int address, unsigned long data)
|
|
||||||
{
|
|
||||||
// Set IR carrier frequency
|
|
||||||
enableIROut(35);
|
|
||||||
|
|
||||||
// Header
|
|
||||||
mark(PANASONIC_HDR_MARK);
|
|
||||||
space(PANASONIC_HDR_SPACE);
|
|
||||||
|
|
||||||
// Address
|
|
||||||
for (unsigned long mask = 1UL << (16 - 1); mask; mask >>= 1) {
|
|
||||||
mark(PANASONIC_BIT_MARK);
|
|
||||||
if (address & mask) space(PANASONIC_ONE_SPACE) ;
|
|
||||||
else space(PANASONIC_ZERO_SPACE) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Data
|
|
||||||
for (unsigned long mask = 1UL << (32 - 1); mask; mask >>= 1) {
|
|
||||||
mark(PANASONIC_BIT_MARK);
|
|
||||||
if (data & mask) space(PANASONIC_ONE_SPACE) ;
|
|
||||||
else space(PANASONIC_ZERO_SPACE) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Footer
|
|
||||||
mark(PANASONIC_BIT_MARK);
|
|
||||||
space(0); // Always end with the LED off
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
#if DECODE_PANASONIC
|
|
||||||
bool IRrecv::decodePanasonic (decode_results *results)
|
|
||||||
{
|
|
||||||
unsigned long long data = 0;
|
|
||||||
int offset = 1;
|
|
||||||
|
|
||||||
if (!MATCH_MARK(results->rawbuf[offset++], PANASONIC_HDR_MARK )) return false ;
|
|
||||||
if (!MATCH_MARK(results->rawbuf[offset++], PANASONIC_HDR_SPACE)) return false ;
|
|
||||||
|
|
||||||
// decode address
|
|
||||||
for (int i = 0; i < PANASONIC_BITS; i++) {
|
|
||||||
if (!MATCH_MARK(results->rawbuf[offset++], PANASONIC_BIT_MARK)) return false ;
|
|
||||||
|
|
||||||
if (MATCH_SPACE(results->rawbuf[offset],PANASONIC_ONE_SPACE )) data = (data << 1) | 1 ;
|
|
||||||
else if (MATCH_SPACE(results->rawbuf[offset],PANASONIC_ZERO_SPACE)) data = (data << 1) | 0 ;
|
|
||||||
else return false ;
|
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
|
|
||||||
results->value = (unsigned long)data;
|
|
||||||
results->address = (unsigned int)(data >> 32);
|
|
||||||
results->decode_type = PANASONIC;
|
|
||||||
results->bits = PANASONIC_BITS;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
205
ir_RC5_RC6.cpp
205
ir_RC5_RC6.cpp
@@ -1,205 +0,0 @@
|
|||||||
#include "IRremote.h"
|
|
||||||
#include "IRremoteInt.h"
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// Gets one undecoded level at a time from the raw buffer.
|
|
||||||
// The RC5/6 decoding is easier if the data is broken into time intervals.
|
|
||||||
// E.g. if the buffer has MARK for 2 time intervals and SPACE for 1,
|
|
||||||
// successive calls to getRClevel will return MARK, MARK, SPACE.
|
|
||||||
// offset and used are updated to keep track of the current position.
|
|
||||||
// t1 is the time interval for a single bit in microseconds.
|
|
||||||
// Returns -1 for error (measured time interval is not a multiple of t1).
|
|
||||||
//
|
|
||||||
int IRrecv::getRClevel (decode_results *results, int *offset, int *used, int t1)
|
|
||||||
{
|
|
||||||
int width;
|
|
||||||
int val;
|
|
||||||
int correction;
|
|
||||||
int avail;
|
|
||||||
|
|
||||||
if (*offset >= results->rawlen) return SPACE ; // After end of recorded buffer, assume SPACE.
|
|
||||||
width = results->rawbuf[*offset];
|
|
||||||
val = ((*offset) % 2) ? MARK : SPACE;
|
|
||||||
correction = (val == MARK) ? MARK_EXCESS : - MARK_EXCESS;
|
|
||||||
|
|
||||||
if (MATCH(width, ( t1) + correction)) avail = 1 ;
|
|
||||||
else if (MATCH(width, (2*t1) + correction)) avail = 2 ;
|
|
||||||
else if (MATCH(width, (3*t1) + correction)) avail = 3 ;
|
|
||||||
else return -1 ;
|
|
||||||
|
|
||||||
(*used)++;
|
|
||||||
if (*used >= avail) {
|
|
||||||
*used = 0;
|
|
||||||
(*offset)++;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG_PRINTLN( (val == MARK) ? "MARK" : "SPACE" );
|
|
||||||
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
// RRRR CCCC 55555
|
|
||||||
// R R C 5
|
|
||||||
// RRRR C 5555
|
|
||||||
// R R C 5
|
|
||||||
// R R CCCC 5555
|
|
||||||
//
|
|
||||||
// NB: First bit must be a one (start bit)
|
|
||||||
//
|
|
||||||
#define MIN_RC5_SAMPLES 11
|
|
||||||
#define RC5_T1 889
|
|
||||||
#define RC5_RPT_LENGTH 46000
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
#if SEND_RC5
|
|
||||||
void IRsend::sendRC5 (unsigned long data, int nbits)
|
|
||||||
{
|
|
||||||
// Set IR carrier frequency
|
|
||||||
enableIROut(36);
|
|
||||||
|
|
||||||
// Start
|
|
||||||
mark(RC5_T1);
|
|
||||||
space(RC5_T1);
|
|
||||||
mark(RC5_T1);
|
|
||||||
|
|
||||||
// Data
|
|
||||||
for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) {
|
|
||||||
if (data & mask) {
|
|
||||||
space(RC5_T1); // 1 is space, then mark
|
|
||||||
mark(RC5_T1);
|
|
||||||
} else {
|
|
||||||
mark(RC5_T1);
|
|
||||||
space(RC5_T1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
space(0); // Always end with the LED off
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
#if DECODE_RC5
|
|
||||||
bool IRrecv::decodeRC5 (decode_results *results)
|
|
||||||
{
|
|
||||||
int nbits;
|
|
||||||
long data = 0;
|
|
||||||
int used = 0;
|
|
||||||
int offset = 1; // Skip gap space
|
|
||||||
|
|
||||||
if (irparams.rawlen < MIN_RC5_SAMPLES + 2) return false ;
|
|
||||||
|
|
||||||
// Get start bits
|
|
||||||
if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return false ;
|
|
||||||
if (getRClevel(results, &offset, &used, RC5_T1) != SPACE) return false ;
|
|
||||||
if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return false ;
|
|
||||||
|
|
||||||
for (nbits = 0; offset < irparams.rawlen; nbits++) {
|
|
||||||
int levelA = getRClevel(results, &offset, &used, RC5_T1);
|
|
||||||
int levelB = getRClevel(results, &offset, &used, RC5_T1);
|
|
||||||
|
|
||||||
if ((levelA == SPACE) && (levelB == MARK )) data = (data << 1) | 1 ;
|
|
||||||
else if ((levelA == MARK ) && (levelB == SPACE)) data = (data << 1) | 0 ;
|
|
||||||
else return false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Success
|
|
||||||
results->bits = nbits;
|
|
||||||
results->value = data;
|
|
||||||
results->decode_type = RC5;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// RRRR CCCC 6666
|
|
||||||
// R R C 6
|
|
||||||
// RRRR C 6666
|
|
||||||
// R R C 6 6
|
|
||||||
// R R CCCC 666
|
|
||||||
//
|
|
||||||
// NB : Caller needs to take care of flipping the toggle bit
|
|
||||||
//
|
|
||||||
#define MIN_RC6_SAMPLES 1
|
|
||||||
#define RC6_HDR_MARK 2666
|
|
||||||
#define RC6_HDR_SPACE 889
|
|
||||||
#define RC6_T1 444
|
|
||||||
#define RC6_RPT_LENGTH 46000
|
|
||||||
|
|
||||||
#if SEND_RC6
|
|
||||||
void IRsend::sendRC6 (unsigned long data, int nbits)
|
|
||||||
{
|
|
||||||
// Set IR carrier frequency
|
|
||||||
enableIROut(36);
|
|
||||||
|
|
||||||
// Header
|
|
||||||
mark(RC6_HDR_MARK);
|
|
||||||
space(RC6_HDR_SPACE);
|
|
||||||
|
|
||||||
// Start bit
|
|
||||||
mark(RC6_T1);
|
|
||||||
space(RC6_T1);
|
|
||||||
|
|
||||||
// Data
|
|
||||||
for (unsigned long i = 1, mask = 1UL << (nbits - 1); mask; i++, mask >>= 1) {
|
|
||||||
// The fourth bit we send is a "double width trailer bit"
|
|
||||||
int t = (i == 4) ? (RC6_T1 * 2) : (RC6_T1) ;
|
|
||||||
if (data & mask) {
|
|
||||||
mark(t);
|
|
||||||
space(t);
|
|
||||||
} else {
|
|
||||||
space(t);
|
|
||||||
mark(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
space(0); // Always end with the LED off
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
#if DECODE_RC6
|
|
||||||
bool IRrecv::decodeRC6 (decode_results *results)
|
|
||||||
{
|
|
||||||
int nbits;
|
|
||||||
long data = 0;
|
|
||||||
int used = 0;
|
|
||||||
int offset = 1; // Skip first space
|
|
||||||
|
|
||||||
if (results->rawlen < MIN_RC6_SAMPLES) return false ;
|
|
||||||
|
|
||||||
// Initial mark
|
|
||||||
if (!MATCH_MARK(results->rawbuf[offset++], RC6_HDR_MARK)) return false ;
|
|
||||||
if (!MATCH_SPACE(results->rawbuf[offset++], RC6_HDR_SPACE)) return false ;
|
|
||||||
|
|
||||||
// Get start bit (1)
|
|
||||||
if (getRClevel(results, &offset, &used, RC6_T1) != MARK) return false ;
|
|
||||||
if (getRClevel(results, &offset, &used, RC6_T1) != SPACE) return false ;
|
|
||||||
|
|
||||||
for (nbits = 0; offset < results->rawlen; nbits++) {
|
|
||||||
int levelA, levelB; // Next two levels
|
|
||||||
|
|
||||||
levelA = getRClevel(results, &offset, &used, RC6_T1);
|
|
||||||
if (nbits == 3) {
|
|
||||||
// T bit is double wide; make sure second half matches
|
|
||||||
if (levelA != getRClevel(results, &offset, &used, RC6_T1)) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
levelB = getRClevel(results, &offset, &used, RC6_T1);
|
|
||||||
if (nbits == 3) {
|
|
||||||
// T bit is double wide; make sure second half matches
|
|
||||||
if (levelB != getRClevel(results, &offset, &used, RC6_T1)) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((levelA == MARK ) && (levelB == SPACE)) data = (data << 1) | 1 ; // inverted compared to RC5
|
|
||||||
else if ((levelA == SPACE) && (levelB == MARK )) data = (data << 1) | 0 ; // ...
|
|
||||||
else return false ; // Error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Success
|
|
||||||
results->bits = nbits;
|
|
||||||
results->value = data;
|
|
||||||
results->decode_type = RC6;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
#include "IRremote.h"
|
|
||||||
#include "IRremoteInt.h"
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
// SSSS AAA MMM SSSS U U N N GGGG
|
|
||||||
// S A A M M M S U U NN N G
|
|
||||||
// SSS AAAAA M M M SSS U U N N N G GG
|
|
||||||
// S A A M M S U U N NN G G
|
|
||||||
// SSSS A A M M SSSS UUU N N GGG
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#define SAMSUNG_BITS 32
|
|
||||||
#define SAMSUNG_HDR_MARK 5000
|
|
||||||
#define SAMSUNG_HDR_SPACE 5000
|
|
||||||
#define SAMSUNG_BIT_MARK 560
|
|
||||||
#define SAMSUNG_ONE_SPACE 1600
|
|
||||||
#define SAMSUNG_ZERO_SPACE 560
|
|
||||||
#define SAMSUNG_RPT_SPACE 2250
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
#if SEND_SAMSUNG
|
|
||||||
void IRsend::sendSAMSUNG (unsigned long data, int nbits)
|
|
||||||
{
|
|
||||||
// Set IR carrier frequency
|
|
||||||
enableIROut(38);
|
|
||||||
|
|
||||||
// Header
|
|
||||||
mark(SAMSUNG_HDR_MARK);
|
|
||||||
space(SAMSUNG_HDR_SPACE);
|
|
||||||
|
|
||||||
// Data
|
|
||||||
for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) {
|
|
||||||
if (data & mask) {
|
|
||||||
mark(SAMSUNG_BIT_MARK);
|
|
||||||
space(SAMSUNG_ONE_SPACE);
|
|
||||||
} else {
|
|
||||||
mark(SAMSUNG_BIT_MARK);
|
|
||||||
space(SAMSUNG_ZERO_SPACE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Footer
|
|
||||||
mark(SAMSUNG_BIT_MARK);
|
|
||||||
space(0); // Always end with the LED off
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// SAMSUNGs have a repeat only 4 items long
|
|
||||||
//
|
|
||||||
#if DECODE_SAMSUNG
|
|
||||||
bool IRrecv::decodeSAMSUNG (decode_results *results)
|
|
||||||
{
|
|
||||||
long data = 0;
|
|
||||||
int offset = 1; // Skip first space
|
|
||||||
|
|
||||||
// Initial mark
|
|
||||||
if (!MATCH_MARK(results->rawbuf[offset], SAMSUNG_HDR_MARK)) return false ;
|
|
||||||
offset++;
|
|
||||||
|
|
||||||
// Check for repeat
|
|
||||||
if ( (irparams.rawlen == 4)
|
|
||||||
&& MATCH_SPACE(results->rawbuf[offset], SAMSUNG_RPT_SPACE)
|
|
||||||
&& MATCH_MARK(results->rawbuf[offset+1], SAMSUNG_BIT_MARK)
|
|
||||||
) {
|
|
||||||
results->bits = 0;
|
|
||||||
results->value = REPEAT;
|
|
||||||
results->decode_type = SAMSUNG;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (irparams.rawlen < (2 * SAMSUNG_BITS) + 4) return false ;
|
|
||||||
|
|
||||||
// Initial space
|
|
||||||
if (!MATCH_SPACE(results->rawbuf[offset++], SAMSUNG_HDR_SPACE)) return false ;
|
|
||||||
|
|
||||||
for (int i = 0; i < SAMSUNG_BITS; i++) {
|
|
||||||
if (!MATCH_MARK(results->rawbuf[offset++], SAMSUNG_BIT_MARK)) return false ;
|
|
||||||
|
|
||||||
if (MATCH_SPACE(results->rawbuf[offset], SAMSUNG_ONE_SPACE)) data = (data << 1) | 1 ;
|
|
||||||
else if (MATCH_SPACE(results->rawbuf[offset], SAMSUNG_ZERO_SPACE)) data = (data << 1) | 0 ;
|
|
||||||
else return false ;
|
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Success
|
|
||||||
results->bits = SAMSUNG_BITS;
|
|
||||||
results->value = data;
|
|
||||||
results->decode_type = SAMSUNG;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
76
ir_Sanyo.cpp
76
ir_Sanyo.cpp
@@ -1,76 +0,0 @@
|
|||||||
#include "IRremote.h"
|
|
||||||
#include "IRremoteInt.h"
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
// SSSS AAA N N Y Y OOO
|
|
||||||
// S A A NN N Y Y O O
|
|
||||||
// SSS AAAAA N N N Y O O
|
|
||||||
// S A A N NN Y O O
|
|
||||||
// SSSS A A N N Y OOO
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
// I think this is a Sanyo decoder: Serial = SA 8650B
|
|
||||||
// Looks like Sony except for timings, 48 chars of data and time/space different
|
|
||||||
|
|
||||||
#define SANYO_BITS 12
|
|
||||||
#define SANYO_HDR_MARK 3500 // seen range 3500
|
|
||||||
#define SANYO_HDR_SPACE 950 // seen 950
|
|
||||||
#define SANYO_ONE_MARK 2400 // seen 2400
|
|
||||||
#define SANYO_ZERO_MARK 700 // seen 700
|
|
||||||
#define SANYO_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround
|
|
||||||
#define SANYO_RPT_LENGTH 45000
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
#if DECODE_SANYO
|
|
||||||
bool IRrecv::decodeSanyo (decode_results *results)
|
|
||||||
{
|
|
||||||
long data = 0;
|
|
||||||
int offset = 0; // Skip first space <-- CHECK THIS!
|
|
||||||
|
|
||||||
if (irparams.rawlen < (2 * SANYO_BITS) + 2) return false ;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// Put this back in for debugging - note can't use #DEBUG as if Debug on we don't see the repeat cos of the delay
|
|
||||||
Serial.print("IR Gap: ");
|
|
||||||
Serial.println( results->rawbuf[offset]);
|
|
||||||
Serial.println( "test against:");
|
|
||||||
Serial.println(results->rawbuf[offset]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Initial space
|
|
||||||
if (results->rawbuf[offset] < SANYO_DOUBLE_SPACE_USECS) {
|
|
||||||
//Serial.print("IR Gap found: ");
|
|
||||||
results->bits = 0;
|
|
||||||
results->value = REPEAT;
|
|
||||||
results->decode_type = SANYO;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
offset++;
|
|
||||||
|
|
||||||
// Initial mark
|
|
||||||
if (!MATCH_MARK(results->rawbuf[offset++], SANYO_HDR_MARK)) return false ;
|
|
||||||
|
|
||||||
// Skip Second Mark
|
|
||||||
if (!MATCH_MARK(results->rawbuf[offset++], SANYO_HDR_MARK)) return false ;
|
|
||||||
|
|
||||||
while (offset + 1 < irparams.rawlen) {
|
|
||||||
if (!MATCH_SPACE(results->rawbuf[offset++], SANYO_HDR_SPACE)) break ;
|
|
||||||
|
|
||||||
if (MATCH_MARK(results->rawbuf[offset], SANYO_ONE_MARK)) data = (data << 1) | 1 ;
|
|
||||||
else if (MATCH_MARK(results->rawbuf[offset], SANYO_ZERO_MARK)) data = (data << 1) | 0 ;
|
|
||||||
else return false ;
|
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Success
|
|
||||||
results->bits = (offset - 1) / 2;
|
|
||||||
if (results->bits < 12) {
|
|
||||||
results->bits = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
results->value = data;
|
|
||||||
results->decode_type = SANYO;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
71
ir_Sharp.cpp
71
ir_Sharp.cpp
@@ -1,71 +0,0 @@
|
|||||||
#include "IRremote.h"
|
|
||||||
#include "IRremoteInt.h"
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
// SSSS H H AAA RRRR PPPP
|
|
||||||
// S H H A A R R P P
|
|
||||||
// SSS HHHHH AAAAA RRRR PPPP
|
|
||||||
// S H H A A R R P
|
|
||||||
// SSSS H H A A R R P
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
// Sharp and DISH support by Todd Treece: http://unionbridge.org/design/ircommand
|
|
||||||
//
|
|
||||||
// The send function has the necessary repeat built in because of the need to
|
|
||||||
// invert the signal.
|
|
||||||
//
|
|
||||||
// Sharp protocol documentation:
|
|
||||||
// http://www.sbprojects.com/knowledge/ir/sharp.htm
|
|
||||||
//
|
|
||||||
// Here is the LIRC file I found that seems to match the remote codes from the
|
|
||||||
// oscilloscope:
|
|
||||||
// Sharp LCD TV:
|
|
||||||
// http://lirc.sourceforge.net/remotes/sharp/GA538WJSA
|
|
||||||
|
|
||||||
#define SHARP_BITS 15
|
|
||||||
#define SHARP_BIT_MARK 245
|
|
||||||
#define SHARP_ONE_SPACE 1805
|
|
||||||
#define SHARP_ZERO_SPACE 795
|
|
||||||
#define SHARP_GAP 600000
|
|
||||||
#define SHARP_RPT_SPACE 3000
|
|
||||||
|
|
||||||
#define SHARP_TOGGLE_MASK 0x3FF
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
#if SEND_SHARP
|
|
||||||
void IRsend::sendSharpRaw (unsigned long data, int nbits)
|
|
||||||
{
|
|
||||||
enableIROut(38);
|
|
||||||
|
|
||||||
// Sending codes in bursts of 3 (normal, inverted, normal) makes transmission
|
|
||||||
// much more reliable. That's the exact behaviour of CD-S6470 remote control.
|
|
||||||
for (int n = 0; n < 3; n++) {
|
|
||||||
for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) {
|
|
||||||
if (data & mask) {
|
|
||||||
mark(SHARP_BIT_MARK);
|
|
||||||
space(SHARP_ONE_SPACE);
|
|
||||||
} else {
|
|
||||||
mark(SHARP_BIT_MARK);
|
|
||||||
space(SHARP_ZERO_SPACE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mark(SHARP_BIT_MARK);
|
|
||||||
space(SHARP_ZERO_SPACE);
|
|
||||||
delay(40);
|
|
||||||
|
|
||||||
data = data ^ SHARP_TOGGLE_MASK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
// Sharp send compatible with data obtained through decodeSharp()
|
|
||||||
// ^^^^^^^^^^^^^ FUNCTION MISSING!
|
|
||||||
//
|
|
||||||
#if SEND_SHARP
|
|
||||||
void IRsend::sendSharp (unsigned int address, unsigned int command)
|
|
||||||
{
|
|
||||||
sendSharpRaw((address << 10) | (command << 2) | 2, SHARP_BITS);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
95
ir_Sony.cpp
95
ir_Sony.cpp
@@ -1,95 +0,0 @@
|
|||||||
#include "IRremote.h"
|
|
||||||
#include "IRremoteInt.h"
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
// SSSS OOO N N Y Y
|
|
||||||
// S O O NN N Y Y
|
|
||||||
// SSS O O N N N Y
|
|
||||||
// S O O N NN Y
|
|
||||||
// SSSS OOO N N Y
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#define SONY_BITS 12
|
|
||||||
#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 SONY_DOUBLE_SPACE_USECS 500 // usually ssee 713 - not using ticks as get number wrapround
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
#if SEND_SONY
|
|
||||||
void IRsend::sendSony (unsigned long data, int nbits)
|
|
||||||
{
|
|
||||||
// Set IR carrier frequency
|
|
||||||
enableIROut(40);
|
|
||||||
|
|
||||||
// Header
|
|
||||||
mark(SONY_HDR_MARK);
|
|
||||||
space(SONY_HDR_SPACE);
|
|
||||||
|
|
||||||
// Data
|
|
||||||
for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) {
|
|
||||||
if (data & mask) {
|
|
||||||
mark(SONY_ONE_MARK);
|
|
||||||
space(SONY_HDR_SPACE);
|
|
||||||
} else {
|
|
||||||
mark(SONY_ZERO_MARK);
|
|
||||||
space(SONY_HDR_SPACE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We will have ended with LED off
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
#if DECODE_SONY
|
|
||||||
bool IRrecv::decodeSony (decode_results *results)
|
|
||||||
{
|
|
||||||
long data = 0;
|
|
||||||
int offset = 0; // Dont skip first space, check its size
|
|
||||||
|
|
||||||
if (irparams.rawlen < (2 * SONY_BITS) + 2) return false ;
|
|
||||||
|
|
||||||
// Some Sony's deliver repeats fast after first
|
|
||||||
// unfortunately can't spot difference from of repeat from two fast clicks
|
|
||||||
if (results->rawbuf[offset] < SONY_DOUBLE_SPACE_USECS) {
|
|
||||||
// Serial.print("IR Gap found: ");
|
|
||||||
results->bits = 0;
|
|
||||||
results->value = REPEAT;
|
|
||||||
|
|
||||||
# ifdef DECODE_SANYO
|
|
||||||
results->decode_type = SANYO;
|
|
||||||
# else
|
|
||||||
results->decode_type = UNKNOWN;
|
|
||||||
# endif
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
offset++;
|
|
||||||
|
|
||||||
// Initial mark
|
|
||||||
if (!MATCH_MARK(results->rawbuf[offset++], SONY_HDR_MARK)) return false ;
|
|
||||||
|
|
||||||
while (offset + 1 < irparams.rawlen) {
|
|
||||||
if (!MATCH_SPACE(results->rawbuf[offset++], SONY_HDR_SPACE)) break ;
|
|
||||||
|
|
||||||
if (MATCH_MARK(results->rawbuf[offset], SONY_ONE_MARK)) data = (data << 1) | 1 ;
|
|
||||||
else if (MATCH_MARK(results->rawbuf[offset], SONY_ZERO_MARK)) data = (data << 1) | 0 ;
|
|
||||||
else return false ;
|
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Success
|
|
||||||
results->bits = (offset - 1) / 2;
|
|
||||||
if (results->bits < 12) {
|
|
||||||
results->bits = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
results->value = data;
|
|
||||||
results->decode_type = SONY;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
179
ir_Template.cpp
179
ir_Template.cpp
@@ -1,179 +0,0 @@
|
|||||||
/*
|
|
||||||
Assuming the protocol we are adding is for the (imaginary) manufacturer: Shuzu
|
|
||||||
|
|
||||||
Our fantasy protocol is a standard protocol, so we can use this standard
|
|
||||||
template without too much work. Some protocols are quite unique and will require
|
|
||||||
considerably more work in this file! It is way beyond the scope of this text to
|
|
||||||
explain how to reverse engineer "unusual" IR protocols. But, unless you own an
|
|
||||||
oscilloscope, the starting point is probably to use the rawDump.ino sketch and
|
|
||||||
try to spot the pattern!
|
|
||||||
|
|
||||||
Before you start, make sure the IR library is working OK:
|
|
||||||
# Open up the Arduino IDE
|
|
||||||
# Load up the rawDump.ino example sketch
|
|
||||||
# Run it
|
|
||||||
|
|
||||||
Now we can start to add our new protocol...
|
|
||||||
|
|
||||||
1. Copy this file to : ir_Shuzu.cpp
|
|
||||||
|
|
||||||
2. Replace all occurrences of "Shuzu" with the name of your protocol.
|
|
||||||
|
|
||||||
3. Tweak the #defines to suit your protocol.
|
|
||||||
|
|
||||||
4. If you're lucky, tweaking the #defines will make the default send() function
|
|
||||||
work.
|
|
||||||
|
|
||||||
5. Again, if you're lucky, tweaking the #defines will have made the default
|
|
||||||
decode() function work.
|
|
||||||
|
|
||||||
You have written the code to support your new protocol!
|
|
||||||
|
|
||||||
Now you must do a few things to add it to the IRremote system:
|
|
||||||
|
|
||||||
1. Open IRremote.h and make the following changes:
|
|
||||||
REMEMEBER to change occurences of "SHUZU" with the name of your protocol
|
|
||||||
|
|
||||||
A. At the top, in the section "Supported Protocols", add:
|
|
||||||
#define DECODE_SHUZU 1
|
|
||||||
#define SEND_SHUZU 1
|
|
||||||
|
|
||||||
B. In the section "enumerated list of all supported formats", add:
|
|
||||||
SHUZU,
|
|
||||||
to the end of the list (notice there is a comma after the protocol name)
|
|
||||||
|
|
||||||
C. Further down in "Main class for receiving IR", add:
|
|
||||||
//......................................................................
|
|
||||||
#if DECODE_SHUZU
|
|
||||||
bool decodeShuzu (decode_results *results) ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
D. Further down in "Main class for sending IR", add:
|
|
||||||
//......................................................................
|
|
||||||
#if SEND_SHUZU
|
|
||||||
void sendShuzu (unsigned long data, int nbits) ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
E. Save your changes and close the file
|
|
||||||
|
|
||||||
2. Now open irRecv.cpp and make the following change:
|
|
||||||
|
|
||||||
A. In the function IRrecv::decode(), add:
|
|
||||||
#ifdef DECODE_NEC
|
|
||||||
DBG_PRINTLN("Attempting Shuzu decode");
|
|
||||||
if (decodeShuzu(results)) return true ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
B. Save your changes and close the file
|
|
||||||
|
|
||||||
You will probably want to add your new protocol to the example sketch
|
|
||||||
|
|
||||||
3. Open MyDocuments\Arduino\libraries\IRremote\examples\IRrecvDumpV2.ino
|
|
||||||
|
|
||||||
A. In the encoding() function, add:
|
|
||||||
case SHUZU: Serial.print("SHUZU"); break ;
|
|
||||||
|
|
||||||
Now open the Arduino IDE, load up the rawDump.ino sketch, and run it.
|
|
||||||
Hopefully it will compile and upload.
|
|
||||||
If it doesn't, you've done something wrong. Check your work.
|
|
||||||
If you can't get it to work - seek help from somewhere.
|
|
||||||
|
|
||||||
If you get this far, I will assume you have successfully added your new protocol
|
|
||||||
There is one last thing to do.
|
|
||||||
|
|
||||||
1. Delete this giant instructional comment.
|
|
||||||
|
|
||||||
2. Send a copy of your work to us so we can include it in the library and
|
|
||||||
others may benefit from your hard work and maybe even write a song about how
|
|
||||||
great you are for helping them! :)
|
|
||||||
|
|
||||||
Regards,
|
|
||||||
BlueChip
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "IRremote.h"
|
|
||||||
#include "IRremoteInt.h"
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// S H U Z U
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#define BITS 32 // The number of bits in the command
|
|
||||||
|
|
||||||
#define HDR_MARK 1000 // The length of the Header:Mark
|
|
||||||
#define HDR_SPACE 2000 // The lenght of the Header:Space
|
|
||||||
|
|
||||||
#define BIT_MARK 3000 // The length of a Bit:Mark
|
|
||||||
#define ONE_SPACE 4000 // The length of a Bit:Space for 1's
|
|
||||||
#define ZERO_SPACE 5000 // The length of a Bit:Space for 0's
|
|
||||||
|
|
||||||
#define OTHER 1234 // Other things you may need to define
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
//
|
|
||||||
#if SEND_SHUZU
|
|
||||||
void IRsend::sendShuzu (unsigned long data, int nbits)
|
|
||||||
{
|
|
||||||
// Set IR carrier frequency
|
|
||||||
enableIROut(38);
|
|
||||||
|
|
||||||
// Header
|
|
||||||
mark (HDR_MARK);
|
|
||||||
space(HDR_SPACE);
|
|
||||||
|
|
||||||
// Data
|
|
||||||
for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) {
|
|
||||||
if (data & mask) {
|
|
||||||
mark (BIT_MARK);
|
|
||||||
space(ONE_SPACE);
|
|
||||||
} else {
|
|
||||||
mark (BIT_MARK);
|
|
||||||
space(ZERO_SPACE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Footer
|
|
||||||
mark(BIT_MARK);
|
|
||||||
space(0); // Always end with the LED off
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
//
|
|
||||||
#if DECODE_SHUZU
|
|
||||||
bool IRrecv::decodeShuzu (decode_results *results)
|
|
||||||
{
|
|
||||||
unsigned long data = 0; // Somewhere to build our code
|
|
||||||
int offset = 1; // Skip the Gap reading
|
|
||||||
|
|
||||||
// Check we have the right amount of data
|
|
||||||
if (irparams.rawlen != 1 + 2 + (2 * BITS) + 1) return false ;
|
|
||||||
|
|
||||||
// Check initial Mark+Space match
|
|
||||||
if (!MATCH_MARK (results->rawbuf[offset++], HDR_MARK )) return false ;
|
|
||||||
if (!MATCH_SPACE(results->rawbuf[offset++], HDR_SPACE)) return false ;
|
|
||||||
|
|
||||||
// Read the bits in
|
|
||||||
for (int i = 0; i < SHUZU_BITS; i++) {
|
|
||||||
// Each bit looks like: MARK + SPACE_1 -> 1
|
|
||||||
// or : MARK + SPACE_0 -> 0
|
|
||||||
if (!MATCH_MARK(results->rawbuf[offset++], BIT_MARK)) return false ;
|
|
||||||
|
|
||||||
// IR data is big-endian, so we shuffle it in from the right:
|
|
||||||
if (MATCH_SPACE(results->rawbuf[offset], ONE_SPACE)) data = (data << 1) | 1 ;
|
|
||||||
else if (MATCH_SPACE(results->rawbuf[offset], ZERO_SPACE)) data = (data << 1) | 0 ;
|
|
||||||
else return false ;
|
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Success
|
|
||||||
results->bits = BITS;
|
|
||||||
results->value = data;
|
|
||||||
results->decode_type = SHUZU;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
#include "IRremote.h"
|
|
||||||
#include "IRremoteInt.h"
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
// W W H H Y Y N N TTTTT EEEEE RRRRR
|
|
||||||
// W W H H Y Y NN N T E R R
|
|
||||||
// W W W HHHHH Y N N N T EEE RRRR
|
|
||||||
// W W W H H Y N NN T E R R
|
|
||||||
// WWW H H Y N N T EEEEE R R
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#define WHYNTER_BITS 32
|
|
||||||
#define WHYNTER_HDR_MARK 2850
|
|
||||||
#define WHYNTER_HDR_SPACE 2850
|
|
||||||
#define WHYNTER_BIT_MARK 750
|
|
||||||
#define WHYNTER_ONE_MARK 750
|
|
||||||
#define WHYNTER_ONE_SPACE 2150
|
|
||||||
#define WHYNTER_ZERO_MARK 750
|
|
||||||
#define WHYNTER_ZERO_SPACE 750
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
#if SEND_WHYNTER
|
|
||||||
void IRsend::sendWhynter (unsigned long data, int nbits)
|
|
||||||
{
|
|
||||||
// Set IR carrier frequency
|
|
||||||
enableIROut(38);
|
|
||||||
|
|
||||||
// Start
|
|
||||||
mark(WHYNTER_ZERO_MARK);
|
|
||||||
space(WHYNTER_ZERO_SPACE);
|
|
||||||
|
|
||||||
// Header
|
|
||||||
mark(WHYNTER_HDR_MARK);
|
|
||||||
space(WHYNTER_HDR_SPACE);
|
|
||||||
|
|
||||||
// Data
|
|
||||||
for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) {
|
|
||||||
if (data & mask) {
|
|
||||||
mark(WHYNTER_ONE_MARK);
|
|
||||||
space(WHYNTER_ONE_SPACE);
|
|
||||||
} else {
|
|
||||||
mark(WHYNTER_ZERO_MARK);
|
|
||||||
space(WHYNTER_ZERO_SPACE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Footer
|
|
||||||
mark(WHYNTER_ZERO_MARK);
|
|
||||||
space(WHYNTER_ZERO_SPACE); // Always end with the LED off
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//+=============================================================================
|
|
||||||
#if DECODE_WHYNTER
|
|
||||||
bool IRrecv::decodeWhynter (decode_results *results)
|
|
||||||
{
|
|
||||||
long data = 0;
|
|
||||||
int offset = 1; // skip initial space
|
|
||||||
|
|
||||||
// Check we have the right amount of data
|
|
||||||
if (irparams.rawlen < (2 * WHYNTER_BITS) + 6) return false ;
|
|
||||||
|
|
||||||
// Sequence begins with a bit mark and a zero space
|
|
||||||
if (!MATCH_MARK (results->rawbuf[offset++], WHYNTER_BIT_MARK )) return false ;
|
|
||||||
if (!MATCH_SPACE(results->rawbuf[offset++], WHYNTER_ZERO_SPACE)) return false ;
|
|
||||||
|
|
||||||
// header mark and space
|
|
||||||
if (!MATCH_MARK (results->rawbuf[offset++], WHYNTER_HDR_MARK )) return false ;
|
|
||||||
if (!MATCH_SPACE(results->rawbuf[offset++], WHYNTER_HDR_SPACE)) return false ;
|
|
||||||
|
|
||||||
// data bits
|
|
||||||
for (int i = 0; i < WHYNTER_BITS; i++) {
|
|
||||||
if (!MATCH_MARK(results->rawbuf[offset++], WHYNTER_BIT_MARK)) return false ;
|
|
||||||
|
|
||||||
if (MATCH_SPACE(results->rawbuf[offset], WHYNTER_ONE_SPACE )) data = (data << 1) | 1 ;
|
|
||||||
else if (MATCH_SPACE(results->rawbuf[offset], WHYNTER_ZERO_SPACE)) data = (data << 1) | 0 ;
|
|
||||||
else return false ;
|
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// trailing mark
|
|
||||||
if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_BIT_MARK)) return false ;
|
|
||||||
|
|
||||||
// Success
|
|
||||||
results->bits = WHYNTER_BITS;
|
|
||||||
results->value = data;
|
|
||||||
results->decode_type = WHYNTER;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -48,6 +48,6 @@ SHARP LITERAL1
|
|||||||
PANASONIC LITERAL1
|
PANASONIC LITERAL1
|
||||||
JVC LITERAL1
|
JVC LITERAL1
|
||||||
LG LITERAL1
|
LG LITERAL1
|
||||||
AIWA_RC_T501 LITERAL1
|
SHARP LITERAL1
|
||||||
UNKNOWN LITERAL1
|
UNKNOWN LITERAL1
|
||||||
REPEAT LITERAL1
|
REPEAT LITERAL1
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
name=IRremote
|
|
||||||
version=1.0
|
|
||||||
author=shirriff
|
|
||||||
maintainer=shirriff
|
|
||||||
sentence=Send and receive infrared signals with multiple protocols
|
|
||||||
paragraph=Send and receive infrared signals with multiple protocols
|
|
||||||
category=Signal Input/Output
|
|
||||||
url=https://github.com/shirriff/Arduino-IRremote.git
|
|
||||||
architectures=*
|
|
||||||
Reference in New Issue
Block a user