Update IR lib/sensor to use the latest IR_Remote fork by Chris Young (IRLib)
https://github.com/cyborg5/IRLib
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
||||
# Custom for Visual Studio
|
||||
*.cs diff=csharp
|
||||
*.sln merge=union
|
||||
*.csproj merge=union
|
||||
*.vbproj merge=union
|
||||
*.fsproj merge=union
|
||||
*.dbproj merge=union
|
||||
|
||||
# Standard to msysgit
|
||||
*.doc diff=astextplain
|
||||
*.DOC diff=astextplain
|
||||
*.docx diff=astextplain
|
||||
*.DOCX diff=astextplain
|
||||
*.dot diff=astextplain
|
||||
*.DOT diff=astextplain
|
||||
*.pdf diff=astextplain
|
||||
*.PDF diff=astextplain
|
||||
*.rtf diff=astextplain
|
||||
*.RTF diff=astextplain
|
||||
@@ -0,0 +1,215 @@
|
||||
#################
|
||||
## Eclipse
|
||||
#################
|
||||
|
||||
*.pydevproject
|
||||
.project
|
||||
.metadata
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.classpath
|
||||
.settings/
|
||||
.loadpath
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# CDT-specific
|
||||
.cproject
|
||||
|
||||
# PDT-specific
|
||||
.buildpath
|
||||
|
||||
|
||||
#################
|
||||
## Visual Studio
|
||||
#################
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.sln.docstates
|
||||
|
||||
# Build results
|
||||
|
||||
[Dd]ebug/
|
||||
[Rr]elease/
|
||||
x64/
|
||||
build/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.log
|
||||
*.scc
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
*.ncrunch*
|
||||
.*crunch*.local.xml
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.Publish.xml
|
||||
*.pubxml
|
||||
|
||||
# NuGet Packages Directory
|
||||
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
|
||||
#packages/
|
||||
|
||||
# Windows Azure Build Output
|
||||
csx
|
||||
*.build.csdef
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
|
||||
# Others
|
||||
sql/
|
||||
*.Cache
|
||||
ClientBin/
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.[Pp]ublish.xml
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file to a newer
|
||||
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
App_Data/*.mdf
|
||||
App_Data/*.ldf
|
||||
|
||||
#############
|
||||
## Windows detritus
|
||||
#############
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Mac crap
|
||||
.DS_Store
|
||||
|
||||
|
||||
#############
|
||||
## Python
|
||||
#############
|
||||
|
||||
*.py[co]
|
||||
|
||||
# Packages
|
||||
*.egg
|
||||
*.egg-info
|
||||
dist/
|
||||
build/
|
||||
eggs/
|
||||
parts/
|
||||
var/
|
||||
sdist/
|
||||
develop-eggs/
|
||||
.installed.cfg
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
.coverage
|
||||
.tox
|
||||
|
||||
#Translations
|
||||
*.mo
|
||||
|
||||
#Mr Developer
|
||||
.mr.developer.cfg
|
||||
@@ -0,0 +1,50 @@
|
||||
Change Log for IRLib – an Arduino library for infrared encoding and decoding
|
||||
Copyright 2013-2014 by Chris Young http://tech.cyborg5.com/irlib/
|
||||
|
||||
Version 1.4 – March 2014
|
||||
Added IRLIB_ prefix to debug macros to avoid name collisions
|
||||
Debug macros now report more information
|
||||
Added example new protocol Phillips RCMM used by AT&T U-Verse boxes and Nokia satellite boxes
|
||||
Added ABS_MATCH macro which allows you to match using absolute number of microseconds versus the old way which used a percentage. Necessary for implementing RCMM protocol.
|
||||
Added IRLIB_USE_PERCENT definition which when commented out changes the default from percentage match to absolute match. Also added DEFAULT_ABS_TOLERANCE. More details on these changes will be provided in the documentation when the section on adding new protocols is completed.
|
||||
Version 1.31 – March 2014
|
||||
Commented out debug code that was accidentally left active in 1.3 release
|
||||
Version 1.3 – January 2014
|
||||
NEW FILES
|
||||
Added new file IRLibRData.h and moved irparams structure and related items to that file. Allows users to create custom IRrecv classes
|
||||
NEW EXAMPLES
|
||||
Rewrote Samsung36 example to include both send and receive
|
||||
Added new examples for new protocols DirecTV and GIcable
|
||||
Added new example IRanalyze gives more detailed analysis of timing. Useful in analyzing the protocols
|
||||
Added new example IRfreq reports modulation frequency of a signal. Requires TSMP58000 IR learner chip
|
||||
Cleanup of other example routines.
|
||||
NEW CLASSES
|
||||
Created IRrecvBase class to allow custom receiver classes. IRrecv is now a derived class from it.
|
||||
Created IRrecvLoop class which receives IR signals without using any hardware interrupts or timers. Also created IRrecvPCI class which uses Pin Change Interrupts to receive IR signals. These new receivers are more accurate than the 50µs timing of the original IRrecv. However they also have other limitations described in comments.
|
||||
New functions, variables and methods
|
||||
In IRrecvBase added "unsigned char Mark_Excess" with default value 100. Was a define macro but now is user settable.
|
||||
In IRrecvBase added method "unsigned char getPinNum(void);" which retrieves the pin number used from irparams.recvpin. This value not normally accessible to end user.
|
||||
Globally available function "void do_Blink(void);" blinks pin 13 LED. For use by user created extensions of IRrecvBase.
|
||||
INTERNAL CHANGES
|
||||
Data collected by IRrecvBase classes in irparams.rawbuf is now converted to actual microseconds rather than clock ticks of 50 µs each. IRrecvBase::GetResults has a new parameter "Time_per_Ticks" that is used to convert ticks into actual microseconds if needed.
|
||||
Adjustments to mark and space to deal with overreporting and underreporting of intervals is now done once in IRrecvBase::GetResults eliminating the need for MATCH_MARK(d,v) and MATCH_SPACE(d,v). Just use MATCH(d,v) everywhere.
|
||||
Modified IRLibsendBase::mark() and IRLibsendBase::space() to overcome limitations of "delayMicroseconds()".
|
||||
Changed many int to char or unsigned char to save memory
|
||||
Eliminated DEBUG macro in IRLib.h and its use elsewhere. Macro TRACE is more useful.
|
||||
Changed IRTYPES to unsigned char and a list of #defines rather than an enum (even though I still really like enums, changing it saves memory)
|
||||
MEMORY EFFICIENCY
|
||||
Code changes result in memory savings of approximately 54 bytes in code space and 39 bytes of RAM.
|
||||
--------------------------------
|
||||
Version 1.2 – July 2013
|
||||
Internal version. No public release
|
||||
--------------------------------
|
||||
Version 1.1 – April 2013
|
||||
Constructor of IRsendBase now initializes output pin and forces it low immediately.
|
||||
New IRrecv::No_Output() method initializes output pin and forces it low. Use this in sketches which receive only by the have output hardware connected.
|
||||
Added examples IRservo and IRserial_remote
|
||||
--------------------------------
|
||||
Version 1.0a – February 2013
|
||||
Removed debugging test switch which was accidentally left on in file "IRLib.h"
|
||||
--------------------------------
|
||||
Version 1.0 – January 2013
|
||||
Initial Release
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,323 @@
|
||||
/* IRLib.h from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.4 March 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
*
|
||||
* This library is a major rewrite of IRemote by Ken Shirriff which was covered by
|
||||
* GNU LESSER GENERAL PUBLIC LICENSE which as I read it allows me to make modified versions.
|
||||
* That same license applies to this modified version. See his original copyright below.
|
||||
* The latest Ken Shirriff code can be found at https://github.com/shirriff/Arduino-IRremote
|
||||
* My purpose was to reorganize the code to make it easier to add or remove protocols.
|
||||
* As a result I have separated the act of receiving a set of raw timing codes from the act of decoding them
|
||||
* by making them separate classes. That way the receiving aspect can be more black box and implementers
|
||||
* of decoders and senders can just deal with the decoding of protocols. It also allows for alternative
|
||||
* types of receivers independent of the decoding. This makes porting to different hardware platforms easier.
|
||||
* Also added provisions to make the classes base classes that could be extended with new protocols
|
||||
* which would not require recompiling of the original library nor understanding of its detailed contents.
|
||||
* Some of the changes were made to reduce code size such as unnecessary use of long versus bool.
|
||||
* Some changes were just my weird programming style. Also extended debugging information added.
|
||||
*/
|
||||
/*
|
||||
* IRremote
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* For details, see http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html http://www.righto.com/
|
||||
*
|
||||
* Interrupt code based on NECIRrcv by Joe Knapp
|
||||
* http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
|
||||
* Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
|
||||
*/
|
||||
|
||||
#ifndef IRLib_h
|
||||
#define IRLib_h
|
||||
#include <Arduino.h>
|
||||
|
||||
// The following are compile-time library options.
|
||||
// If you change them, recompile the library.
|
||||
// If IRLIB_TRACE is defined, some debugging information about the decode will be printed
|
||||
// IRLIB_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 IRLIB_TRACE
|
||||
// #define IRLIB_TEST
|
||||
|
||||
// Only used for testing; can remove virtual for shorter code
|
||||
#ifdef IRLIB_TEST
|
||||
#define VIRTUAL virtual
|
||||
#else
|
||||
#define VIRTUAL
|
||||
#endif
|
||||
|
||||
#define RAWBUF 100 // Length of raw duration buffer (cannot exceed 255)
|
||||
|
||||
typedef char IRTYPES; //formerly was an enum
|
||||
#define UNKNOWN 0
|
||||
#define NEC 1
|
||||
#define SONY 2
|
||||
#define RC5 3
|
||||
#define RC6 4
|
||||
#define PANASONIC_OLD 5
|
||||
#define JVC 6
|
||||
#define NECX 7
|
||||
//#define ADDITIONAL (number) //make additional protocol 8 and change HASH_CODE to 9
|
||||
#define HASH_CODE 8
|
||||
#define LAST_PROTOCOL HASH_CODE
|
||||
|
||||
const __FlashStringHelper *Pnames(IRTYPES Type); //Returns a character string that is name of protocol.
|
||||
|
||||
// Base class for decoding raw results
|
||||
class IRdecodeBase
|
||||
{
|
||||
public:
|
||||
IRdecodeBase(void);
|
||||
IRTYPES decode_type; // NEC, SONY, RC5, UNKNOWN etc.
|
||||
unsigned long value; // Decoded value
|
||||
unsigned char bits; // Number of bits in decoded value
|
||||
volatile unsigned int *rawbuf; // Raw intervals in microseconds
|
||||
unsigned char rawlen; // Number of records in rawbuf.
|
||||
virtual void Reset(void); // Initializes the decoder
|
||||
virtual bool decode(void); // This base routine always returns false override with your routine
|
||||
bool decodeGeneric(unsigned char Raw_Count, unsigned int Head_Mark, unsigned int Head_Space,
|
||||
unsigned int Mark_One, unsigned int Mark_Zero, unsigned int Space_One, unsigned int Space_Zero);
|
||||
virtual void DumpResults (void);
|
||||
void UseExtnBuf(void *P); //Normally uses same rawbuf as IRrecv. Use this to define your own buffer.
|
||||
void copyBuf (IRdecodeBase *source);//copies rawbuf and rawlen from one decoder to another
|
||||
protected:
|
||||
unsigned char offset; // Index into rawbuf used various places
|
||||
};
|
||||
|
||||
class IRdecodeHash: public virtual IRdecodeBase
|
||||
{
|
||||
public:
|
||||
unsigned long hash;
|
||||
virtual bool decode(void);//made virtual in case you want to substitute your own hash code
|
||||
protected:
|
||||
int compare(unsigned int oldval, unsigned int newval);//used by decodeHash
|
||||
};
|
||||
|
||||
|
||||
class IRdecodeNEC: public virtual IRdecodeBase
|
||||
{
|
||||
public:
|
||||
virtual bool decode(void);
|
||||
};
|
||||
|
||||
class IRdecodeSony: public virtual IRdecodeBase
|
||||
{
|
||||
public:
|
||||
virtual bool decode(void);
|
||||
};
|
||||
|
||||
class IRdecodeRC: public virtual IRdecodeBase
|
||||
{
|
||||
public:
|
||||
enum RCLevel {MARK, SPACE, ERROR};//used by decoders for RC5/RC6
|
||||
// These are called by decode
|
||||
RCLevel getRClevel(unsigned char *used, const unsigned int t1);
|
||||
protected:
|
||||
unsigned char nbits;
|
||||
unsigned char used;
|
||||
long data;
|
||||
};
|
||||
|
||||
class IRdecodeRC5: public virtual IRdecodeRC
|
||||
{
|
||||
public:
|
||||
virtual bool decode(void);
|
||||
};
|
||||
|
||||
class IRdecodeRC6: public virtual IRdecodeRC
|
||||
{
|
||||
public:
|
||||
virtual bool decode(void);
|
||||
};
|
||||
|
||||
class IRdecodePanasonic_Old: public virtual IRdecodeBase
|
||||
{
|
||||
public:
|
||||
virtual bool decode(void);
|
||||
};
|
||||
|
||||
class IRdecodeJVC: public virtual IRdecodeBase
|
||||
{
|
||||
public:
|
||||
virtual bool decode(void);
|
||||
};
|
||||
|
||||
class IRdecodeNECx: public virtual IRdecodeBase
|
||||
{
|
||||
public:
|
||||
virtual bool decode(void);
|
||||
};
|
||||
|
||||
// main class for decoding all supported protocols
|
||||
class IRdecode:
|
||||
public virtual IRdecodeNEC,
|
||||
public virtual IRdecodeSony,
|
||||
public virtual IRdecodeRC5,
|
||||
public virtual IRdecodeRC6,
|
||||
public virtual IRdecodePanasonic_Old,
|
||||
public virtual IRdecodeJVC,
|
||||
public virtual IRdecodeNECx
|
||||
// , public virtual IRdecodeADDITIONAL //add additional protocols here
|
||||
{
|
||||
public:
|
||||
virtual bool decode(void); // Calls each decode routine individually
|
||||
};
|
||||
|
||||
//Base class for sending signals
|
||||
class IRsendBase
|
||||
{
|
||||
public:
|
||||
IRsendBase();
|
||||
void sendGeneric(unsigned long data, unsigned char Num_Bits, unsigned int Head_Mark, unsigned int Head_Space,
|
||||
unsigned int Mark_One, unsigned int Mark_Zero, unsigned int Space_One, unsigned int Space_Zero,
|
||||
unsigned char kHz, bool Stop_Bits, unsigned long Max_Extent=0);
|
||||
protected:
|
||||
void enableIROut(unsigned char khz);
|
||||
VIRTUAL void mark(unsigned int usec);
|
||||
VIRTUAL void space(unsigned int usec);
|
||||
unsigned long Extent;
|
||||
};
|
||||
|
||||
class IRsendNEC: public virtual IRsendBase
|
||||
{
|
||||
public:
|
||||
void send(unsigned long data);
|
||||
};
|
||||
|
||||
class IRsendSony: public virtual IRsendBase
|
||||
{
|
||||
public:
|
||||
void send(unsigned long data, int nbits);
|
||||
};
|
||||
|
||||
class IRsendRaw: public virtual IRsendBase
|
||||
{
|
||||
public:
|
||||
void send(unsigned int buf[], unsigned char len, unsigned char khz);
|
||||
};
|
||||
|
||||
class IRsendRC5: public virtual IRsendBase
|
||||
{
|
||||
public:
|
||||
void send(unsigned long data);
|
||||
};
|
||||
|
||||
class IRsendRC6: public virtual IRsendBase
|
||||
{
|
||||
public:
|
||||
void send(unsigned long data, unsigned char nbits);
|
||||
};
|
||||
|
||||
class IRsendPanasonic_Old: public virtual IRsendBase
|
||||
{
|
||||
public:
|
||||
void send(unsigned long data);
|
||||
};
|
||||
|
||||
class IRsendJVC: public virtual IRsendBase
|
||||
{
|
||||
public:
|
||||
void send(unsigned long data, bool First);
|
||||
};
|
||||
|
||||
class IRsendNECx: public virtual IRsendBase
|
||||
{
|
||||
public:
|
||||
void send(unsigned long data);
|
||||
};
|
||||
|
||||
class IRsend:
|
||||
public virtual IRsendNEC,
|
||||
public virtual IRsendSony,
|
||||
public virtual IRsendRaw,
|
||||
public virtual IRsendRC5,
|
||||
public virtual IRsendRC6,
|
||||
public virtual IRsendPanasonic_Old,
|
||||
public virtual IRsendJVC,
|
||||
public virtual IRsendNECx
|
||||
// , public virtual IRsendADDITIONAL //add additional protocols here
|
||||
{
|
||||
public:
|
||||
void send(IRTYPES Type, unsigned long data, unsigned int data2);
|
||||
};
|
||||
|
||||
// Changed this to a base class so it can be extended
|
||||
class IRrecvBase
|
||||
{
|
||||
public:
|
||||
IRrecvBase(void) {};
|
||||
IRrecvBase(unsigned char recvpin);
|
||||
void No_Output(void);
|
||||
void blink13(bool blinkflag);
|
||||
bool GetResults(IRdecodeBase *decoder, const unsigned int Time_per_Ticks=1);
|
||||
void enableIRIn(void);
|
||||
virtual void resume(void);
|
||||
unsigned char getPinNum(void);
|
||||
unsigned char Mark_Excess;
|
||||
protected:
|
||||
void Init(void);
|
||||
};
|
||||
|
||||
/* Original IRrecv class uses 50µs interrupts to sample input. While this is generally
|
||||
* accurate enough for everyday purposes, it may be difficult to port to other
|
||||
* hardware unless you know a lot about hardware timers and interrupts. Also
|
||||
* when trying to analyze unknown protocols, the 50µs granularity may not be sufficient.
|
||||
* In that case use either the IRrecvLoop or the IRrecvPCI class.
|
||||
*/
|
||||
class IRrecv: public IRrecvBase
|
||||
{
|
||||
public:
|
||||
IRrecv(unsigned char recvpin):IRrecvBase(recvpin){};
|
||||
bool GetResults(IRdecodeBase *decoder);
|
||||
void enableIRIn(void);
|
||||
void resume(void);
|
||||
};
|
||||
/* This receiver uses no interrupts or timers. Other interrupt driven receivers
|
||||
* allow you to do other things and call GetResults at your leisure to see if perhaps
|
||||
* a sequence has been received. Typically you would put GetResults in your loop
|
||||
* and it would return false until the sequence had been received. However because this
|
||||
* receiver uses no interrupts, it takes control of your program when you call GetResults
|
||||
* and doesn't let go until it's got something to show you. The advantage is you don't need
|
||||
* interrupts which would make it easier to use and nonstandard hardware and will allow you to
|
||||
* use any digital input pin. Timing of this routine is only as accurate as your "micros();"
|
||||
*/
|
||||
class IRrecvLoop: public IRrecvBase
|
||||
{
|
||||
public:
|
||||
IRrecvLoop(unsigned char recvpin):IRrecvBase(recvpin){};
|
||||
bool GetResults(IRdecodeBase *decoder);
|
||||
};
|
||||
|
||||
/* This receiver uses the pin change hardware interrupt to detect when your input pin
|
||||
* changes state. It gives more detailed results than the 50µs interrupts of IRrecv
|
||||
* and theoretically is more accurate than IRrecvLoop. However because it only detects
|
||||
* pin changes, it doesn't always know when it's finished. GetResults attempts to detect
|
||||
* a long gap of space but sometimes the next signal gets there before GetResults notices.
|
||||
* This means the second set of signals can get messed up unless there is a long gap.
|
||||
* This receiver is based in part on Arduino firmware for use with AnalysIR IR signal analysis
|
||||
* software for Windows PCs. Many thanks to the people at http://analysir.com for their
|
||||
* assistance in developing this section of code.
|
||||
*/
|
||||
class IRrecvPCI: public IRrecvBase
|
||||
{
|
||||
public:
|
||||
//Note this is interrupt number not pin number
|
||||
IRrecvPCI(unsigned char inum);
|
||||
bool GetResults(IRdecodeBase *decoder);
|
||||
void resume(void);
|
||||
private:
|
||||
unsigned char intrnum;
|
||||
};
|
||||
|
||||
|
||||
//Do the actual blinking off and on
|
||||
//This is not part of IRrecvBase because it may need to be inside an ISR
|
||||
//and we cannot pass parameters to them.
|
||||
void do_Blink(void);
|
||||
|
||||
// Some useful constants
|
||||
// Decoded value for NEC when a repeat code is received
|
||||
#define REPEAT 0xffffffff
|
||||
|
||||
|
||||
#endif //IRLib_h
|
||||
@@ -0,0 +1,100 @@
|
||||
/* IRLibMatch.h from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.4 March 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
*
|
||||
* This library is a major rewrite of IRemote by Ken Shirriff which was covered by
|
||||
* GNU LESSER GENERAL PUBLIC LICENSE which as I read it allows me to make modified versions.
|
||||
* That same license applies to this modified version. See his original copyright below.
|
||||
* The latest Ken Shirriff code can be found at https://github.com/shirriff/Arduino-IRremote
|
||||
* My purpose was to reorganize the code to make it easier to add or remove protocols.
|
||||
* As a result I have separated the act of receiving a set of raw timing codes from the act of decoding them
|
||||
* by making them separate classes. That way the receiving aspect can be more black box and implementers
|
||||
* of decoders and senders can just deal with the decoding of protocols. It also allows for alternative
|
||||
* types of receivers independent of the decoding. This makes porting to different hardware platforms easier.
|
||||
* Also added provisions to make the classes base classes that could be extended with new protocols
|
||||
* which would not require recompiling of the original library nor understanding of its detailed contents.
|
||||
* Some of the changes were made to reduce code size such as unnecessary use of long versus bool.
|
||||
* Some changes were just my weird programming style. Also extended debugging information added.
|
||||
*/
|
||||
/*
|
||||
* IRremote
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* For details, see http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html http://www.righto.com/
|
||||
*
|
||||
* Interrupt code based on NECIRrcv by Joe Knapp
|
||||
* http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
|
||||
* Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
|
||||
*/
|
||||
|
||||
#ifndef IRLibMatch_h
|
||||
#define IRLibMatch_h
|
||||
|
||||
/*
|
||||
* Originally all timing comparisons for decoding were based on a percent of the
|
||||
* target value. However when target values are relatively large, the percent tolerance
|
||||
* is too much. In some instances an absolute tolerance is needed. In order to maintain
|
||||
* backward compatibility, the default will be to continue to use percent. If you wish to default
|
||||
* to an absolute tolerance, you should comment out the line below.
|
||||
*/
|
||||
#define IRLIB_USE_PERCENT
|
||||
|
||||
/*
|
||||
* These are some miscellaneous definitions that are needed by the decoding routines.
|
||||
* You need not include this file unless you are creating custom decode routines
|
||||
* which will require these macros and definitions. Even if you include it, you probably
|
||||
* don't need to be intimately familiar with the internal details.
|
||||
*/
|
||||
|
||||
#define USECPERTICK 50 // microseconds per clock interrupt tick
|
||||
#define PERCENT_TOLERANCE 25 // percent tolerance in measurements
|
||||
#define DEFAULT_ABS_TOLERANCE 75 //absolute tolerance in microseconds
|
||||
|
||||
/*
|
||||
* These revised MATCH routines allow you to use either percentage were absolute tolerances.
|
||||
* Use ABS_MATCH for absolute and PERC_MATCH percentages. The original MATCH macro
|
||||
* is controlled by the IRLIB_USE_PERCENT definition a few lines above.
|
||||
*/
|
||||
|
||||
#define PERCENT_LOW(us) (unsigned int) (((us)*(1.0 - PERCENT_TOLERANCE/100.)))
|
||||
#define PERCENT_HIGH(us) (unsigned int) (((us)*(1.0 + PERCENT_TOLERANCE/100.) + 1))
|
||||
|
||||
#define ABS_MATCH(v,e,t) ((v) >= ((e)-(t)) && (v) <= ((e)+(t)))
|
||||
#define PERC_MATCH(v,e) ((v) >= PERCENT_LOW(e) && (v) <= PERCENT_HIGH(e))
|
||||
|
||||
#ifdef IRLIB_USE_PERCENT
|
||||
#define MATCH(v,e) PERC_MATCH(v,e)
|
||||
#else
|
||||
#define MATCH(v,e) ABS_MATCH(v,e,DEFAULT_ABS_TOLERANCE)
|
||||
#endif
|
||||
|
||||
//The following two routines are no longer necessary because mark/space adjustments are done elsewhere
|
||||
//These definitions maintain backward compatibility.
|
||||
#define MATCH_MARK(t,u) MATCH(t,u)
|
||||
#define MATCH_SPACE(t,u) MATCH(t,u)
|
||||
|
||||
#ifdef IRLIB_TRACE
|
||||
void IRLIB_ATTEMPT_MESSAGE(const __FlashStringHelper * s);
|
||||
void IRLIB_TRACE_MESSAGE(const __FlashStringHelper * s);
|
||||
byte IRLIB_REJECTION_MESSAGE(const __FlashStringHelper * s);
|
||||
byte IRLIB_DATA_ERROR_MESSAGE(const __FlashStringHelper * s, unsigned char index, unsigned int value, unsigned int expected);
|
||||
#define RAW_COUNT_ERROR IRLIB_REJECTION_MESSAGE(F("number of raw samples"));
|
||||
#define HEADER_MARK_ERROR(expected) IRLIB_DATA_ERROR_MESSAGE(F("header mark"),offset,rawbuf[offset],expected);
|
||||
#define HEADER_SPACE_ERROR(expected) IRLIB_DATA_ERROR_MESSAGE(F("header space"),offset,rawbuf[offset],expected);
|
||||
#define DATA_MARK_ERROR(expected) IRLIB_DATA_ERROR_MESSAGE(F("data mark"),offset,rawbuf[offset],expected);
|
||||
#define DATA_SPACE_ERROR(expected) IRLIB_DATA_ERROR_MESSAGE(F("data space"),offset,rawbuf[offset],expected);
|
||||
#define TRAILER_BIT_ERROR(expected) IRLIB_DATA_ERROR_MESSAGE(F("RC5/RC6 trailer bit length"),offset,rawbuf[offset],expected);
|
||||
#else
|
||||
#define IRLIB_ATTEMPT_MESSAGE(s)
|
||||
#define IRLIB_TRACE_MESSAGE(s)
|
||||
#define IRLIB_REJECTION_MESSAGE(s) false
|
||||
#define IRLIB_DATA_ERROR_MESSAGE(s,i,v,e) false
|
||||
#define RAW_COUNT_ERROR false
|
||||
#define HEADER_MARK_ERROR(expected) false
|
||||
#define HEADER_SPACE_ERROR(expected) false
|
||||
#define DATA_MARK_ERROR(expected) false
|
||||
#define DATA_SPACE_ERROR(expected) false
|
||||
#define TRAILER_BIT_ERROR(expected) false
|
||||
#endif
|
||||
|
||||
#endif //IRLibMatch_h
|
||||
@@ -0,0 +1,54 @@
|
||||
/* IRLibRData.h from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.4 March 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
*
|
||||
* This library is a major rewrite of IRemote by Ken Shirriff which was covered by
|
||||
* GNU LESSER GENERAL PUBLIC LICENSE which as I read it allows me to make modified versions.
|
||||
* That same license applies to this modified version. See his original copyright below.
|
||||
* The latest Ken Shirriff code can be found at https://github.com/shirriff/Arduino-IRremote
|
||||
* My purpose was to reorganize the code to make it easier to add or remove protocols.
|
||||
* As a result I have separated the act of receiving a set of raw timing codes from the act of decoding them
|
||||
* by making them separate classes. That way the receiving aspect can be more black box and implementers
|
||||
* of decoders and senders can just deal with the decoding of protocols. It also allows for alternative
|
||||
* types of receivers independent of the decoding. This makes porting to different hardware platforms easier.
|
||||
* Also added provisions to make the classes base classes that could be extended with new protocols
|
||||
* which would not require recompiling of the original library nor understanding of its detailed contents.
|
||||
* Some of the changes were made to reduce code size such as unnecessary use of long versus bool.
|
||||
* Some changes were just my weird programming style. Also extended debugging information added.
|
||||
*/
|
||||
/*
|
||||
* IRremote
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* For details, see http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html http://www.righto.com/
|
||||
*
|
||||
* Interrupt code based on NECIRrcv by Joe Knapp
|
||||
* http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
|
||||
* Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
|
||||
*/
|
||||
|
||||
#ifndef IRLibRData_h
|
||||
#define IRLibRData_h
|
||||
|
||||
/*
|
||||
* The structure contains a variety of variables needed by the receiver routines.
|
||||
* Typically this data would be part of the IRrecv class however the interrupt service routine
|
||||
* must have access to it and you cannot pass a parameter to such a routine. The data must be global.
|
||||
* You need not include this file unless you are creating a custom receiver class or extending
|
||||
* the provided IRrecv class.
|
||||
*/
|
||||
|
||||
// receiver states
|
||||
enum rcvstate_t {STATE_UNKNOWN, STATE_IDLE, STATE_MARK, STATE_SPACE, STATE_STOP, STATE_RUNNING};
|
||||
// information for the interrupt handler
|
||||
typedef struct {
|
||||
unsigned char recvpin; // pin for IR data from detector
|
||||
rcvstate_t rcvstate; // state machine
|
||||
bool blinkflag; // TRUE to enable blinking of pin 13 on IR processing
|
||||
unsigned long timer; // state timer, counts 50uS ticks.(and other uses)
|
||||
unsigned int rawbuf[RAWBUF]; // raw data
|
||||
unsigned char rawlen; // counter of entries in rawbuf
|
||||
}
|
||||
irparams_t;
|
||||
extern volatile irparams_t irparams;
|
||||
#endif
|
||||
@@ -0,0 +1,330 @@
|
||||
/* IRLibTimer.h from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.4 March 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
*
|
||||
* This library is a major rewrite of IRemote by Ken Shirriff which was covered by
|
||||
* GNU LESSER GENERAL PUBLIC LICENSE which as I read it allows me to make modified versions.
|
||||
* That same license applies to this modified version. See his original copyright below.
|
||||
* The latest Ken Shirriff code can be found at https://github.com/shirriff/Arduino-IRremote
|
||||
* My purpose was to reorganize the code to make it easier to add or remove protocols.
|
||||
* As a result I have separated the act of receiving a set of raw timing codes from the act of decoding them
|
||||
* by making them separate classes. That way the receiving aspect can be more black box and implementers
|
||||
* of decoders and senders can just deal with the decoding of protocols. It also allows for alternative
|
||||
* types of receivers independent of the decoding. This makes porting to different hardware platforms easier.
|
||||
* Also added provisions to make the classes base classes that could be extended with new protocols
|
||||
* which would not require recompiling of the original library nor understanding of its detailed contents.
|
||||
* Some of the changes were made to reduce code size such as unnecessary use of long versus bool.
|
||||
* Some changes were just my weird programming style. Also extended debugging information added.
|
||||
*/
|
||||
/*
|
||||
* IRremote
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* For details, see http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html http://www.righto.com/
|
||||
*
|
||||
* Interrupt code based on NECIRrcv by Joe Knapp
|
||||
* http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
|
||||
* Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
|
||||
*/
|
||||
/* This file defines which timer you wish to use. Different versions of Arduino and related boards
|
||||
* have different timers available to them. For various reasons you might want to use something other than
|
||||
* timer 2. Some boards do not have timer 2. This attempts to detect which type of board you are using.
|
||||
* You need uncomment wish to use on your board. You probably will not need to include this in your
|
||||
* program unless you want to see which timer is being used and which board has been detected.
|
||||
* This information came from an alternative fork of the original Ken Shirriff library found here
|
||||
* https://github.com/TKJElectronics/Arduino-IRremote
|
||||
*/
|
||||
#ifndef IRLibTimer_h
|
||||
#define IRLibTimer_h
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
// Arduino Mega
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
//#define IR_USE_TIMER1 // tx = pin 11
|
||||
#define IR_USE_TIMER2 // tx = pin 9
|
||||
//#define IR_USE_TIMER3 // tx = pin 5
|
||||
//#define IR_USE_TIMER4 // tx = pin 6
|
||||
//#define IR_USE_TIMER5 // tx = pin 46
|
||||
|
||||
// Teensy 1.0
|
||||
#elif defined(__AVR_AT90USB162__)
|
||||
#define IR_USE_TIMER1 // tx = pin 17
|
||||
|
||||
// Teensy 2.0 versus Leonardo
|
||||
// These boards use the same chip but the pinouts are different.
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#ifdef CORE_TEENSY
|
||||
// it's Teensy 2.0
|
||||
//#define IR_USE_TIMER1 // tx = pin 14
|
||||
//#define IR_USE_TIMER3 // tx = pin 9
|
||||
#define IR_USE_TIMER4_HS // tx = pin 10
|
||||
#else
|
||||
// it's probably Leonardo
|
||||
#define IR_USE_TIMER1 // tx = pin 9
|
||||
//#define IR_USE_TIMER3 // tx = pin 5
|
||||
//#define IR_USE_TIMER4_HS // tx = pin 13
|
||||
#endif
|
||||
|
||||
// Teensy++ 1.0 & 2.0
|
||||
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
|
||||
//#define IR_USE_TIMER1 // tx = pin 25
|
||||
#define IR_USE_TIMER2 // tx = pin 1
|
||||
//#define IR_USE_TIMER3 // tx = pin 16
|
||||
|
||||
// Sanguino
|
||||
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||
//#define IR_USE_TIMER1 // tx = pin 13
|
||||
#define IR_USE_TIMER2 // tx = pin 14
|
||||
|
||||
// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, etc
|
||||
#else
|
||||
//#define IR_USE_TIMER1 // tx = pin 9
|
||||
#define IR_USE_TIMER2 // tx = pin 3
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// defines for timer2 (8 bits)
|
||||
#if defined(IR_USE_TIMER2)
|
||||
#define TIMER_RESET
|
||||
#define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1))
|
||||
#define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1)))
|
||||
#define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK2 = 0)
|
||||
#define TIMER_INTR_NAME TIMER2_COMPA_vect
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
const uint8_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||
TCCR2A = _BV(WGM20); \
|
||||
TCCR2B = _BV(WGM22) | _BV(CS20); \
|
||||
OCR2A = pwmval; \
|
||||
OCR2B = pwmval / 3; \
|
||||
})
|
||||
#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000)
|
||||
#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
|
||||
|
||||
|
||||
// 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)))
|
||||
#define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK1 = 0)
|
||||
#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_ENABLE_PWM (TCCR3A |= _BV(COM3A1))
|
||||
#define TIMER_DISABLE_PWM (TCCR3A &= ~(_BV(COM3A1)))
|
||||
#define TIMER_ENABLE_INTR (TIMSK3 = _BV(OCIE3A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK3 = 0)
|
||||
#define TIMER_INTR_NAME TIMER3_COMPA_vect
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||
TCCR3A = _BV(WGM31); \
|
||||
TCCR3B = _BV(WGM33) | _BV(CS30); \
|
||||
ICR3 = pwmval; \
|
||||
OCR3A = pwmval / 3; \
|
||||
})
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR3A = 0; \
|
||||
TCCR3B = _BV(WGM32) | _BV(CS30); \
|
||||
OCR3A = SYSCLOCK * USECPERTICK / 1000000; \
|
||||
TCNT3 = 0; \
|
||||
})
|
||||
#if defined(CORE_OC3A_PIN)
|
||||
#define TIMER_PWM_PIN CORE_OC3A_PIN /* Teensy */
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define TIMER_PWM_PIN 5 /* Arduino Mega */
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#define TIMER_PWM_PIN 5 /* Arduino Leonardo note already checked for Teensy */
|
||||
#else
|
||||
#error "Please add OC3A pin number here\n"
|
||||
#endif
|
||||
|
||||
|
||||
// defines for timer4 (10 bits, high speed option)
|
||||
#elif defined(IR_USE_TIMER4_HS)
|
||||
#define TIMER_RESET
|
||||
#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1))
|
||||
#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1)))
|
||||
#define TIMER_ENABLE_INTR (TIMSK4 = _BV(TOIE4))
|
||||
#define TIMER_DISABLE_INTR (TIMSK4 = 0)
|
||||
#define TIMER_INTR_NAME TIMER4_OVF_vect
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||
TCCR4A = (1<<PWM4A); \
|
||||
TCCR4B = _BV(CS40); \
|
||||
TCCR4C = 0; \
|
||||
TCCR4D = (1<<WGM40); \
|
||||
TCCR4E = 0; \
|
||||
TC4H = pwmval >> 8; \
|
||||
OCR4C = pwmval; \
|
||||
TC4H = (pwmval / 3) >> 8; \
|
||||
OCR4A = (pwmval / 3) & 255; \
|
||||
})
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR4A = 0; \
|
||||
TCCR4B = _BV(CS40); \
|
||||
TCCR4C = 0; \
|
||||
TCCR4D = 0; \
|
||||
TCCR4E = 0; \
|
||||
TC4H = (SYSCLOCK * USECPERTICK / 1000000) >> 8; \
|
||||
OCR4C = (SYSCLOCK * USECPERTICK / 1000000) & 255; \
|
||||
TC4H = 0; \
|
||||
TCNT4 = 0; \
|
||||
})
|
||||
#if defined(CORE_OC4A_PIN)
|
||||
#define TIMER_PWM_PIN CORE_OC4A_PIN /* Teensy */
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#define TIMER_PWM_PIN 13 /*Leonardo*/
|
||||
#else
|
||||
#error "Please add OC4A pin number here\n"
|
||||
#endif
|
||||
|
||||
|
||||
// defines for timer4 (16 bits)
|
||||
#elif defined(IR_USE_TIMER4)
|
||||
#define TIMER_RESET
|
||||
#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1))
|
||||
#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1)))
|
||||
#define TIMER_ENABLE_INTR (TIMSK4 = _BV(OCIE4A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK4 = 0)
|
||||
#define TIMER_INTR_NAME TIMER4_COMPA_vect
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||
TCCR4A = _BV(WGM41); \
|
||||
TCCR4B = _BV(WGM43) | _BV(CS40); \
|
||||
ICR4 = pwmval; \
|
||||
OCR4A = pwmval / 3; \
|
||||
})
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR4A = 0; \
|
||||
TCCR4B = _BV(WGM42) | _BV(CS40); \
|
||||
OCR4A = SYSCLOCK * USECPERTICK / 1000000; \
|
||||
TCNT4 = 0; \
|
||||
})
|
||||
#if defined(CORE_OC4A_PIN)
|
||||
#define TIMER_PWM_PIN CORE_OC4A_PIN
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define TIMER_PWM_PIN 6 /* Arduino Mega */
|
||||
#else
|
||||
#error "Please add OC4A pin number here\n"
|
||||
#endif
|
||||
|
||||
|
||||
// defines for timer5 (16 bits)
|
||||
#elif defined(IR_USE_TIMER5)
|
||||
#define TIMER_RESET
|
||||
#define TIMER_ENABLE_PWM (TCCR5A |= _BV(COM5A1))
|
||||
#define TIMER_DISABLE_PWM (TCCR5A &= ~(_BV(COM5A1)))
|
||||
#define TIMER_ENABLE_INTR (TIMSK5 = _BV(OCIE5A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK5 = 0)
|
||||
#define TIMER_INTR_NAME TIMER5_COMPA_vect
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||
TCCR5A = _BV(WGM51); \
|
||||
TCCR5B = _BV(WGM53) | _BV(CS50); \
|
||||
ICR5 = pwmval; \
|
||||
OCR5A = pwmval / 3; \
|
||||
})
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR5A = 0; \
|
||||
TCCR5B = _BV(WGM52) | _BV(CS50); \
|
||||
OCR5A = SYSCLOCK * USECPERTICK / 1000000; \
|
||||
TCNT5 = 0; \
|
||||
})
|
||||
#if defined(CORE_OC5A_PIN)
|
||||
#define TIMER_PWM_PIN CORE_OC5A_PIN
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define TIMER_PWM_PIN 46 /* Arduino Mega */
|
||||
#else
|
||||
#error "Please add OC5A pin number here\n"
|
||||
#endif
|
||||
|
||||
|
||||
#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)
|
||||
#elif defined(__AVR_ATmega32U4__) && defined(IR_USE_TIMER4_HS)
|
||||
//Leonardo not teensy. When using Timer4 output is on 13. Therefore disabling blink LED
|
||||
//You can add an LED elsewhere if you want
|
||||
#define BLINKLED 1
|
||||
#define BLINKLED_ON() (digitalWrite(BLINKLED, HIGH))
|
||||
#define BLINKLED_OFF() (digitalWrite(BLINKLED, LOW))
|
||||
#else
|
||||
#define BLINKLED 13
|
||||
#define BLINKLED_ON() (PORTB |= B00100000)
|
||||
#define BLINKLED_OFF() (PORTB &= B11011111)
|
||||
#endif
|
||||
|
||||
#endif //IRLibTimer_h
|
||||
Binary file not shown.
@@ -0,0 +1,84 @@
|
||||
IRLib – an Arduino library for infrared encoding and decoding
|
||||
Version 1.32 January 2014
|
||||
Copyright 2013, 2014 by Chris Young http://cyborg5.com
|
||||
|
||||
This library is a major rewrite of IRemote by Ken Shirriff which was covered
|
||||
by GNU LESSER GENERAL PUBLIC LICENSE which as I read it allows me to make
|
||||
modified versions. That same license applies to this modified version. See
|
||||
his original copyright below.
|
||||
|
||||
The latest Ken Shirriff code can be found at
|
||||
https://github.com/shirriff/Arduino-IRremote
|
||||
|
||||
My purpose was to reorganize the code to make it easier to add or remove
|
||||
protocols. As a result I have separated the act of receiving a set of raw timing
|
||||
codes from the act of decoding them by making them separate classes. That way
|
||||
the receiving aspect can be more black box and implementers of decoders and
|
||||
senders can just deal with the decoding of protocols.
|
||||
|
||||
Also added provisions to make the classes base classes that could be extended
|
||||
with new protocols which would not require recompiling of the original library nor
|
||||
understanding of its detailed contents. Some of the changes were made to reduce
|
||||
code size such as unnecessary use of long versus bool. Some changes were just my
|
||||
weird programming style. Also extended debugging information added.
|
||||
|
||||
IRremote
|
||||
Version 0.1 July, 2009
|
||||
Copyright 2009 Ken Shirriff
|
||||
For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.htm
|
||||
http://arcfn.com
|
||||
|
||||
Interrupt code based on NECIRrcv by Joe Knapp
|
||||
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
|
||||
Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
|
||||
|
||||
****************************************************
|
||||
The package contains:
|
||||
IRLib.cpp Code for the library written in object C++
|
||||
IRLib.h Header file which you will include in your sketch
|
||||
IRLibMatch.h Match macros used internally. Need not include this unless you implement
|
||||
your own protocols
|
||||
iRLibTimer.h Attempts to detect type of Arduino board and allows you to modify which
|
||||
interrupt timer you will use. Defaults to timer 2 as did the original KS
|
||||
library. Alternate board and timer information based on a fork of the
|
||||
original KS library. That for can be found here.
|
||||
https://github.com/TKJElectronics/Arduino-IRremote
|
||||
IRLibRData.h Moved irparams structure and related data to this header to facilitate
|
||||
user created extensions to IRrecvBase.
|
||||
|
||||
Note: there is no "IRremoteInt.h" header as in the original library. Those values were
|
||||
moved elsewhere.
|
||||
|
||||
The examples directory contains:
|
||||
IRanalyze Dumps detailed information about a recent signal. Useful for analyzing
|
||||
unknown protocols
|
||||
IRfreq Reports modulation frequency of IR signal. Requires TSMP58000 IR learner
|
||||
IRhashdecode Demonstrates hash decoder.
|
||||
IRrecord Recording incoming signal and play it back when a character is sent
|
||||
through the serial console. By using the console you no longer need
|
||||
to wire up a pushbutton to run this code.
|
||||
IRrecvDump Receives a code, attempts to decode it, produces well formatted
|
||||
output of the results using the new "dump" method.
|
||||
IRsendDemo Simplistic demo to send a Sony DVD power signal every time a
|
||||
character is received from the serial monitor.
|
||||
IRsendJVC Demonstrates sending a code using JVC protocol which is tricky.
|
||||
IRservo Demonstrates controlling a servo motor using an IR remote
|
||||
IRserial_remote Demonstrates a Python application that runs on your PC and sends
|
||||
serial data to Arduino which in turn sends IR remote signals.
|
||||
Samsung36 Demonstrates how to expand the library without recompiling it.
|
||||
Also demonstrates how to handle codes that are longer than 32 bits.
|
||||
DirecTV Demonstrates additional protocol for DirecTV
|
||||
GIcable Demonstrates additional protocol for GIcable used by Motorola cable boxes
|
||||
rcmm Additional protocol Phillips RCMM used by AT&T U-Verse boxes
|
||||
Note: I did not port any of the other demo sketches although I may add IRTest later.
|
||||
The manuals directory contains:
|
||||
IRLibReference.docx Reference manual in Microsoft Word format
|
||||
IRLibReference.pdf Reference manual in Adobe PDF format
|
||||
Online version of this manual is also available at:
|
||||
http://tech.cyborg5.com/irlib/docs/
|
||||
****************************************************
|
||||
The library handles the following protocols:
|
||||
NEC, Sony, RC5, RC6, Raw all of which were supported in the KS version.
|
||||
Additionally added Panasonic_Old, JVC, NECx.
|
||||
Also added KS hash code routines which he released separately.
|
||||
Example code included but not in the library: Samsung36, DirecTV, GIcable.
|
||||
@@ -0,0 +1,201 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.4 March 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009I know prescription and no
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://www.righto.com/
|
||||
*/
|
||||
/*
|
||||
* This example demonstrates how to extend this library to add a new protocol
|
||||
* without actually modifying or recompiling the library itself. It implements the protocol
|
||||
* used by DirecTV. This protocol actually comes in six different varieties.
|
||||
* It uses three different frequencies 38, 40, or 57 kHz. It also uses two different varieties
|
||||
* lead out times either 9000us or 30000us. The default is 38 kHz and 30000us.
|
||||
* You can use a different constructor for the other varieties.
|
||||
* This is a modified version of the IRecord example.
|
||||
* If you would like to make this a permanent part of your library you could copy the class
|
||||
* prototypes to IRLib.h and the code itself to IRLib.cpp. Search for the word "ADDITIONAL"
|
||||
* to see where to add various pieces of code. Also see the Samsung36 example for details.
|
||||
*/
|
||||
#include <IRLib.h>
|
||||
#include <IRLibMatch.h>
|
||||
|
||||
class IRdecodeDirecTV: public virtual IRdecodeBase
|
||||
{
|
||||
public:
|
||||
bool decode(void);
|
||||
bool Repeat;
|
||||
};
|
||||
|
||||
class IRsendDirecTV: public virtual IRsendBase
|
||||
{
|
||||
public:
|
||||
IRsendDirecTV (int khz= 38,bool LongLeadOut=true);
|
||||
void send(unsigned long data, bool Repeat);
|
||||
int Freq;
|
||||
unsigned int LeadOut;
|
||||
};
|
||||
|
||||
#define DIRECTV (LAST_PROTOCOL+1)
|
||||
|
||||
/*
|
||||
* According to http://www.hifi-remote.com/johnsfine/DecodeIR.html#DirecTV
|
||||
* The IRP notation for this protocol is:
|
||||
*{38k,600,msb}<1,-1|1,-2|2,-1|2,-2>(5,(5,-2,D:4,F:8,C:4,1,-50)+) {C=7*(F:2:6)+5*(F:2:4)+3*(F:2:2)+(F:2)}
|
||||
* Unlike most protocols which use a fixed length mark and a variable length or a variable length
|
||||
* mark a fixed length space, this protocol varies both the mark and the space.
|
||||
* The stream is still a series of marks and spaces but the length of either of those
|
||||
* denotes a one or zero. A length of 1200us=logical 1 and length 600us=logical 0
|
||||
* It also makes changes to the length of the header mark to devote repeat codes.
|
||||
* The first header mark should be 6000us but repeat codes should only be 3000us.
|
||||
*/
|
||||
bool IRdecodeDirecTV::decode(void) {
|
||||
long data; int offset;
|
||||
IRLIB_ATTEMPT_MESSAGE(F("DirecTV"));
|
||||
if (rawlen != 20) return RAW_COUNT_ERROR;
|
||||
if (MATCH(rawbuf[1],3000))
|
||||
Repeat=true;
|
||||
else
|
||||
if (!MATCH(rawbuf[1],6000)){
|
||||
return HEADER_MARK_ERROR(6000);
|
||||
} else {
|
||||
Repeat=false;
|
||||
}
|
||||
if (!MATCH(rawbuf[2],1200)) return HEADER_SPACE_ERROR(1200);
|
||||
offset=3; data=0;
|
||||
while (offset < 18) {
|
||||
if (MATCH(rawbuf[offset],1200)) {
|
||||
data = (data << 1) | 1;
|
||||
}
|
||||
else if (MATCH(rawbuf[offset],600)) {
|
||||
data <<= 1;
|
||||
}
|
||||
else return DATA_MARK_ERROR(1200);
|
||||
offset++;
|
||||
if (MATCH(rawbuf[offset],1200)) {
|
||||
data = (data << 1) | 1;
|
||||
}
|
||||
else if (MATCH (rawbuf[offset],600)) {
|
||||
data <<= 1;
|
||||
}
|
||||
else return DATA_SPACE_ERROR(1200);
|
||||
offset++;
|
||||
}
|
||||
if (!MATCH(rawbuf[1],6000)) return DATA_MARK_ERROR(6000);
|
||||
bits = 16;//set bit length
|
||||
value = data;//put remaining bits in value
|
||||
decode_type= static_cast<IRTYPES>DIRECTV;
|
||||
return true;
|
||||
};
|
||||
|
||||
//See the comment at the top about different frequencies and lead out times
|
||||
IRsendDirecTV::IRsendDirecTV (int khz, bool LongLeadOut){
|
||||
Freq=khz;
|
||||
if (LongLeadOut) LeadOut=50*600; else LeadOut=15*600;
|
||||
};
|
||||
|
||||
void IRsendDirecTV::send(unsigned long data, bool Repeat) {
|
||||
enableIROut(Freq);
|
||||
if(Repeat) mark(3000); else mark(6000);
|
||||
space(1200);//Send header
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (data & 0x8000) mark(1200); else mark(600);
|
||||
data <<= 1;
|
||||
if (data & 0x8000) space(1200); else space(600);
|
||||
data <<= 1;
|
||||
};
|
||||
mark(600);
|
||||
space(LeadOut);
|
||||
};
|
||||
|
||||
//Create a custom class that combines this new protocol with all the others
|
||||
class MyCustomSend:
|
||||
public virtual IRsend,
|
||||
public virtual IRsendDirecTV
|
||||
{
|
||||
public:
|
||||
void send(IRTYPES Type, unsigned long data, int nbits);
|
||||
};
|
||||
void MyCustomSend::send(IRTYPES Type, unsigned long data, int nbits) {
|
||||
if (Type==DIRECTV)
|
||||
IRsendDirecTV::send(data,false);
|
||||
else
|
||||
IRsend::send(Type, data, nbits);
|
||||
}
|
||||
class MyCustomDecode:
|
||||
public virtual IRdecode,
|
||||
public virtual IRdecodeDirecTV
|
||||
{
|
||||
public:
|
||||
virtual bool decode(void); // Calls each decode routine individually
|
||||
void DumpResults(void);
|
||||
};
|
||||
bool MyCustomDecode::decode(void) {
|
||||
if (IRdecodeDirecTV::decode()) return true;
|
||||
return IRdecode::decode ();
|
||||
}
|
||||
void MyCustomDecode::DumpResults(void){
|
||||
if(decode_type==DIRECTV) {
|
||||
Serial.print(F("Decoded DirecTV: Value:")); Serial.print(value, HEX);
|
||||
if (Repeat) Serial.print(F(" repeat flag"));
|
||||
};
|
||||
IRdecode::DumpResults();
|
||||
};
|
||||
|
||||
MyCustomDecode My_Decoder;
|
||||
|
||||
MyCustomSend My_Sender;
|
||||
|
||||
int RECV_PIN = 11;
|
||||
|
||||
IRrecv My_Receiver(RECV_PIN);
|
||||
IRTYPES codeType; // The type of code
|
||||
unsigned long codeValue; // The data bits
|
||||
int codeBits; // The length of the code in bits
|
||||
bool GotOne;
|
||||
|
||||
void setup()
|
||||
{
|
||||
GotOne=false;
|
||||
codeType=UNKNOWN;
|
||||
codeValue=0;
|
||||
codeBits=0;
|
||||
Serial.begin(9600);
|
||||
Serial.println(F("Send a code from your remote and we will record it."));
|
||||
Serial.println(F("Type any character and press enter. We will send the recorded code."));
|
||||
My_Receiver.enableIRIn(); // Start the receiver
|
||||
}
|
||||
void loop() {
|
||||
if (Serial.available()>0) {
|
||||
unsigned char c=Serial.read();
|
||||
if (c=='p') {//Send a test pattern
|
||||
GotOne= true; codeType=DIRECTV; codeValue=0x1234; codeBits=16;
|
||||
}
|
||||
if(GotOne) {
|
||||
My_Sender.send(codeType,codeValue,codeBits);
|
||||
Serial.print(F("Sent "));
|
||||
if (codeType== DIRECTV) Serial.print(F("DirecTV")); else Serial.print(Pnames(codeType));
|
||||
Serial.print(F(" Value:0x"));
|
||||
Serial.print(codeValue, HEX);
|
||||
Serial.print(F(" Bits:"));
|
||||
Serial.println(codeBits, DEC);
|
||||
My_Receiver.enableIRIn(); // Re-enable receiver
|
||||
}
|
||||
}
|
||||
else if (My_Receiver.GetResults(&My_Decoder)) {
|
||||
My_Decoder.decode();
|
||||
if(My_Decoder.decode_type == UNKNOWN) {
|
||||
Serial.println(F("Unknown type received. Ignoring."));
|
||||
} else {
|
||||
codeType= My_Decoder.decode_type;
|
||||
codeValue= My_Decoder.value;
|
||||
codeBits= My_Decoder.bits;
|
||||
GotOne=true;
|
||||
}
|
||||
My_Decoder.DumpResults();
|
||||
delay(1000);
|
||||
My_Receiver.resume();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.4 March 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009I know prescription and no
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://www.righto.com/
|
||||
*/
|
||||
/*
|
||||
* This example demonstrates how to extend this library to add a new protocol
|
||||
* without actually modifying or recompiling the library itself. It implements the protocol
|
||||
* known as GIcable which is used by some Motorola cable boxes.
|
||||
* This is a modified version of the IRecord example.
|
||||
* If you would like to make this a permanent part of your library you could copy the class
|
||||
* prototypes to IRLib.h and the code itself to IRLib.cpp. Search for the word "ADDITIONAL"
|
||||
* to see where to add various pieces of code. Also see the Samsung36 example for details.
|
||||
*/
|
||||
#include <IRLib.h>
|
||||
#include <IRLibMatch.h>
|
||||
|
||||
class IRdecodeGIcable: public virtual IRdecodeBase
|
||||
{
|
||||
public:
|
||||
bool decode(void);
|
||||
};
|
||||
class IRsendGIcable: public virtual IRsendBase
|
||||
{
|
||||
public:
|
||||
void send(unsigned long data, bool Repeat);
|
||||
};
|
||||
|
||||
#define GICABLE (LAST_PROTOCOL+1)
|
||||
|
||||
/* The IRP notation for this protocol according to
|
||||
* http://www.hifi-remote.com/johnsfine/DecodeIR.html#G.I. Cable
|
||||
* is "{38.7k,490}<1,-4.5|1,-9>(18,-9,F:8,D:4,C:4,1,-84,(18,-4.5,1,-178)*) {C = -(D + F:4 + F:4:4)}"
|
||||
*/
|
||||
bool IRdecodeGIcable::decode(void) {
|
||||
IRLIB_ATTEMPT_MESSAGE(F("GIcable"));
|
||||
// Check for repeat
|
||||
if (rawlen == 4 && MATCH(rawbuf[1], 490*18) && MATCH(rawbuf[2],2205)) {
|
||||
bits = 0;
|
||||
value = REPEAT;
|
||||
decode_type= static_cast<IRTYPES>GICABLE;
|
||||
return true;
|
||||
}
|
||||
if(!decodeGeneric(36, 18*490, 9*490, 0, 490, 9*490, 2205/*(4.5*490)*/)) return false;
|
||||
decode_type= static_cast<IRTYPES>GICABLE;
|
||||
return true;
|
||||
};
|
||||
|
||||
void IRsendGIcable::send(unsigned long data, bool Repeat) {
|
||||
if(Repeat) {
|
||||
enableIROut(39);
|
||||
mark (490*18); space (2205); mark (490); space(220);delay (87);//actually "space(87200);"
|
||||
} else {
|
||||
sendGeneric(data,16, 490*18, 490*9, 490, 490, 490*9, 2205, 39, true);
|
||||
}
|
||||
};
|
||||
|
||||
//Create a custom class that combines this new protocol with all the others
|
||||
class MyCustomSend:
|
||||
public virtual IRsend,
|
||||
public virtual IRsendGIcable
|
||||
{
|
||||
public:
|
||||
void send(IRTYPES Type, unsigned long data, int nbits);
|
||||
};
|
||||
void MyCustomSend::send(IRTYPES Type, unsigned long data, int nbits) {
|
||||
if (Type==GICABLE){
|
||||
IRsendGIcable::send(data,false);
|
||||
//un-comment the line below to text repeats
|
||||
//delay(3000); IRsendGIcable::send(data,true);
|
||||
}
|
||||
else
|
||||
IRsend::send(Type, data, nbits);
|
||||
}
|
||||
class MyCustomDecode:
|
||||
public virtual IRdecode,
|
||||
public virtual IRdecodeGIcable
|
||||
{
|
||||
public:
|
||||
virtual bool decode(void); // Calls each decode routine individually
|
||||
void DumpResults(void);
|
||||
};
|
||||
bool MyCustomDecode::decode(void) {
|
||||
if (IRdecodeGIcable::decode()) return true;
|
||||
return IRdecode::decode ();
|
||||
}
|
||||
void MyCustomDecode::DumpResults(void){
|
||||
if(decode_type==GICABLE) {
|
||||
Serial.print(F("Decoded GIcable: Value:")); Serial.print(value, HEX);
|
||||
};
|
||||
IRdecode::DumpResults();
|
||||
};
|
||||
|
||||
MyCustomDecode My_Decoder;
|
||||
|
||||
MyCustomSend My_Sender;
|
||||
|
||||
int RECV_PIN =11;
|
||||
|
||||
IRrecv My_Receiver(RECV_PIN);
|
||||
IRTYPES codeType; // The type of code
|
||||
unsigned long codeValue; // The data bits
|
||||
int codeBits; // The length of the code in bits
|
||||
bool GotOne;
|
||||
|
||||
void setup()
|
||||
{
|
||||
GotOne=false;
|
||||
codeType=UNKNOWN;
|
||||
codeValue=0;
|
||||
codeBits=0;
|
||||
Serial.begin(9600);
|
||||
Serial.println(F("Send a code from your remote and we will record it."));
|
||||
Serial.println(F("Type any character and press enter. We will send the recorded code."));
|
||||
My_Receiver.enableIRIn(); // Start the receiver
|
||||
}
|
||||
void loop() {
|
||||
if (Serial.available()>0) {
|
||||
unsigned char c=Serial.read();
|
||||
if (c=='p') {//Send a test pattern
|
||||
GotOne= true; codeType=GICABLE; codeValue=0x1234; codeBits=16;
|
||||
}
|
||||
if(GotOne) {
|
||||
My_Sender.send(codeType,codeValue,codeBits);
|
||||
Serial.print(F("Sent "));
|
||||
if (codeType== GICABLE) Serial.print(F("GIcable")); else Serial.print(Pnames(codeType));
|
||||
Serial.print(F(" Value:0x"));
|
||||
Serial.print(codeValue, HEX);
|
||||
Serial.print(F(" Bits:"));
|
||||
Serial.println(codeBits, DEC);
|
||||
My_Receiver.enableIRIn(); // Re-enable receiver
|
||||
}
|
||||
}
|
||||
else if (My_Receiver.GetResults(&My_Decoder)) {
|
||||
My_Decoder.decode();
|
||||
if(My_Decoder.decode_type == UNKNOWN) {
|
||||
Serial.println(F("Unknown type received. Ignoring."));
|
||||
} else {
|
||||
codeType= My_Decoder.decode_type;
|
||||
codeValue= My_Decoder.value;
|
||||
codeBits= My_Decoder.bits;
|
||||
GotOne=true;
|
||||
}
|
||||
My_Decoder.DumpResults();
|
||||
delay(1000);
|
||||
My_Receiver.resume();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.3 January 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://www.righto.com/
|
||||
*/
|
||||
/* IRanalyze receives repeated values from a remote and averages the results. Should help in
|
||||
* analyzing unknown protocols. You have to press the same key repeatedly. If you press a
|
||||
* different key the totals reset and it computes new averages.
|
||||
*/
|
||||
#include <IRLib.h>
|
||||
#include <IRLibRData.h>
|
||||
|
||||
int RECV_PIN = 11;
|
||||
|
||||
unsigned int Samples,i, LowSpace, LowMark, HighMark, HighSpace, interval,
|
||||
balm,aalm,bahm,aahm,bals,aals,bahs,aahs;
|
||||
unsigned char bacm,aacm,bacs,aacs, Mark_Count,Space_Count;
|
||||
unsigned int Accumulated_Time[RAWBUF];
|
||||
unsigned long Mark_Avg, Space_Avg,baam,aaam,baas,aaas;
|
||||
//Try this program with various receivers
|
||||
IRrecv My_Receiver(RECV_PIN);
|
||||
//IRrecvLoop My_Receiver(RECV_PIN);
|
||||
//Use interrupt=0. This is pin 2 on Arduino Uno and Mega, pin 3 on Leonardo
|
||||
//IRrecvPCI My_Receiver(0);
|
||||
|
||||
IRdecode My_Decoder;
|
||||
IRTYPES Old_Type;
|
||||
unsigned long Old_Value;
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
delay(1000);while(!Serial);
|
||||
My_Receiver.enableIRIn();
|
||||
// My_Receiver.Mark_Excess=50;//Try different values here
|
||||
Samples=0;Old_Value=0; Old_Type=UNKNOWN;
|
||||
Serial.println(F("Send a signal repeatedly. We will report averages and statistics."));
|
||||
}
|
||||
void Tab(void) {Serial.print("\t");};
|
||||
void loop() {
|
||||
if (My_Receiver.GetResults(&My_Decoder)) {
|
||||
My_Decoder.decode();
|
||||
if( (My_Decoder.decode_type != Old_Type) || (My_Decoder.value != Old_Value)) {
|
||||
Serial.println(F("Resetting counters"));
|
||||
for(i=0;i<RAWBUF;i++) {
|
||||
Accumulated_Time[i]=0;
|
||||
};
|
||||
Samples=0;Old_Value= My_Decoder.value; Old_Type=My_Decoder.decode_type;
|
||||
};
|
||||
Samples++;
|
||||
Serial.print(F("\nSamples=")); Serial.println(Samples,DEC);
|
||||
LowSpace = LowMark=65535;
|
||||
HighSpace = HighMark=0;
|
||||
Mark_Avg= Space_Avg= Mark_Count= Space_Count=0;
|
||||
for(i=0;i<My_Decoder.rawlen;i++){
|
||||
Accumulated_Time[i]+=My_Decoder.rawbuf[i];
|
||||
My_Decoder.rawbuf[i]= Accumulated_Time[i]/Samples;//Put back average so DumpResults can report
|
||||
}
|
||||
My_Decoder.DumpResults();
|
||||
//Perform additional analysis
|
||||
for(i=3;i<My_Decoder.rawlen;i++){ //Compute low, high and average mark and space
|
||||
interval=My_Decoder.rawbuf[i];
|
||||
if(i % 2) {
|
||||
Mark_Avg += interval; LowMark=min(LowMark, interval); HighMark=max(HighMark, interval);Mark_Count++;
|
||||
} else {
|
||||
Space_Avg += interval; LowSpace=min(LowSpace, interval); HighSpace=max (HighSpace, interval);Space_Count++;
|
||||
}
|
||||
My_Decoder.rawbuf[i]= Accumulated_Time[i]/Samples;//Put back average so DumpResults can report
|
||||
}
|
||||
Mark_Avg /= Mark_Count; Space_Avg /= Space_Count;
|
||||
//Now compute below average highs and lows and above average highs and lows
|
||||
balm=bals=aalm=aals=32766;
|
||||
bahm=bahs=aahm=aahs=baam=baas=aaam=aaas=0;
|
||||
bacm=bacs=aacm=aacs=0;
|
||||
for(i=3;i<My_Decoder.rawlen;i++){
|
||||
interval=My_Decoder.rawbuf[i];
|
||||
if(i % 2) {
|
||||
if (interval>Mark_Avg) {
|
||||
aalm=min(aalm,interval); aahm=max(aahm,interval);aacm++;aaam+=interval;
|
||||
} else {
|
||||
balm=min(balm,interval); bahm=max(bahm,interval);bacm++;baam+=interval;
|
||||
}
|
||||
} else {
|
||||
if (interval>Space_Avg) {
|
||||
aals=min(aals,interval); aahs=max(aahs,interval);aacs++;aaas+=interval;
|
||||
} else {
|
||||
bals=min(bals,interval); bahs=max(bahs,interval);bacs++;baas+=interval;
|
||||
}
|
||||
}
|
||||
}
|
||||
baam/=bacm;baas/=bacs;aaam/=aacm;aaas/=aacs;
|
||||
Serial.println(F("\t #\tLow\tHigh\tAvg."));
|
||||
Serial.print(F("Mark\t"));Serial.print(Mark_Count,DEC);Tab();Serial.print(LowMark,DEC);Tab();Serial.print(HighMark,DEC);Tab();Serial.println(Mark_Avg,DEC);
|
||||
Serial.print(F("Space\t"));Serial.print(Space_Count,DEC);Tab();Serial.print(LowSpace,DEC);Tab();Serial.print(HighSpace,DEC);Tab();Serial.println(Space_Avg,DEC);
|
||||
|
||||
Serial.println(F("\nMarks\t\t #\tLow\tHigh\tAvg."));
|
||||
Serial.print(F("Above Avg\t"));Serial.print(aacm,DEC);Tab();Serial.print(aalm,DEC);Tab();Serial.print(aahm,DEC);Tab();Serial.println(aaam,DEC);
|
||||
Serial.print(F("Belows Avg.\t"));Serial.print(bacm,DEC);Tab();Serial.print(balm,DEC);Tab();Serial.print(bahm,DEC);Tab();Serial.println(baam,DEC);
|
||||
|
||||
Serial.println(F("\nSpaces\t\t #\tLow\tHigh\tAvg."));
|
||||
Serial.print(F("Above Avg.\t"));Serial.print(aacs,DEC);Tab();Serial.print(aals,DEC);Tab();Serial.print(aahs,DEC);Tab();Serial.println(aaas,DEC);
|
||||
Serial.print(F("Below Avg.\t"));Serial.print(bacs,DEC);Tab();Serial.print(bals,DEC);Tab();Serial.print(bahs,DEC);Tab();Serial.println(baas,DEC);
|
||||
|
||||
#define RATIO(n,d) Tab(); Serial.print(float(n)/float(d));
|
||||
Serial.print(F("\nRatios\t\tBelow\tAbove\n"));
|
||||
Serial.print(F("Head Mark"));RATIO(My_Decoder.rawbuf[1],baam);RATIO(My_Decoder.rawbuf[1],aaam);
|
||||
Serial.print(F("\nHead Space"));RATIO(My_Decoder.rawbuf[2],baas);RATIO(My_Decoder.rawbuf[2],aaas);
|
||||
Serial.print(F("\n\nMark Above/Below="));RATIO(aaam,baam);
|
||||
Serial.print(F("\nSpace Above/Below="));RATIO(aaas,baas);
|
||||
Serial.println();
|
||||
delay(500);
|
||||
My_Receiver.resume();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/* IRfreq: estimate modulation frequency of IR transmitter
|
||||
* Version 1.3 January 2014
|
||||
* Copyright 2014 by Chris Young http://tech.cyborg5.com
|
||||
* Based on Arduino firmware for use with AnalysIR IR signal analysis
|
||||
* software for Windows PCs. Many thanks to the people
|
||||
* at http://analysir.com for their assistance In developing this program.
|
||||
*/
|
||||
#define INTERRUPT_USED 1 // Value can be 0-5 depending on board.
|
||||
// You should attach your TSMP5800 or equivalent
|
||||
// receiver to appropriate pin as defined below.
|
||||
|
||||
// Do not modified this section
|
||||
#if defined(__AVR_ATmega32U4__) //Assume Arduino Leonardo
|
||||
#if(INTERRUPT_USED==0)
|
||||
#define PIN_USED 3
|
||||
#elif (INTERRUPT_USED==1)
|
||||
#define PIN_USED 2
|
||||
#elif (INTERRUPT_USED==2)
|
||||
#define PIN_USED 0
|
||||
#elif (INTERRUPT_USED==3)
|
||||
#define PIN_USED 1
|
||||
#elif (INTERRUPT_USED==4)
|
||||
#define PIN_USED 7
|
||||
#else
|
||||
#error "Invalid value for INTERRUPT_USED on Leonardo"
|
||||
#endif
|
||||
#elif (INTERRUPT_USED==0) //Uno or Mega
|
||||
#define PIN_USED 2
|
||||
#elif (INTERRUPT_USED==1) //Uno or Mega
|
||||
#define PIN_USED 3
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#if (INTERRUPT_USED==2) //Mega only
|
||||
#define PIN_USED 21
|
||||
#elif (INTERRUPT_USED==3) //Mega only
|
||||
#define PIN_USED 20
|
||||
#elif (INTERRUPT_USED==4) //Mega only
|
||||
#define PIN_USED 19
|
||||
#elif (INTERRUPT_USED==5) //Mega only
|
||||
#define PIN_USED 18
|
||||
#else
|
||||
#error "invalid value for INTERRUPT_USED on Arduino press delete this Michael down five mega"
|
||||
#endif
|
||||
#else
|
||||
#error "Invalid value for INTERRUPT_USED on non-Leonardo non-Mega board"
|
||||
#endif
|
||||
|
||||
#define BUF_SIZE 200
|
||||
// These are "volatile" because they are modified inside the interrupt handler
|
||||
volatile byte Time_Stamp[BUF_SIZE]; //Punch the time clock using "micros()" each time a pulse causes interrupt
|
||||
volatile byte Count; //Index into Time_Stamp
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
while(!Serial);//for Leonardo
|
||||
pinMode(PIN_USED, INPUT);
|
||||
Serial.print(F("Using interrupt="));Serial.println(INTERRUPT_USED,DEC);
|
||||
Serial.println(F("You should have Vishay TSMP58000 or equivalent"));
|
||||
Serial.print(F("connected to pin=")); Serial.println(PIN_USED,DEC);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
attachInterrupt(INTERRUPT_USED, My_Interrupt_Handler, FALLING);
|
||||
while(Count < (BUF_SIZE-10)); //do nothing but process interrupts until buffer almost fills
|
||||
//We took that extra 10 off just in case interrupt came too fast for us to turn them off
|
||||
detachInterrupt (INTERRUPT_USED);
|
||||
Report_Freq();//reports modulation frequency to host over serial
|
||||
}
|
||||
|
||||
void Report_Freq(){
|
||||
byte Count_Usable=0; //Counts the number of usable valid intervals
|
||||
unsigned long Sum=0; //Accumulate total of usable intervals
|
||||
byte I;
|
||||
byte Interval;//Interval between timestamps
|
||||
Count--;//last one doesn't count
|
||||
for (I=1;I<Count;I++){
|
||||
Interval=(Time_Stamp[I]-Time_Stamp[I-1]);
|
||||
if (Interval>50 || Interval<10) continue;//this is the period range length exclude extraneous ones
|
||||
Sum +=Interval; // Accumulate usable intervals
|
||||
Count_Usable++; // Count usable intervals
|
||||
Time_Stamp[I-1]=0;//finished with it so clear for next time
|
||||
}
|
||||
Time_Stamp[I-1]=0;//now clear last one, which was missed in loop
|
||||
Serial.print(F("Based on ")); Serial.print(Count_Usable,DEC);
|
||||
Serial.print(F(" intervals totaling ")); Serial.print(Sum,DEC);
|
||||
double Frequency=(double)Count_Usable/(double)Sum*1000;
|
||||
Serial.print(F(" microseconds, the frequency is approx. =")); Serial.print(Frequency);
|
||||
Serial.println(F("kHz"));
|
||||
delay(1000);
|
||||
Count=0; //reset value for next time
|
||||
}
|
||||
|
||||
void My_Interrupt_Handler(){
|
||||
Time_Stamp[Count++]=micros();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.3 January 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://www.righto.com/
|
||||
*/
|
||||
/*
|
||||
* IRhashdecode - 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.
|
||||
* This should produce a unique 32-bit number however that number cannot be used
|
||||
* to retransmit the same code. This is just a quick and dirty way to detect a unique code
|
||||
* for controlling a device when you don't really care what protocol or values
|
||||
* are being sent.
|
||||
*/
|
||||
|
||||
#include <IRLib.h>
|
||||
|
||||
int RECV_PIN = 11;
|
||||
|
||||
IRrecv My_Receiver(RECV_PIN);
|
||||
IRdecode My_Decoder;
|
||||
IRdecodeHash My_Hash_Decoder;
|
||||
|
||||
void setup()
|
||||
{
|
||||
My_Receiver.enableIRIn(); // Start the receiver
|
||||
Serial.begin(9600);
|
||||
delay(2000);while(!Serial);//delay for Leonardo
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (My_Receiver.GetResults(&My_Decoder)) {//Puts results in My_Decoder
|
||||
My_Hash_Decoder.copyBuf(&My_Decoder);//copy the results to the hash decoder
|
||||
My_Decoder.decode();
|
||||
Serial.print("real decode type:");
|
||||
Serial.print(Pnames(My_Decoder.decode_type));
|
||||
Serial.print(" value: 0x");
|
||||
Serial.print(My_Decoder.value, HEX);
|
||||
My_Hash_Decoder.decode();
|
||||
Serial.print(", hash decode: 0x");
|
||||
Serial.println(My_Hash_Decoder.hash, HEX); // Do something interesting with this value
|
||||
delay(1000);
|
||||
My_Receiver.resume();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.3 January 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://www.righto.com/
|
||||
*/
|
||||
/*
|
||||
* IRrecord: record and play back IR signals
|
||||
* An IR detector/demodulator must be connected to the input RECV_PIN.
|
||||
* An IR LED must be connected to the appropriate pin.(See IRLibTimer.h) for your
|
||||
* machine's timers and erupts.
|
||||
* Record a value by pointing your remote at the device then send any character
|
||||
* from the serial monitor to send the recorded value.
|
||||
* Also demonstrates how to use toggle bits which must be controlled outside
|
||||
* the library routines.
|
||||
* The logic is:
|
||||
* If an IR code is received, record it.
|
||||
* If g serial character is received, send the IR code.
|
||||
*/
|
||||
|
||||
#include <IRLib.h>
|
||||
|
||||
int RECV_PIN = 11;
|
||||
|
||||
IRrecv My_Receiver(RECV_PIN);
|
||||
IRdecode My_Decoder;
|
||||
IRsend My_Sender;
|
||||
/*
|
||||
* Because this version of the library separated the receiver from the decoder,
|
||||
* technically you would not need to "store" the code outside the decoder object
|
||||
* for this overly simple example. All of the details would remain in the object.
|
||||
* However we are going to go ahead and store them just to show you how.
|
||||
*/
|
||||
// Storage for the recorded code
|
||||
IRTYPES codeType; // The type of code
|
||||
unsigned long codeValue; // The data bits if type is not raw
|
||||
int codeBits; // The length of the code in bits
|
||||
|
||||
// These values are only stored if it's an unknown type and we are going to use
|
||||
// raw codes to resend the information.
|
||||
unsigned int rawCodes[RAWBUF]; // The durations if raw
|
||||
int rawCount; //The number of interval samples
|
||||
|
||||
bool GotOne, GotNew;
|
||||
|
||||
void setup()
|
||||
{
|
||||
GotOne=false; GotNew=false;
|
||||
codeType=UNKNOWN;
|
||||
codeValue=0;
|
||||
Serial.begin(9600);
|
||||
delay(2000);while(!Serial);//delay for Leonardo
|
||||
Serial.println(F("Send a code from your remote and we will record it."));
|
||||
Serial.println(F("Type any character and press enter. We will send the recorded code."));
|
||||
My_Receiver.enableIRIn(); // Start the receiver
|
||||
}
|
||||
|
||||
// Stores the code for later playback
|
||||
void storeCode(void) {
|
||||
GotNew=true;
|
||||
codeType = My_Decoder.decode_type;
|
||||
if (codeType == UNKNOWN) {
|
||||
Serial.println("Received unknown code, saving as raw");
|
||||
// To store raw codes:
|
||||
// Drop first value (gap)
|
||||
// As of v1.3 of IRLib global values are already in microseconds rather than ticks
|
||||
// They have also been adjusted for overreporting/underreporting of marks and spaces
|
||||
rawCount = My_Decoder.rawlen-1;
|
||||
for (int i = 1; i <=rawCount; i++) {
|
||||
rawCodes[i - 1] = My_Decoder.rawbuf[i];
|
||||
};
|
||||
My_Decoder.DumpResults();
|
||||
codeType=UNKNOWN;
|
||||
}
|
||||
else {
|
||||
Serial.print(F("Received "));
|
||||
Serial.print(Pnames(codeType));
|
||||
if (My_Decoder.value == REPEAT) {
|
||||
// Don't record a NEC repeat value as that's useless.
|
||||
Serial.println(F("repeat; ignoring."));
|
||||
}
|
||||
else {
|
||||
codeValue = My_Decoder.value;
|
||||
codeBits = My_Decoder.bits;
|
||||
}
|
||||
Serial.print(F(" Value:0x"));
|
||||
Serial.println(My_Decoder.value, HEX);
|
||||
}
|
||||
}
|
||||
void sendCode(int repeat) {
|
||||
if(codeType== UNKNOWN) {
|
||||
// Assume 38 KHz
|
||||
My_Sender.IRsendRaw::send(rawCodes,rawCount,38);
|
||||
Serial.println(F("Sent raw"));
|
||||
return;
|
||||
}
|
||||
if( !GotNew ) {//We've already sent this so handle toggle bits
|
||||
if (codeType == RC5) {
|
||||
codeValue ^= 0x0800;
|
||||
}
|
||||
else if (codeType == RC6) {
|
||||
codeValue ^= 0x10000;
|
||||
}
|
||||
}
|
||||
GotNew=false;
|
||||
My_Sender.send(codeType,codeValue,codeBits);
|
||||
Serial.print(F("Sent "));
|
||||
Serial.print(Pnames(codeType));
|
||||
Serial.print(F(" Value:0x"));
|
||||
Serial.println(codeValue, HEX);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (Serial.read() != -1) {
|
||||
if(GotOne) {
|
||||
sendCode(0);
|
||||
My_Receiver.enableIRIn(); // Re-enable receiver
|
||||
}
|
||||
}
|
||||
else if (My_Receiver.GetResults(&My_Decoder)) {
|
||||
My_Decoder.decode();
|
||||
GotOne=true;
|
||||
storeCode();
|
||||
delay(1000);
|
||||
My_Receiver.resume();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.3 January 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://www.righto.com/
|
||||
*/
|
||||
/*
|
||||
* IRLib: IRrecvDump - dump details of IR codes with IRrecv
|
||||
* An IR detector/demodulator must be connected to the input RECV_PIN.
|
||||
*/
|
||||
|
||||
#include <IRLib.h>
|
||||
|
||||
int RECV_PIN = 11;
|
||||
|
||||
IRrecv My_Receiver(RECV_PIN);
|
||||
|
||||
IRdecode My_Decoder;
|
||||
unsigned int Buffer[RAWBUF];
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
delay(2000);while(!Serial);//delay for Leonardo
|
||||
My_Receiver.enableIRIn(); // Start the receiver
|
||||
My_Decoder.UseExtnBuf(Buffer);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (My_Receiver.GetResults(&My_Decoder)) {
|
||||
//Restart the receiver so it can be capturing another code
|
||||
//while we are working on decoding this one.
|
||||
My_Receiver.resume();
|
||||
My_Decoder.decode();
|
||||
My_Decoder.DumpResults();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.3 January 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://www.righto.com/
|
||||
*/
|
||||
#include <IRLib.h>
|
||||
|
||||
IRsend My_Sender;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (Serial.read() != -1) {
|
||||
//send a code every time a character is received from the serial port
|
||||
//Sony DVD power A8BCA
|
||||
My_Sender.send(SONY,0xa8bca, 20);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.3 January 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://www.righto.com/
|
||||
*/
|
||||
/*
|
||||
* JVC sends repeat codes that are identical to the regular JVC codes
|
||||
* however they have no header. Therefore there is an additional parameter
|
||||
* that tells you whether or not to send as an original code or as a repeat.
|
||||
*
|
||||
* The only device I had to test this protocol was an old JVC VCR. It would only work if at least
|
||||
* 2 frames are sent separated by 45us of "space". All JVC is the same bit length so we use
|
||||
* the third parameter as a flag to tell it whether or not to send the header.
|
||||
* Send once with the third parameter "1" then delay about 50 microseconds and send again
|
||||
* with the third parameter "0".
|
||||
*/
|
||||
|
||||
#include <IRLib.h>
|
||||
|
||||
IRsend My_Sender;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
//send a code every time a character is received from the serial port
|
||||
void loop() {
|
||||
if (Serial.read() != -1) {
|
||||
My_Sender.send(JVC,0xc2d0,1); delayMicroseconds (50);
|
||||
My_Sender.send(JVC,0xc2d0,0); delayMicroseconds (50);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.3 January 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
* Use serial port to send codes. For details on this project see
|
||||
http://tech.cyborg5.com/2013/05/30/irlib-tutorial-part-3-overview-sending-ir-codes/
|
||||
*/
|
||||
#include <IRLib.h>
|
||||
|
||||
IRsend My_Sender;
|
||||
|
||||
int protocol;
|
||||
long code;
|
||||
int bits;
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
delay(2000);while(!Serial);//delay for Leonardo
|
||||
}
|
||||
|
||||
long parseHex (void) {
|
||||
long Value=0; char C;delay(100);
|
||||
while (Serial.available()>0) {
|
||||
C= tolower(Serial.read());
|
||||
if ((C>='0')&&(C<='9'))
|
||||
C=C-'0';
|
||||
else
|
||||
if ((C>='a') && (C<='f'))
|
||||
C=C-'a'+10;
|
||||
else
|
||||
return Value;
|
||||
Value= C+(Value<<4);
|
||||
};
|
||||
return Value;
|
||||
}
|
||||
void parseDelimiter () {
|
||||
char C;
|
||||
while(Serial.available()>0) {
|
||||
C=tolower(Serial.peek());
|
||||
if( (C>='0') && (C<='9') )return;
|
||||
if( (C>='a') && (C<='f') )return;
|
||||
C=Serial.read();//throwaway delimiters
|
||||
delay (5);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (Serial.available ()>0) {
|
||||
protocol = Serial.parseInt (); parseDelimiter();
|
||||
code = parseHex (); parseDelimiter();
|
||||
bits = Serial.parseInt (); parseDelimiter();
|
||||
Serial.print("Prot:"); Serial.print(protocol);
|
||||
Serial.print(" Code:"); Serial.print(code,HEX);
|
||||
Serial.print(" Bits:"); Serial.println(bits);
|
||||
My_Sender.send(IRTYPES(protocol), code, bits);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
# IRLib demo script
|
||||
# version 1.0 by Chris Young http://tech.cyborg5.com/irlib/
|
||||
# Displays a "Virtual remote" on your screen. Clicking on the
|
||||
# buttons sends serial datato the Arduino which in turn
|
||||
# since IR signals to a cable box in TV.
|
||||
|
||||
# Import all of the necessary pieces of code
|
||||
import serial, sys, pygame, pygame.mixer
|
||||
from pygame.locals import *
|
||||
|
||||
# You will have to edit this to the proper port and speed
|
||||
ser = serial.Serial('COM4', 9600)
|
||||
|
||||
pygame.init()
|
||||
# Established screen size, size of buttons and position
|
||||
size = width, height = 400, 768
|
||||
button_size=54; button_offset=71
|
||||
button_x1=65;button_y1=39
|
||||
max_rows=10; max_columns=4
|
||||
|
||||
# Specify a font. I'm using Arial narrow bold from my Windows
|
||||
# font folder. However the default font shown below also works.
|
||||
myfont =pygame.font.Font ("c:/windows/fonts/ARIALNB.TTF",30)
|
||||
#myfont=pygame.font.Font(None,36)
|
||||
|
||||
# These are the text labels that will appear on each button
|
||||
label_text=("TVp", "CBp", "P^", "Pv",\
|
||||
"<<", ">", ">>", "->",\
|
||||
"Rec", "=", "s", "<-",\
|
||||
"Gd", "^", "Fav", "Inf",\
|
||||
|
||||
"<", "sel", ">", "Lis",\
|
||||
"ret", "v", "Prv", "Mnu",\
|
||||
"1", "2", "3", "Ch+",\
|
||||
|
||||
"4", "5", "6", "Ch-",\
|
||||
"7", "8", "9", "Vol+",\
|
||||
"Pip", "0", "Mut", "Vol-",\
|
||||
)
|
||||
# Each of these 40 strings of text correspond to the
|
||||
# protocol in code which will be sent over the USB serial
|
||||
# to the Arduino. The first number is the protocol number.
|
||||
# See the defined protocols in "IRLib.h"for the
|
||||
# enum IRTYPES at about line 50. This example uses
|
||||
# protocol 3 which is "RC5" used by my Magnavox TV
|
||||
# and protocol 5 "PANASONIC_OLD" used by my Scientific
|
||||
# Atlantic SA 8300 DVR. The protocol number is followed by
|
||||
# the hex code to be transmitted. That is followed by the
|
||||
# number of bits. Note that the PANASONIC_OLD protocol
|
||||
# does not need the number of bits specified so they are omitted.
|
||||
IR_Codes= ("3,180c,13","5,37c107","5,36d924","5,37d904",\
|
||||
"5,37291a","5,37990c","5,36293a","5,36b129",\
|
||||
"5,375914","5,374117","5,365934","5,37c906",\
|
||||
"5,36c127","5,36812f","5,37f101","5,36213b",\
|
||||
|
||||
"5,37810f","5,366133","5,364137","5,36c926",\
|
||||
"5,366932","5,37a10b","5,36e123","5,373918",\
|
||||
"5,36113d","5,37111d","5,36912d","5,377111",\
|
||||
|
||||
"5,37910d","5,365135","5,375115","5,36f121",\
|
||||
"5,36d125","5,37d105","5,363139","3,1810,13",\
|
||||
"5,37b908","5,373119","3,180d,13","3,1811,13",\
|
||||
)
|
||||
# This function gets called to shut everything down
|
||||
def Finished():
|
||||
pygame.quit()
|
||||
sys.exit()
|
||||
|
||||
# Gets the button index based on mouse position. Returned
|
||||
# value is from 0 to 39 (number of buttons-1)
|
||||
# Returns -1 if you are not over a button.
|
||||
def ComputeButton():
|
||||
mx,my=pygame.mouse.get_pos()
|
||||
mx=mx-button_x1
|
||||
my=my-button_y1
|
||||
bx=mx/button_offset; by=my/button_offset
|
||||
if bx<0 or bx>=max_columns:return -1
|
||||
if by<0 or by> max_rows:return -1
|
||||
if (mx%button_offset)>button_size:return -1
|
||||
if (my%button_offset)>button_size:return -1
|
||||
return bx+by*max_columns
|
||||
|
||||
# Blits the button text from button number "i"
|
||||
# onto the specified layer using the specified color.
|
||||
def Show_Text(i,Layer,color=(0,0,0)):
|
||||
t=label_text[i]
|
||||
label = myfont.render (t,1,color)
|
||||
labelpos= label.get_rect()
|
||||
labelpos.centerx=button_x1+button_size/2+i%max_columns*button_offset
|
||||
labelpos.centery=button_y1+button_size/2+i/max_columns*button_offset
|
||||
Layer.blit(label,labelpos)
|
||||
|
||||
# Create the screen and load the background image.
|
||||
screen = pygame.display.set_mode(size)
|
||||
bg = pygame.image.load("remotebg.png")
|
||||
|
||||
# Blit black text labels onto the background image
|
||||
for i in range (max_rows*max_columns):
|
||||
Show_Text(i, bg)
|
||||
# Copy the background to the display
|
||||
screen.blit(bg,(0,0))
|
||||
pygame.display.flip()
|
||||
|
||||
# Load the clicking sound
|
||||
Click=pygame.mixer.Sound("click.wav")
|
||||
|
||||
# Used to detect when the mouse hovers over a different button
|
||||
previous=-1
|
||||
|
||||
while 1:
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
Finished()
|
||||
elif event.type == KEYDOWN and event.key == K_ESCAPE:
|
||||
Finished ()
|
||||
elif event.type == MOUSEBUTTONDOWN:
|
||||
i=ComputeButton() #which button did we click
|
||||
if i>=0:
|
||||
Click.play() #play the sound
|
||||
ser.write(IR_Codes[i]) #send the codes
|
||||
elif event.type==MOUSEMOTION:
|
||||
i=ComputeButton() #which button are we over
|
||||
if i!=previous: #difference in the last one?
|
||||
if i>=0: #turn it red
|
||||
Show_Text(i,screen,(255,0,0))
|
||||
else: #or put it back the way it was
|
||||
screen.blit(bg,(0,0))
|
||||
previous=i
|
||||
pygame.display.flip() #update the display
|
||||
# That's all folks
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
//POV-Ray source to generate the background image for IRserial_remote
|
||||
// create rectangular areas with rounded corners for use as
|
||||
// buttons and background objects.
|
||||
|
||||
// Render at 1024x768 then crop 312 pixels from each side
|
||||
// leaving 400x768 final image.
|
||||
#declare Area=15; //size of area lights
|
||||
#declare CR=0.1; //corner radius
|
||||
#declare ER= 0.5; //edge radius
|
||||
#declare CX= 3; //width from corner to corner
|
||||
#declare CY= 7.75; //height from corner to corner
|
||||
#declare BZ=-ER; //Z offset for buttons
|
||||
|
||||
plane {z,0 pigment{rgb<0.8,0.85,1>*0.8}}//background
|
||||
|
||||
#macro Thing (ER,CR,CX,CY,T)
|
||||
#local Corner=
|
||||
union {
|
||||
torus {CR,ER rotate x*90}
|
||||
cylinder {ER*z,-ER*z,CR}
|
||||
}
|
||||
union {
|
||||
object{Corner translate< CX,CY,0>}
|
||||
object{Corner translate<-CX,CY,0>}
|
||||
object{Corner translate< CX,-CY,0>}
|
||||
object{Corner translate<-CX,-CY,0>}
|
||||
cylinder{CY*y,-CY*y,ER translate<-CX-CR,0,0>}
|
||||
cylinder{CY*y,-CY*y,ER translate< CX+CR,0,0>}
|
||||
cylinder{CX*x,-CX*x,ER translate<0,-CY-CR,0>}
|
||||
cylinder{CX*x,-CX*x,ER translate<0, CY+CR,0>}
|
||||
box{<-CX,-CY-CR,-ER><CX,CY+CR,ER>}
|
||||
box{<-CX-CR,-CY,-ER><CX+CR,CY,ER>}
|
||||
texture {T}
|
||||
}
|
||||
#end
|
||||
|
||||
#declare BX= 0.4; #declare BY=BX;//size of the buttons
|
||||
#declare White_Texture=texture{pigment{rgb 1}finish {ambient 0.3}}
|
||||
#declare Blue_Texture=texture{pigment {rgb<0.85,0.9 ,1>}}
|
||||
|
||||
object {Thing(ER,CR,CX,CY, White_Texture)}//main object
|
||||
//loop through the buttons
|
||||
#declare R=-4.5;
|
||||
#while (R<5.5)
|
||||
#declare C=-1.5;
|
||||
#while (C<=1.5)
|
||||
object{Thing(0.1,0.2,(BX*0.8),(BY*0.8), Blue_Texture)
|
||||
translate <C*BX*4,R*BY*4,BZ>
|
||||
}
|
||||
#declare C=C+1;
|
||||
#end
|
||||
#declare R=R+1;
|
||||
#end
|
||||
|
||||
|
||||
light_source{<50,50,-100>*5 color 0.8
|
||||
#if (Area)area_light x*Area,y*Area,9,9#end
|
||||
}
|
||||
light_source{<0,0,-400>*3 rgb 1}
|
||||
|
||||
camera{orthographic location <0,0,-120> look_at <0,0,0> angle 11 }
|
||||
//That's all folks!
|
||||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 48 KiB |
@@ -0,0 +1,75 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.3 January 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
* "IRservo" Control a servo using an IR remote
|
||||
*/
|
||||
#include <IRLib.h>
|
||||
#include <Servo.h>
|
||||
/* Note: Servo library uses TIMER1. The default timer for IRLib on Arduino Uno
|
||||
* is TIMER2 so there is no conflict. However a default timer on Arduino Leonardo
|
||||
* is TIMER1 so you will have to modify the timer used to use TIMER3 or TIMER4
|
||||
* as specified in IRLibTimer.h. Also you will need to modify the input being used.
|
||||
*/
|
||||
// You will have to set these values depending on the protocol
|
||||
// and remote codes that you are using. These are from my Sony DVD/VCR
|
||||
#define MY_PROTOCOL SONY
|
||||
#define RIGHT_ARROW 0x86bca //Move several clockwise
|
||||
#define LEFT_ARROW 0x46bca //Move servo counterclockwise
|
||||
#define SELECT_BUTTON 0xd0bca //Center the servo
|
||||
#define UP_ARROW 0x42bca //Increased number of degrees servo moves
|
||||
#define DOWN_ARROW 0xc2bca //Decrease number of degrees servo moves
|
||||
#define BUTTON_0 0x90bca //Pushing buttons 0-9 moves to fix positions
|
||||
#define BUTTON_1 0x00bca // each 20 degrees greater
|
||||
#define BUTTON_2 0x80bca
|
||||
#define BUTTON_3 0x40bca
|
||||
#define BUTTON_4 0xc0bca
|
||||
#define BUTTON_5 0x20bca
|
||||
#define BUTTON_6 0xa0bca
|
||||
#define BUTTON_7 0x60bca
|
||||
#define BUTTON_8 0xe0bca
|
||||
#define BUTTON_9 0x10bca
|
||||
|
||||
IRrecv My_Receiver(11);//Receive on pin 11
|
||||
IRdecode My_Decoder;
|
||||
Servo My_Servo; // create servo object to control a servo
|
||||
int pos; // variable to store the servo position
|
||||
int Speed; // Number of degrees to move each time a left/right button is pressed
|
||||
|
||||
void setup()
|
||||
{
|
||||
My_Receiver.No_Output();//Turn off any unused IR LED output circuit
|
||||
My_Servo.attach(9); // attaches the servo on pin 9 to the servo object
|
||||
pos = 90; // start at midpoint 90 degrees
|
||||
Speed = 3; // servo moves 3 degrees each time left/right is pushed
|
||||
My_Servo.write(pos); // Set initial position
|
||||
My_Receiver.enableIRIn(); // Start the receiver
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (My_Receiver.GetResults(&My_Decoder)) {
|
||||
My_Decoder.decode();
|
||||
if(My_Decoder.decode_type==MY_PROTOCOL) {
|
||||
switch(My_Decoder.value) {
|
||||
case LEFT_ARROW: pos=min(180,pos+Speed); break;
|
||||
case RIGHT_ARROW: pos=max(0,pos-Speed); break;
|
||||
case SELECT_BUTTON: pos=90; break;
|
||||
case UP_ARROW: Speed=min(10, Speed+1); break;
|
||||
case DOWN_ARROW: Speed=max(1, Speed-1); break;
|
||||
case BUTTON_0: pos=0*20; break;
|
||||
case BUTTON_1: pos=1*20; break;
|
||||
case BUTTON_2: pos=2*20; break;
|
||||
case BUTTON_3: pos=3*20; break;
|
||||
case BUTTON_4: pos=4*20; break;
|
||||
case BUTTON_5: pos=5*20; break;
|
||||
case BUTTON_6: pos=6*20; break;
|
||||
case BUTTON_7: pos=7*20; break;
|
||||
case BUTTON_8: pos=8*20; break;
|
||||
case BUTTON_9: pos=9*20; break;
|
||||
}
|
||||
My_Servo.write(pos); // tell servo to go to position in variable 'pos'
|
||||
}
|
||||
My_Receiver.resume();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,258 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.4 March 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009I know prescription and no
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://www.righto.com/
|
||||
*/
|
||||
/*
|
||||
* This example demonstrates how to extend this library to add a new protocol
|
||||
* without actually modifying or recompiling the library itself. It implements a 36 bit
|
||||
* Samsung protocol that is used on a Blu-ray player that I own.
|
||||
* Because a 36 bit value will not fit in the value field (only 32 bits) we have to create
|
||||
* a second value field. This is a modified version of the IRecord example.
|
||||
*/
|
||||
#include <IRLib.h>
|
||||
#include <IRLibMatch.h>
|
||||
/* Although it is not necessary for this example to run, everything in this section
|
||||
* this section of the code could be moved to the actual IRLib.h file
|
||||
*/
|
||||
class IRdecodeSamsung36: public virtual IRdecodeBase
|
||||
{
|
||||
public:
|
||||
bool decode(void);
|
||||
unsigned int value2;
|
||||
void Reset(void);
|
||||
private:
|
||||
bool GetBit(void);
|
||||
int offset;
|
||||
unsigned long data;
|
||||
};
|
||||
|
||||
class IRsendSamsung36: public virtual IRsendBase
|
||||
{
|
||||
public:
|
||||
void send(unsigned long data, unsigned long data2);
|
||||
private:
|
||||
void PutBits (unsigned long data, int nbits);
|
||||
};
|
||||
/* If moving this code to IRLib.h instead of the line below at about
|
||||
line 60 you should search for the line that says...
|
||||
#define ADDITIONAL (number)
|
||||
and change the code to read as follows‘
|
||||
#define NECX 7
|
||||
#define SAMSUNG36 8
|
||||
#define HASH_CODE 9
|
||||
#define LAST_PROTOCOL HASH_CODE
|
||||
Also at approximately line 160 look for the line that says...
|
||||
, public virtual IRdecodeADDITIONAL
|
||||
and change it to read...
|
||||
public virtual IRdecodeNECx, //Be sure to add the comma
|
||||
public virtual IRdecodeSamsung36 //No comma here
|
||||
And at about line 238 change to read...
|
||||
public virtual IRsendNECx, //Be sure to add the comma
|
||||
public virtual IRsendSamsung36 //No comma here
|
||||
Which will add this protocol to the master send and decode classes
|
||||
*/
|
||||
#define SAMSUNG36 (LAST_PROTOCOL+1)
|
||||
|
||||
/* Although it is not necessary for this example to run, everything in this section
|
||||
* this section of the code could be moved to the actual IRLib.cpp file
|
||||
*/
|
||||
/*
|
||||
* According to http://www.hifi-remote.com/johnsfine/DecodeIR.html#Samsung36
|
||||
* The IRP notation for this protocol is:
|
||||
* {38k,500}<1,-1|1,-3>(9,-9,D:8,S:8,1,-9,E:4,F:8,-68u,~F:8,1,-118)+
|
||||
* This means it uses 38k frequency. Base timing is multiples of 500.
|
||||
* A "0" is mark(500) space(500). A "1" is mark (500) space(1500)
|
||||
* The header is mark(4500) space(4500).
|
||||
* The header is followed by 16 bits (8 device, 8 sub device)
|
||||
* This is followed by a mark(500) space(4500).
|
||||
* This is followed by 12 more bits (4+8)
|
||||
* This is followed by 68us ofspace. Followed by eight more bits
|
||||
* and a final stop bit.
|
||||
*/
|
||||
/* Because not all of the data bits are contiguous in the stream
|
||||
* we created this little routine to get one data bit.
|
||||
* We then call it in a loop as needed.
|
||||
*/
|
||||
bool IRdecodeSamsung36::GetBit(void) {
|
||||
if (!MATCH(rawbuf[offset],500)) return DATA_MARK_ERROR(500);
|
||||
offset++;
|
||||
if (MATCH(rawbuf[offset],1500))
|
||||
data = (data << 1) | 1;
|
||||
else if (MATCH(rawbuf[offset],500))
|
||||
data <<= 1;
|
||||
else return DATA_SPACE_ERROR(1500);
|
||||
offset++;
|
||||
return true;
|
||||
};
|
||||
bool IRdecodeSamsung36::decode(void) {
|
||||
IRLIB_ATTEMPT_MESSAGE(F("Samsung36"));
|
||||
if (rawlen != 78) return RAW_COUNT_ERROR;
|
||||
if (!MATCH(rawbuf[1],4500)) return HEADER_MARK_ERROR(4500);
|
||||
if (!MATCH(rawbuf[2],4500)) return HEADER_SPACE_ERROR(4500);
|
||||
offset=3; data=0;
|
||||
//Get first 16 bits
|
||||
while (offset < 16*2+2) if(!GetBit()) return false;
|
||||
//Skip middle header
|
||||
if (!MATCH(rawbuf[offset],500)) return DATA_MARK_ERROR(500);
|
||||
offset++;
|
||||
if (!MATCH(rawbuf[offset],4500)) return DATA_SPACE_ERROR(4400);
|
||||
//save first 16 bits in "value2" and reset data
|
||||
offset++; value2=data; data=0;
|
||||
//12 bits into this second segment there is a 68us space
|
||||
//so we find one of the raw values to eliminate that
|
||||
rawbuf[62]=rawbuf[62]-68;
|
||||
//this gets remaining 20 bits
|
||||
while(offset<77)if(!GetBit()) return false;
|
||||
bits =36;//set bit length
|
||||
value = data;//put remaining 12 bits in value
|
||||
decode_type= static_cast<IRTYPES>SAMSUNG36;
|
||||
return true;
|
||||
};
|
||||
//The Reset method clears out the data however we have extra data to clear
|
||||
void IRdecodeSamsung36::Reset(void) {
|
||||
IRdecodeBase::Reset();//respect your parents
|
||||
value2=0;
|
||||
};
|
||||
//Similar to GetBits, this routine sends just one bit of data.
|
||||
//Need this because data bits are not contiguous in the stream
|
||||
void IRsendSamsung36::PutBits (unsigned long data, int nbits){
|
||||
for (int i = 0; i < nbits; i++) {
|
||||
if (data & 0x80000000) {
|
||||
mark(500); space(1500);
|
||||
} else {
|
||||
mark(500); space(500);
|
||||
};
|
||||
data <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void IRsendSamsung36::send(unsigned long data, unsigned long data2) {
|
||||
data <<= 32-20;
|
||||
data2 <<= 32-16;
|
||||
enableIROut(38);
|
||||
mark(4500); space(4500);//Send header
|
||||
PutBits (data2, 16);//Send data2 16 bits
|
||||
mark (500); space (4500);//Send break
|
||||
PutBits (data, 12);//Send 12 bits
|
||||
space(68);//Send tiny break
|
||||
data <<= 12;
|
||||
PutBits (data, 8);mark(500); //Final eight bits and one stop bit
|
||||
space(118*500);//Lead out is 118 times the base time 500
|
||||
};
|
||||
/*
|
||||
* This concludes the portion that you could move to IRLib.cpp
|
||||
* Additionally at apprx. line 39 add F("Samsung36"), to the list
|
||||
* between NECx and hash code.
|
||||
* Also add "case SAMSUNG36:IRsendSamsung36::send(data,nbits); break;
|
||||
* at about line 238. Also at about 400 add
|
||||
* if (IRdecodeSamsung36::decode()) return true;
|
||||
*/
|
||||
|
||||
/*
|
||||
* The remaining code is unique to the example sketch.
|
||||
* We will create a custom class which is a combination
|
||||
* of all other protocols and our new protocol.
|
||||
*/
|
||||
|
||||
class MyCustomSend:
|
||||
public virtual IRsend,
|
||||
public virtual IRsendSamsung36
|
||||
{
|
||||
public:
|
||||
//Note: data2 is the number of bits for non-Samsung36 protocols
|
||||
void send(IRTYPES Type, unsigned long data, int data2);
|
||||
};
|
||||
void MyCustomSend::send(IRTYPES Type, unsigned long data, int data2) {
|
||||
if (Type==SAMSUNG36)
|
||||
IRsendSamsung36::send(data,data2);
|
||||
else
|
||||
IRsend::send(Type, data, data2);
|
||||
}
|
||||
class MyCustomDecode:
|
||||
public virtual IRdecode,
|
||||
public virtual IRdecodeSamsung36
|
||||
{
|
||||
public:
|
||||
virtual bool decode(void); // Calls each decode routine individually
|
||||
void DumpResults(void);
|
||||
};
|
||||
bool MyCustomDecode::decode(void) {
|
||||
if (IRdecodeSamsung36::decode()) return true;
|
||||
return IRdecode::decode ();
|
||||
}
|
||||
void MyCustomDecode::DumpResults(void){
|
||||
if(decode_type==SAMSUNG36) {
|
||||
Serial.print(F("Decoded Samsung36: Value:")); Serial.print(value, HEX);
|
||||
Serial.print(F(": Value2:")); Serial.print(value2, HEX);
|
||||
};
|
||||
IRdecode::DumpResults();
|
||||
};
|
||||
|
||||
MyCustomDecode My_Decoder;
|
||||
|
||||
MyCustomSend My_Sender;
|
||||
|
||||
int RECV_PIN = 11;
|
||||
|
||||
IRrecv My_Receiver(RECV_PIN);
|
||||
IRTYPES codeType; // The type of code
|
||||
unsigned long codeValue; // The data bits
|
||||
int codeBits; // The length of the code in bits or for Samsung is storage for data2
|
||||
bool GotOne;
|
||||
|
||||
void setup()
|
||||
{
|
||||
GotOne=false;
|
||||
codeType=UNKNOWN;
|
||||
codeValue=0;
|
||||
codeBits=0;//Stores data2 on Samsung36. Stores number of bits on another protocols
|
||||
Serial.begin(9600);
|
||||
delay(2000); while(!Serial);
|
||||
Serial.println(F("Send a code from your remote and we will record it."));
|
||||
Serial.println(F("Type any character and press enter. We will send the recorded code."));
|
||||
My_Receiver.enableIRIn(); // Start the receiver
|
||||
}
|
||||
void loop() {
|
||||
if (Serial.available()>0) {
|
||||
unsigned char c=Serial.read();
|
||||
if (c=='p') {//Send a test pattern
|
||||
GotOne= true; codeType=SAMSUNG36; codeValue=0x12345; codeBits=0x6789;
|
||||
}
|
||||
if(GotOne) {
|
||||
My_Sender.send(codeType,codeValue,codeBits);
|
||||
Serial.print(F("Sent "));
|
||||
if (codeType==SAMSUNG36) {
|
||||
Serial.print(F("Samsung36 Value:0x"));
|
||||
Serial.print(codeValue, HEX);
|
||||
Serial.print(F(" Value2:0x"));
|
||||
Serial.println(codeBits, HEX);
|
||||
} else {
|
||||
Serial.print(Pnames(codeType));
|
||||
Serial.print(F(" Value:0x"));
|
||||
Serial.print(codeValue, HEX);
|
||||
Serial.print(F(" Bits:"));
|
||||
Serial.println(codeBits, DEC);
|
||||
};
|
||||
My_Receiver.enableIRIn(); // Re-enable receiver
|
||||
}
|
||||
}
|
||||
else if (My_Receiver.GetResults(&My_Decoder)) {
|
||||
My_Decoder.decode();
|
||||
if(My_Decoder.decode_type == UNKNOWN) {
|
||||
Serial.println(F("Unknown type received. Ignoring."));
|
||||
} else {
|
||||
codeType= My_Decoder.decode_type;
|
||||
codeValue= My_Decoder.value;
|
||||
codeBits= My_Decoder.bits;
|
||||
GotOne=true;
|
||||
}
|
||||
My_Decoder.DumpResults();
|
||||
delay(1000);
|
||||
My_Receiver.resume();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.4 March 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009I know prescription and no
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://www.righto.com/
|
||||
*/
|
||||
/*
|
||||
* This example demonstrates how to extend this library to add a new protocol
|
||||
* without actually modifying or recompiling the libnonstickrary itself. It implements the
|
||||
* Phillips RC-MM also known as Nokia Protocol. Is used by AT&T U-Verse cable boxes.
|
||||
* There are three different varieties that are 12, 24, or 32 bits.
|
||||
* This is a modified version of the IRecord example.
|
||||
* If you would like to make this a permanent part of your library you could copy the class
|
||||
* prototypes to IRLib.h and the code itself to IRLib.cpp. Search for the word "ADDITIONAL"
|
||||
* to see where to add various pieces of code. Also see the Samsung36 example for details.
|
||||
*/
|
||||
#include <IRLib.h>
|
||||
#include <IRLibMatch.h>
|
||||
|
||||
class IRdecodeRCMM: public virtual IRdecodeBase
|
||||
{
|
||||
public:
|
||||
bool decode(void);
|
||||
};
|
||||
|
||||
class IRsendRCMM: public virtual IRsendBase
|
||||
{
|
||||
public:
|
||||
void send(unsigned long data, unsigned char nbits);
|
||||
};
|
||||
|
||||
#define RCMM (LAST_PROTOCOL+1)
|
||||
#define RCMM_HEAD_MARK 417
|
||||
#define RCMM_DATA_MARK 167
|
||||
#define RCMM_ZERO 278
|
||||
#define RCMM_ONE 444
|
||||
#define RCMM_TWO 611
|
||||
#define RCMM_THREE 778
|
||||
|
||||
/*
|
||||
* According to http://www.hifi-remote.com/johnsfine/DecodeIR.html#Nokia
|
||||
* The IRP notation for these protocols are:
|
||||
* Nokia 12 bit: {36k,msb}<164,-276|164,-445|164,-614|164,-783>(412,-276,D:4,F:8,164,-???)+
|
||||
* Nokia 24-bit: {36k,msb}<164,-276|164,-445|164,-614|164,-783>(412,-276,D:8,S:8,F:8,164,-???)+
|
||||
* Nokia 32 bit: {36k,msb}<164,-276|164,-445|164,-614|164,-783>(412,-276,D:8,S:8,X:8,F:8,164,^100m)+
|
||||
* Slightly different timing values are documented at
|
||||
* http://www.sbprojects.com/knowledge/ir/rcmm.php
|
||||
* We will use the timing from the latter reference.
|
||||
* Unlike most protocols which defined sequences for a logical "0" and "1", this protocol
|
||||
* encodes 2 bits per pulse. Therefore it encodes a logical "2" and "3" as well.
|
||||
* The length of the mark is constant but the length of the space denotes the bit values.
|
||||
* Note the 32-bit version uses a toggle bit of 0x8000 and as usual it is up to the end-user
|
||||
* to implement it outside the library routines.
|
||||
*/
|
||||
/*
|
||||
* Normally IRLib uses a plus or minus percentage to determine if an interval matches the
|
||||
* desired value. However this protocol uses extremely long intervals of similar length.
|
||||
* For example using the default 25% tolerance the RCMM_TWO value 611 would be accepted for
|
||||
* anything between 458 and 763. The low end is actually closer to RCMM_ONE value of 444
|
||||
* and the upper range is closer to RCM_THREE value of 778. To implement this protocol
|
||||
* we created a new match routine ABS_MATCH which allows you to specify an absolute
|
||||
* number of microseconds of tolerance for comparison.
|
||||
*/
|
||||
#define RCMM_TOLERANCE 80
|
||||
bool IRdecodeRCMM::decode(void) {
|
||||
long data;
|
||||
IRLIB_ATTEMPT_MESSAGE(F("RCMM"));
|
||||
if ( (rawlen!=(12+2)) && (rawlen!=(24+2)) && (rawlen!=(32+4)) ) return RAW_COUNT_ERROR;
|
||||
if (!MATCH(rawbuf[1],RCMM_HEAD_MARK)) return HEADER_MARK_ERROR(RCMM_HEAD_MARK);
|
||||
if (!MATCH(rawbuf[2],RCMM_ZERO)) return HEADER_SPACE_ERROR(RCMM_ZERO);
|
||||
offset=3; data=0;
|
||||
while (offset < (rawlen-1)) {
|
||||
if (!ABS_MATCH(rawbuf[offset],RCMM_DATA_MARK, RCMM_TOLERANCE+50)) return DATA_MARK_ERROR(RCMM_DATA_MARK);
|
||||
offset++;
|
||||
if (ABS_MATCH(rawbuf[offset],RCMM_ZERO, RCMM_TOLERANCE) ) { //Logical "0"
|
||||
data <<= 2;
|
||||
}
|
||||
else if (ABS_MATCH(rawbuf[offset],RCMM_ONE, RCMM_TOLERANCE) ) { //Logical "1"
|
||||
data = (data<<2) + 1;
|
||||
}
|
||||
else if (ABS_MATCH(rawbuf[offset],RCMM_TWO, RCMM_TOLERANCE) ) { //Logical "2"
|
||||
data = (data<<2) + 2;
|
||||
}
|
||||
else if (ABS_MATCH(rawbuf[offset],RCMM_THREE, RCMM_TOLERANCE) ) { //Logical "3"
|
||||
data = (data<<2) + 3;
|
||||
}
|
||||
else return DATA_SPACE_ERROR(RCMM_ZERO);
|
||||
offset++;
|
||||
}
|
||||
if (!MATCH(rawbuf[offset],RCMM_DATA_MARK)) return DATA_MARK_ERROR(RCMM_DATA_MARK);
|
||||
bits = rawlen-4;//set bit length
|
||||
value = data;//put remaining bits in value
|
||||
decode_type= static_cast<IRTYPES>RCMM;
|
||||
return true;
|
||||
};
|
||||
|
||||
void IRsendRCMM::send(unsigned long data, unsigned char nbits) {
|
||||
Extent=0;
|
||||
data = data << (32 - nbits);
|
||||
nbits=nbits/2;
|
||||
enableIROut(36);
|
||||
mark(RCMM_HEAD_MARK); space(RCMM_ZERO);//Send header
|
||||
for (int i = 0; i < nbits; i++) {
|
||||
mark(RCMM_DATA_MARK);
|
||||
switch (data & 0xC0000000UL) {//use the leftmost two bits
|
||||
case 0x00000000UL: space(RCMM_ZERO); break;
|
||||
case 0x40000000UL: space(RCMM_ONE); break;
|
||||
case 0x80000000UL: space(RCMM_TWO); break;
|
||||
case 0xC0000000UL: space(RCMM_THREE); break;
|
||||
default: Serial.println("sending error");
|
||||
}
|
||||
data <<= 2;
|
||||
};
|
||||
mark(RCMM_DATA_MARK);
|
||||
space(27778-Extent);
|
||||
};
|
||||
|
||||
//Create a custom class that combines this new protocol with all the others
|
||||
class MyCustomSend:
|
||||
public virtual IRsend,
|
||||
public virtual IRsendRCMM
|
||||
{
|
||||
public:
|
||||
void send(IRTYPES Type, unsigned long data, int nbits);
|
||||
};
|
||||
void MyCustomSend::send(IRTYPES Type, unsigned long data, int nbits) {
|
||||
if (Type==RCMM)
|
||||
IRsendRCMM::send(data,nbits);
|
||||
else
|
||||
IRsend::send(Type, data, nbits);
|
||||
}
|
||||
class MyCustomDecode:
|
||||
public virtual IRdecode,
|
||||
public virtual IRdecodeRCMM
|
||||
{
|
||||
public:
|
||||
virtual bool decode(void); // Calls each decode routine individually
|
||||
void DumpResults(void);
|
||||
};
|
||||
bool MyCustomDecode::decode(void) {
|
||||
if (IRdecodeRCMM::decode()) return true;
|
||||
return IRdecode::decode ();
|
||||
}
|
||||
void MyCustomDecode::DumpResults(void){
|
||||
if(decode_type==RCMM) {
|
||||
Serial.print(F("Decoded RCMM: Value:")); Serial.print(value, HEX);
|
||||
};
|
||||
IRdecode::DumpResults();
|
||||
};
|
||||
|
||||
MyCustomDecode My_Decoder;
|
||||
|
||||
MyCustomSend My_Sender;
|
||||
|
||||
int RECV_PIN = 11;
|
||||
|
||||
IRrecv My_Receiver(RECV_PIN);
|
||||
IRTYPES codeType; // The type of code
|
||||
unsigned long codeValue; // The data bits
|
||||
int codeBits; // The length of the code in bits or for Samsung is storage for data2
|
||||
bool GotOne;
|
||||
char c;
|
||||
|
||||
void setup()
|
||||
{
|
||||
GotOne=false;
|
||||
codeType=UNKNOWN;
|
||||
codeValue=0;
|
||||
codeBits=0;
|
||||
Serial.begin(9600);while (! Serial) {};
|
||||
Serial.println(F("Send a code from your remote and we will record it."));
|
||||
Serial.println(F("Type any character and press enter. We will send the recorded code."));
|
||||
My_Receiver.enableIRIn(); // Start the receiver
|
||||
My_Receiver.Mark_Excess=40;
|
||||
}
|
||||
void loop() {
|
||||
if (Serial.available()>0) {
|
||||
c=Serial.read();
|
||||
if (c=='p') {//Send a test pattern
|
||||
GotOne= true; codeType=RCMM; codeValue=0x12345678; codeBits= 32;
|
||||
}
|
||||
if(GotOne) {
|
||||
My_Sender.send(codeType,codeValue,codeBits);
|
||||
Serial.print(F("Sent "));
|
||||
if (codeType== RCMM) Serial.print(F("RCMM")); else Serial.print(Pnames(codeType));
|
||||
Serial.print(F(" Value:0x"));
|
||||
Serial.print(codeValue, HEX);
|
||||
Serial.print(F(" Bits:"));
|
||||
Serial.println(codeBits, DEC);
|
||||
My_Receiver.enableIRIn(); // Re-enable receiver
|
||||
}
|
||||
}
|
||||
else if (My_Receiver.GetResults(&My_Decoder)) {
|
||||
My_Decoder.decode();
|
||||
if(My_Decoder.decode_type == UNKNOWN) {
|
||||
Serial.println(F("Unknown type received. Ignoring."));
|
||||
} else {
|
||||
codeType= My_Decoder.decode_type;
|
||||
codeValue= My_Decoder.value;
|
||||
codeBits= My_Decoder.bits;
|
||||
GotOne=true;
|
||||
}
|
||||
My_Decoder.DumpResults();
|
||||
delay(1000);
|
||||
My_Receiver.resume();
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user