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:
@@ -38,7 +38,7 @@
|
||||
//Gateway gw;
|
||||
|
||||
// To start gateway with include button and led blinking functionality enabled use this instead!
|
||||
Gateway gw(9, 10, INCLUSION_MODE_TIME, INCLUSION_MODE_PIN, 6, 5, 4);
|
||||
Gateway gw(5, 6, INCLUSION_MODE_TIME, INCLUSION_MODE_PIN, 6, 5, 4);
|
||||
|
||||
|
||||
char inputString[MAX_RECEIVE_LENGTH] = ""; // A string to hold incoming commands from serial/ethernet interface
|
||||
|
||||
@@ -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
|
||||
@@ -1,33 +1,48 @@
|
||||
/* 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://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
|
||||
*
|
||||
* Modified by Paul Stoffregen <paul@pjrc.com> to support other boards and timers
|
||||
* 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/
|
||||
*
|
||||
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
|
||||
*/
|
||||
|
||||
#ifndef IRremoteint_h
|
||||
#define IRremoteint_h
|
||||
/* 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>
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
// define which timer to use
|
||||
//
|
||||
// Uncomment the timer you wish to use on your board. If you
|
||||
// are using another library which uses timer2, you have options
|
||||
// to switch IRremote to use a different timer.
|
||||
|
||||
// Arduino Mega
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
//#define IR_USE_TIMER1 // tx = pin 11
|
||||
@@ -40,11 +55,20 @@
|
||||
#elif defined(__AVR_AT90USB162__)
|
||||
#define IR_USE_TIMER1 // tx = pin 17
|
||||
|
||||
// Teensy 2.0
|
||||
// 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__)
|
||||
@@ -56,14 +80,7 @@
|
||||
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||
//#define IR_USE_TIMER1 // tx = pin 13
|
||||
#define IR_USE_TIMER2 // tx = pin 14
|
||||
|
||||
// Atmega8
|
||||
#elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__)
|
||||
#define IR_USE_TIMER1 // tx = pin 9
|
||||
|
||||
#elif defined( __AVR_ATtinyX4__ )
|
||||
#define IR_USE_TIMER1 // tx = pin 6
|
||||
|
||||
|
||||
// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, etc
|
||||
#else
|
||||
//#define IR_USE_TIMER1 // tx = pin 9
|
||||
@@ -72,152 +89,6 @@
|
||||
|
||||
|
||||
|
||||
#ifdef F_CPU
|
||||
#define SYSCLOCK F_CPU // main Arduino clock
|
||||
#else
|
||||
#define SYSCLOCK 16000000 // main Arduino clock
|
||||
#endif
|
||||
|
||||
#define ERR 0
|
||||
#define DECODED 1
|
||||
|
||||
|
||||
// defines for setting and clearing register bits
|
||||
#ifndef cbi
|
||||
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
|
||||
#endif
|
||||
#ifndef sbi
|
||||
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
|
||||
#endif
|
||||
|
||||
// Pulse parms are *50-100 for the Mark and *50+100 for the space
|
||||
// First MARK is the one after the long gap
|
||||
// pulse parameters in usec
|
||||
#define NEC_HDR_MARK 9000
|
||||
#define NEC_HDR_SPACE 4500
|
||||
#define NEC_BIT_MARK 560
|
||||
#define NEC_ONE_SPACE 1692
|
||||
#define NEC_ZERO_SPACE 560
|
||||
#define NEC_RPT_SPACE 2250
|
||||
|
||||
#define SONY_HDR_MARK 2400
|
||||
#define SONY_HDR_SPACE 600
|
||||
#define SONY_ONE_MARK 1200
|
||||
#define SONY_ZERO_MARK 600
|
||||
#define SONY_RPT_LENGTH 45000
|
||||
#define SONY_DOUBLE_SPACE_USECS 500 // usually ssee 713 - not using ticks as get number wrapround
|
||||
|
||||
// SA 8650B
|
||||
#define SANYO_HDR_MARK 3500 // seen range 3500
|
||||
#define SANYO_HDR_SPACE 950 // seen 950
|
||||
#define SANYO_ONE_MARK 2400 // seen 2400
|
||||
#define SANYO_ZERO_MARK 700 // seen 700
|
||||
#define SANYO_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround
|
||||
#define SANYO_RPT_LENGTH 45000
|
||||
|
||||
// Mitsubishi RM 75501
|
||||
// 14200 7 41 7 42 7 42 7 17 7 17 7 18 7 41 7 18 7 17 7 17 7 18 7 41 8 17 7 17 7 18 7 17 7
|
||||
|
||||
// #define MITSUBISHI_HDR_MARK 250 // seen range 3500
|
||||
#define MITSUBISHI_HDR_SPACE 350 // 7*50+100
|
||||
#define MITSUBISHI_ONE_MARK 1950 // 41*50-100
|
||||
#define MITSUBISHI_ZERO_MARK 750 // 17*50-100
|
||||
// #define MITSUBISHI_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround
|
||||
// #define MITSUBISHI_RPT_LENGTH 45000
|
||||
|
||||
|
||||
#define RC5_T1 889
|
||||
#define RC5_RPT_LENGTH 46000
|
||||
|
||||
#define RC6_HDR_MARK 2666
|
||||
#define RC6_HDR_SPACE 889
|
||||
#define RC6_T1 444
|
||||
#define RC6_RPT_LENGTH 46000
|
||||
|
||||
#define SHARP_BIT_MARK 245
|
||||
#define SHARP_ONE_SPACE 1805
|
||||
#define SHARP_ZERO_SPACE 795
|
||||
#define SHARP_GAP 600000
|
||||
#define SHARP_TOGGLE_MASK 0x3FF
|
||||
#define SHARP_RPT_SPACE 3000
|
||||
|
||||
#define DISH_HDR_MARK 400
|
||||
#define DISH_HDR_SPACE 6100
|
||||
#define DISH_BIT_MARK 400
|
||||
#define DISH_ONE_SPACE 1700
|
||||
#define DISH_ZERO_SPACE 2800
|
||||
#define DISH_RPT_SPACE 6200
|
||||
#define DISH_TOP_BIT 0x8000
|
||||
|
||||
#define PANASONIC_HDR_MARK 3502
|
||||
#define PANASONIC_HDR_SPACE 1750
|
||||
#define PANASONIC_BIT_MARK 502
|
||||
#define PANASONIC_ONE_SPACE 1244
|
||||
#define PANASONIC_ZERO_SPACE 400
|
||||
|
||||
#define JVC_HDR_MARK 8000
|
||||
#define JVC_HDR_SPACE 4000
|
||||
#define JVC_BIT_MARK 600
|
||||
#define JVC_ONE_SPACE 1600
|
||||
#define JVC_ZERO_SPACE 550
|
||||
#define JVC_RPT_LENGTH 60000
|
||||
|
||||
#define SHARP_BITS 15
|
||||
#define DISH_BITS 16
|
||||
|
||||
#define TOLERANCE 25 // percent tolerance in measurements
|
||||
#define LTOL (1.0 - TOLERANCE/100.)
|
||||
#define UTOL (1.0 + TOLERANCE/100.)
|
||||
|
||||
#define _GAP 5000 // Minimum map between transmissions
|
||||
#define GAP_TICKS (_GAP/USECPERTICK)
|
||||
|
||||
#define TICKS_LOW(us) (int) (((us)*LTOL/USECPERTICK))
|
||||
#define TICKS_HIGH(us) (int) (((us)*UTOL/USECPERTICK + 1))
|
||||
|
||||
#ifndef DEBUG
|
||||
int MATCH(int measured, int desired) {return measured >= TICKS_LOW(desired) && measured <= TICKS_HIGH(desired);}
|
||||
int MATCH_MARK(int measured_ticks, int desired_us) {return MATCH(measured_ticks, (desired_us + MARK_EXCESS));}
|
||||
int MATCH_SPACE(int measured_ticks, int desired_us) {return MATCH(measured_ticks, (desired_us - MARK_EXCESS));}
|
||||
// Debugging versions are in IRremote.cpp
|
||||
#endif
|
||||
|
||||
// receiver states
|
||||
#define STATE_IDLE 2
|
||||
#define STATE_MARK 3
|
||||
#define STATE_SPACE 4
|
||||
#define STATE_STOP 5
|
||||
|
||||
// information for the interrupt handler
|
||||
typedef struct {
|
||||
uint8_t recvpin; // pin for IR data from detector
|
||||
uint8_t rcvstate; // state machine
|
||||
uint8_t blinkflag; // TRUE to enable blinking of pin 13 on IR processing
|
||||
unsigned int timer; // state timer, counts 50uS ticks.
|
||||
unsigned int rawbuf[RAWBUF]; // raw data
|
||||
uint8_t rawlen; // counter of entries in rawbuf
|
||||
}
|
||||
irparams_t;
|
||||
|
||||
// Defined in IRremote.cpp
|
||||
extern volatile irparams_t irparams;
|
||||
|
||||
// IR detector output is active low
|
||||
#define MARK 0
|
||||
#define SPACE 1
|
||||
|
||||
#define TOPBIT 0x80000000
|
||||
|
||||
#define NEC_BITS 32
|
||||
#define SONY_BITS 12
|
||||
#define SANYO_BITS 12
|
||||
#define MITSUBISHI_BITS 16
|
||||
#define MIN_RC5_SAMPLES 11
|
||||
#define MIN_RC6_SAMPLES 1
|
||||
#define PANASONIC_BITS 48
|
||||
#define JVC_BITS 16
|
||||
|
||||
|
||||
|
||||
|
||||
// defines for timer2 (8 bits)
|
||||
@@ -267,20 +138,9 @@ extern volatile irparams_t irparams;
|
||||
#define TIMER_RESET
|
||||
#define TIMER_ENABLE_PWM (TCCR1A |= _BV(COM1A1))
|
||||
#define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1)))
|
||||
#if defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__)
|
||||
#define TIMER_ENABLE_INTR (TIMSK = _BV(OCIE1A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK = 0)
|
||||
#else
|
||||
#define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK1 = 0)
|
||||
#endif
|
||||
|
||||
#if defined(__AVR_ATtinyX4__)
|
||||
#define TIMER_INTR_NAME TIM1_COMPA_vect
|
||||
#else
|
||||
#define TIMER_INTR_NAME TIMER1_COMPA_vect
|
||||
#endif
|
||||
|
||||
#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); \
|
||||
@@ -300,8 +160,6 @@ extern volatile irparams_t irparams;
|
||||
#define TIMER_PWM_PIN 11 /* Arduino Mega */
|
||||
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||
#define TIMER_PWM_PIN 13 /* Sanguino */
|
||||
#elif defined(__AVR_ATtinyX4__)
|
||||
#define TIMER_PWM_PIN 6 /* ATTiny84 */
|
||||
#else
|
||||
#define TIMER_PWM_PIN 9 /* Arduino Duemilanove, Diecimila, LilyPad, etc */
|
||||
#endif
|
||||
@@ -332,6 +190,8 @@ extern volatile irparams_t irparams;
|
||||
#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
|
||||
@@ -371,7 +231,7 @@ extern volatile irparams_t irparams;
|
||||
#if defined(CORE_OC4A_PIN)
|
||||
#define TIMER_PWM_PIN CORE_OC4A_PIN /* Teensy */
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#define TIMER_PWM_PIN 13 /* Leonardo */
|
||||
#define TIMER_PWM_PIN 13 /*Leonardo*/
|
||||
#else
|
||||
#error "Please add OC4A pin number here\n"
|
||||
#endif
|
||||
@@ -455,10 +315,16 @@ extern volatile irparams_t irparams;
|
||||
#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
|
||||
#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.
File diff suppressed because it is too large
Load Diff
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
* Edited by Mitra to add new controller SANYO
|
||||
*
|
||||
* 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/
|
||||
*
|
||||
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
|
||||
*/
|
||||
|
||||
#ifndef IRremote_h
|
||||
#define IRremote_h
|
||||
|
||||
// The following are compile-time library options.
|
||||
// If you change them, recompile the library.
|
||||
// If DEBUG is defined, a lot of debugging output will be printed during decoding.
|
||||
// TEST must be defined for the IRtest unittests to work. It will make some
|
||||
// methods virtual, which will be slightly slower, which is why it is optional.
|
||||
// #define DEBUG
|
||||
// #define TEST
|
||||
|
||||
// Results returned from the decoder
|
||||
class decode_results {
|
||||
public:
|
||||
int decode_type; // NEC, SONY, RC5, UNKNOWN
|
||||
unsigned int panasonicAddress; // This is only used for decoding Panasonic data
|
||||
unsigned long value; // Decoded value
|
||||
int bits; // Number of bits in decoded value
|
||||
volatile unsigned int *rawbuf; // Raw intervals in .5 us ticks
|
||||
int rawlen; // Number of records in rawbuf.
|
||||
};
|
||||
|
||||
// Values for decode_type
|
||||
#define NEC 1
|
||||
#define SONY 2
|
||||
#define RC5 3
|
||||
#define RC6 4
|
||||
#define DISH 5
|
||||
#define SHARP 6
|
||||
#define PANASONIC 7
|
||||
#define JVC 8
|
||||
#define SANYO 9
|
||||
#define MITSUBISHI 10
|
||||
#define UNKNOWN -1
|
||||
|
||||
// Decoded value for NEC when a repeat code is received
|
||||
#define REPEAT 0xffffffff
|
||||
|
||||
// main class for receiving IR
|
||||
class IRrecv
|
||||
{
|
||||
public:
|
||||
IRrecv(int recvpin);
|
||||
void blink13(int blinkflag);
|
||||
int decode(decode_results *results);
|
||||
void enableIRIn();
|
||||
void resume();
|
||||
private:
|
||||
// These are called by decode
|
||||
int getRClevel(decode_results *results, int *offset, int *used, int t1);
|
||||
long decodeNEC(decode_results *results);
|
||||
long decodeSony(decode_results *results);
|
||||
long decodeSanyo(decode_results *results);
|
||||
long decodeMitsubishi(decode_results *results);
|
||||
long decodeRC5(decode_results *results);
|
||||
long decodeRC6(decode_results *results);
|
||||
long decodePanasonic(decode_results *results);
|
||||
long decodeJVC(decode_results *results);
|
||||
long decodeHash(decode_results *results);
|
||||
int compare(unsigned int oldval, unsigned int newval);
|
||||
|
||||
}
|
||||
;
|
||||
|
||||
// Only used for testing; can remove virtual for shorter code
|
||||
#ifdef TEST
|
||||
#define VIRTUAL virtual
|
||||
#else
|
||||
#define VIRTUAL
|
||||
#endif
|
||||
|
||||
class IRsend
|
||||
{
|
||||
public:
|
||||
IRsend() {}
|
||||
void sendNEC(unsigned long data, int nbits);
|
||||
void sendSony(unsigned long data, int nbits);
|
||||
// Neither Sanyo nor Mitsubishi send is implemented yet
|
||||
// void sendSanyo(unsigned long data, int nbits);
|
||||
// void sendMitsubishi(unsigned long data, int nbits);
|
||||
void sendRaw(unsigned int buf[], int len, int hz);
|
||||
void sendRC5(unsigned long data, int nbits);
|
||||
void sendRC6(unsigned long data, int nbits);
|
||||
void sendDISH(unsigned long data, int nbits);
|
||||
void sendSharp(unsigned long data, int nbits);
|
||||
void sendPanasonic(unsigned int address, unsigned long data);
|
||||
void sendJVC(unsigned long data, int nbits, int repeat); // *Note instead of sending the REPEAT constant if you want the JVC repeat signal sent, send the original code value and change the repeat argument from 0 to 1. JVC protocol repeats by skipping the header NOT by sending a separate code value like NEC does.
|
||||
// private:
|
||||
void enableIROut(int khz);
|
||||
VIRTUAL void mark(int usec);
|
||||
VIRTUAL void space(int usec);
|
||||
}
|
||||
;
|
||||
|
||||
// Some useful constants
|
||||
|
||||
#define USECPERTICK 50 // microseconds per clock interrupt tick
|
||||
#define RAWBUF 100 // Length of raw duration buffer
|
||||
|
||||
// Marks tend to be 100us too long, and spaces 100us too short
|
||||
// when received due to sensor lag.
|
||||
#define MARK_EXCESS 100
|
||||
|
||||
#endif
|
||||
@@ -1,458 +0,0 @@
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
@@ -1,167 +0,0 @@
|
||||
/*
|
||||
* IRrecord: record and play back IR signals as a minimal
|
||||
* An IR detector/demodulator must be connected to the input RECV_PIN.
|
||||
* An IR LED must be connected to the output PWM pin 3.
|
||||
* A button must be connected to the input BUTTON_PIN; this is the
|
||||
* send button.
|
||||
* A visible LED can be connected to STATUS_PIN to provide status.
|
||||
*
|
||||
* The logic is:
|
||||
* If the button is pressed, send the IR code.
|
||||
* If an IR code is received, record it.
|
||||
*
|
||||
* Version 0.11 September, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
*/
|
||||
|
||||
#include <IRremote.h>
|
||||
|
||||
int RECV_PIN = 11;
|
||||
int BUTTON_PIN = 12;
|
||||
int STATUS_PIN = 13;
|
||||
|
||||
IRrecv irrecv(RECV_PIN);
|
||||
IRsend irsend;
|
||||
|
||||
decode_results results;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
irrecv.enableIRIn(); // Start the receiver
|
||||
pinMode(BUTTON_PIN, INPUT);
|
||||
pinMode(STATUS_PIN, OUTPUT);
|
||||
}
|
||||
|
||||
// Storage for the recorded code
|
||||
int codeType = -1; // The type of code
|
||||
unsigned long codeValue; // The code value if not raw
|
||||
unsigned int rawCodes[RAWBUF]; // The durations if raw
|
||||
int codeLen; // The length of the code
|
||||
int toggle = 0; // The RC5/6 toggle state
|
||||
|
||||
// Stores the code for later playback
|
||||
// Most of this code is just logging
|
||||
void storeCode(decode_results *results) {
|
||||
codeType = results->decode_type;
|
||||
int count = results->rawlen;
|
||||
if (codeType == UNKNOWN) {
|
||||
Serial.println("Received unknown code, saving as raw");
|
||||
codeLen = results->rawlen - 1;
|
||||
// To store raw codes:
|
||||
// Drop first value (gap)
|
||||
// Convert from ticks to microseconds
|
||||
// Tweak marks shorter, and spaces longer to cancel out IR receiver distortion
|
||||
for (int i = 1; i <= codeLen; i++) {
|
||||
if (i % 2) {
|
||||
// Mark
|
||||
rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK - MARK_EXCESS;
|
||||
Serial.print(" m");
|
||||
}
|
||||
else {
|
||||
// Space
|
||||
rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK + MARK_EXCESS;
|
||||
Serial.print(" s");
|
||||
}
|
||||
Serial.print(rawCodes[i - 1], DEC);
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
else {
|
||||
if (codeType == NEC) {
|
||||
Serial.print("Received NEC: ");
|
||||
if (results->value == REPEAT) {
|
||||
// Don't record a NEC repeat value as that's useless.
|
||||
Serial.println("repeat; ignoring.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (codeType == SONY) {
|
||||
Serial.print("Received SONY: ");
|
||||
}
|
||||
else if (codeType == RC5) {
|
||||
Serial.print("Received RC5: ");
|
||||
}
|
||||
else if (codeType == RC6) {
|
||||
Serial.print("Received RC6: ");
|
||||
}
|
||||
else {
|
||||
Serial.print("Unexpected codeType ");
|
||||
Serial.print(codeType, DEC);
|
||||
Serial.println("");
|
||||
}
|
||||
Serial.println(results->value, HEX);
|
||||
codeValue = results->value;
|
||||
codeLen = results->bits;
|
||||
}
|
||||
}
|
||||
|
||||
void sendCode(int repeat) {
|
||||
if (codeType == NEC) {
|
||||
if (repeat) {
|
||||
irsend.sendNEC(REPEAT, codeLen);
|
||||
Serial.println("Sent NEC repeat");
|
||||
}
|
||||
else {
|
||||
irsend.sendNEC(codeValue, codeLen);
|
||||
Serial.print("Sent NEC ");
|
||||
Serial.println(codeValue, HEX);
|
||||
}
|
||||
}
|
||||
else if (codeType == SONY) {
|
||||
irsend.sendSony(codeValue, codeLen);
|
||||
Serial.print("Sent Sony ");
|
||||
Serial.println(codeValue, HEX);
|
||||
}
|
||||
else if (codeType == RC5 || codeType == RC6) {
|
||||
if (!repeat) {
|
||||
// Flip the toggle bit for a new button press
|
||||
toggle = 1 - toggle;
|
||||
}
|
||||
// Put the toggle bit into the code to send
|
||||
codeValue = codeValue & ~(1 << (codeLen - 1));
|
||||
codeValue = codeValue | (toggle << (codeLen - 1));
|
||||
if (codeType == RC5) {
|
||||
Serial.print("Sent RC5 ");
|
||||
Serial.println(codeValue, HEX);
|
||||
irsend.sendRC5(codeValue, codeLen);
|
||||
}
|
||||
else {
|
||||
irsend.sendRC6(codeValue, codeLen);
|
||||
Serial.print("Sent RC6 ");
|
||||
Serial.println(codeValue, HEX);
|
||||
}
|
||||
}
|
||||
else if (codeType == UNKNOWN /* i.e. raw */) {
|
||||
// Assume 38 KHz
|
||||
irsend.sendRaw(rawCodes, codeLen, 38);
|
||||
Serial.println("Sent raw");
|
||||
}
|
||||
}
|
||||
|
||||
int lastButtonState;
|
||||
|
||||
void loop() {
|
||||
// If button pressed, send the code.
|
||||
int buttonState = digitalRead(BUTTON_PIN);
|
||||
if (lastButtonState == HIGH && buttonState == LOW) {
|
||||
Serial.println("Released");
|
||||
irrecv.enableIRIn(); // Re-enable receiver
|
||||
}
|
||||
|
||||
if (buttonState) {
|
||||
Serial.println("Pressed, sending");
|
||||
digitalWrite(STATUS_PIN, HIGH);
|
||||
sendCode(lastButtonState == buttonState);
|
||||
digitalWrite(STATUS_PIN, LOW);
|
||||
delay(50); // Wait a bit between retransmissions
|
||||
}
|
||||
else if (irrecv.decode(&results)) {
|
||||
digitalWrite(STATUS_PIN, HIGH);
|
||||
storeCode(&results);
|
||||
irrecv.resume(); // resume receiver
|
||||
digitalWrite(STATUS_PIN, LOW);
|
||||
}
|
||||
lastButtonState = buttonState;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv
|
||||
* An IR detector/demodulator must be connected to the input RECV_PIN.
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
*/
|
||||
|
||||
#include <IRremote.h>
|
||||
|
||||
int RECV_PIN = 11;
|
||||
|
||||
IRrecv irrecv(RECV_PIN);
|
||||
|
||||
decode_results results;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
irrecv.enableIRIn(); // Start the receiver
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (irrecv.decode(&results)) {
|
||||
Serial.println(results.value, HEX);
|
||||
irrecv.resume(); // Receive the next value
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* IRremote: IRrecvDump - dump details of IR codes with IRrecv
|
||||
* An IR detector/demodulator must be connected to the input RECV_PIN.
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
|
||||
*/
|
||||
|
||||
#include <IRremote.h>
|
||||
|
||||
int RECV_PIN = 8;
|
||||
|
||||
IRrecv irrecv(RECV_PIN);
|
||||
|
||||
decode_results results;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
irrecv.enableIRIn(); // Start the receiver
|
||||
}
|
||||
|
||||
// Dumps out the decode_results structure.
|
||||
// Call this after IRrecv::decode()
|
||||
// void * to work around compiler issue
|
||||
//void dump(void *v) {
|
||||
// decode_results *results = (decode_results *)v
|
||||
void dump(decode_results *results) {
|
||||
int count = results->rawlen;
|
||||
if (results->decode_type == UNKNOWN) {
|
||||
Serial.print("Unknown encoding: ");
|
||||
}
|
||||
else if (results->decode_type == NEC) {
|
||||
Serial.print("Decoded NEC: ");
|
||||
}
|
||||
else if (results->decode_type == SONY) {
|
||||
Serial.print("Decoded SONY: ");
|
||||
}
|
||||
else if (results->decode_type == RC5) {
|
||||
Serial.print("Decoded RC5: ");
|
||||
}
|
||||
else if (results->decode_type == RC6) {
|
||||
Serial.print("Decoded RC6: ");
|
||||
}
|
||||
else if (results->decode_type == PANASONIC) {
|
||||
Serial.print("Decoded PANASONIC - Address: ");
|
||||
Serial.print(results->panasonicAddress,HEX);
|
||||
Serial.print(" Value: ");
|
||||
}
|
||||
else if (results->decode_type == JVC) {
|
||||
Serial.print("Decoded JVC: ");
|
||||
}
|
||||
Serial.print(results->value, HEX);
|
||||
Serial.print(" (");
|
||||
Serial.print(results->bits, DEC);
|
||||
Serial.println(" bits)");
|
||||
Serial.print("Raw (");
|
||||
Serial.print(count, DEC);
|
||||
Serial.print("): ");
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if ((i % 2) == 1) {
|
||||
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
else {
|
||||
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
if (irrecv.decode(&results)) {
|
||||
Serial.println(results.value, HEX);
|
||||
dump(&results);
|
||||
irrecv.resume(); // Receive the next value
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv
|
||||
* An IR detector/demodulator must be connected to the input RECV_PIN.
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
*/
|
||||
|
||||
#include <IRremote.h>
|
||||
|
||||
int RECV_PIN = 11;
|
||||
int RELAY_PIN = 4;
|
||||
|
||||
IRrecv irrecv(RECV_PIN);
|
||||
decode_results results;
|
||||
|
||||
// Dumps out the decode_results structure.
|
||||
// Call this after IRrecv::decode()
|
||||
// void * to work around compiler issue
|
||||
//void dump(void *v) {
|
||||
// decode_results *results = (decode_results *)v
|
||||
void dump(decode_results *results) {
|
||||
int count = results->rawlen;
|
||||
if (results->decode_type == UNKNOWN) {
|
||||
Serial.println("Could not decode message");
|
||||
}
|
||||
else {
|
||||
if (results->decode_type == NEC) {
|
||||
Serial.print("Decoded NEC: ");
|
||||
}
|
||||
else if (results->decode_type == SONY) {
|
||||
Serial.print("Decoded SONY: ");
|
||||
}
|
||||
else if (results->decode_type == RC5) {
|
||||
Serial.print("Decoded RC5: ");
|
||||
}
|
||||
else if (results->decode_type == RC6) {
|
||||
Serial.print("Decoded RC6: ");
|
||||
}
|
||||
Serial.print(results->value, HEX);
|
||||
Serial.print(" (");
|
||||
Serial.print(results->bits, DEC);
|
||||
Serial.println(" bits)");
|
||||
}
|
||||
Serial.print("Raw (");
|
||||
Serial.print(count, DEC);
|
||||
Serial.print("): ");
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if ((i % 2) == 1) {
|
||||
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
else {
|
||||
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(RELAY_PIN, OUTPUT);
|
||||
pinMode(13, OUTPUT);
|
||||
Serial.begin(9600);
|
||||
irrecv.enableIRIn(); // Start the receiver
|
||||
}
|
||||
|
||||
int on = 0;
|
||||
unsigned long last = millis();
|
||||
|
||||
void loop() {
|
||||
if (irrecv.decode(&results)) {
|
||||
// If it's been at least 1/4 second since the last
|
||||
// IR received, toggle the relay
|
||||
if (millis() - last > 250) {
|
||||
on = !on;
|
||||
digitalWrite(RELAY_PIN, on ? HIGH : LOW);
|
||||
digitalWrite(13, on ? HIGH : LOW);
|
||||
dump(&results);
|
||||
}
|
||||
last = millis();
|
||||
irrecv.resume(); // Receive the next value
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* IRremote: IRsendDemo - demonstrates sending IR codes with IRsend
|
||||
* An IR LED must be connected to Arduino PWM pin 3.
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
*/
|
||||
|
||||
#include <IRremote.h>
|
||||
|
||||
IRsend irsend;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (Serial.read() != -1) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
irsend.sendSony(0xa90, 12); // Sony TV power code
|
||||
delay(40);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,190 +0,0 @@
|
||||
/*
|
||||
* IRremote: IRtest unittest
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
*
|
||||
* Note: to run these tests, edit IRremote/IRremote.h to add "#define TEST"
|
||||
* You must then recompile the library by removing IRremote.o and restarting
|
||||
* the arduino IDE.
|
||||
*/
|
||||
|
||||
#include <IRremote.h>
|
||||
#include <IRremoteInt.h>
|
||||
|
||||
// Dumps out the decode_results structure.
|
||||
// Call this after IRrecv::decode()
|
||||
// void * to work around compiler issue
|
||||
//void dump(void *v) {
|
||||
// decode_results *results = (decode_results *)v
|
||||
void dump(decode_results *results) {
|
||||
int count = results->rawlen;
|
||||
if (results->decode_type == UNKNOWN) {
|
||||
Serial.println("Could not decode message");
|
||||
}
|
||||
else {
|
||||
if (results->decode_type == NEC) {
|
||||
Serial.print("Decoded NEC: ");
|
||||
}
|
||||
else if (results->decode_type == SONY) {
|
||||
Serial.print("Decoded SONY: ");
|
||||
}
|
||||
else if (results->decode_type == RC5) {
|
||||
Serial.print("Decoded RC5: ");
|
||||
}
|
||||
else if (results->decode_type == RC6) {
|
||||
Serial.print("Decoded RC6: ");
|
||||
}
|
||||
Serial.print(results->value, HEX);
|
||||
Serial.print(" (");
|
||||
Serial.print(results->bits, DEC);
|
||||
Serial.println(" bits)");
|
||||
}
|
||||
Serial.print("Raw (");
|
||||
Serial.print(count, DEC);
|
||||
Serial.print("): ");
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if ((i % 2) == 1) {
|
||||
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
else {
|
||||
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
IRrecv irrecv(0);
|
||||
decode_results results;
|
||||
|
||||
class IRsendDummy :
|
||||
public IRsend
|
||||
{
|
||||
public:
|
||||
// For testing, just log the marks/spaces
|
||||
#define SENDLOG_LEN 128
|
||||
int sendlog[SENDLOG_LEN];
|
||||
int sendlogcnt;
|
||||
IRsendDummy() :
|
||||
IRsend() {
|
||||
}
|
||||
void reset() {
|
||||
sendlogcnt = 0;
|
||||
}
|
||||
void mark(int time) {
|
||||
sendlog[sendlogcnt] = time;
|
||||
if (sendlogcnt < SENDLOG_LEN) sendlogcnt++;
|
||||
}
|
||||
void space(int time) {
|
||||
sendlog[sendlogcnt] = -time;
|
||||
if (sendlogcnt < SENDLOG_LEN) sendlogcnt++;
|
||||
}
|
||||
// Copies the dummy buf into the interrupt buf
|
||||
void useDummyBuf() {
|
||||
int last = SPACE;
|
||||
irparams.rcvstate = STATE_STOP;
|
||||
irparams.rawlen = 1; // Skip the gap
|
||||
for (int i = 0 ; i < sendlogcnt; i++) {
|
||||
if (sendlog[i] < 0) {
|
||||
if (last == MARK) {
|
||||
// New space
|
||||
irparams.rawbuf[irparams.rawlen++] = (-sendlog[i] - MARK_EXCESS) / USECPERTICK;
|
||||
last = SPACE;
|
||||
}
|
||||
else {
|
||||
// More space
|
||||
irparams.rawbuf[irparams.rawlen - 1] += -sendlog[i] / USECPERTICK;
|
||||
}
|
||||
}
|
||||
else if (sendlog[i] > 0) {
|
||||
if (last == SPACE) {
|
||||
// New mark
|
||||
irparams.rawbuf[irparams.rawlen++] = (sendlog[i] + MARK_EXCESS) / USECPERTICK;
|
||||
last = MARK;
|
||||
}
|
||||
else {
|
||||
// More mark
|
||||
irparams.rawbuf[irparams.rawlen - 1] += sendlog[i] / USECPERTICK;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (irparams.rawlen % 2) {
|
||||
irparams.rawlen--; // Remove trailing space
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
IRsendDummy irsenddummy;
|
||||
|
||||
void verify(unsigned long val, int bits, int type) {
|
||||
irsenddummy.useDummyBuf();
|
||||
irrecv.decode(&results);
|
||||
Serial.print("Testing ");
|
||||
Serial.print(val, HEX);
|
||||
if (results.value == val && results.bits == bits && results.decode_type == type) {
|
||||
Serial.println(": OK");
|
||||
}
|
||||
else {
|
||||
Serial.println(": Error");
|
||||
dump(&results);
|
||||
}
|
||||
}
|
||||
|
||||
void testNEC(unsigned long val, int bits) {
|
||||
irsenddummy.reset();
|
||||
irsenddummy.sendNEC(val, bits);
|
||||
verify(val, bits, NEC);
|
||||
}
|
||||
void testSony(unsigned long val, int bits) {
|
||||
irsenddummy.reset();
|
||||
irsenddummy.sendSony(val, bits);
|
||||
verify(val, bits, SONY);
|
||||
}
|
||||
void testRC5(unsigned long val, int bits) {
|
||||
irsenddummy.reset();
|
||||
irsenddummy.sendRC5(val, bits);
|
||||
verify(val, bits, RC5);
|
||||
}
|
||||
void testRC6(unsigned long val, int bits) {
|
||||
irsenddummy.reset();
|
||||
irsenddummy.sendRC6(val, bits);
|
||||
verify(val, bits, RC6);
|
||||
}
|
||||
|
||||
void test() {
|
||||
Serial.println("NEC tests");
|
||||
testNEC(0x00000000, 32);
|
||||
testNEC(0xffffffff, 32);
|
||||
testNEC(0xaaaaaaaa, 32);
|
||||
testNEC(0x55555555, 32);
|
||||
testNEC(0x12345678, 32);
|
||||
Serial.println("Sony tests");
|
||||
testSony(0xfff, 12);
|
||||
testSony(0x000, 12);
|
||||
testSony(0xaaa, 12);
|
||||
testSony(0x555, 12);
|
||||
testSony(0x123, 12);
|
||||
Serial.println("RC5 tests");
|
||||
testRC5(0xfff, 12);
|
||||
testRC5(0x000, 12);
|
||||
testRC5(0xaaa, 12);
|
||||
testRC5(0x555, 12);
|
||||
testRC5(0x123, 12);
|
||||
Serial.println("RC6 tests");
|
||||
testRC6(0xfffff, 20);
|
||||
testRC6(0x00000, 20);
|
||||
testRC6(0xaaaaa, 20);
|
||||
testRC6(0x55555, 20);
|
||||
testRC6(0x12345, 20);
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
test();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
}
|
||||
@@ -1,290 +0,0 @@
|
||||
/*
|
||||
* Test send/receive functions of IRremote, using a pair of Arduinos.
|
||||
*
|
||||
* Arduino #1 should have an IR LED connected to the send pin (3).
|
||||
* Arduino #2 should have an IR detector/demodulator connected to the
|
||||
* receive pin (11) and a visible LED connected to pin 3.
|
||||
*
|
||||
* The cycle:
|
||||
* Arduino #1 will wait 2 seconds, then run through the tests.
|
||||
* It repeats this forever.
|
||||
* Arduino #2 will wait for at least one second of no signal
|
||||
* (to synchronize with #1). It will then wait for the same test
|
||||
* signals. It will log all the status to the serial port. It will
|
||||
* also indicate status through the LED, which will flash each time a test
|
||||
* is completed. If there is an error, it will light up for 5 seconds.
|
||||
*
|
||||
* The test passes if the LED flashes 19 times, pauses, and then repeats.
|
||||
* The test fails if the LED lights for 5 seconds.
|
||||
*
|
||||
* The test software automatically decides which board is the sender and which is
|
||||
* the receiver by looking for an input on the send pin, which will indicate
|
||||
* the sender. You should hook the serial port to the receiver for debugging.
|
||||
*
|
||||
* Copyright 2010 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
*/
|
||||
|
||||
#include <IRremote.h>
|
||||
|
||||
int RECV_PIN = 11;
|
||||
int LED_PIN = 3;
|
||||
|
||||
IRrecv irrecv(RECV_PIN);
|
||||
IRsend irsend;
|
||||
|
||||
decode_results results;
|
||||
|
||||
#define RECEIVER 1
|
||||
#define SENDER 2
|
||||
#define ERROR 3
|
||||
|
||||
int mode;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
// Check RECV_PIN to decide if we're RECEIVER or SENDER
|
||||
if (digitalRead(RECV_PIN) == HIGH) {
|
||||
mode = RECEIVER;
|
||||
irrecv.enableIRIn();
|
||||
pinMode(LED_PIN, OUTPUT);
|
||||
digitalWrite(LED_PIN, LOW);
|
||||
Serial.println("Receiver mode");
|
||||
}
|
||||
else {
|
||||
mode = SENDER;
|
||||
Serial.println("Sender mode");
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for the gap between tests, to synchronize with
|
||||
// the sender.
|
||||
// Specifically, wait for a signal followed by a gap of at last gap ms.
|
||||
void waitForGap(int gap) {
|
||||
Serial.println("Waiting for gap");
|
||||
while (1) {
|
||||
while (digitalRead(RECV_PIN) == LOW) {
|
||||
}
|
||||
unsigned long time = millis();
|
||||
while (digitalRead(RECV_PIN) == HIGH) {
|
||||
if (millis() - time > gap) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dumps out the decode_results structure.
|
||||
// Call this after IRrecv::decode()
|
||||
void dump(decode_results *results) {
|
||||
int count = results->rawlen;
|
||||
if (results->decode_type == UNKNOWN) {
|
||||
Serial.println("Could not decode message");
|
||||
}
|
||||
else {
|
||||
if (results->decode_type == NEC) {
|
||||
Serial.print("Decoded NEC: ");
|
||||
}
|
||||
else if (results->decode_type == SONY) {
|
||||
Serial.print("Decoded SONY: ");
|
||||
}
|
||||
else if (results->decode_type == RC5) {
|
||||
Serial.print("Decoded RC5: ");
|
||||
}
|
||||
else if (results->decode_type == RC6) {
|
||||
Serial.print("Decoded RC6: ");
|
||||
}
|
||||
Serial.print(results->value, HEX);
|
||||
Serial.print(" (");
|
||||
Serial.print(results->bits, DEC);
|
||||
Serial.println(" bits)");
|
||||
}
|
||||
Serial.print("Raw (");
|
||||
Serial.print(count, DEC);
|
||||
Serial.print("): ");
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if ((i % 2) == 1) {
|
||||
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
else {
|
||||
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
|
||||
// Test send or receive.
|
||||
// If mode is SENDER, send a code of the specified type, value, and bits
|
||||
// If mode is RECEIVER, receive a code and verify that it is of the
|
||||
// specified type, value, and bits. For success, the LED is flashed;
|
||||
// for failure, the mode is set to ERROR.
|
||||
// The motivation behind this method is that the sender and the receiver
|
||||
// can do the same test calls, and the mode variable indicates whether
|
||||
// to send or receive.
|
||||
void test(char *label, int type, unsigned long value, int bits) {
|
||||
if (mode == SENDER) {
|
||||
Serial.println(label);
|
||||
if (type == NEC) {
|
||||
irsend.sendNEC(value, bits);
|
||||
}
|
||||
else if (type == SONY) {
|
||||
irsend.sendSony(value, bits);
|
||||
}
|
||||
else if (type == RC5) {
|
||||
irsend.sendRC5(value, bits);
|
||||
}
|
||||
else if (type == RC6) {
|
||||
irsend.sendRC6(value, bits);
|
||||
}
|
||||
else {
|
||||
Serial.print(label);
|
||||
Serial.println("Bad type!");
|
||||
}
|
||||
delay(200);
|
||||
}
|
||||
else if (mode == RECEIVER) {
|
||||
irrecv.resume(); // Receive the next value
|
||||
unsigned long max_time = millis() + 30000;
|
||||
Serial.print(label);
|
||||
|
||||
// Wait for decode or timeout
|
||||
while (!irrecv.decode(&results)) {
|
||||
if (millis() > max_time) {
|
||||
Serial.println("Timeout receiving data");
|
||||
mode = ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (type == results.decode_type && value == results.value && bits == results.bits) {
|
||||
Serial.println (": OK");
|
||||
digitalWrite(LED_PIN, HIGH);
|
||||
delay(20);
|
||||
digitalWrite(LED_PIN, LOW);
|
||||
}
|
||||
else {
|
||||
Serial.println(": BAD");
|
||||
dump(&results);
|
||||
mode = ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test raw send or receive. This is similar to the test method,
|
||||
// except it send/receives raw data.
|
||||
void testRaw(char *label, unsigned int *rawbuf, int rawlen) {
|
||||
if (mode == SENDER) {
|
||||
Serial.println(label);
|
||||
irsend.sendRaw(rawbuf, rawlen, 38 /* kHz */);
|
||||
delay(200);
|
||||
}
|
||||
else if (mode == RECEIVER ) {
|
||||
irrecv.resume(); // Receive the next value
|
||||
unsigned long max_time = millis() + 30000;
|
||||
Serial.print(label);
|
||||
|
||||
// Wait for decode or timeout
|
||||
while (!irrecv.decode(&results)) {
|
||||
if (millis() > max_time) {
|
||||
Serial.println("Timeout receiving data");
|
||||
mode = ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Received length has extra first element for gap
|
||||
if (rawlen != results.rawlen - 1) {
|
||||
Serial.print("Bad raw length ");
|
||||
Serial.println(results.rawlen, DEC);
|
||||
mode = ERROR;
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < rawlen; i++) {
|
||||
long got = results.rawbuf[i+1] * USECPERTICK;
|
||||
// Adjust for extra duration of marks
|
||||
if (i % 2 == 0) {
|
||||
got -= MARK_EXCESS;
|
||||
}
|
||||
else {
|
||||
got += MARK_EXCESS;
|
||||
}
|
||||
// See if close enough, within 25%
|
||||
if (rawbuf[i] * 1.25 < got || got * 1.25 < rawbuf[i]) {
|
||||
Serial.println(": BAD");
|
||||
dump(&results);
|
||||
mode = ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
Serial.println (": OK");
|
||||
digitalWrite(LED_PIN, HIGH);
|
||||
delay(20);
|
||||
digitalWrite(LED_PIN, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
// This is the raw data corresponding to NEC 0x12345678
|
||||
unsigned int sendbuf[] = { /* NEC format */
|
||||
9000, 4500,
|
||||
560, 560, 560, 560, 560, 560, 560, 1690, /* 1 */
|
||||
560, 560, 560, 560, 560, 1690, 560, 560, /* 2 */
|
||||
560, 560, 560, 560, 560, 1690, 560, 1690, /* 3 */
|
||||
560, 560, 560, 1690, 560, 560, 560, 560, /* 4 */
|
||||
560, 560, 560, 1690, 560, 560, 560, 1690, /* 5 */
|
||||
560, 560, 560, 1690, 560, 1690, 560, 560, /* 6 */
|
||||
560, 560, 560, 1690, 560, 1690, 560, 1690, /* 7 */
|
||||
560, 1690, 560, 560, 560, 560, 560, 560, /* 8 */
|
||||
560};
|
||||
|
||||
void loop() {
|
||||
if (mode == SENDER) {
|
||||
delay(2000); // Delay for more than gap to give receiver a better chance to sync.
|
||||
}
|
||||
else if (mode == RECEIVER) {
|
||||
waitForGap(1000);
|
||||
}
|
||||
else if (mode == ERROR) {
|
||||
// Light up for 5 seconds for error
|
||||
digitalWrite(LED_PIN, HIGH);
|
||||
delay(5000);
|
||||
digitalWrite(LED_PIN, LOW);
|
||||
mode = RECEIVER; // Try again
|
||||
return;
|
||||
}
|
||||
|
||||
// The test suite.
|
||||
test("SONY1", SONY, 0x123, 12);
|
||||
test("SONY2", SONY, 0x000, 12);
|
||||
test("SONY3", SONY, 0xfff, 12);
|
||||
test("SONY4", SONY, 0x12345, 20);
|
||||
test("SONY5", SONY, 0x00000, 20);
|
||||
test("SONY6", SONY, 0xfffff, 20);
|
||||
test("NEC1", NEC, 0x12345678, 32);
|
||||
test("NEC2", NEC, 0x00000000, 32);
|
||||
test("NEC3", NEC, 0xffffffff, 32);
|
||||
test("NEC4", NEC, REPEAT, 32);
|
||||
test("RC51", RC5, 0x12345678, 32);
|
||||
test("RC52", RC5, 0x0, 32);
|
||||
test("RC53", RC5, 0xffffffff, 32);
|
||||
test("RC61", RC6, 0x12345678, 32);
|
||||
test("RC62", RC6, 0x0, 32);
|
||||
test("RC63", RC6, 0xffffffff, 32);
|
||||
|
||||
// Tests of raw sending and receiving.
|
||||
// First test sending raw and receiving raw.
|
||||
// Then test sending raw and receiving decoded NEC
|
||||
// Then test sending NEC and receiving raw
|
||||
testRaw("RAW1", sendbuf, 67);
|
||||
if (mode == SENDER) {
|
||||
testRaw("RAW2", sendbuf, 67);
|
||||
test("RAW3", NEC, 0x12345678, 32);
|
||||
}
|
||||
else {
|
||||
test("RAW2", NEC, 0x12345678, 32);
|
||||
testRaw("RAW3", sendbuf, 67);
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* IRremote: IRsendDemo - demonstrates sending IR codes with IRsend
|
||||
* An IR LED must be connected to Arduino PWM pin 3.
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
|
||||
*/
|
||||
#include <IRremote.h>
|
||||
|
||||
#define PanasonicAddress 0x4004 // Panasonic address (Pre data)
|
||||
#define PanasonicPower 0x100BCBD // Panasonic Power button
|
||||
|
||||
#define JVCPower 0xC5E8
|
||||
|
||||
IRsend irsend;
|
||||
|
||||
void setup()
|
||||
{
|
||||
}
|
||||
|
||||
void loop() {
|
||||
irsend.sendPanasonic(PanasonicAddress,PanasonicPower); // This should turn your TV on and off
|
||||
|
||||
irsend.sendJVC(JVCPower, 16,0); // hex value, 16 bits, no repeat
|
||||
delayMicroseconds(50); // see http://www.sbprojects.com/knowledge/ir/jvc.php for information
|
||||
irsend.sendJVC(JVCPower, 16,1); // hex value, 16 bits, repeat
|
||||
delayMicroseconds(50);
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map For IRremote
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
decode_results KEYWORD1
|
||||
IRrecv KEYWORD1
|
||||
IRsend KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
blink13 KEYWORD2
|
||||
decode KEYWORD2
|
||||
enableIRIn KEYWORD2
|
||||
resume KEYWORD2
|
||||
enableIROut KEYWORD2
|
||||
sendNEC KEYWORD2
|
||||
sendSony KEYWORD2
|
||||
sendSanyo KEYWORD2
|
||||
sendMitsubishi KEYWORD2
|
||||
sendRaw KEYWORD2
|
||||
sendRC5 KEYWORD2
|
||||
sendRC6 KEYWORD2
|
||||
sendDISH KEYWORD2
|
||||
sendSharp KEYWORD2
|
||||
sendPanasonic KEYWORD2
|
||||
sendJVC KEYWORD2
|
||||
|
||||
#
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
|
||||
NEC LITERAL1
|
||||
SONY LITERAL1
|
||||
SANYO LITERAL1
|
||||
MITSUBISHI LITERAL1
|
||||
RC5 LITERAL1
|
||||
RC6 LITERAL1
|
||||
DISH LITERAL1
|
||||
SHARP LITERAL1
|
||||
PANASONIC LITERAL1
|
||||
JVC LITERAL1
|
||||
UNKNOWN LITERAL1
|
||||
REPEAT LITERAL1
|
||||
@@ -1,14 +0,0 @@
|
||||
This is the IRremote library for the Arduino.
|
||||
|
||||
To download from github (http://github.com/shirriff/Arduino-IRremote), click on the "Downloads" link in the upper right, click "Download as zip", and get a zip file. Unzip it and rename the directory shirriff-Arduino-IRremote-nnn to IRremote
|
||||
|
||||
To install, move the downloaded IRremote directory to:
|
||||
arduino-1.x/libraries/IRremote
|
||||
where arduino-1.x is your Arduino installation directory
|
||||
|
||||
After installation you should have files such as:
|
||||
arduino-1.x/libraries/IRremote/IRremote.cpp
|
||||
|
||||
For details on the library see the Wiki on github or the blog post http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
|
||||
|
||||
Copyright 2009-2012 Ken Shirriff
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <SPI.h>
|
||||
#include <EEPROM.h>
|
||||
#include <RF24.h>
|
||||
#include <IRremote.h>
|
||||
#include <IRLib.h>
|
||||
|
||||
int RECV_PIN = 8;
|
||||
|
||||
@@ -17,13 +17,16 @@ int RECV_PIN = 8;
|
||||
|
||||
IRsend irsend;
|
||||
IRrecv irrecv(RECV_PIN);
|
||||
decode_results results;
|
||||
IRdecode decoder;
|
||||
//decode_results results;
|
||||
unsigned int Buffer[RAWBUF];
|
||||
|
||||
Sensor gw;
|
||||
|
||||
void setup()
|
||||
{
|
||||
irrecv.enableIRIn(); // Start the ir receiver
|
||||
decoder.UseExtnBuf(Buffer);
|
||||
gw.begin();
|
||||
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
@@ -41,22 +44,24 @@ void loop()
|
||||
|
||||
int incomingRelayStatus = atoi(message.data);
|
||||
if (incomingRelayStatus == 1) {
|
||||
irsend.sendNEC(0x1EE17887, 32); // Vol up yamaha ysp-900
|
||||
irsend.send(NEC, 0x1EE17887, 32); // Vol up yamaha ysp-900
|
||||
} else {
|
||||
irsend.sendNEC(0x1EE1F807, 32); // Vol down yamaha ysp-900
|
||||
irsend.send(NEC, 0x1EE1F807, 32); // Vol down yamaha ysp-900
|
||||
}
|
||||
// Start receiving ir again...
|
||||
irrecv.enableIRIn();
|
||||
}
|
||||
|
||||
|
||||
if (irrecv.decode(&results)) {
|
||||
if (irrecv.GetResults(&decoder)) {
|
||||
irrecv.resume();
|
||||
decoder.decode();
|
||||
decoder.DumpResults();
|
||||
|
||||
char buffer[10];
|
||||
sprintf(buffer, "%08lx", results.value);
|
||||
dump(&results);
|
||||
sprintf(buffer, "%08lx", decoder.value);
|
||||
// Send ir result to gw
|
||||
gw.sendVariable(CHILD_1, V_VAR1, buffer);
|
||||
irrecv.resume(); // Receive the next value
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +71,7 @@ void loop()
|
||||
// void * to work around compiler issue
|
||||
//void dump(void *v) {
|
||||
// decode_results *results = (decode_results *)v
|
||||
void dump(decode_results *results) {
|
||||
/*void dump(decode_results *results) {
|
||||
int count = results->rawlen;
|
||||
if (results->decode_type == UNKNOWN) {
|
||||
Serial.print("Unknown encoding: ");
|
||||
@@ -110,4 +115,4 @@ void dump(decode_results *results) {
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user