mirror of
https://github.com/digistump/DigistumpArduino.git
synced 2025-09-17 09:22:28 -07:00
added updated tinypinchange and associated libraries to support PRO
This commit is contained in:
22
hardware/digistump/avr/libraries/DigisparkIRLib/.gitattributes
vendored
Normal file
22
hardware/digistump/avr/libraries/DigisparkIRLib/.gitattributes
vendored
Normal file
@@ -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
|
215
hardware/digistump/avr/libraries/DigisparkIRLib/.gitignore
vendored
Normal file
215
hardware/digistump/avr/libraries/DigisparkIRLib/.gitignore
vendored
Normal file
@@ -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,16 @@
|
||||
Change Log for IRLib <20> an Arduino library for infrared encoding and decoding
|
||||
Copyright 2013 by Chris Young http://cyborg5.com
|
||||
|
||||
April 2013 Version 1.1 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
|
||||
|
||||
February 2013 Version 1.0a Removed debugging test switch which was accidentally
|
||||
left on in file "IRLib.h"
|
||||
|
||||
January 2013 Version 1.0 Initial Release
|
988
hardware/digistump/avr/libraries/DigisparkIRLib/IRLib.cpp
Normal file
988
hardware/digistump/avr/libraries/DigisparkIRLib/IRLib.cpp
Normal file
@@ -0,0 +1,988 @@
|
||||
/* IRLib.cpp from IRLib <20> an Arduino library for infrared encoding and decoding
|
||||
* Version 1.1 April 2013
|
||||
* Copyright 2013 by Chris Young http://cyborg5.com
|
||||
*
|
||||
* Port to Digispark (size optimization) August 2013
|
||||
* by RC Navy http://p.loussouarn.free.fr
|
||||
*
|
||||
* 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/
|
||||
*/
|
||||
|
||||
#include "IRLib.h"
|
||||
#include "IRLibMatch.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
|
||||
/*
|
||||
* Returns a pointer to a flash stored string that is the name of the protocol received.
|
||||
*/
|
||||
#if defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
|
||||
const char *Pnames(IRTYPES Type) {
|
||||
return(NULL);
|
||||
};
|
||||
#else
|
||||
const __FlashStringHelper *Pnames(IRTYPES Type) {
|
||||
if(Type>LAST_PROTOCOL) Type=UNKNOWN;
|
||||
const __FlashStringHelper *Names[LAST_PROTOCOL+1]={F("Unknown"),
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_NEC)
|
||||
F("NEC")
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL)
|
||||
,
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_SONY)
|
||||
F("Sony")
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL)
|
||||
,
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_RC5)
|
||||
F("RC5")
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL)
|
||||
,
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_RC6)
|
||||
F("RC6")
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL)
|
||||
,
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_PANASONIC_OLD)
|
||||
F("Panasonic Old")
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL)
|
||||
,
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_JVC)
|
||||
F("JVC")
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL)
|
||||
,
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_NECX)
|
||||
F("NECx")
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL)
|
||||
,
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_HASH_CODE)
|
||||
F("Hash Code")
|
||||
#endif
|
||||
};
|
||||
#if defined(ALL_IR_PROTOCOL)
|
||||
return Names[Type];
|
||||
#else
|
||||
return Names[!!Type];
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
#define RC5_T1 889
|
||||
#define RC5_RPT_LENGTH 46000
|
||||
|
||||
#define RC6_HDR_MARK 2666
|
||||
#define RC6_HDR_SPACE 889
|
||||
#define RC6_T1 444
|
||||
|
||||
#ifdef USE_IR_SEND
|
||||
|
||||
#define TOPBIT 0x80000000
|
||||
|
||||
/*
|
||||
* The IRsend classes contain a series of methods for sending various protocols.
|
||||
* Each of these begin by calling enableIROut(int kHz) to set the carrier frequency.
|
||||
* It then calls mark(int usec) and space(inc usec) to transmit marks and
|
||||
* spaces of varying length of microseconds however the protocol defines.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Most of the protocols have a header consisting of a mark/space of a particular length followed by
|
||||
* a series of variable length mark/space signals. Depending on the protocol they very the links of the
|
||||
* mark or the space to indicate a data bit of "0" or "1". Most also end with a stop bit of "1".
|
||||
* The basic structure of the sending and decoding these protocols led to lots of redundant code.
|
||||
* Therefore I have implemented generic sending and decoding routines. You just need to pass a bunch of customized
|
||||
* parameters and it does the work. This reduces compiled code size with only minor speed degradation.
|
||||
* You may be able to implement additional protocols by simply passing the proper values to these generic routines.
|
||||
* The decoding routines do not encode stop bits. So you have to tell this routine whether or not to send one.
|
||||
*/
|
||||
|
||||
void IRsendBase::sendGeneric(unsigned long data, int Num_Bits, int Head_Mark, int Head_Space, int Mark_One, int Mark_Zero, int Space_One, int Space_Zero, int mHz, bool Use_Stop) {
|
||||
data = data << (32 - Num_Bits);
|
||||
enableIROut(mHz);
|
||||
//Some protocols do not send a header when sending repeat codes. So we pass a zero value to indicate skipping this.
|
||||
if(Head_Mark) mark(Head_Mark);
|
||||
if(Head_Space) space(Head_Space);
|
||||
for (int i = 0; i <Num_Bits; i++) {
|
||||
if (data & TOPBIT) {
|
||||
mark(Mark_One); space(Space_One);
|
||||
}
|
||||
else {
|
||||
mark(Mark_Zero); space(Space_Zero);
|
||||
}
|
||||
data <<= 1;
|
||||
}
|
||||
if (Use_Stop) mark(Mark_One); space(0) ; //stop bit of "1"
|
||||
};
|
||||
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_NEC)
|
||||
void IRsendNEC::send(unsigned long data)
|
||||
{
|
||||
ATTEMPT_MESSAGE(F("sending NEC"));
|
||||
if (data==REPEAT) {
|
||||
mark (564* 16); space (564*4); mark(564);space (96000);
|
||||
}
|
||||
else {
|
||||
sendGeneric(data,32, 564*16, 564*8, 564, 564, 564*3, 564, 38, true);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_SONY)
|
||||
/*
|
||||
* Sony is backwards from most protocols. It uses a variable length mark and a fixed length space rather than
|
||||
* a fixed mark and a variable space. Our generic send will still work. According to the protocol you must send
|
||||
* Sony commands at least three times so we automatically do it here.
|
||||
*/
|
||||
void IRsendSony::send(unsigned long data, int nbits) {
|
||||
for(int i=0; i<3;i++)
|
||||
sendGeneric(data,nbits, 600*4, 600, 600*2, 600, 600, 600, 40, false);
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_NECX)
|
||||
/*
|
||||
* This next section of send routines were added by Chris Young. They all use the generic send.
|
||||
*/
|
||||
void IRsendNECx::send(unsigned long data)
|
||||
{
|
||||
sendGeneric(data,32, 564*8, 564*8, 564, 564, 564*3, 564, 38, true);
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_PANASONIC_OLD)
|
||||
void IRsendPanasonic_Old::send(unsigned long data)
|
||||
{
|
||||
sendGeneric(data,22, 833*4, 833*4, 833, 833, 833*3, 833,57, true);
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_JVC)
|
||||
/*
|
||||
* JVC omits the Mark/space header on repeat sending. Therefore we multiply it by 0 if it's 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". Therefore you should call this routine once with
|
||||
* "First=true"and it will send a first frame followed by one repeat frame. If First== false,
|
||||
* it will only send a single repeat frame.
|
||||
*/
|
||||
void IRsendJVC::send(unsigned long data, bool First)
|
||||
{
|
||||
sendGeneric(data, 16,525*16*First, 525*8*First, 525, 525,525*3, 525, 38, true);
|
||||
delayMicroseconds(45);
|
||||
if(First) sendGeneric(data, 16,0,0, 525, 525,525*3, 525, 38, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The remaining protocols require special treatment. They were in the original IRremote library.
|
||||
*/
|
||||
void IRsendRaw::send(unsigned int buf[], int len, int hz)
|
||||
{
|
||||
enableIROut(hz);
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (i & 1) {
|
||||
space(buf[i]);
|
||||
}
|
||||
else {
|
||||
mark(buf[i]);
|
||||
}
|
||||
}
|
||||
space(0); // Just to be sure
|
||||
}
|
||||
/*
|
||||
* The RC5 protocol uses a phase encoding of data bits. A space/mark pair indicates "1"
|
||||
* and a mark/space indicates a "0". It begins with a single "1" bit which is not encoded
|
||||
* in the data. The high order data bit is a toggle bit that indicates individual
|
||||
* keypresses. You must toggle this bit yourself when sending data.
|
||||
*/
|
||||
|
||||
void IRsendRC5::send(unsigned long data)
|
||||
{
|
||||
enableIROut(36);
|
||||
data = data << (32 - 13);
|
||||
mark(RC5_T1); // First start bit
|
||||
//Note: Original IRremote library incorrectly assumed second bit was always a "1"
|
||||
//bit patterns from this decoder are not backward compatible with patterns produced
|
||||
//by original library. Ucomment the following two lines to maintain backward compatibility.
|
||||
//space(RC5_T1); // Second start bit
|
||||
//mark(RC5_T1); // Second start bit
|
||||
for (int i = 0; i < 13; i++) {
|
||||
if (data & TOPBIT) {
|
||||
space(RC5_T1); mark(RC5_T1);// 1 is space, then mark
|
||||
}
|
||||
else {
|
||||
mark(RC5_T1); space(RC5_T1);// 0 is mark, then space
|
||||
}
|
||||
data <<= 1;
|
||||
}
|
||||
space(0); // Turn off at end
|
||||
}
|
||||
|
||||
/*
|
||||
* The RC6 protocol also phase encodes databits although the phasing is opposite of RC5.
|
||||
*/
|
||||
void IRsendRC6::send(unsigned long data, int nbits)
|
||||
{
|
||||
enableIROut(36);
|
||||
data = data << (32 - nbits);
|
||||
mark(RC6_HDR_MARK); space(RC6_HDR_SPACE);
|
||||
mark(RC6_T1); space(RC6_T1);// start bit "1"
|
||||
int t;
|
||||
for (int i = 0; i < nbits; i++) {
|
||||
if (i == 3) {
|
||||
t = 2 * RC6_T1; // double-wide trailer bit
|
||||
}
|
||||
else {
|
||||
t = RC6_T1;
|
||||
}
|
||||
if (data & TOPBIT) {
|
||||
mark(t); space(t);//"1" is a Mark/space
|
||||
}
|
||||
else {
|
||||
space(t); mark(t);//"0" is a space/Mark
|
||||
}
|
||||
data <<= 1;
|
||||
}
|
||||
space(0); // Turn off at end
|
||||
}
|
||||
/*
|
||||
* This method can be used to send any of the supported types except for raw and hash code.
|
||||
* There is no hash code send possible. You can call sendRaw directly if necessary.
|
||||
*/
|
||||
void IRsend::send(IRTYPES Type, unsigned long data, int nbits) {
|
||||
switch(Type) {
|
||||
case NEC: IRsendNEC::send(data); break;
|
||||
case SONY: IRsendSony::send(data,nbits); break;
|
||||
case RC5: IRsendRC5::send(data); break;
|
||||
case RC6: IRsendRC6::send(data,nbits); break;
|
||||
case PANASONIC_OLD: IRsendPanasonic_Old::send(data); break;
|
||||
case NECX: IRsendNECx::send(data); break;
|
||||
case JVC: IRsendJVC::send(data,(bool)nbits); break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Although I tried to keep all of the interrupt handling code at the bottom of this file
|
||||
* so you didn't have to mess with it if you didn't want to, I needed to move this definition
|
||||
* forwarded so it could be used by IRdecodeBase constructor.
|
||||
*/
|
||||
// receiver states
|
||||
enum rcvstate_t {STATE_UNKNOWN, STATE_IDLE, STATE_MARK, STATE_SPACE, STATE_STOP};
|
||||
// information for the interrupt handler
|
||||
typedef struct {
|
||||
uint8_t recvpin; // pin for IR data from detector
|
||||
rcvstate_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;
|
||||
volatile irparams_t irparams;
|
||||
|
||||
/*
|
||||
* We've chosen to separate the decoding routines from the receiving routines to isolate
|
||||
* the technical hardware and interrupt portion of the code which should never need modification
|
||||
* from the protocol decoding portion that will likely be extended and modified.
|
||||
*/
|
||||
IRdecodeBase::IRdecodeBase(void) {
|
||||
rawbuf=(volatile unsigned int*)irparams.rawbuf;
|
||||
Reset();
|
||||
};
|
||||
/*
|
||||
* Normally the decoder uses irparams.rawbuf but if you want to resume receiving while
|
||||
* still decoding you can define a separate buffer and pass the address here.
|
||||
* Then IRrecv::GetResults will copy the raw values from its buffer to yours allowing you to
|
||||
* call IRrecv::resume immediately before you call decode.
|
||||
*/
|
||||
void IRdecodeBase::UseExtnBuf(void *P){
|
||||
rawbuf=(volatile unsigned int*)P;
|
||||
};
|
||||
/*
|
||||
* Copies rawbuf and rawlen from one decoder to another. See IRhashdecode example
|
||||
* for usage.
|
||||
*/
|
||||
void IRdecodeBase::copyBuf (IRdecodeBase *source){
|
||||
memcpy((void *)rawbuf,(const void *)source->rawbuf,sizeof(irparams.rawbuf));
|
||||
rawlen=source->rawlen;
|
||||
};
|
||||
|
||||
/*
|
||||
* This routine is actually quite useful. See the Samsung36 sketch in the examples
|
||||
*/
|
||||
bool IRdecodeBase::decode(void) {
|
||||
return false;
|
||||
};
|
||||
|
||||
void IRdecodeBase::Reset(void) {
|
||||
decode_type= UNKNOWN;
|
||||
value=0;
|
||||
bits=0;
|
||||
rawlen=0;
|
||||
};
|
||||
/*
|
||||
* This method dumps useful information about the decoded values.
|
||||
*/
|
||||
void IRdecodeBase::DumpResults(void) {
|
||||
int i;
|
||||
if(decode_type<=LAST_PROTOCOL){
|
||||
Serial.print(F("Decoded ")); Serial.print(Pnames(decode_type));
|
||||
Serial.print(F(": Value:")); Serial.print(value, HEX);
|
||||
};
|
||||
#ifdef DETAILLED_DUMP
|
||||
Serial.print(F(" (")); Serial.print(bits, DEC); Serial.println(F(" bits)"));
|
||||
Serial.print(F("Raw samples(")); Serial.print(rawlen, DEC);
|
||||
Serial.print(F("): Gap:")); Serial.println(Interval_uSec(0), DEC);
|
||||
Serial.print(F(" Head: m")); Serial.print(Interval_uSec(1), DEC);
|
||||
Serial.print(F(" s")); Serial.println(Interval_uSec(2), DEC);
|
||||
int LowSpace= 32767; int LowMark= 32767;
|
||||
int HiSpace=0; int HiMark= 0;
|
||||
for (i = 3; i < rawlen; i++) {
|
||||
int interval= Interval_uSec(i);
|
||||
if (i % 2) {
|
||||
LowMark=min(LowMark, interval); HiMark=max(HiMark, interval);
|
||||
Serial.print(i/2-1,DEC); Serial.print(F(":m"));
|
||||
}
|
||||
else {
|
||||
if(interval>0)LowSpace=min(LowSpace, interval); HiSpace=max (HiSpace, interval);
|
||||
Serial.print(F(" s"));
|
||||
}
|
||||
Serial.print(interval, DEC);
|
||||
int j=i-1;
|
||||
if ((j % 2)==1)Serial.print(F("\t"));
|
||||
if ((j % 4)==1)Serial.print(F("\t "));
|
||||
if ((j % 8)==1)Serial.println();
|
||||
if ((j % 32)==1)Serial.println();
|
||||
}
|
||||
Serial.println();
|
||||
Serial.print(F("Mark min:")); Serial.print(LowMark,DEC);Serial.print(F("\t max:")); Serial.println(HiMark,DEC);
|
||||
Serial.print(F("Space min:")); Serial.print(LowSpace,DEC);Serial.print(F("\t max:")); Serial.println(HiSpace,DEC);
|
||||
#endif
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
/*
|
||||
* This handy little routine converts ticks from rawbuf[index] into uSec intervals adjusting for the
|
||||
* Mark/space bias.
|
||||
*/
|
||||
unsigned long IRdecodeBase::Interval_uSec(int index)
|
||||
{
|
||||
return rawbuf[index]*USECPERTICK+( (index%2)?-MARK_EXCESS: MARK_EXCESS);
|
||||
};
|
||||
|
||||
/*
|
||||
* Again we use a generic routine because most protocols have the same basic structure. However we need to
|
||||
* indicate whether or not the protocol varies the length of the mark or the space to indicate a "0" or "1".
|
||||
* If "Mark_One" is zero. We assume that the length of the space varies. If "Mark_One" is not zero then
|
||||
* we assume that the length of Mark varies and the value passed as "Space_Zero" is ignored.
|
||||
* When using variable length Mark, assumes Head_Space==Space_One. If it doesn't, you need a specialized decoder.
|
||||
*/
|
||||
bool IRdecodeBase::decodeGeneric(/*int*/int8_t Raw_Count, int Head_Mark,int Head_Space, int Mark_One, int Mark_Zero, int Space_One,int Space_Zero) {
|
||||
// If raw samples count or head mark are zero then don't perform these tests.
|
||||
// Some protocols need to do custom header work.
|
||||
long data = 0; /*int*/int8_t Max; /*int*/int8_t offset;
|
||||
if (Raw_Count) {if (rawlen != Raw_Count) return RAW_COUNT_ERROR;}
|
||||
if (Head_Mark) {if (!MATCH_MARK(rawbuf[1],Head_Mark)) return HEADER_MARK_ERROR;}
|
||||
if (Head_Space) {if (!MATCH_SPACE(rawbuf[2],Head_Space)) return HEADER_SPACE_ERROR;}
|
||||
|
||||
if (Mark_One) {//Length of a mark indicates data "0" or "1". Space_Zero is ignored.
|
||||
offset=2;//skip initial gap plus header Mark.
|
||||
Max=rawlen;
|
||||
while (offset < Max) {
|
||||
if (!MATCH_SPACE(rawbuf[offset], Space_One)) return DATA_SPACE_ERROR;
|
||||
offset++;
|
||||
if (MATCH_MARK(rawbuf[offset], Mark_One)) {
|
||||
data = (data << 1) | 1;
|
||||
}
|
||||
else if (MATCH_MARK(rawbuf[offset], Mark_Zero)) {
|
||||
data <<= 1;
|
||||
}
|
||||
else return DATA_MARK_ERROR;
|
||||
offset++;
|
||||
}
|
||||
bits = (offset - 1) / 2;
|
||||
}
|
||||
else {//Mark_One was 0 therefore length of a space indicates data "0" or "1".
|
||||
Max=rawlen-1; //ignore stop bit
|
||||
offset=3;//skip initial gap plus two header items
|
||||
while (offset < Max) {
|
||||
if (!MATCH_MARK (rawbuf[offset],Mark_Zero)) return DATA_MARK_ERROR;
|
||||
offset++;
|
||||
if (MATCH_SPACE(rawbuf[offset],Space_One)) {
|
||||
data = (data << 1) | 1;
|
||||
}
|
||||
else if (MATCH_SPACE (rawbuf[offset],Space_Zero)) {
|
||||
data <<= 1;
|
||||
}
|
||||
else return DATA_SPACE_ERROR;
|
||||
offset++;
|
||||
}
|
||||
bits = (offset - 1) / 2 -1;//didn't encode stop bit
|
||||
}
|
||||
// Success
|
||||
value = data;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine has been modified significantly from the original IRremote.
|
||||
* It assumes you've already called IRrecvBase::GetResults and it was true.
|
||||
* The purpose of GetResults is to determine if a complete set of signals
|
||||
* has been received. It then copies the raw data into your decode_results
|
||||
* structure. By moving the test for completion and the copying of the buffer
|
||||
* outside of this "decode" method you can use the individual decode
|
||||
* methods or make your own custom "decode" without checking for
|
||||
* protocols you don't use.
|
||||
* Note: Don't forget to call IRrecvBase::resume(); after decoding is complete.
|
||||
*/
|
||||
bool IRdecode::decode(void) {
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_NEC)
|
||||
if (IRdecodeNEC::decode()) return true;
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_SONY)
|
||||
if (IRdecodeSony::decode()) return true;
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_RC5)
|
||||
if (IRdecodeRC5::decode()) return true;
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_RC6)
|
||||
if (IRdecodeRC6::decode()) return true;
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_PANASONIC_OLD)
|
||||
if (IRdecodePanasonic_Old::decode()) return true;
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_NECX)
|
||||
if (IRdecodeNECx::decode()) return true;
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_JVC)
|
||||
if (IRdecodeJVC::decode()) return true;
|
||||
#endif
|
||||
//Deliberately did not add hash code decoding. If you get decode_type==UNKNOWN and
|
||||
// you want to know a hash code you can call IRhash::decode() yourself.
|
||||
// BTW This is another reason we separated IRrecv from IRdecode.
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_NEC)
|
||||
#define NEC_RPT_SPACE 2250
|
||||
bool IRdecodeNEC::decode(void) {
|
||||
ATTEMPT_MESSAGE(F("NEC"));
|
||||
// Check for repeat
|
||||
if (rawlen == 4 && MATCH_SPACE(rawbuf[2], NEC_RPT_SPACE) &&
|
||||
MATCH_MARK(rawbuf[3],564)) {
|
||||
bits = 0;
|
||||
value = REPEAT;
|
||||
decode_type = NEC;
|
||||
return true;
|
||||
}
|
||||
if(!decodeGeneric(68, 564*16, 564*8, 0, 564, 564*3, 564)) return false;
|
||||
decode_type = NEC;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_SONY)
|
||||
// According to http://www.hifi-remote.com/johnsfine/DecodeIR.html#Sony8
|
||||
// Sony protocol can only be 8, 12, 15, or 20 bits in length.
|
||||
bool IRdecodeSony::decode(void) {
|
||||
ATTEMPT_MESSAGE(F("Sony"));
|
||||
if(rawlen!=2*8+2 && rawlen!=2*12+2 && rawlen!=2*15+2 && rawlen!=2*20+2) return RAW_COUNT_ERROR;
|
||||
if(!decodeGeneric(0, 600*4, 600, 600*2, 600, 600,0)) return false;
|
||||
decode_type = SONY;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The next several decoders were added by Chris Young. They illustrate some of the special cases
|
||||
* that can come up when decoding using the generic decoder.
|
||||
*/
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_PANASONIC_OLD)
|
||||
/*
|
||||
* A very good source for protocol information is<69> http://www.hifi-remote.com/johnsfine/DecodeIR.html
|
||||
* I used that information to understand what they call the "Panasonic old" protocol which is used by
|
||||
* Scientific Atlanta cable boxes. That website uses a very strange notation called IRP notation.
|
||||
* For this protocol, the notation was:
|
||||
* {57.6k,833}<1,-1|1,-3>(4,-4,D:5,F:6,~D:5,~F:6,1,-???)+
|
||||
* This indicates that the frequency is 57.6, the base length for the pulse is 833
|
||||
* The first part of the <x,-x|x,-x> section tells you what a "0" is and the second part
|
||||
* tells you what a "1" is. That means "0" is 833 on, 833 off while an "1" is 833 on
|
||||
* followed by 833*3=2499 off. The section in parentheses tells you what data gets sent.
|
||||
* The protocol begins with header consisting of 4*833 on and 4*833 off. The other items
|
||||
* describe what the remaining data bits are.
|
||||
* It reads as 5 device bits followed by 6 function bits. You then repeat those bits complemented.
|
||||
* It concludes with a single "1" bit followed by and an undetermined amount of blank space.
|
||||
* This makes the entire protocol 5+6+5+6= 22 bits long since we don't encode the stop bit.
|
||||
* The "+" at the end means you only need to send it once and it can repeat as many times as you want.
|
||||
*/
|
||||
bool IRdecodePanasonic_Old::decode(void) {
|
||||
ATTEMPT_MESSAGE(F("Panasonic_Old"));
|
||||
if(!decodeGeneric(48,833*4,833*4,0,833,833*3,833)) return false;
|
||||
/*
|
||||
* The protocol spec says that the first 11 bits described the device and function.
|
||||
* The next 11 bits are the same thing only it is the logical Bitwise complement.
|
||||
* Many protocols have such check features in their definition but our code typically doesn't
|
||||
* perform these checks. For example NEC's least significant 8 bits are the complement of
|
||||
* of the next more significant 8 bits. While it's probably not necessary to error check this,
|
||||
* here is some sample code to show you how.
|
||||
*/
|
||||
long S1= (value & 0x0007ff); // 00 0000 0000 0111 1111 1111 //00000 000000 11111 111111
|
||||
long S2= (value & 0x3ff800)>> 11; // 11 1111 1111 1000 0000 0000 //11111 111111 00000 000000
|
||||
S2= (~S2) & 0x0007ff;
|
||||
if (S1!=S2) {REJECTION_MESSAGE(F("inverted bit redundancy")); return false;};
|
||||
// Success
|
||||
decode_type = PANASONIC_OLD;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_NECX)
|
||||
bool IRdecodeNECx::decode(void) {
|
||||
ATTEMPT_MESSAGE(F("NECx"));
|
||||
if(!decodeGeneric(68,564*8,564*8,0,564,564*3,564)) return false;
|
||||
decode_type = NECX;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_JVC)
|
||||
// JVC does not send any header if there is a repeat.
|
||||
bool IRdecodeJVC::decode(void) {
|
||||
ATTEMPT_MESSAGE(F("JVC"));
|
||||
if(!decodeGeneric(36,525*16,525*8,0,525,525*3,525))
|
||||
{
|
||||
ATTEMPT_MESSAGE(F("JVC Repeat"));
|
||||
if (rawlen==34)
|
||||
{
|
||||
if(!decodeGeneric(0,525,0,0,525,525*3,525))
|
||||
{REJECTION_MESSAGE(F("JVC repeat failed generic")); return false;}
|
||||
else {
|
||||
//If this is a repeat code then IRdecodeBase::decode fails to add the most significant bit
|
||||
if (MATCH_SPACE(rawbuf[4],(525*3)))
|
||||
{
|
||||
value |= 0x8000;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!MATCH_SPACE(rawbuf[4],525)) return DATA_SPACE_ERROR;
|
||||
}
|
||||
}
|
||||
bits++;
|
||||
}
|
||||
else return RAW_COUNT_ERROR;
|
||||
}
|
||||
decode_type =JVC;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_RC5) || (MY_IR_PROTOCOL == PROTO_RC6)
|
||||
/*
|
||||
* The remaining protocols from the original IRremote library require special handling
|
||||
* This routine gets one undecoded level at a time from the raw buffer.
|
||||
* The RC5/6 decoding is easier if the data is broken into time intervals.
|
||||
* E.g. if the buffer has MARK for 2 time intervals and SPACE for 1,
|
||||
* successive calls to getRClevel will return MARK, MARK, SPACE.
|
||||
* offset and used are updated to keep track of the current position.
|
||||
* t1 is the time interval for a single bit in microseconds.
|
||||
* Returns ERROR if the measured time interval is not a multiple of t1.
|
||||
*/
|
||||
IRdecodeRC::RCLevel IRdecodeRC::getRClevel(int *offset, int *used, int t1) {
|
||||
if (*offset >= rawlen) {
|
||||
// After end of recorded buffer, assume SPACE.
|
||||
return SPACE;
|
||||
}
|
||||
int width = rawbuf[*offset];
|
||||
IRdecodeRC::RCLevel val;
|
||||
if ((*offset) % 2) val=MARK; else val=SPACE;
|
||||
int correction = (val == MARK) ? MARK_EXCESS : - MARK_EXCESS;
|
||||
|
||||
int avail;
|
||||
if (MATCH(width, t1 + correction)) {
|
||||
avail = 1;
|
||||
}
|
||||
else if (MATCH(width, 2*t1 + correction)) {
|
||||
avail = 2;
|
||||
}
|
||||
else if (MATCH(width, 3*t1 + correction)) {
|
||||
avail = 3;
|
||||
}
|
||||
else {
|
||||
return ERROR;
|
||||
}
|
||||
(*used)++;
|
||||
if (*used >= avail) {
|
||||
*used = 0;
|
||||
(*offset)++;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (val == MARK) Serial.println("MARK"); else Serial.println("SPACE");
|
||||
#endif
|
||||
return val;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define MIN_RC5_SAMPLES 11
|
||||
#define MIN_RC6_SAMPLES 1
|
||||
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_RC5)
|
||||
bool IRdecodeRC5::decode(void) {
|
||||
ATTEMPT_MESSAGE(F("RC5"));
|
||||
if (rawlen < MIN_RC5_SAMPLES + 2) return RAW_COUNT_ERROR;
|
||||
int offset = 1; // Skip gap space
|
||||
long data = 0;
|
||||
int used = 0;
|
||||
// Get start bits
|
||||
if (getRClevel(&offset, &used, RC5_T1) != MARK) return HEADER_MARK_ERROR;
|
||||
//Note: Original IRremote library incorrectly assumed second bit was always a "1"
|
||||
//bit patterns from this decoder are not backward compatible with patterns produced
|
||||
//by original library. Ucomment the following two lines to maintain backward compatibility.
|
||||
//if (getRClevel(&offset, &used, RC5_T1) != SPACE) return HEADER_SPACE_ERROR;
|
||||
//if (getRClevel(&offset, &used, RC5_T1) != MARK) return HEADER_MARK_ERROR;
|
||||
int nbits;
|
||||
for (nbits = 0; offset < rawlen; nbits++) {
|
||||
RCLevel levelA = getRClevel(&offset, &used, RC5_T1);
|
||||
RCLevel levelB = getRClevel(&offset, &used, RC5_T1);
|
||||
if (levelA == SPACE && levelB == MARK) {
|
||||
// 1 bit
|
||||
data = (data << 1) | 1;
|
||||
}
|
||||
else if (levelA == MARK && levelB == SPACE) {
|
||||
// zero bit
|
||||
data <<= 1;
|
||||
}
|
||||
else return DATA_MARK_ERROR;
|
||||
}
|
||||
// Success
|
||||
bits = 13;
|
||||
value = data;
|
||||
decode_type = RC5;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_RC6)
|
||||
bool IRdecodeRC6::decode(void) {
|
||||
ATTEMPT_MESSAGE(F("RC6"));
|
||||
if (rawlen < MIN_RC6_SAMPLES) return RAW_COUNT_ERROR;
|
||||
// Initial mark
|
||||
if (!MATCH_MARK(rawbuf[1], RC6_HDR_MARK)) return HEADER_MARK_ERROR;
|
||||
if (!MATCH_SPACE(rawbuf[2], RC6_HDR_SPACE)) return HEADER_SPACE_ERROR;
|
||||
int offset=3;//Skip gap and header
|
||||
long data = 0;
|
||||
int used = 0;
|
||||
// Get start bit (1)
|
||||
if (getRClevel(&offset, &used, RC6_T1) != MARK) return DATA_MARK_ERROR;
|
||||
if (getRClevel(&offset, &used, RC6_T1) != SPACE) return DATA_SPACE_ERROR;
|
||||
int nbits;
|
||||
for (nbits = 0; offset < rawlen; nbits++) {
|
||||
RCLevel levelA, levelB; // Next two levels
|
||||
levelA = getRClevel(&offset, &used, RC6_T1);
|
||||
if (nbits == 3) {
|
||||
// T bit is double wide; make sure second half matches
|
||||
if (levelA != getRClevel(&offset, &used, RC6_T1)) return TRAILER_BIT_ERROR;
|
||||
}
|
||||
levelB = getRClevel(&offset, &used, RC6_T1);
|
||||
if (nbits == 3) {
|
||||
// T bit is double wide; make sure second half matches
|
||||
if (levelB != getRClevel(&offset, &used, RC6_T1)) return TRAILER_BIT_ERROR;
|
||||
}
|
||||
if (levelA == MARK && levelB == SPACE) { // reversed compared to RC5
|
||||
// 1 bit
|
||||
data = (data << 1) | 1;
|
||||
}
|
||||
else if (levelA == SPACE && levelB == MARK) {
|
||||
// zero bit
|
||||
data <<= 1;
|
||||
}
|
||||
else {
|
||||
return DATA_MARK_ERROR;
|
||||
}
|
||||
}
|
||||
// Success
|
||||
bits = nbits;
|
||||
value = data;
|
||||
decode_type = RC6;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ALL_IR_PROTOCOL) //|| (MY_IR_PROTOCOL == HASH_CODE)
|
||||
/*
|
||||
* This Hash decoder is based on IRhashcode
|
||||
* Copyright 2010 Ken Shirriff
|
||||
* For details see http://www.arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html
|
||||
* Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param
|
||||
* Converts the raw code values into a 32-bit hash code.
|
||||
* Hopefully this code is unique for each button.
|
||||
*/
|
||||
#define FNV_PRIME_32 16777619
|
||||
#define FNV_BASIS_32 2166136261
|
||||
// Compare two tick values, returning 0 if newval is shorter,
|
||||
// 1 if newval is equal, and 2 if newval is longer
|
||||
int IRdecodeHash::compare(unsigned int oldval, unsigned int newval) {
|
||||
if (newval < oldval * .8) return 0;
|
||||
if (oldval < newval * .8) return 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool IRdecodeHash::decode(void) {
|
||||
hash = FNV_BASIS_32;
|
||||
for (int i = 1; i+2 < rawlen; i++) {
|
||||
hash = (hash * FNV_PRIME_32) ^ compare(rawbuf[i], rawbuf[i+2]);
|
||||
}
|
||||
//note: does not set decode_type=HASH_CODE nor "value" because you might not want to.
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This section is all related to interrupt handling and hardware issues. It has nothing to do with IR protocols.
|
||||
* You need not understand this is all you're doing is adding new protocols or improving the decoding and sending
|
||||
* of protocols.
|
||||
*
|
||||
*/
|
||||
|
||||
// Provides ISR
|
||||
#include <avr/interrupt.h>
|
||||
// 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
|
||||
#define CLKFUDGE 5 // fudge factor for clock interrupt overhead
|
||||
#ifdef F_CPU
|
||||
#define SYSCLOCK F_CPU // main Arduino clock
|
||||
#else
|
||||
#define SYSCLOCK 16000000 // main Arduino clock
|
||||
#endif
|
||||
#define PRESCALE 8 // timer clock prescale
|
||||
#define CLKSPERUSEC (SYSCLOCK/PRESCALE/1000000) // timer clocks per microsecond
|
||||
|
||||
#include <IRLibTimer.h>
|
||||
|
||||
|
||||
IRrecv::IRrecv(int recvpin)
|
||||
{
|
||||
irparams.recvpin = recvpin;
|
||||
irparams.blinkflag = 0;
|
||||
}
|
||||
/* If your hardware is set up to do both output and input but your particular sketch
|
||||
* doesn't do any output, this method will ensure that your output pin is low
|
||||
* and doesn't turn on your IR LED or any output circuit.
|
||||
*/
|
||||
void IRrecv::No_Output (void) {
|
||||
pinMode(TIMER_PWM_PIN, OUTPUT);
|
||||
digitalWrite(TIMER_PWM_PIN, LOW); // When not sending PWM, we want it low
|
||||
}
|
||||
|
||||
void IRrecv::enableIRIn() {
|
||||
// setup pulse clock timer interrupt
|
||||
cli();
|
||||
TIMER_CONFIG_NORMAL();
|
||||
TIMER_ENABLE_INTR;
|
||||
TIMER_RESET;
|
||||
sei();
|
||||
// initialize state machine variables
|
||||
irparams.rcvstate = STATE_IDLE;
|
||||
irparams.rawlen = 0;
|
||||
// set pin modes
|
||||
pinMode(irparams.recvpin, INPUT);
|
||||
}
|
||||
// enable/disable blinking of pin 13 on IR processing
|
||||
void IRrecv::blink13(int blinkflag)
|
||||
{
|
||||
irparams.blinkflag = blinkflag;
|
||||
if (blinkflag)
|
||||
pinMode(BLINKLED, OUTPUT);
|
||||
}
|
||||
void IRrecv::resume() {
|
||||
irparams.rcvstate = STATE_IDLE;
|
||||
irparams.rawlen = 0;
|
||||
}
|
||||
bool IRrecv::GetResults(IRdecodeBase *decoder) {
|
||||
if (irparams.rcvstate != STATE_STOP) return false;
|
||||
decoder->Reset();//clear out any old values.
|
||||
decoder->rawlen = (unsigned int)irparams.rawlen;
|
||||
//By copying the entire array we could call IRrecv::resume immediately while decoding
|
||||
//is still in progress.
|
||||
if(decoder->rawbuf != irparams.rawbuf)
|
||||
memcpy((void *)decoder->rawbuf,(const void *)irparams.rawbuf,sizeof(irparams.rawbuf));
|
||||
return true;
|
||||
}
|
||||
#define _GAP 5000 // Minimum map between transmissions
|
||||
#define GAP_TICKS (_GAP/USECPERTICK)
|
||||
|
||||
// TIMER2 interrupt code to collect raw data.
|
||||
// Widths of alternating SPACE, MARK are recorded in rawbuf.
|
||||
// Recorded in ticks of 50 microseconds.
|
||||
// rawlen counts the number of entries recorded so far.
|
||||
// First entry is the SPACE between transmissions.
|
||||
// As soon as a SPACE gets long, ready is set, state switches to IDLE, timing of SPACE continues.
|
||||
// As soon as first MARK arrives, gap width is recorded, ready is cleared, and new logging starts
|
||||
ISR(TIMER_INTR_NAME)
|
||||
{
|
||||
TIMER_RESET;
|
||||
enum irdata_t {IR_MARK=0, IR_SPACE=1};
|
||||
irdata_t irdata = (irdata_t)digitalRead(irparams.recvpin);
|
||||
irparams.timer++; // One more 50us tick
|
||||
if (irparams.rawlen >= RAWBUF) {
|
||||
// Buffer overflow
|
||||
irparams.rcvstate = STATE_STOP;
|
||||
}
|
||||
switch(irparams.rcvstate) {
|
||||
case STATE_IDLE: // In the middle of a gap
|
||||
if (irdata == IR_MARK) {
|
||||
if (irparams.timer < GAP_TICKS) {
|
||||
// Not big enough to be a gap.
|
||||
irparams.timer = 0;
|
||||
}
|
||||
else {
|
||||
// gap just ended, record duration and start recording transmission
|
||||
irparams.rawlen = 0;
|
||||
irparams.rawbuf[irparams.rawlen++] = irparams.timer;
|
||||
irparams.timer = 0;
|
||||
irparams.rcvstate = STATE_MARK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STATE_MARK: // timing MARK
|
||||
if (irdata == IR_SPACE) { // MARK ended, record time
|
||||
irparams.rawbuf[irparams.rawlen++] = irparams.timer;
|
||||
irparams.timer = 0;
|
||||
irparams.rcvstate = STATE_SPACE;
|
||||
}
|
||||
break;
|
||||
case STATE_SPACE: // timing SPACE
|
||||
if (irdata == IR_MARK) { // SPACE just ended, record it
|
||||
irparams.rawbuf[irparams.rawlen++] = irparams.timer;
|
||||
irparams.timer = 0;
|
||||
irparams.rcvstate = STATE_MARK;
|
||||
}
|
||||
else { // SPACE
|
||||
if (irparams.timer > GAP_TICKS) {
|
||||
// big SPACE, indicates gap between codes
|
||||
// Mark current code as ready for processing
|
||||
// Switch to STOP
|
||||
// Don't reset timer; keep counting space width
|
||||
irparams.rcvstate = STATE_STOP;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STATE_STOP: // waiting, measuring gap
|
||||
if (irdata == IR_MARK) { // reset gap timer
|
||||
irparams.timer = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (irparams.blinkflag) {
|
||||
if (irdata == IR_MARK) {
|
||||
BLINKLED_ON(); // turn pin 13 LED on
|
||||
}
|
||||
else {
|
||||
BLINKLED_OFF(); // turn pin 13 LED off
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_IR_SEND
|
||||
IRsendBase::IRsendBase () {
|
||||
pinMode(TIMER_PWM_PIN, OUTPUT);
|
||||
digitalWrite(TIMER_PWM_PIN, LOW); // When not sending PWM, we want it low
|
||||
}
|
||||
|
||||
void IRsendBase::enableIROut(int khz) {
|
||||
// Enables IR output. The khz value controls the modulation frequency in kilohertz.
|
||||
// The IR output will be on pin 3 (OC2B).
|
||||
// This routine is designed for 36-40KHz; if you use it for other values, it's up to you
|
||||
// to make sure it gives reasonable results. (Watch out for overflow / underflow / rounding.)
|
||||
// TIMER2 is used in phase-correct PWM mode, with OCR2A controlling the frequency and OCR2B
|
||||
// controlling the duty cycle.
|
||||
// There is no prescaling, so the output frequency is 16MHz / (2 * OCR2A)
|
||||
// To turn the output on and off, we leave the PWM running, but connect and disconnect the output pin.
|
||||
// A few hours staring at the ATmega documentation and this will all make sense.
|
||||
// See my Secrets of Arduino PWM at http://arcfn.com/2009/07/secrets-of-arduino-pwm.html for details.
|
||||
|
||||
// Disable the Timer2 Interrupt (which is used for receiving IR)
|
||||
TIMER_DISABLE_INTR; //Timer2 Overflow Interrupt
|
||||
pinMode(TIMER_PWM_PIN, OUTPUT);
|
||||
digitalWrite(TIMER_PWM_PIN, LOW); // When not sending PWM, we want it low
|
||||
TIMER_CONFIG_KHZ(khz);
|
||||
}
|
||||
|
||||
void IRsendBase::mark(int time) {
|
||||
TIMER_ENABLE_PWM;
|
||||
delayMicroseconds(time);
|
||||
}
|
||||
|
||||
void IRsendBase::space(int time) {
|
||||
TIMER_DISABLE_PWM;
|
||||
delayMicroseconds(time);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Various debugging routines
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
int MATCH(int measured, int desired) {
|
||||
Serial.print("Testing: "); Serial.print(TICKS_LOW(desired), DEC);
|
||||
Serial.print(" <= "); Serial.print(measured, DEC); Serial.print(" <= "); Serial.println(TICKS_HIGH(desired), DEC);
|
||||
return measured >= TICKS_LOW(desired) && measured <= TICKS_HIGH(desired);
|
||||
}
|
||||
|
||||
int MATCH_MARK(int measured_ticks, int desired_us) {
|
||||
Serial.print("Testing mark "); Serial.print(measured_ticks * USECPERTICK, DEC); Serial.print(" vs "); Serial.print(desired_us, DEC); Serial.print(": ");
|
||||
Serial.print(TICKS_LOW(desired_us + MARK_EXCESS), DEC); Serial.print(" <= "); Serial.print(measured_ticks, DEC);
|
||||
Serial.print(" <= "); Serial.println(TICKS_HIGH(desired_us + MARK_EXCESS), DEC);
|
||||
return measured_ticks >= TICKS_LOW(desired_us + MARK_EXCESS) && measured_ticks <= TICKS_HIGH(desired_us + MARK_EXCESS);
|
||||
}
|
||||
|
||||
int MATCH_SPACE(int measured_ticks, int desired_us) {
|
||||
Serial.print("Testing space "); Serial.print(measured_ticks * USECPERTICK, DEC); Serial.print(" vs "); Serial.print(desired_us, DEC); Serial.print(": ");
|
||||
Serial.print(TICKS_LOW(desired_us - MARK_EXCESS), DEC); Serial.print(" <= "); Serial.print(measured_ticks, DEC);
|
||||
Serial.print(" <= "); Serial.println(TICKS_HIGH(desired_us - MARK_EXCESS), DEC);
|
||||
return measured_ticks >= TICKS_LOW(desired_us - MARK_EXCESS) && measured_ticks <= TICKS_HIGH(desired_us - MARK_EXCESS);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef TRACE
|
||||
void ATTEMPT_MESSAGE(const __FlashStringHelper * s) {Serial.print(F("Attempting ")); Serial.print(s); Serial.println(F(" decode:"));};
|
||||
byte REJECTION_MESSAGE(const __FlashStringHelper * s) { Serial.print(F(" Protocol failed because ")); Serial.print(s); Serial.println(F(" wrong.")); return false;};
|
||||
#endif
|
318
hardware/digistump/avr/libraries/DigisparkIRLib/IRLib.h
Normal file
318
hardware/digistump/avr/libraries/DigisparkIRLib/IRLib.h
Normal file
@@ -0,0 +1,318 @@
|
||||
/* IRLib.h from IRLib an Arduino library for infrared encoding and decoding
|
||||
* Version 1.1 April 2013
|
||||
* Copyright 2013 by Chris Young http://cyborg5.com
|
||||
*
|
||||
* Port to Digispark (size optimization) August 2013
|
||||
* by RC Navy http://p.loussouarn.free.fr
|
||||
*
|
||||
* 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/
|
||||
*/
|
||||
|
||||
#ifndef IRLib_h
|
||||
#define IRLib_h
|
||||
#include <Arduino.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.
|
||||
// If TRACE is defined, some debugging information about the decode will be printed
|
||||
// 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.
|
||||
// If DETAILLED_DUMP is defined the dump informations are more detailled
|
||||
// If ALL_IR_PROTOCOL is defined, it allows to discover the protocol used by the IR transmitter (eg, with an arduino UNO)
|
||||
// Once the protocol used by the IR transmitter discovered, set MY_IR_PROTOCOL to PROTO_xxxx and comment ALL_IR_PROTOCOL
|
||||
// this will reduce dramatically the size of the sketch
|
||||
// #define DEBUG
|
||||
// #define TRACE
|
||||
// #define TEST
|
||||
|
||||
//#define USE_IR_SEND
|
||||
//#define DETAILLED_DUMP
|
||||
//#define ALL_IR_PROTOCOL
|
||||
#define MY_IR_PROTOCOL PROTO_NEC /* Set Here the protocol you want to use among the following ones */
|
||||
|
||||
// Only used for testing; can remove virtual for shorter code
|
||||
#ifdef TEST
|
||||
#define VIRTUAL virtual
|
||||
#else
|
||||
#define VIRTUAL
|
||||
#endif
|
||||
|
||||
#define RAWBUF 70//100 // Length of raw duration buffer
|
||||
#define USE_TIMER1 1 //should be "1" for timer 1, should be "0" for timer 2
|
||||
|
||||
/* Use one of the protocol in the list below if you want to support a single one */
|
||||
#define PROTO_UNKNOWN 0
|
||||
#define PROTO_NEC 1
|
||||
#define PROTO_SONY 2
|
||||
#define PROTO_RC5 3
|
||||
#define PROTO_RC6 4
|
||||
#define PROTO_PANASONIC_OLD 5
|
||||
#define PROTO_JVC 6
|
||||
#define PROTO_NECX 7
|
||||
#define PROTO_HASH_CODE 8
|
||||
|
||||
enum IRTYPES {UNKNOWN, NEC, SONY, RC5, RC6, PANASONIC_OLD, JVC, NECX, HASH_CODE, LAST_PROTOCOL=HASH_CODE};
|
||||
|
||||
#if defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
|
||||
const char *Pnames(IRTYPES Type); //Returns a character string that is name of protocol.
|
||||
#else
|
||||
const __FlashStringHelper *Pnames(IRTYPES Type); //Returns a character string that is name of protocol.
|
||||
#endif
|
||||
// Base class for decoding raw results
|
||||
class IRdecodeBase
|
||||
{
|
||||
public:
|
||||
IRdecodeBase(void);
|
||||
IRTYPES decode_type; // NEC, SONY, RC5, UNKNOWN etc.
|
||||
unsigned long value; // Decoded value
|
||||
int bits; // Number of bits in decoded value
|
||||
volatile unsigned int *rawbuf; // Raw intervals in .5 us ticks
|
||||
/*int*/uint8_t 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(/*int*/int8_t Raw_Count,int Head_Mark,int Head_Space, int Mark_One, int Mark_Zero, int Space_One,int Space_Zero);
|
||||
unsigned long Interval_uSec(int index);
|
||||
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
|
||||
};
|
||||
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_HASH_CODE)
|
||||
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
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_NEC)
|
||||
class IRdecodeNEC: public virtual IRdecodeBase
|
||||
{
|
||||
public:
|
||||
virtual bool decode(void);
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_SONY)
|
||||
class IRdecodeSony: public virtual IRdecodeBase
|
||||
{
|
||||
public:
|
||||
virtual bool decode(void);
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_RC5) || (MY_IR_PROTOCOL == PROTO_RC6)
|
||||
class IRdecodeRC: public virtual IRdecodeBase
|
||||
{
|
||||
public:
|
||||
enum RCLevel {MARK, SPACE, ERROR};//used by decoders for RC5/RC6
|
||||
// These are called by decode
|
||||
RCLevel getRClevel(int *offset, int *used, int t1);
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_RC5)
|
||||
class IRdecodeRC5: public virtual IRdecodeRC
|
||||
{
|
||||
public:
|
||||
virtual bool decode(void);
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_RC6)
|
||||
class IRdecodeRC6: public virtual IRdecodeRC
|
||||
{
|
||||
public:
|
||||
virtual bool decode(void);
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_PANASONIC_OLD)
|
||||
class IRdecodePanasonic_Old: public virtual IRdecodeBase
|
||||
{
|
||||
public:
|
||||
virtual bool decode(void);
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_JVC)
|
||||
class IRdecodeJVC: public virtual IRdecodeBase
|
||||
{
|
||||
public:
|
||||
virtual bool decode(void);
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_NECX)
|
||||
class IRdecodeNECx: public virtual IRdecodeBase
|
||||
{
|
||||
public:
|
||||
virtual bool decode(void);
|
||||
};
|
||||
#endif
|
||||
|
||||
// main class for decoding all supported protocols
|
||||
class IRdecode:
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_NEC)
|
||||
public virtual IRdecodeNEC
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL)
|
||||
,
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_SONY)
|
||||
public virtual IRdecodeSony
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL)
|
||||
,
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_RC5)
|
||||
public virtual IRdecodeRC5
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL)
|
||||
,
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_RC6)
|
||||
public virtual IRdecodeRC6
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL)
|
||||
,
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_PANASONIC_OLD)
|
||||
public virtual IRdecodePanasonic_Old
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL)
|
||||
,
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_JVC)
|
||||
public virtual IRdecodeJVC
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL)
|
||||
,
|
||||
#endif
|
||||
#if defined(ALL_IR_PROTOCOL) || (MY_IR_PROTOCOL == PROTO_NECX)
|
||||
public virtual IRdecodeNECx
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
virtual bool decode(void); // Calls each decode routine individually
|
||||
};
|
||||
|
||||
#ifdef USE_IR_SEND
|
||||
//Base class for sending signals
|
||||
class IRsendBase
|
||||
{
|
||||
public:
|
||||
IRsendBase() ;
|
||||
void sendGeneric(unsigned long data, int Num_Bits, int Head_Mark, int Head_Space, int Mark_One, int Mark_Zero, int Space_One, int Space_Zero, int mHz, bool Stop_Bits);
|
||||
protected:
|
||||
void enableIROut(int khz);
|
||||
VIRTUAL void mark(int usec);
|
||||
VIRTUAL void space(int usec);
|
||||
};
|
||||
|
||||
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[], int len, int hz);
|
||||
};
|
||||
|
||||
class IRsendRC5: public virtual IRsendBase
|
||||
{
|
||||
public:
|
||||
void send(unsigned long data);
|
||||
};
|
||||
|
||||
class IRsendRC6: public virtual IRsendBase
|
||||
{
|
||||
public:
|
||||
void send(unsigned long data, int 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:
|
||||
void send(IRTYPES Type, unsigned long data, int nbits);
|
||||
};
|
||||
#endif
|
||||
|
||||
// main class for receiving IR
|
||||
class IRrecv
|
||||
{
|
||||
public:
|
||||
IRrecv(int recvpin);
|
||||
void No_Output(void);
|
||||
void blink13(int blinkflag);
|
||||
bool GetResults(IRdecodeBase *decoder);
|
||||
void enableIRIn();
|
||||
void resume();
|
||||
};
|
||||
|
||||
// Some useful constants
|
||||
// Decoded value for NEC when a repeat code is received
|
||||
#define REPEAT 0xffffffff
|
||||
|
||||
|
||||
#endif //IRLib_h
|
83
hardware/digistump/avr/libraries/DigisparkIRLib/IRLibMatch.h
Normal file
83
hardware/digistump/avr/libraries/DigisparkIRLib/IRLibMatch.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/* IRLibMatch.h from IRLib <20> an Arduino library for infrared encoding and decoding
|
||||
* Version 1.0 January 2013
|
||||
* Copyright 2013 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/
|
||||
*/
|
||||
|
||||
#ifndef IRLibMatch_h
|
||||
#define IRLibMatch_h
|
||||
|
||||
/*
|
||||
* This is some miscellaneous definition that is 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.
|
||||
*/
|
||||
|
||||
// Marks tend to be 100us too long, and spaces 100us too short
|
||||
// when received due to sensor lag.
|
||||
#define MARK_EXCESS 100
|
||||
#define USECPERTICK 50 // microseconds per clock interrupt tick
|
||||
#if 0
|
||||
#define TOLERANCE 25 // percent tolerance in measurements
|
||||
#define TICKS_LOW(us) (int) (((us)*(1.0 - TOLERANCE/100.)/USECPERTICK))
|
||||
#define TICKS_HIGH(us) (int) (((us)*(1.0 + TOLERANCE/100.)/USECPERTICK + 1))
|
||||
#else
|
||||
#define TICKS_LOW(us) (((us) - (us>>2))/USECPERTICK)
|
||||
#define TICKS_HIGH(us) (((us) + (us>>2))/USECPERTICK)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
int MATCH(int measured, int desired);
|
||||
int MATCH_MARK(int measured_ticks, int desired_us);
|
||||
int MATCH_SPACE(int measured_ticks, int desired_us);
|
||||
#else
|
||||
#define MATCH(measured_ticks, desired_us) ((measured_ticks) >= TICKS_LOW(desired_us) && (measured_ticks) <= TICKS_HIGH(desired_us))
|
||||
#define MATCH_MARK(measured_ticks, desired_us) MATCH(measured_ticks, (desired_us) + MARK_EXCESS)
|
||||
#define MATCH_SPACE(measured_ticks, desired_us) MATCH((measured_ticks), (desired_us) - MARK_EXCESS)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef TRACE
|
||||
void ATTEMPT_MESSAGE(const __FlashStringHelper * s);
|
||||
byte REJECTION_MESSAGE(const __FlashStringHelper * s);
|
||||
#define RAW_COUNT_ERROR REJECTION_MESSAGE(F("number of raw samples"));
|
||||
#define HEADER_MARK_ERROR REJECTION_MESSAGE(F("header mark"));
|
||||
#define HEADER_SPACE_ERROR REJECTION_MESSAGE(F("header space"));
|
||||
#define DATA_MARK_ERROR REJECTION_MESSAGE(F("data mark"));
|
||||
#define DATA_SPACE_ERROR REJECTION_MESSAGE(F("data space"));
|
||||
#define TRAILER_BIT_ERROR REJECTION_MESSAGE(F("RC5/RC6 trailer bit length"));
|
||||
#else
|
||||
#define ATTEMPT_MESSAGE(s)
|
||||
#define REJECTION_MESSAGE(s) false
|
||||
#define RAW_COUNT_ERROR false
|
||||
#define HEADER_MARK_ERROR false
|
||||
#define HEADER_SPACE_ERROR false
|
||||
#define DATA_MARK_ERROR false
|
||||
#define DATA_SPACE_ERROR false
|
||||
#define TRAILER_BIT_ERROR false
|
||||
#endif
|
||||
|
||||
#endif //IRLibMatch_h
|
380
hardware/digistump/avr/libraries/DigisparkIRLib/IRLibTimer.h
Normal file
380
hardware/digistump/avr/libraries/DigisparkIRLib/IRLibTimer.h
Normal file
@@ -0,0 +1,380 @@
|
||||
/* IRLibTimer.h from IRLib <20> an Arduino library for infrared encoding and decoding
|
||||
* Version 1.0 January 2013
|
||||
* Copyright 2013 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/
|
||||
*/
|
||||
/* This file defines which timer you wish to use. Different versions of Arduino and related boards
|
||||
* have different timers available to them. For various reasons you might want to use something other than
|
||||
* timer 2. Some boards do not have timer 2. This attempts to detect which type of board you are using.
|
||||
* You need uncomment wish to use on your board. You probably will not need to include this in your
|
||||
* program unless you want to see which timer is being used and which board has been detected.
|
||||
* This information came from an alternative fork of the original Ken Shirriff library found here
|
||||
* https://github.com/TKJElectronics/Arduino-IRremote
|
||||
*/
|
||||
#ifndef IRLibTimer_h
|
||||
#define IRLibTimer_h
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
#ifdef F_CPU
|
||||
#define SYSCLOCK F_CPU // main Arduino clock
|
||||
#else
|
||||
#define SYSCLOCK 16000000 // main Arduino clock
|
||||
#endif
|
||||
|
||||
// Arduino Mega
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
//#define IR_USE_TIMER1 // tx = pin 11
|
||||
#define IR_USE_TIMER2 // tx = pin 9
|
||||
//#define IR_USE_TIMER3 // tx = pin 5
|
||||
//#define IR_USE_TIMER4 // tx = pin 6
|
||||
//#define IR_USE_TIMER5 // tx = pin 46
|
||||
|
||||
// Teensy 1.0
|
||||
#elif defined(__AVR_AT90USB162__)
|
||||
#define IR_USE_TIMER1 // tx = pin 17
|
||||
|
||||
// Teensy 2.0 versus Leonardo
|
||||
// These boards use the same chip but the pinouts are different.
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#ifdef CORE_TEENSY
|
||||
// it's Teensy 2.0
|
||||
//#define IR_USE_TIMER1 // tx = pin 14
|
||||
//#define IR_USE_TIMER3 // tx = pin 9
|
||||
#define IR_USE_TIMER4_HS // tx = pin 10
|
||||
#else
|
||||
// it's probably Leonardo
|
||||
#define IR_USE_TIMER1 // tx = pin 9
|
||||
//#define IR_USE_TIMER3 // tx = pin 5
|
||||
//#define IR_USE_TIMER4_HS // tx = pin 13
|
||||
#endif
|
||||
|
||||
// Teensy++ 1.0 & 2.0
|
||||
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
|
||||
//#define IR_USE_TIMER1 // tx = pin 25
|
||||
#define IR_USE_TIMER2 // tx = pin 1
|
||||
//#define IR_USE_TIMER3 // tx = pin 16
|
||||
|
||||
// Sanguino
|
||||
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||
//#define IR_USE_TIMER1 // tx = pin 13
|
||||
#define IR_USE_TIMER2 // tx = pin 14
|
||||
|
||||
// Tested with ATtiny85, presumably works with ATtiny45, possibly with ATtiny25
|
||||
// The attiny core uses Timer 0 for millis() etc., so using timer 1 is advisable
|
||||
// for IR out. Pin 4 also conveniently is not used in any role for ISP.
|
||||
// The Arduino-tiny core uses Timer 1 for millis(), so using timer 0 is advisable
|
||||
// for IR out. Pin 0 is used by default for IR out in the Tinyspark IR shield, but
|
||||
// is not usable for PWM waveforms where the frequency, not just the duty cycle,
|
||||
// needs to be controlled.
|
||||
#elif defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
|
||||
// #define IR_USE_TIMER1_TINY // tx = pin 4 (OC1B)
|
||||
#define IR_USE_TIMER0 // tx = pin 1 (OC0B)
|
||||
// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, etc
|
||||
#else
|
||||
//#define IR_USE_TIMER1 // tx = pin 9
|
||||
#define IR_USE_TIMER2 // tx = pin 3
|
||||
#endif
|
||||
|
||||
|
||||
// defines for timer0 (8 bits). Tested on ATtiny85, may also work on other
|
||||
// processors, but most of them use Timer 0 to keep system time
|
||||
#if defined(IR_USE_TIMER0)
|
||||
#define TIMER_RESET
|
||||
#define TIMER_ENABLE_PWM (TCCR0A |= _BV(COM0B1))
|
||||
#define TIMER_DISABLE_PWM (TCCR0A &= ~(_BV(COM0B1)))
|
||||
#define TIMER_ENABLE_INTR (TIMSK = _BV(OCIE0A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK = 0)
|
||||
#define TIMER_INTR_NAME TIMER0_COMPA_vect
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
const uint8_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||
TCCR0A = _BV(WGM00); \
|
||||
TCCR0B = _BV(WGM02) | _BV(CS00); \
|
||||
OCR0A = pwmval; \
|
||||
OCR0B = pwmval / 3; \
|
||||
})
|
||||
#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000)
|
||||
#if (TIMER_COUNT_TOP < 256)
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR0A = _BV(WGM01); \
|
||||
TCCR0B = _BV(CS00); \
|
||||
OCR0A = TIMER_COUNT_TOP; \
|
||||
TCNT0 = 0; \
|
||||
})
|
||||
#else
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR0A = _BV(WGM01); \
|
||||
TCCR0B = _BV(CS01); \
|
||||
OCR0A = TIMER_COUNT_TOP / 8; \
|
||||
TCNT0 = 0; \
|
||||
})
|
||||
#endif
|
||||
#if defined(CORE_OC0A_PIN)
|
||||
#define TIMER_PWM_PIN CORE_OC0B_PIN
|
||||
#else
|
||||
#define TIMER_PWM_PIN 1 /* Attiny core */
|
||||
#endif
|
||||
|
||||
// defines for timer2 (8 bits)
|
||||
#elif defined(IR_USE_TIMER2)
|
||||
#define TIMER_RESET
|
||||
#define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1))
|
||||
#define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1)))
|
||||
#define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK2 = 0)
|
||||
#define TIMER_INTR_NAME TIMER2_COMPA_vect
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
const uint8_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||
TCCR2A = _BV(WGM20); \
|
||||
TCCR2B = _BV(WGM22) | _BV(CS20); \
|
||||
OCR2A = pwmval; \
|
||||
OCR2B = pwmval / 3; \
|
||||
})
|
||||
#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000)
|
||||
#if (TIMER_COUNT_TOP < 256)
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR2A = _BV(WGM21); \
|
||||
TCCR2B = _BV(CS20); \
|
||||
OCR2A = TIMER_COUNT_TOP; \
|
||||
TCNT2 = 0; \
|
||||
})
|
||||
#else
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR2A = _BV(WGM21); \
|
||||
TCCR2B = _BV(CS21); \
|
||||
OCR2A = TIMER_COUNT_TOP / 8; \
|
||||
TCNT2 = 0; \
|
||||
})
|
||||
#endif
|
||||
#if defined(CORE_OC2B_PIN)
|
||||
#define TIMER_PWM_PIN CORE_OC2B_PIN /* Teensy */
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define TIMER_PWM_PIN 9 /* Arduino Mega */
|
||||
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||
#define TIMER_PWM_PIN 14 /* Sanguino */
|
||||
#else
|
||||
#define TIMER_PWM_PIN 3 /* Arduino Duemilanove, Diecimila, LilyPad, etc */
|
||||
#endif
|
||||
|
||||
|
||||
// defines for timer1 (16 bits)
|
||||
#elif defined(IR_USE_TIMER1)
|
||||
#define TIMER_RESET
|
||||
#define TIMER_ENABLE_PWM (TCCR1A |= _BV(COM1A1))
|
||||
#define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1)))
|
||||
#define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK1 = 0)
|
||||
#define TIMER_INTR_NAME TIMER1_COMPA_vect
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||
TCCR1A = _BV(WGM11); \
|
||||
TCCR1B = _BV(WGM13) | _BV(CS10); \
|
||||
ICR1 = pwmval; \
|
||||
OCR1A = pwmval / 3; \
|
||||
})
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR1A = 0; \
|
||||
TCCR1B = _BV(WGM12) | _BV(CS10); \
|
||||
OCR1A = SYSCLOCK * USECPERTICK / 1000000; \
|
||||
TCNT1 = 0; \
|
||||
})
|
||||
#if defined(CORE_OC1A_PIN)
|
||||
#define TIMER_PWM_PIN CORE_OC1A_PIN /* Teensy */
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define TIMER_PWM_PIN 11 /* Arduino Mega */
|
||||
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||
#define TIMER_PWM_PIN 13 /* Sanguino */
|
||||
#else
|
||||
#define TIMER_PWM_PIN 9 /* Arduino Duemilanove, Diecimila, LilyPad, etc */
|
||||
#endif
|
||||
|
||||
|
||||
// defines for timer3 (16 bits)
|
||||
#elif defined(IR_USE_TIMER3)
|
||||
#define TIMER_RESET
|
||||
#define TIMER_ENABLE_PWM (TCCR3A |= _BV(COM3A1))
|
||||
#define TIMER_DISABLE_PWM (TCCR3A &= ~(_BV(COM3A1)))
|
||||
#define TIMER_ENABLE_INTR (TIMSK3 = _BV(OCIE3A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK3 = 0)
|
||||
#define TIMER_INTR_NAME TIMER3_COMPA_vect
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||
TCCR3A = _BV(WGM31); \
|
||||
TCCR3B = _BV(WGM33) | _BV(CS30); \
|
||||
ICR3 = pwmval; \
|
||||
OCR3A = pwmval / 3; \
|
||||
})
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR3A = 0; \
|
||||
TCCR3B = _BV(WGM32) | _BV(CS30); \
|
||||
OCR3A = SYSCLOCK * USECPERTICK / 1000000; \
|
||||
TCNT3 = 0; \
|
||||
})
|
||||
#if defined(CORE_OC3A_PIN)
|
||||
#define TIMER_PWM_PIN CORE_OC3A_PIN /* Teensy */
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define TIMER_PWM_PIN 5 /* Arduino Mega */
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#define TIMER_PWM_PIN 5 /* Arduino Leonardo note already checked for Teensy */
|
||||
#else
|
||||
#error "Please add OC3A pin number here\n"
|
||||
#endif
|
||||
|
||||
|
||||
// defines for timer4 (10 bits, high speed option)
|
||||
#elif defined(IR_USE_TIMER4_HS)
|
||||
#define TIMER_RESET
|
||||
#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1))
|
||||
#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1)))
|
||||
#define TIMER_ENABLE_INTR (TIMSK4 = _BV(TOIE4))
|
||||
#define TIMER_DISABLE_INTR (TIMSK4 = 0)
|
||||
#define TIMER_INTR_NAME TIMER4_OVF_vect
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||
TCCR4A = (1<<PWM4A); \
|
||||
TCCR4B = _BV(CS40); \
|
||||
TCCR4C = 0; \
|
||||
TCCR4D = (1<<WGM40); \
|
||||
TCCR4E = 0; \
|
||||
TC4H = pwmval >> 8; \
|
||||
OCR4C = pwmval; \
|
||||
TC4H = (pwmval / 3) >> 8; \
|
||||
OCR4A = (pwmval / 3) & 255; \
|
||||
})
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR4A = 0; \
|
||||
TCCR4B = _BV(CS40); \
|
||||
TCCR4C = 0; \
|
||||
TCCR4D = 0; \
|
||||
TCCR4E = 0; \
|
||||
TC4H = (SYSCLOCK * USECPERTICK / 1000000) >> 8; \
|
||||
OCR4C = (SYSCLOCK * USECPERTICK / 1000000) & 255; \
|
||||
TC4H = 0; \
|
||||
TCNT4 = 0; \
|
||||
})
|
||||
#if defined(CORE_OC4A_PIN)
|
||||
#define TIMER_PWM_PIN CORE_OC4A_PIN /* Teensy */
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#define TIMER_PWM_PIN 13 /*Leonardo*/
|
||||
#else
|
||||
#error "Please add OC4A pin number here\n"
|
||||
#endif
|
||||
|
||||
|
||||
// defines for timer4 (16 bits)
|
||||
#elif defined(IR_USE_TIMER4)
|
||||
#define TIMER_RESET
|
||||
#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1))
|
||||
#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1)))
|
||||
#define TIMER_ENABLE_INTR (TIMSK4 = _BV(OCIE4A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK4 = 0)
|
||||
#define TIMER_INTR_NAME TIMER4_COMPA_vect
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||
TCCR4A = _BV(WGM41); \
|
||||
TCCR4B = _BV(WGM43) | _BV(CS40); \
|
||||
ICR4 = pwmval; \
|
||||
OCR4A = pwmval / 3; \
|
||||
})
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR4A = 0; \
|
||||
TCCR4B = _BV(WGM42) | _BV(CS40); \
|
||||
OCR4A = SYSCLOCK * USECPERTICK / 1000000; \
|
||||
TCNT4 = 0; \
|
||||
})
|
||||
#if defined(CORE_OC4A_PIN)
|
||||
#define TIMER_PWM_PIN CORE_OC4A_PIN
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define TIMER_PWM_PIN 6 /* Arduino Mega */
|
||||
#else
|
||||
#error "Please add OC4A pin number here\n"
|
||||
#endif
|
||||
|
||||
|
||||
// defines for timer5 (16 bits)
|
||||
#elif defined(IR_USE_TIMER5)
|
||||
#define TIMER_RESET
|
||||
#define TIMER_ENABLE_PWM (TCCR5A |= _BV(COM5A1))
|
||||
#define TIMER_DISABLE_PWM (TCCR5A &= ~(_BV(COM5A1)))
|
||||
#define TIMER_ENABLE_INTR (TIMSK5 = _BV(OCIE5A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK5 = 0)
|
||||
#define TIMER_INTR_NAME TIMER5_COMPA_vect
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||
TCCR5A = _BV(WGM51); \
|
||||
TCCR5B = _BV(WGM53) | _BV(CS50); \
|
||||
ICR5 = pwmval; \
|
||||
OCR5A = pwmval / 3; \
|
||||
})
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR5A = 0; \
|
||||
TCCR5B = _BV(WGM52) | _BV(CS50); \
|
||||
OCR5A = SYSCLOCK * USECPERTICK / 1000000; \
|
||||
TCNT5 = 0; \
|
||||
})
|
||||
#if defined(CORE_OC5A_PIN)
|
||||
#define TIMER_PWM_PIN CORE_OC5A_PIN
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define TIMER_PWM_PIN 46 /* Arduino Mega */
|
||||
#else
|
||||
#error "Please add OC5A pin number here\n"
|
||||
#endif
|
||||
|
||||
|
||||
#else // unknown timer
|
||||
#error "Internal code configuration error, no known IR_USE_TIMER# defined\n"
|
||||
#endif
|
||||
|
||||
|
||||
// defines for blinking the LED
|
||||
#if defined(CORE_LED0_PIN)
|
||||
#define BLINKLED CORE_LED0_PIN
|
||||
#define BLINKLED_ON() (digitalWrite(CORE_LED0_PIN, HIGH))
|
||||
#define BLINKLED_OFF() (digitalWrite(CORE_LED0_PIN, LOW))
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define BLINKLED 13
|
||||
#define BLINKLED_ON() (PORTB |= B10000000)
|
||||
#define BLINKLED_OFF() (PORTB &= B01111111)
|
||||
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||
#define BLINKLED 0
|
||||
#define BLINKLED_ON() (PORTD |= B00000001)
|
||||
#define BLINKLED_OFF() (PORTD &= B11111110)
|
||||
#elif defined(__AVR_ATmega32U4__) && defined(IR_USE_TIMER4_HS)
|
||||
//Leonardo not teensy. When using Timer4 output is on 13. Therefore disabling blink LED
|
||||
//You can add an LED elsewhere if you want
|
||||
#define BLINKLED 1
|
||||
#define BLINKLED_ON() (digitalWrite(BLINKLED, HIGH))
|
||||
#define BLINKLED_OFF() (digitalWrite(BLINKLED, LOW))
|
||||
#else
|
||||
#define BLINKLED 13
|
||||
#define BLINKLED_ON() (PORTB |= B00100000)
|
||||
#define BLINKLED_OFF() (PORTB &= B11011111)
|
||||
#endif
|
||||
|
||||
#endif //IRLibTimer_h
|
BIN
hardware/digistump/avr/libraries/DigisparkIRLib/LICENSE.txt
Normal file
BIN
hardware/digistump/avr/libraries/DigisparkIRLib/LICENSE.txt
Normal file
Binary file not shown.
70
hardware/digistump/avr/libraries/DigisparkIRLib/README.txt
Normal file
70
hardware/digistump/avr/libraries/DigisparkIRLib/README.txt
Normal file
@@ -0,0 +1,70 @@
|
||||
IRLib <20> an Arduino library for infrared encoding and decoding
|
||||
Version 1.1 april 2013
|
||||
Copyright 2013 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
|
||||
|
||||
Note: there is no "IRremoteInt.h" header as in the original library. Those values were
|
||||
moved elsewhere.
|
||||
|
||||
The examples directory contains:
|
||||
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.
|
||||
Samsung36 Demonstrates how to expand the library without recompiling it.
|
||||
Also demonstrates how to handle codes that are longer than 32 bits.
|
||||
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.
|
||||
Note: I did not port any of the other demo sketches although I may add IRTest later.
|
||||
****************************************************
|
||||
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.
|
@@ -0,0 +1,84 @@
|
||||
#include <IRLib.h> // In {path_of_installation}/Digispark-Arduino-1.0.x/libraries/DigisparkIRLib/IRLib.h, set MY_PROTOCOL to NEC, SONY, RC5 to find the one used by your own IR Remote Control
|
||||
#include <DigiUSB.h> // In {path_of_installation}/Digispark-Arduino-1.0.x/libraries/DigisparkUSB/DigiUSB.h, RING_BUFFER_SIZE shall be set to 32
|
||||
/*
|
||||
_____ ____ __ _ ____ _ _ _ _
|
||||
| __ \ / __ \ | \ | | / __ \ | | | | | | | |
|
||||
| |__| | | / \_| | . \ | | / / \ \ | | | | \ \ / /
|
||||
| _ / | | _ | |\ \| | | |__| | | | | | \ ' /
|
||||
| | \ \ | \__/ | | | \ ' | | __ | \ \/ / | |
|
||||
|_| \_\ \____/ |_| \__| |_| |_| \__/ |_| 2013
|
||||
|
||||
http://p.loussouarn.free.fr
|
||||
|
||||
*************************************************
|
||||
* Optimized <IRLib> library Dump Demo *
|
||||
*************************************************
|
||||
|
||||
This sketch allows you to discover the protocol used by your own IR Remote Control and the code of each key when pressed.
|
||||
You will see the decoded key codes in the DigiUSB console.
|
||||
|
||||
IMPORTANT:
|
||||
=========
|
||||
- In {path_of_installation}/Digispark-Arduino-1.0.x/libraries/DigisparkIRLib/IRLib.h, set MY_PROTOCOL to NEC, SONY, RC5 to find the protocol used by your own IR Remote Control
|
||||
- In {path_of_installation}/Digispark-Arduino-1.0.x/libraries/DigisparkUSB/DigiUSB.h, RING_BUFFER_SIZE shall be set to 32
|
||||
|
||||
Sensor wiring: (Warning: the wiring may vary depending of the model of IR sensor)
|
||||
=============
|
||||
.-------.
|
||||
| ___ |
|
||||
| / \ | InfraRed
|
||||
| \___/ | Sensor
|
||||
| |
|
||||
'+--+--+'
|
||||
| | | 100
|
||||
P5 <----' | '--+---###--- +5V
|
||||
| |
|
||||
| '==='4.7uF
|
||||
| |
|
||||
'--+--'
|
||||
|
|
||||
GND
|
||||
|
||||
*/
|
||||
|
||||
#define LED_PIN 1
|
||||
#define IR_RX_PIN 5
|
||||
|
||||
#define BUTTON_OFF 0xF740BF //Set here the OFF code for the built-in LED when determined
|
||||
#define BUTTON_ON 0xF7C03F //Set here the ON code for the built-in LED when determined
|
||||
|
||||
IRrecv My_Receiver(IR_RX_PIN);//Receive on pin IR_RX_PIN
|
||||
IRdecode My_Decoder;
|
||||
|
||||
void setup()
|
||||
{
|
||||
My_Receiver.enableIRIn(); // Start the receiver
|
||||
pinMode(LED_PIN, OUTPUT);
|
||||
DigiUSB.begin();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if(My_Receiver.GetResults(&My_Decoder))
|
||||
{
|
||||
My_Decoder.decode();
|
||||
switch(My_Decoder.value)
|
||||
{
|
||||
case BUTTON_OFF:
|
||||
digitalWrite(LED_PIN, LOW);
|
||||
break;
|
||||
case BUTTON_ON:
|
||||
digitalWrite(LED_PIN, HIGH);
|
||||
break;
|
||||
default:break;
|
||||
}
|
||||
My_Receiver.resume();
|
||||
DigiUSB.println(My_Decoder.value, HEX);
|
||||
}
|
||||
if(DigiUSB.available())
|
||||
{
|
||||
DigiUSB.read();
|
||||
}
|
||||
DigiUSB.refresh();
|
||||
}
|
||||
|
@@ -0,0 +1,201 @@
|
||||
#include <TinySoftPwm.h>
|
||||
#include <IRLib.h>
|
||||
/*
|
||||
_____ ____ __ _ ____ _ _ _ _
|
||||
| __ \ / __ \ | \ | | / __ \ | | | | | | | |
|
||||
| |__| | | / \_| | . \ | | / / \ \ | | | | \ \ / /
|
||||
| _ / | | _ | |\ \| | | |__| | | | | | \ ' /
|
||||
| | \ \ | \__/ | | | \ ' | | __ | \ \/ / | |
|
||||
|_| \_\ \____/ |_| \__| |_| |_| \__/ |_| 2013
|
||||
|
||||
http://p.loussouarn.free.fr
|
||||
|
||||
*************************************************
|
||||
* Optimized <IRLib> library Controller Demo *
|
||||
*************************************************
|
||||
|
||||
This sketch allows you to use the Digispark as an IR RGB Controller.
|
||||
This sketch is designed to used low cost 24 keys IR Remote Control for RGB strip LED,
|
||||
but you can adapt it to your own IR Remote Control.
|
||||
|
||||
Sensor wiring: (Warning: the wiring may vary depending of the model of IR sensor)
|
||||
=============
|
||||
.-------.
|
||||
| ___ |
|
||||
| / \ | InfraRed
|
||||
| \___/ | Sensor
|
||||
| |
|
||||
'+--+--+'
|
||||
| | | 100
|
||||
P5 <----' | '--+---###--- +5V
|
||||
| |
|
||||
| '==='4.7uF
|
||||
| |
|
||||
'--+--'
|
||||
|
|
||||
GND
|
||||
|
||||
/* P0, P1 and P2 shall be declared in Digispark-Arduino-1.0.x/libraries/TinySoftPwm.h */
|
||||
#define LED_GREEN_PIN 0
|
||||
#define LED_RED_PIN 1
|
||||
#define LED_BLUE_PIN 2
|
||||
|
||||
#define IR_RX_PIN 5
|
||||
|
||||
#define CODE_OFF 0xF740BF
|
||||
#define CODE_ON 0xF7C03F
|
||||
#define CODE_BRIGHT_MINUS 0xF7807F
|
||||
#define CODE_BRIGHT_PLUS 0xF700FF
|
||||
|
||||
#define CODE_FLASH 0xF7D02F
|
||||
#define CODE_STROBE 0xF7F00F
|
||||
#define CODE_FADE 0xF7C837
|
||||
#define CODE_SMOOTH 0xF7E817
|
||||
|
||||
#define CODE_RED 0xF720DF
|
||||
#define CODE_GREEN 0xF7A05F
|
||||
#define CODE_BLUE 0xF7609F
|
||||
#define CODE_WHITE 0xF7E01F
|
||||
|
||||
#define CODE_ORANGE 0xF710EF
|
||||
#define CODE_ORANGE_LIGTH 0xF730CF
|
||||
#define CODE_BROWN 0xF708F7
|
||||
#define CODE_YELLOW 0xF728D7
|
||||
|
||||
#define CODE_GREEN_LIGTH 0xF7906F
|
||||
#define CODE_GREEN_BLUE1 0xF7B04F
|
||||
#define CODE_GREEN_BLUE2 0xF78877
|
||||
#define CODE_GREEN_BLUE3 0xF7A857
|
||||
|
||||
#define CODE_BLUE_LIGTH 0xF750AF
|
||||
#define CODE_PURPLE_DARK 0xF7708F
|
||||
#define CODE_PURPLE_LIGTH 0xF748B7
|
||||
#define CODE_PINK 0xF76897
|
||||
|
||||
#define BRIGTH_STEP 10
|
||||
#define CODE_REPEAT 0xFFFFFFFF
|
||||
|
||||
IRrecv My_Receiver(IR_RX_PIN);//Receive on pin IR_RX_PIN
|
||||
IRdecode My_Decoder;
|
||||
|
||||
uint8_t PwmRed=0, PwmGreen=0, PwmBlue=0;
|
||||
|
||||
void setup()
|
||||
{
|
||||
My_Receiver.enableIRIn(); // Start the receiver
|
||||
pinMode(LED_RED_PIN, OUTPUT);
|
||||
TinySoftPwm_begin(255,0);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
static uint32_t StartUs=micros(), LastIrCode=0;
|
||||
|
||||
if(My_Receiver.GetResults(&My_Decoder))
|
||||
{
|
||||
My_Decoder.decode();
|
||||
if(My_Decoder.value==REPEAT && LastIrCode)
|
||||
{
|
||||
My_Decoder.value=LastIrCode;
|
||||
}
|
||||
switch(My_Decoder.value)
|
||||
{
|
||||
case CODE_BRIGHT_MINUS:
|
||||
Tune(&PwmRed, -BRIGTH_STEP);
|
||||
Tune(&PwmGreen, -BRIGTH_STEP);
|
||||
Tune(&PwmBlue, -BRIGTH_STEP);
|
||||
LastIrCode=CODE_BRIGHT_MINUS;
|
||||
break;
|
||||
case CODE_BRIGHT_PLUS:
|
||||
if(PwmRed) Tune(&PwmRed, BRIGTH_STEP);
|
||||
if(PwmGreen) Tune(&PwmGreen, BRIGTH_STEP);
|
||||
if(PwmBlue) Tune(&PwmBlue, BRIGTH_STEP);
|
||||
LastIrCode=CODE_BRIGHT_PLUS;
|
||||
break;
|
||||
default:
|
||||
LastIrCode=0; /* No repeat for the following codes */
|
||||
switch(My_Decoder.value)
|
||||
{
|
||||
case CODE_OFF:
|
||||
RGB(0x00, 0x00, 0x00);
|
||||
break;
|
||||
case CODE_ON:
|
||||
RGB(0x7A, 0x00, 0xBF);
|
||||
break;
|
||||
case CODE_RED: RGB(0xFF, 0x00, 0x00);break;
|
||||
case CODE_GREEN: RGB(0x00, 0xFF, 0x00);break;
|
||||
case CODE_BLUE: RGB(0x00, 0x00, 0xFF);break;
|
||||
case CODE_WHITE: RGB(0xFF, 0xFF, 0xFF);break;
|
||||
|
||||
case CODE_ORANGE: RGB(0xFF, 0x7F, 0x00); break;
|
||||
case CODE_ORANGE_LIGTH: RGB(0xFF, 0xAA, 0x00); break;
|
||||
case CODE_BROWN: RGB(0xFF, 0xD4, 0x00); break;
|
||||
case CODE_YELLOW: RGB(0xFF, 0xFF, 0x00); break;
|
||||
|
||||
case CODE_GREEN_LIGTH: RGB(0x00, 0xFF, 0xAA); break;
|
||||
case CODE_GREEN_BLUE1: RGB(0x00, 0xFF, 0xFF); break;
|
||||
case CODE_GREEN_BLUE2: RGB(0x00, 0xAA, 0xFF); break;
|
||||
case CODE_GREEN_BLUE3: RGB(0x00, 0x55, 0xFF); break;
|
||||
|
||||
case CODE_BLUE_LIGTH: RGB(0x00, 0x00, 0x80); break;
|
||||
case CODE_PURPLE_DARK: RGB(0x3F, 0x00, 0x80); break;
|
||||
case CODE_PURPLE_LIGTH: RGB(0x7A, 0x00, 0xBF); break;
|
||||
case CODE_PINK: RGB(0xFF, 0x00, 0xFF); break;
|
||||
|
||||
case CODE_FLASH: /* to be implemented */break;
|
||||
case CODE_STROBE: /* to be implemented */break;
|
||||
case CODE_FADE: /* to be implemented */break;
|
||||
case CODE_SMOOTH: /* to be implemented */break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
My_Receiver.resume();
|
||||
TinySoftPwm_analogWrite(LED_RED_PIN, GammaCorrection(PwmRed));
|
||||
TinySoftPwm_analogWrite(LED_GREEN_PIN, GammaCorrection(PwmGreen));
|
||||
TinySoftPwm_analogWrite(LED_BLUE_PIN, GammaCorrection(PwmBlue));
|
||||
}
|
||||
/***********************************************************/
|
||||
/* Call TinySoftPwm_process() with a period of 60 us */
|
||||
/* The PWM frequency = 255 x 60 # 15 ms -> F # 65Hz */
|
||||
/* 255 is the first argument passed to TinySoftPwm_begin() */
|
||||
/***********************************************************/
|
||||
if((micros() - StartUs) >= 60)
|
||||
{
|
||||
/* We arrived here every 60 microseconds */
|
||||
StartUs=micros();
|
||||
TinySoftPwm_process(); /* This function shall be called periodically (like here, based on micros(), or in a timer ISR) */
|
||||
}
|
||||
}
|
||||
|
||||
void RGB(uint8_t Red, uint8_t Green, uint8_t Blue)
|
||||
{
|
||||
PwmRed=Red;
|
||||
PwmGreen=Green;
|
||||
PwmBlue=Blue;
|
||||
}
|
||||
|
||||
uint8_t GammaCorrection(uint8_t Pwm)
|
||||
{
|
||||
return((Pwm*Pwm)>>8);
|
||||
}
|
||||
|
||||
void Tune(uint8_t* Color, int8_t Offset)
|
||||
{
|
||||
if (Offset > 0) {
|
||||
if ( *Color + Offset <= 255) {
|
||||
*Color += Offset;
|
||||
} else {
|
||||
*Color = 255;
|
||||
}
|
||||
} else {
|
||||
if (*Color + Offset >= 0) {
|
||||
*Color += Offset;
|
||||
} else {
|
||||
// *Color = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,48 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.0 January 2013
|
||||
* Copyright 2013 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.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);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (My_Receiver.GetResults(&My_Decoder)) {//Puts results in My_Decoder
|
||||
//Restart the receiver so it can be capturing another code
|
||||
//while we are working on decoding this one.
|
||||
My_Receiver.resume();
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,130 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.0 January 2013
|
||||
* Copyright 2013 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.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 output PWM pin 3.
|
||||
* Unlike the original version of this demo sketch, you need not hook up a pushbutton
|
||||
* Simply send any character from the serial screen to send the recorded code.
|
||||
* 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 A 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);
|
||||
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)
|
||||
// Convert from ticks to microseconds
|
||||
// Tweak marks shorter, and spaces longer to cancel out IR receiver distortion
|
||||
rawCount = My_Decoder.rawlen-1;
|
||||
for (int i = 1; i <=rawCount; i++) {
|
||||
rawCodes[i - 1] = My_Decoder.Interval_uSec(i);//Converts to microseconds and adjusts for Mark/space
|
||||
};
|
||||
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("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("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)) {
|
||||
//Restart the receiver so it can be capturing another code
|
||||
//while we are working on decoding this one.
|
||||
if(My_Decoder.decode()) {
|
||||
GotOne=true;
|
||||
storeCode();
|
||||
}
|
||||
delay(500);
|
||||
My_Receiver.resume();
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,39 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.0 January 2013
|
||||
* Copyright 2013 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.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);
|
||||
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.0 January 2013
|
||||
* Copyright 2013 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.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.0 January 2013
|
||||
* Copyright 2013 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.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 to tell it whether or not to send the header.
|
||||
* 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,50 @@
|
||||
#include <IRLib.h>
|
||||
|
||||
IRsend My_Sender;
|
||||
|
||||
int protocol;
|
||||
long code;
|
||||
int bits;
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
// enum IRTYPES {UNKNOWN, NEC, SONY, RC5, RC6, PANASONIC_OLD, JVC, NECX, HASH_CODE, LAST_PROTOCOL=HASH_CODE};
|
||||
|
||||
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,68 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.1 April 2013 by Chris Young http://cyborg5.com
|
||||
* "IRservo" Control a servo using an IR remote
|
||||
*/
|
||||
#include <IRLib.h>
|
||||
#include <Servo.h>
|
||||
// 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,120 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.0 January 2013
|
||||
* Copyright 2013 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.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.
|
||||
*/
|
||||
#include <IRLib.h>
|
||||
#include <IRLibMatch.h>
|
||||
|
||||
int RECV_PIN = 11;
|
||||
|
||||
IRrecv My_Receiver(RECV_PIN);
|
||||
#define SAMSUNG36 (LAST_PROTOCOL+1) //Unfortunately cannot extend an enum. This is the best we can do.
|
||||
|
||||
/*Is the value in this if statement is "1" then we will extend the base decoder.
|
||||
*The result is this will only decode Samsung 36 and no others.
|
||||
*If the value is "0" we will extend the all-inclusive decoder.
|
||||
*Try changing this value and note the effect on code size when compiling.
|
||||
*/
|
||||
#if(1)
|
||||
#define MY_BASE IRdecodeBase
|
||||
#else
|
||||
#define MY_BASE IRdecode
|
||||
#endif
|
||||
class IRdecodeSamsung36: public virtual MY_BASE{
|
||||
public:
|
||||
bool decode(void);
|
||||
unsigned int value2;
|
||||
void Reset(void);
|
||||
void DumpResults(void);
|
||||
private:
|
||||
bool GetBit(void);
|
||||
int offset;
|
||||
unsigned long data;
|
||||
};
|
||||
void IRdecodeSamsung36::Reset(void) {
|
||||
MY_BASE::Reset();//respect your parents
|
||||
value2=0;
|
||||
};
|
||||
|
||||
bool IRdecodeSamsung36::GetBit(void) {
|
||||
if (!MATCH_MARK (rawbuf[offset],500)) return DATA_MARK_ERROR;
|
||||
offset++;
|
||||
if (MATCH_SPACE(rawbuf[offset],1500)) {
|
||||
data = (data << 1) | 1;
|
||||
}
|
||||
else if (MATCH_SPACE (rawbuf[offset],500)) {
|
||||
data <<= 1;
|
||||
}
|
||||
else return DATA_SPACE_ERROR;
|
||||
offset++;
|
||||
return true;
|
||||
};
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
bool IRdecodeSamsung36::decode(void) {
|
||||
if(MY_BASE::decode()) return true;
|
||||
ATTEMPT_MESSAGE(F("Samsung36"));
|
||||
if (rawlen != 78) return RAW_COUNT_ERROR;
|
||||
if (!MATCH_MARK(rawbuf[1],4500)) return HEADER_MARK_ERROR;
|
||||
if (!MATCH_SPACE(rawbuf[2],4500)) return HEADER_SPACE_ERROR;
|
||||
offset=3; data=0;
|
||||
//Get first 18 bits
|
||||
while (offset < 16*2+2) if(!GetBit()) return false;
|
||||
//Skip middle header
|
||||
if (!MATCH_MARK(rawbuf[offset],500)) return DATA_MARK_ERROR;
|
||||
offset++;
|
||||
if (!MATCH_SPACE(rawbuf[offset],4500)) return DATA_SPACE_ERROR;
|
||||
//save first 18 bits in "value" and reset data
|
||||
offset++; value=data; data=0;
|
||||
rawbuf[62]=(rawbuf[62]*USECPERTICK-68)/USECPERTICK;
|
||||
while(offset<77)if(!GetBit()) return false;
|
||||
bits =36;//set bit length
|
||||
value2 = data;//put remaining bits in value2
|
||||
decode_type= static_cast<IRTYPES>SAMSUNG36;
|
||||
return true;
|
||||
};
|
||||
void IRdecodeSamsung36::DumpResults(void){
|
||||
if(decode_type==SAMSUNG36) {
|
||||
Serial.print(F("Decoded Samsung36: Value1:")); Serial.print(value, HEX);
|
||||
Serial.print(F(": Value2:")); Serial.print(value2, HEX);
|
||||
};
|
||||
MY_BASE::DumpResults();
|
||||
};
|
||||
IRdecodeSamsung36 My_Decoder;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
My_Receiver.enableIRIn(); // Start the receiver
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (My_Receiver.GetResults(&My_Decoder)) {
|
||||
My_Decoder.decode();
|
||||
My_Decoder.DumpResults();
|
||||
My_Receiver.resume();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user