Update IR lib/sensor to use the latest IR_Remote fork by Chris Young (IRLib)
https://github.com/cyborg5/IRLib
This commit is contained in:
@@ -0,0 +1,201 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.4 March 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009I know prescription and no
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://www.righto.com/
|
||||
*/
|
||||
/*
|
||||
* This example demonstrates how to extend this library to add a new protocol
|
||||
* without actually modifying or recompiling the library itself. It implements the protocol
|
||||
* used by DirecTV. This protocol actually comes in six different varieties.
|
||||
* It uses three different frequencies 38, 40, or 57 kHz. It also uses two different varieties
|
||||
* lead out times either 9000us or 30000us. The default is 38 kHz and 30000us.
|
||||
* You can use a different constructor for the other varieties.
|
||||
* This is a modified version of the IRecord example.
|
||||
* If you would like to make this a permanent part of your library you could copy the class
|
||||
* prototypes to IRLib.h and the code itself to IRLib.cpp. Search for the word "ADDITIONAL"
|
||||
* to see where to add various pieces of code. Also see the Samsung36 example for details.
|
||||
*/
|
||||
#include <IRLib.h>
|
||||
#include <IRLibMatch.h>
|
||||
|
||||
class IRdecodeDirecTV: public virtual IRdecodeBase
|
||||
{
|
||||
public:
|
||||
bool decode(void);
|
||||
bool Repeat;
|
||||
};
|
||||
|
||||
class IRsendDirecTV: public virtual IRsendBase
|
||||
{
|
||||
public:
|
||||
IRsendDirecTV (int khz= 38,bool LongLeadOut=true);
|
||||
void send(unsigned long data, bool Repeat);
|
||||
int Freq;
|
||||
unsigned int LeadOut;
|
||||
};
|
||||
|
||||
#define DIRECTV (LAST_PROTOCOL+1)
|
||||
|
||||
/*
|
||||
* According to http://www.hifi-remote.com/johnsfine/DecodeIR.html#DirecTV
|
||||
* The IRP notation for this protocol is:
|
||||
*{38k,600,msb}<1,-1|1,-2|2,-1|2,-2>(5,(5,-2,D:4,F:8,C:4,1,-50)+) {C=7*(F:2:6)+5*(F:2:4)+3*(F:2:2)+(F:2)}
|
||||
* Unlike most protocols which use a fixed length mark and a variable length or a variable length
|
||||
* mark a fixed length space, this protocol varies both the mark and the space.
|
||||
* The stream is still a series of marks and spaces but the length of either of those
|
||||
* denotes a one or zero. A length of 1200us=logical 1 and length 600us=logical 0
|
||||
* It also makes changes to the length of the header mark to devote repeat codes.
|
||||
* The first header mark should be 6000us but repeat codes should only be 3000us.
|
||||
*/
|
||||
bool IRdecodeDirecTV::decode(void) {
|
||||
long data; int offset;
|
||||
IRLIB_ATTEMPT_MESSAGE(F("DirecTV"));
|
||||
if (rawlen != 20) return RAW_COUNT_ERROR;
|
||||
if (MATCH(rawbuf[1],3000))
|
||||
Repeat=true;
|
||||
else
|
||||
if (!MATCH(rawbuf[1],6000)){
|
||||
return HEADER_MARK_ERROR(6000);
|
||||
} else {
|
||||
Repeat=false;
|
||||
}
|
||||
if (!MATCH(rawbuf[2],1200)) return HEADER_SPACE_ERROR(1200);
|
||||
offset=3; data=0;
|
||||
while (offset < 18) {
|
||||
if (MATCH(rawbuf[offset],1200)) {
|
||||
data = (data << 1) | 1;
|
||||
}
|
||||
else if (MATCH(rawbuf[offset],600)) {
|
||||
data <<= 1;
|
||||
}
|
||||
else return DATA_MARK_ERROR(1200);
|
||||
offset++;
|
||||
if (MATCH(rawbuf[offset],1200)) {
|
||||
data = (data << 1) | 1;
|
||||
}
|
||||
else if (MATCH (rawbuf[offset],600)) {
|
||||
data <<= 1;
|
||||
}
|
||||
else return DATA_SPACE_ERROR(1200);
|
||||
offset++;
|
||||
}
|
||||
if (!MATCH(rawbuf[1],6000)) return DATA_MARK_ERROR(6000);
|
||||
bits = 16;//set bit length
|
||||
value = data;//put remaining bits in value
|
||||
decode_type= static_cast<IRTYPES>DIRECTV;
|
||||
return true;
|
||||
};
|
||||
|
||||
//See the comment at the top about different frequencies and lead out times
|
||||
IRsendDirecTV::IRsendDirecTV (int khz, bool LongLeadOut){
|
||||
Freq=khz;
|
||||
if (LongLeadOut) LeadOut=50*600; else LeadOut=15*600;
|
||||
};
|
||||
|
||||
void IRsendDirecTV::send(unsigned long data, bool Repeat) {
|
||||
enableIROut(Freq);
|
||||
if(Repeat) mark(3000); else mark(6000);
|
||||
space(1200);//Send header
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (data & 0x8000) mark(1200); else mark(600);
|
||||
data <<= 1;
|
||||
if (data & 0x8000) space(1200); else space(600);
|
||||
data <<= 1;
|
||||
};
|
||||
mark(600);
|
||||
space(LeadOut);
|
||||
};
|
||||
|
||||
//Create a custom class that combines this new protocol with all the others
|
||||
class MyCustomSend:
|
||||
public virtual IRsend,
|
||||
public virtual IRsendDirecTV
|
||||
{
|
||||
public:
|
||||
void send(IRTYPES Type, unsigned long data, int nbits);
|
||||
};
|
||||
void MyCustomSend::send(IRTYPES Type, unsigned long data, int nbits) {
|
||||
if (Type==DIRECTV)
|
||||
IRsendDirecTV::send(data,false);
|
||||
else
|
||||
IRsend::send(Type, data, nbits);
|
||||
}
|
||||
class MyCustomDecode:
|
||||
public virtual IRdecode,
|
||||
public virtual IRdecodeDirecTV
|
||||
{
|
||||
public:
|
||||
virtual bool decode(void); // Calls each decode routine individually
|
||||
void DumpResults(void);
|
||||
};
|
||||
bool MyCustomDecode::decode(void) {
|
||||
if (IRdecodeDirecTV::decode()) return true;
|
||||
return IRdecode::decode ();
|
||||
}
|
||||
void MyCustomDecode::DumpResults(void){
|
||||
if(decode_type==DIRECTV) {
|
||||
Serial.print(F("Decoded DirecTV: Value:")); Serial.print(value, HEX);
|
||||
if (Repeat) Serial.print(F(" repeat flag"));
|
||||
};
|
||||
IRdecode::DumpResults();
|
||||
};
|
||||
|
||||
MyCustomDecode My_Decoder;
|
||||
|
||||
MyCustomSend My_Sender;
|
||||
|
||||
int RECV_PIN = 11;
|
||||
|
||||
IRrecv My_Receiver(RECV_PIN);
|
||||
IRTYPES codeType; // The type of code
|
||||
unsigned long codeValue; // The data bits
|
||||
int codeBits; // The length of the code in bits
|
||||
bool GotOne;
|
||||
|
||||
void setup()
|
||||
{
|
||||
GotOne=false;
|
||||
codeType=UNKNOWN;
|
||||
codeValue=0;
|
||||
codeBits=0;
|
||||
Serial.begin(9600);
|
||||
Serial.println(F("Send a code from your remote and we will record it."));
|
||||
Serial.println(F("Type any character and press enter. We will send the recorded code."));
|
||||
My_Receiver.enableIRIn(); // Start the receiver
|
||||
}
|
||||
void loop() {
|
||||
if (Serial.available()>0) {
|
||||
unsigned char c=Serial.read();
|
||||
if (c=='p') {//Send a test pattern
|
||||
GotOne= true; codeType=DIRECTV; codeValue=0x1234; codeBits=16;
|
||||
}
|
||||
if(GotOne) {
|
||||
My_Sender.send(codeType,codeValue,codeBits);
|
||||
Serial.print(F("Sent "));
|
||||
if (codeType== DIRECTV) Serial.print(F("DirecTV")); else Serial.print(Pnames(codeType));
|
||||
Serial.print(F(" Value:0x"));
|
||||
Serial.print(codeValue, HEX);
|
||||
Serial.print(F(" Bits:"));
|
||||
Serial.println(codeBits, DEC);
|
||||
My_Receiver.enableIRIn(); // Re-enable receiver
|
||||
}
|
||||
}
|
||||
else if (My_Receiver.GetResults(&My_Decoder)) {
|
||||
My_Decoder.decode();
|
||||
if(My_Decoder.decode_type == UNKNOWN) {
|
||||
Serial.println(F("Unknown type received. Ignoring."));
|
||||
} else {
|
||||
codeType= My_Decoder.decode_type;
|
||||
codeValue= My_Decoder.value;
|
||||
codeBits= My_Decoder.bits;
|
||||
GotOne=true;
|
||||
}
|
||||
My_Decoder.DumpResults();
|
||||
delay(1000);
|
||||
My_Receiver.resume();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.4 March 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009I know prescription and no
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://www.righto.com/
|
||||
*/
|
||||
/*
|
||||
* This example demonstrates how to extend this library to add a new protocol
|
||||
* without actually modifying or recompiling the library itself. It implements the protocol
|
||||
* known as GIcable which is used by some Motorola cable boxes.
|
||||
* This is a modified version of the IRecord example.
|
||||
* If you would like to make this a permanent part of your library you could copy the class
|
||||
* prototypes to IRLib.h and the code itself to IRLib.cpp. Search for the word "ADDITIONAL"
|
||||
* to see where to add various pieces of code. Also see the Samsung36 example for details.
|
||||
*/
|
||||
#include <IRLib.h>
|
||||
#include <IRLibMatch.h>
|
||||
|
||||
class IRdecodeGIcable: public virtual IRdecodeBase
|
||||
{
|
||||
public:
|
||||
bool decode(void);
|
||||
};
|
||||
class IRsendGIcable: public virtual IRsendBase
|
||||
{
|
||||
public:
|
||||
void send(unsigned long data, bool Repeat);
|
||||
};
|
||||
|
||||
#define GICABLE (LAST_PROTOCOL+1)
|
||||
|
||||
/* The IRP notation for this protocol according to
|
||||
* http://www.hifi-remote.com/johnsfine/DecodeIR.html#G.I. Cable
|
||||
* is "{38.7k,490}<1,-4.5|1,-9>(18,-9,F:8,D:4,C:4,1,-84,(18,-4.5,1,-178)*) {C = -(D + F:4 + F:4:4)}"
|
||||
*/
|
||||
bool IRdecodeGIcable::decode(void) {
|
||||
IRLIB_ATTEMPT_MESSAGE(F("GIcable"));
|
||||
// Check for repeat
|
||||
if (rawlen == 4 && MATCH(rawbuf[1], 490*18) && MATCH(rawbuf[2],2205)) {
|
||||
bits = 0;
|
||||
value = REPEAT;
|
||||
decode_type= static_cast<IRTYPES>GICABLE;
|
||||
return true;
|
||||
}
|
||||
if(!decodeGeneric(36, 18*490, 9*490, 0, 490, 9*490, 2205/*(4.5*490)*/)) return false;
|
||||
decode_type= static_cast<IRTYPES>GICABLE;
|
||||
return true;
|
||||
};
|
||||
|
||||
void IRsendGIcable::send(unsigned long data, bool Repeat) {
|
||||
if(Repeat) {
|
||||
enableIROut(39);
|
||||
mark (490*18); space (2205); mark (490); space(220);delay (87);//actually "space(87200);"
|
||||
} else {
|
||||
sendGeneric(data,16, 490*18, 490*9, 490, 490, 490*9, 2205, 39, true);
|
||||
}
|
||||
};
|
||||
|
||||
//Create a custom class that combines this new protocol with all the others
|
||||
class MyCustomSend:
|
||||
public virtual IRsend,
|
||||
public virtual IRsendGIcable
|
||||
{
|
||||
public:
|
||||
void send(IRTYPES Type, unsigned long data, int nbits);
|
||||
};
|
||||
void MyCustomSend::send(IRTYPES Type, unsigned long data, int nbits) {
|
||||
if (Type==GICABLE){
|
||||
IRsendGIcable::send(data,false);
|
||||
//un-comment the line below to text repeats
|
||||
//delay(3000); IRsendGIcable::send(data,true);
|
||||
}
|
||||
else
|
||||
IRsend::send(Type, data, nbits);
|
||||
}
|
||||
class MyCustomDecode:
|
||||
public virtual IRdecode,
|
||||
public virtual IRdecodeGIcable
|
||||
{
|
||||
public:
|
||||
virtual bool decode(void); // Calls each decode routine individually
|
||||
void DumpResults(void);
|
||||
};
|
||||
bool MyCustomDecode::decode(void) {
|
||||
if (IRdecodeGIcable::decode()) return true;
|
||||
return IRdecode::decode ();
|
||||
}
|
||||
void MyCustomDecode::DumpResults(void){
|
||||
if(decode_type==GICABLE) {
|
||||
Serial.print(F("Decoded GIcable: Value:")); Serial.print(value, HEX);
|
||||
};
|
||||
IRdecode::DumpResults();
|
||||
};
|
||||
|
||||
MyCustomDecode My_Decoder;
|
||||
|
||||
MyCustomSend My_Sender;
|
||||
|
||||
int RECV_PIN =11;
|
||||
|
||||
IRrecv My_Receiver(RECV_PIN);
|
||||
IRTYPES codeType; // The type of code
|
||||
unsigned long codeValue; // The data bits
|
||||
int codeBits; // The length of the code in bits
|
||||
bool GotOne;
|
||||
|
||||
void setup()
|
||||
{
|
||||
GotOne=false;
|
||||
codeType=UNKNOWN;
|
||||
codeValue=0;
|
||||
codeBits=0;
|
||||
Serial.begin(9600);
|
||||
Serial.println(F("Send a code from your remote and we will record it."));
|
||||
Serial.println(F("Type any character and press enter. We will send the recorded code."));
|
||||
My_Receiver.enableIRIn(); // Start the receiver
|
||||
}
|
||||
void loop() {
|
||||
if (Serial.available()>0) {
|
||||
unsigned char c=Serial.read();
|
||||
if (c=='p') {//Send a test pattern
|
||||
GotOne= true; codeType=GICABLE; codeValue=0x1234; codeBits=16;
|
||||
}
|
||||
if(GotOne) {
|
||||
My_Sender.send(codeType,codeValue,codeBits);
|
||||
Serial.print(F("Sent "));
|
||||
if (codeType== GICABLE) Serial.print(F("GIcable")); else Serial.print(Pnames(codeType));
|
||||
Serial.print(F(" Value:0x"));
|
||||
Serial.print(codeValue, HEX);
|
||||
Serial.print(F(" Bits:"));
|
||||
Serial.println(codeBits, DEC);
|
||||
My_Receiver.enableIRIn(); // Re-enable receiver
|
||||
}
|
||||
}
|
||||
else if (My_Receiver.GetResults(&My_Decoder)) {
|
||||
My_Decoder.decode();
|
||||
if(My_Decoder.decode_type == UNKNOWN) {
|
||||
Serial.println(F("Unknown type received. Ignoring."));
|
||||
} else {
|
||||
codeType= My_Decoder.decode_type;
|
||||
codeValue= My_Decoder.value;
|
||||
codeBits= My_Decoder.bits;
|
||||
GotOne=true;
|
||||
}
|
||||
My_Decoder.DumpResults();
|
||||
delay(1000);
|
||||
My_Receiver.resume();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.3 January 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://www.righto.com/
|
||||
*/
|
||||
/* IRanalyze receives repeated values from a remote and averages the results. Should help in
|
||||
* analyzing unknown protocols. You have to press the same key repeatedly. If you press a
|
||||
* different key the totals reset and it computes new averages.
|
||||
*/
|
||||
#include <IRLib.h>
|
||||
#include <IRLibRData.h>
|
||||
|
||||
int RECV_PIN = 11;
|
||||
|
||||
unsigned int Samples,i, LowSpace, LowMark, HighMark, HighSpace, interval,
|
||||
balm,aalm,bahm,aahm,bals,aals,bahs,aahs;
|
||||
unsigned char bacm,aacm,bacs,aacs, Mark_Count,Space_Count;
|
||||
unsigned int Accumulated_Time[RAWBUF];
|
||||
unsigned long Mark_Avg, Space_Avg,baam,aaam,baas,aaas;
|
||||
//Try this program with various receivers
|
||||
IRrecv My_Receiver(RECV_PIN);
|
||||
//IRrecvLoop My_Receiver(RECV_PIN);
|
||||
//Use interrupt=0. This is pin 2 on Arduino Uno and Mega, pin 3 on Leonardo
|
||||
//IRrecvPCI My_Receiver(0);
|
||||
|
||||
IRdecode My_Decoder;
|
||||
IRTYPES Old_Type;
|
||||
unsigned long Old_Value;
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
delay(1000);while(!Serial);
|
||||
My_Receiver.enableIRIn();
|
||||
// My_Receiver.Mark_Excess=50;//Try different values here
|
||||
Samples=0;Old_Value=0; Old_Type=UNKNOWN;
|
||||
Serial.println(F("Send a signal repeatedly. We will report averages and statistics."));
|
||||
}
|
||||
void Tab(void) {Serial.print("\t");};
|
||||
void loop() {
|
||||
if (My_Receiver.GetResults(&My_Decoder)) {
|
||||
My_Decoder.decode();
|
||||
if( (My_Decoder.decode_type != Old_Type) || (My_Decoder.value != Old_Value)) {
|
||||
Serial.println(F("Resetting counters"));
|
||||
for(i=0;i<RAWBUF;i++) {
|
||||
Accumulated_Time[i]=0;
|
||||
};
|
||||
Samples=0;Old_Value= My_Decoder.value; Old_Type=My_Decoder.decode_type;
|
||||
};
|
||||
Samples++;
|
||||
Serial.print(F("\nSamples=")); Serial.println(Samples,DEC);
|
||||
LowSpace = LowMark=65535;
|
||||
HighSpace = HighMark=0;
|
||||
Mark_Avg= Space_Avg= Mark_Count= Space_Count=0;
|
||||
for(i=0;i<My_Decoder.rawlen;i++){
|
||||
Accumulated_Time[i]+=My_Decoder.rawbuf[i];
|
||||
My_Decoder.rawbuf[i]= Accumulated_Time[i]/Samples;//Put back average so DumpResults can report
|
||||
}
|
||||
My_Decoder.DumpResults();
|
||||
//Perform additional analysis
|
||||
for(i=3;i<My_Decoder.rawlen;i++){ //Compute low, high and average mark and space
|
||||
interval=My_Decoder.rawbuf[i];
|
||||
if(i % 2) {
|
||||
Mark_Avg += interval; LowMark=min(LowMark, interval); HighMark=max(HighMark, interval);Mark_Count++;
|
||||
} else {
|
||||
Space_Avg += interval; LowSpace=min(LowSpace, interval); HighSpace=max (HighSpace, interval);Space_Count++;
|
||||
}
|
||||
My_Decoder.rawbuf[i]= Accumulated_Time[i]/Samples;//Put back average so DumpResults can report
|
||||
}
|
||||
Mark_Avg /= Mark_Count; Space_Avg /= Space_Count;
|
||||
//Now compute below average highs and lows and above average highs and lows
|
||||
balm=bals=aalm=aals=32766;
|
||||
bahm=bahs=aahm=aahs=baam=baas=aaam=aaas=0;
|
||||
bacm=bacs=aacm=aacs=0;
|
||||
for(i=3;i<My_Decoder.rawlen;i++){
|
||||
interval=My_Decoder.rawbuf[i];
|
||||
if(i % 2) {
|
||||
if (interval>Mark_Avg) {
|
||||
aalm=min(aalm,interval); aahm=max(aahm,interval);aacm++;aaam+=interval;
|
||||
} else {
|
||||
balm=min(balm,interval); bahm=max(bahm,interval);bacm++;baam+=interval;
|
||||
}
|
||||
} else {
|
||||
if (interval>Space_Avg) {
|
||||
aals=min(aals,interval); aahs=max(aahs,interval);aacs++;aaas+=interval;
|
||||
} else {
|
||||
bals=min(bals,interval); bahs=max(bahs,interval);bacs++;baas+=interval;
|
||||
}
|
||||
}
|
||||
}
|
||||
baam/=bacm;baas/=bacs;aaam/=aacm;aaas/=aacs;
|
||||
Serial.println(F("\t #\tLow\tHigh\tAvg."));
|
||||
Serial.print(F("Mark\t"));Serial.print(Mark_Count,DEC);Tab();Serial.print(LowMark,DEC);Tab();Serial.print(HighMark,DEC);Tab();Serial.println(Mark_Avg,DEC);
|
||||
Serial.print(F("Space\t"));Serial.print(Space_Count,DEC);Tab();Serial.print(LowSpace,DEC);Tab();Serial.print(HighSpace,DEC);Tab();Serial.println(Space_Avg,DEC);
|
||||
|
||||
Serial.println(F("\nMarks\t\t #\tLow\tHigh\tAvg."));
|
||||
Serial.print(F("Above Avg\t"));Serial.print(aacm,DEC);Tab();Serial.print(aalm,DEC);Tab();Serial.print(aahm,DEC);Tab();Serial.println(aaam,DEC);
|
||||
Serial.print(F("Belows Avg.\t"));Serial.print(bacm,DEC);Tab();Serial.print(balm,DEC);Tab();Serial.print(bahm,DEC);Tab();Serial.println(baam,DEC);
|
||||
|
||||
Serial.println(F("\nSpaces\t\t #\tLow\tHigh\tAvg."));
|
||||
Serial.print(F("Above Avg.\t"));Serial.print(aacs,DEC);Tab();Serial.print(aals,DEC);Tab();Serial.print(aahs,DEC);Tab();Serial.println(aaas,DEC);
|
||||
Serial.print(F("Below Avg.\t"));Serial.print(bacs,DEC);Tab();Serial.print(bals,DEC);Tab();Serial.print(bahs,DEC);Tab();Serial.println(baas,DEC);
|
||||
|
||||
#define RATIO(n,d) Tab(); Serial.print(float(n)/float(d));
|
||||
Serial.print(F("\nRatios\t\tBelow\tAbove\n"));
|
||||
Serial.print(F("Head Mark"));RATIO(My_Decoder.rawbuf[1],baam);RATIO(My_Decoder.rawbuf[1],aaam);
|
||||
Serial.print(F("\nHead Space"));RATIO(My_Decoder.rawbuf[2],baas);RATIO(My_Decoder.rawbuf[2],aaas);
|
||||
Serial.print(F("\n\nMark Above/Below="));RATIO(aaam,baam);
|
||||
Serial.print(F("\nSpace Above/Below="));RATIO(aaas,baas);
|
||||
Serial.println();
|
||||
delay(500);
|
||||
My_Receiver.resume();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/* IRfreq: estimate modulation frequency of IR transmitter
|
||||
* Version 1.3 January 2014
|
||||
* Copyright 2014 by Chris Young http://tech.cyborg5.com
|
||||
* Based on Arduino firmware for use with AnalysIR IR signal analysis
|
||||
* software for Windows PCs. Many thanks to the people
|
||||
* at http://analysir.com for their assistance In developing this program.
|
||||
*/
|
||||
#define INTERRUPT_USED 1 // Value can be 0-5 depending on board.
|
||||
// You should attach your TSMP5800 or equivalent
|
||||
// receiver to appropriate pin as defined below.
|
||||
|
||||
// Do not modified this section
|
||||
#if defined(__AVR_ATmega32U4__) //Assume Arduino Leonardo
|
||||
#if(INTERRUPT_USED==0)
|
||||
#define PIN_USED 3
|
||||
#elif (INTERRUPT_USED==1)
|
||||
#define PIN_USED 2
|
||||
#elif (INTERRUPT_USED==2)
|
||||
#define PIN_USED 0
|
||||
#elif (INTERRUPT_USED==3)
|
||||
#define PIN_USED 1
|
||||
#elif (INTERRUPT_USED==4)
|
||||
#define PIN_USED 7
|
||||
#else
|
||||
#error "Invalid value for INTERRUPT_USED on Leonardo"
|
||||
#endif
|
||||
#elif (INTERRUPT_USED==0) //Uno or Mega
|
||||
#define PIN_USED 2
|
||||
#elif (INTERRUPT_USED==1) //Uno or Mega
|
||||
#define PIN_USED 3
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#if (INTERRUPT_USED==2) //Mega only
|
||||
#define PIN_USED 21
|
||||
#elif (INTERRUPT_USED==3) //Mega only
|
||||
#define PIN_USED 20
|
||||
#elif (INTERRUPT_USED==4) //Mega only
|
||||
#define PIN_USED 19
|
||||
#elif (INTERRUPT_USED==5) //Mega only
|
||||
#define PIN_USED 18
|
||||
#else
|
||||
#error "invalid value for INTERRUPT_USED on Arduino press delete this Michael down five mega"
|
||||
#endif
|
||||
#else
|
||||
#error "Invalid value for INTERRUPT_USED on non-Leonardo non-Mega board"
|
||||
#endif
|
||||
|
||||
#define BUF_SIZE 200
|
||||
// These are "volatile" because they are modified inside the interrupt handler
|
||||
volatile byte Time_Stamp[BUF_SIZE]; //Punch the time clock using "micros()" each time a pulse causes interrupt
|
||||
volatile byte Count; //Index into Time_Stamp
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
while(!Serial);//for Leonardo
|
||||
pinMode(PIN_USED, INPUT);
|
||||
Serial.print(F("Using interrupt="));Serial.println(INTERRUPT_USED,DEC);
|
||||
Serial.println(F("You should have Vishay TSMP58000 or equivalent"));
|
||||
Serial.print(F("connected to pin=")); Serial.println(PIN_USED,DEC);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
attachInterrupt(INTERRUPT_USED, My_Interrupt_Handler, FALLING);
|
||||
while(Count < (BUF_SIZE-10)); //do nothing but process interrupts until buffer almost fills
|
||||
//We took that extra 10 off just in case interrupt came too fast for us to turn them off
|
||||
detachInterrupt (INTERRUPT_USED);
|
||||
Report_Freq();//reports modulation frequency to host over serial
|
||||
}
|
||||
|
||||
void Report_Freq(){
|
||||
byte Count_Usable=0; //Counts the number of usable valid intervals
|
||||
unsigned long Sum=0; //Accumulate total of usable intervals
|
||||
byte I;
|
||||
byte Interval;//Interval between timestamps
|
||||
Count--;//last one doesn't count
|
||||
for (I=1;I<Count;I++){
|
||||
Interval=(Time_Stamp[I]-Time_Stamp[I-1]);
|
||||
if (Interval>50 || Interval<10) continue;//this is the period range length exclude extraneous ones
|
||||
Sum +=Interval; // Accumulate usable intervals
|
||||
Count_Usable++; // Count usable intervals
|
||||
Time_Stamp[I-1]=0;//finished with it so clear for next time
|
||||
}
|
||||
Time_Stamp[I-1]=0;//now clear last one, which was missed in loop
|
||||
Serial.print(F("Based on ")); Serial.print(Count_Usable,DEC);
|
||||
Serial.print(F(" intervals totaling ")); Serial.print(Sum,DEC);
|
||||
double Frequency=(double)Count_Usable/(double)Sum*1000;
|
||||
Serial.print(F(" microseconds, the frequency is approx. =")); Serial.print(Frequency);
|
||||
Serial.println(F("kHz"));
|
||||
delay(1000);
|
||||
Count=0; //reset value for next time
|
||||
}
|
||||
|
||||
void My_Interrupt_Handler(){
|
||||
Time_Stamp[Count++]=micros();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.3 January 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://www.righto.com/
|
||||
*/
|
||||
/*
|
||||
* IRhashdecode - decode an arbitrary IR code.
|
||||
* Instead of decoding using a standard encoding scheme
|
||||
* (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value.
|
||||
* This should produce a unique 32-bit number however that number cannot be used
|
||||
* to retransmit the same code. This is just a quick and dirty way to detect a unique code
|
||||
* for controlling a device when you don't really care what protocol or values
|
||||
* are being sent.
|
||||
*/
|
||||
|
||||
#include <IRLib.h>
|
||||
|
||||
int RECV_PIN = 11;
|
||||
|
||||
IRrecv My_Receiver(RECV_PIN);
|
||||
IRdecode My_Decoder;
|
||||
IRdecodeHash My_Hash_Decoder;
|
||||
|
||||
void setup()
|
||||
{
|
||||
My_Receiver.enableIRIn(); // Start the receiver
|
||||
Serial.begin(9600);
|
||||
delay(2000);while(!Serial);//delay for Leonardo
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (My_Receiver.GetResults(&My_Decoder)) {//Puts results in My_Decoder
|
||||
My_Hash_Decoder.copyBuf(&My_Decoder);//copy the results to the hash decoder
|
||||
My_Decoder.decode();
|
||||
Serial.print("real decode type:");
|
||||
Serial.print(Pnames(My_Decoder.decode_type));
|
||||
Serial.print(" value: 0x");
|
||||
Serial.print(My_Decoder.value, HEX);
|
||||
My_Hash_Decoder.decode();
|
||||
Serial.print(", hash decode: 0x");
|
||||
Serial.println(My_Hash_Decoder.hash, HEX); // Do something interesting with this value
|
||||
delay(1000);
|
||||
My_Receiver.resume();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.3 January 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://www.righto.com/
|
||||
*/
|
||||
/*
|
||||
* IRrecord: record and play back IR signals
|
||||
* An IR detector/demodulator must be connected to the input RECV_PIN.
|
||||
* An IR LED must be connected to the appropriate pin.(See IRLibTimer.h) for your
|
||||
* machine's timers and erupts.
|
||||
* Record a value by pointing your remote at the device then send any character
|
||||
* from the serial monitor to send the recorded value.
|
||||
* Also demonstrates how to use toggle bits which must be controlled outside
|
||||
* the library routines.
|
||||
* The logic is:
|
||||
* If an IR code is received, record it.
|
||||
* If g serial character is received, send the IR code.
|
||||
*/
|
||||
|
||||
#include <IRLib.h>
|
||||
|
||||
int RECV_PIN = 11;
|
||||
|
||||
IRrecv My_Receiver(RECV_PIN);
|
||||
IRdecode My_Decoder;
|
||||
IRsend My_Sender;
|
||||
/*
|
||||
* Because this version of the library separated the receiver from the decoder,
|
||||
* technically you would not need to "store" the code outside the decoder object
|
||||
* for this overly simple example. All of the details would remain in the object.
|
||||
* However we are going to go ahead and store them just to show you how.
|
||||
*/
|
||||
// Storage for the recorded code
|
||||
IRTYPES codeType; // The type of code
|
||||
unsigned long codeValue; // The data bits if type is not raw
|
||||
int codeBits; // The length of the code in bits
|
||||
|
||||
// These values are only stored if it's an unknown type and we are going to use
|
||||
// raw codes to resend the information.
|
||||
unsigned int rawCodes[RAWBUF]; // The durations if raw
|
||||
int rawCount; //The number of interval samples
|
||||
|
||||
bool GotOne, GotNew;
|
||||
|
||||
void setup()
|
||||
{
|
||||
GotOne=false; GotNew=false;
|
||||
codeType=UNKNOWN;
|
||||
codeValue=0;
|
||||
Serial.begin(9600);
|
||||
delay(2000);while(!Serial);//delay for Leonardo
|
||||
Serial.println(F("Send a code from your remote and we will record it."));
|
||||
Serial.println(F("Type any character and press enter. We will send the recorded code."));
|
||||
My_Receiver.enableIRIn(); // Start the receiver
|
||||
}
|
||||
|
||||
// Stores the code for later playback
|
||||
void storeCode(void) {
|
||||
GotNew=true;
|
||||
codeType = My_Decoder.decode_type;
|
||||
if (codeType == UNKNOWN) {
|
||||
Serial.println("Received unknown code, saving as raw");
|
||||
// To store raw codes:
|
||||
// Drop first value (gap)
|
||||
// As of v1.3 of IRLib global values are already in microseconds rather than ticks
|
||||
// They have also been adjusted for overreporting/underreporting of marks and spaces
|
||||
rawCount = My_Decoder.rawlen-1;
|
||||
for (int i = 1; i <=rawCount; i++) {
|
||||
rawCodes[i - 1] = My_Decoder.rawbuf[i];
|
||||
};
|
||||
My_Decoder.DumpResults();
|
||||
codeType=UNKNOWN;
|
||||
}
|
||||
else {
|
||||
Serial.print(F("Received "));
|
||||
Serial.print(Pnames(codeType));
|
||||
if (My_Decoder.value == REPEAT) {
|
||||
// Don't record a NEC repeat value as that's useless.
|
||||
Serial.println(F("repeat; ignoring."));
|
||||
}
|
||||
else {
|
||||
codeValue = My_Decoder.value;
|
||||
codeBits = My_Decoder.bits;
|
||||
}
|
||||
Serial.print(F(" Value:0x"));
|
||||
Serial.println(My_Decoder.value, HEX);
|
||||
}
|
||||
}
|
||||
void sendCode(int repeat) {
|
||||
if(codeType== UNKNOWN) {
|
||||
// Assume 38 KHz
|
||||
My_Sender.IRsendRaw::send(rawCodes,rawCount,38);
|
||||
Serial.println(F("Sent raw"));
|
||||
return;
|
||||
}
|
||||
if( !GotNew ) {//We've already sent this so handle toggle bits
|
||||
if (codeType == RC5) {
|
||||
codeValue ^= 0x0800;
|
||||
}
|
||||
else if (codeType == RC6) {
|
||||
codeValue ^= 0x10000;
|
||||
}
|
||||
}
|
||||
GotNew=false;
|
||||
My_Sender.send(codeType,codeValue,codeBits);
|
||||
Serial.print(F("Sent "));
|
||||
Serial.print(Pnames(codeType));
|
||||
Serial.print(F(" Value:0x"));
|
||||
Serial.println(codeValue, HEX);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (Serial.read() != -1) {
|
||||
if(GotOne) {
|
||||
sendCode(0);
|
||||
My_Receiver.enableIRIn(); // Re-enable receiver
|
||||
}
|
||||
}
|
||||
else if (My_Receiver.GetResults(&My_Decoder)) {
|
||||
My_Decoder.decode();
|
||||
GotOne=true;
|
||||
storeCode();
|
||||
delay(1000);
|
||||
My_Receiver.resume();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.3 January 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://www.righto.com/
|
||||
*/
|
||||
/*
|
||||
* IRLib: IRrecvDump - dump details of IR codes with IRrecv
|
||||
* An IR detector/demodulator must be connected to the input RECV_PIN.
|
||||
*/
|
||||
|
||||
#include <IRLib.h>
|
||||
|
||||
int RECV_PIN = 11;
|
||||
|
||||
IRrecv My_Receiver(RECV_PIN);
|
||||
|
||||
IRdecode My_Decoder;
|
||||
unsigned int Buffer[RAWBUF];
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
delay(2000);while(!Serial);//delay for Leonardo
|
||||
My_Receiver.enableIRIn(); // Start the receiver
|
||||
My_Decoder.UseExtnBuf(Buffer);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (My_Receiver.GetResults(&My_Decoder)) {
|
||||
//Restart the receiver so it can be capturing another code
|
||||
//while we are working on decoding this one.
|
||||
My_Receiver.resume();
|
||||
My_Decoder.decode();
|
||||
My_Decoder.DumpResults();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.3 January 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://www.righto.com/
|
||||
*/
|
||||
#include <IRLib.h>
|
||||
|
||||
IRsend My_Sender;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (Serial.read() != -1) {
|
||||
//send a code every time a character is received from the serial port
|
||||
//Sony DVD power A8BCA
|
||||
My_Sender.send(SONY,0xa8bca, 20);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.3 January 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://www.righto.com/
|
||||
*/
|
||||
/*
|
||||
* JVC sends repeat codes that are identical to the regular JVC codes
|
||||
* however they have no header. Therefore there is an additional parameter
|
||||
* that tells you whether or not to send as an original code or as a repeat.
|
||||
*
|
||||
* The only device I had to test this protocol was an old JVC VCR. It would only work if at least
|
||||
* 2 frames are sent separated by 45us of "space". All JVC is the same bit length so we use
|
||||
* the third parameter as a flag to tell it whether or not to send the header.
|
||||
* Send once with the third parameter "1" then delay about 50 microseconds and send again
|
||||
* with the third parameter "0".
|
||||
*/
|
||||
|
||||
#include <IRLib.h>
|
||||
|
||||
IRsend My_Sender;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
//send a code every time a character is received from the serial port
|
||||
void loop() {
|
||||
if (Serial.read() != -1) {
|
||||
My_Sender.send(JVC,0xc2d0,1); delayMicroseconds (50);
|
||||
My_Sender.send(JVC,0xc2d0,0); delayMicroseconds (50);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.3 January 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
* Use serial port to send codes. For details on this project see
|
||||
http://tech.cyborg5.com/2013/05/30/irlib-tutorial-part-3-overview-sending-ir-codes/
|
||||
*/
|
||||
#include <IRLib.h>
|
||||
|
||||
IRsend My_Sender;
|
||||
|
||||
int protocol;
|
||||
long code;
|
||||
int bits;
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
delay(2000);while(!Serial);//delay for Leonardo
|
||||
}
|
||||
|
||||
long parseHex (void) {
|
||||
long Value=0; char C;delay(100);
|
||||
while (Serial.available()>0) {
|
||||
C= tolower(Serial.read());
|
||||
if ((C>='0')&&(C<='9'))
|
||||
C=C-'0';
|
||||
else
|
||||
if ((C>='a') && (C<='f'))
|
||||
C=C-'a'+10;
|
||||
else
|
||||
return Value;
|
||||
Value= C+(Value<<4);
|
||||
};
|
||||
return Value;
|
||||
}
|
||||
void parseDelimiter () {
|
||||
char C;
|
||||
while(Serial.available()>0) {
|
||||
C=tolower(Serial.peek());
|
||||
if( (C>='0') && (C<='9') )return;
|
||||
if( (C>='a') && (C<='f') )return;
|
||||
C=Serial.read();//throwaway delimiters
|
||||
delay (5);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (Serial.available ()>0) {
|
||||
protocol = Serial.parseInt (); parseDelimiter();
|
||||
code = parseHex (); parseDelimiter();
|
||||
bits = Serial.parseInt (); parseDelimiter();
|
||||
Serial.print("Prot:"); Serial.print(protocol);
|
||||
Serial.print(" Code:"); Serial.print(code,HEX);
|
||||
Serial.print(" Bits:"); Serial.println(bits);
|
||||
My_Sender.send(IRTYPES(protocol), code, bits);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
# IRLib demo script
|
||||
# version 1.0 by Chris Young http://tech.cyborg5.com/irlib/
|
||||
# Displays a "Virtual remote" on your screen. Clicking on the
|
||||
# buttons sends serial datato the Arduino which in turn
|
||||
# since IR signals to a cable box in TV.
|
||||
|
||||
# Import all of the necessary pieces of code
|
||||
import serial, sys, pygame, pygame.mixer
|
||||
from pygame.locals import *
|
||||
|
||||
# You will have to edit this to the proper port and speed
|
||||
ser = serial.Serial('COM4', 9600)
|
||||
|
||||
pygame.init()
|
||||
# Established screen size, size of buttons and position
|
||||
size = width, height = 400, 768
|
||||
button_size=54; button_offset=71
|
||||
button_x1=65;button_y1=39
|
||||
max_rows=10; max_columns=4
|
||||
|
||||
# Specify a font. I'm using Arial narrow bold from my Windows
|
||||
# font folder. However the default font shown below also works.
|
||||
myfont =pygame.font.Font ("c:/windows/fonts/ARIALNB.TTF",30)
|
||||
#myfont=pygame.font.Font(None,36)
|
||||
|
||||
# These are the text labels that will appear on each button
|
||||
label_text=("TVp", "CBp", "P^", "Pv",\
|
||||
"<<", ">", ">>", "->",\
|
||||
"Rec", "=", "s", "<-",\
|
||||
"Gd", "^", "Fav", "Inf",\
|
||||
|
||||
"<", "sel", ">", "Lis",\
|
||||
"ret", "v", "Prv", "Mnu",\
|
||||
"1", "2", "3", "Ch+",\
|
||||
|
||||
"4", "5", "6", "Ch-",\
|
||||
"7", "8", "9", "Vol+",\
|
||||
"Pip", "0", "Mut", "Vol-",\
|
||||
)
|
||||
# Each of these 40 strings of text correspond to the
|
||||
# protocol in code which will be sent over the USB serial
|
||||
# to the Arduino. The first number is the protocol number.
|
||||
# See the defined protocols in "IRLib.h"for the
|
||||
# enum IRTYPES at about line 50. This example uses
|
||||
# protocol 3 which is "RC5" used by my Magnavox TV
|
||||
# and protocol 5 "PANASONIC_OLD" used by my Scientific
|
||||
# Atlantic SA 8300 DVR. The protocol number is followed by
|
||||
# the hex code to be transmitted. That is followed by the
|
||||
# number of bits. Note that the PANASONIC_OLD protocol
|
||||
# does not need the number of bits specified so they are omitted.
|
||||
IR_Codes= ("3,180c,13","5,37c107","5,36d924","5,37d904",\
|
||||
"5,37291a","5,37990c","5,36293a","5,36b129",\
|
||||
"5,375914","5,374117","5,365934","5,37c906",\
|
||||
"5,36c127","5,36812f","5,37f101","5,36213b",\
|
||||
|
||||
"5,37810f","5,366133","5,364137","5,36c926",\
|
||||
"5,366932","5,37a10b","5,36e123","5,373918",\
|
||||
"5,36113d","5,37111d","5,36912d","5,377111",\
|
||||
|
||||
"5,37910d","5,365135","5,375115","5,36f121",\
|
||||
"5,36d125","5,37d105","5,363139","3,1810,13",\
|
||||
"5,37b908","5,373119","3,180d,13","3,1811,13",\
|
||||
)
|
||||
# This function gets called to shut everything down
|
||||
def Finished():
|
||||
pygame.quit()
|
||||
sys.exit()
|
||||
|
||||
# Gets the button index based on mouse position. Returned
|
||||
# value is from 0 to 39 (number of buttons-1)
|
||||
# Returns -1 if you are not over a button.
|
||||
def ComputeButton():
|
||||
mx,my=pygame.mouse.get_pos()
|
||||
mx=mx-button_x1
|
||||
my=my-button_y1
|
||||
bx=mx/button_offset; by=my/button_offset
|
||||
if bx<0 or bx>=max_columns:return -1
|
||||
if by<0 or by> max_rows:return -1
|
||||
if (mx%button_offset)>button_size:return -1
|
||||
if (my%button_offset)>button_size:return -1
|
||||
return bx+by*max_columns
|
||||
|
||||
# Blits the button text from button number "i"
|
||||
# onto the specified layer using the specified color.
|
||||
def Show_Text(i,Layer,color=(0,0,0)):
|
||||
t=label_text[i]
|
||||
label = myfont.render (t,1,color)
|
||||
labelpos= label.get_rect()
|
||||
labelpos.centerx=button_x1+button_size/2+i%max_columns*button_offset
|
||||
labelpos.centery=button_y1+button_size/2+i/max_columns*button_offset
|
||||
Layer.blit(label,labelpos)
|
||||
|
||||
# Create the screen and load the background image.
|
||||
screen = pygame.display.set_mode(size)
|
||||
bg = pygame.image.load("remotebg.png")
|
||||
|
||||
# Blit black text labels onto the background image
|
||||
for i in range (max_rows*max_columns):
|
||||
Show_Text(i, bg)
|
||||
# Copy the background to the display
|
||||
screen.blit(bg,(0,0))
|
||||
pygame.display.flip()
|
||||
|
||||
# Load the clicking sound
|
||||
Click=pygame.mixer.Sound("click.wav")
|
||||
|
||||
# Used to detect when the mouse hovers over a different button
|
||||
previous=-1
|
||||
|
||||
while 1:
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
Finished()
|
||||
elif event.type == KEYDOWN and event.key == K_ESCAPE:
|
||||
Finished ()
|
||||
elif event.type == MOUSEBUTTONDOWN:
|
||||
i=ComputeButton() #which button did we click
|
||||
if i>=0:
|
||||
Click.play() #play the sound
|
||||
ser.write(IR_Codes[i]) #send the codes
|
||||
elif event.type==MOUSEMOTION:
|
||||
i=ComputeButton() #which button are we over
|
||||
if i!=previous: #difference in the last one?
|
||||
if i>=0: #turn it red
|
||||
Show_Text(i,screen,(255,0,0))
|
||||
else: #or put it back the way it was
|
||||
screen.blit(bg,(0,0))
|
||||
previous=i
|
||||
pygame.display.flip() #update the display
|
||||
# That's all folks
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
//POV-Ray source to generate the background image for IRserial_remote
|
||||
// create rectangular areas with rounded corners for use as
|
||||
// buttons and background objects.
|
||||
|
||||
// Render at 1024x768 then crop 312 pixels from each side
|
||||
// leaving 400x768 final image.
|
||||
#declare Area=15; //size of area lights
|
||||
#declare CR=0.1; //corner radius
|
||||
#declare ER= 0.5; //edge radius
|
||||
#declare CX= 3; //width from corner to corner
|
||||
#declare CY= 7.75; //height from corner to corner
|
||||
#declare BZ=-ER; //Z offset for buttons
|
||||
|
||||
plane {z,0 pigment{rgb<0.8,0.85,1>*0.8}}//background
|
||||
|
||||
#macro Thing (ER,CR,CX,CY,T)
|
||||
#local Corner=
|
||||
union {
|
||||
torus {CR,ER rotate x*90}
|
||||
cylinder {ER*z,-ER*z,CR}
|
||||
}
|
||||
union {
|
||||
object{Corner translate< CX,CY,0>}
|
||||
object{Corner translate<-CX,CY,0>}
|
||||
object{Corner translate< CX,-CY,0>}
|
||||
object{Corner translate<-CX,-CY,0>}
|
||||
cylinder{CY*y,-CY*y,ER translate<-CX-CR,0,0>}
|
||||
cylinder{CY*y,-CY*y,ER translate< CX+CR,0,0>}
|
||||
cylinder{CX*x,-CX*x,ER translate<0,-CY-CR,0>}
|
||||
cylinder{CX*x,-CX*x,ER translate<0, CY+CR,0>}
|
||||
box{<-CX,-CY-CR,-ER><CX,CY+CR,ER>}
|
||||
box{<-CX-CR,-CY,-ER><CX+CR,CY,ER>}
|
||||
texture {T}
|
||||
}
|
||||
#end
|
||||
|
||||
#declare BX= 0.4; #declare BY=BX;//size of the buttons
|
||||
#declare White_Texture=texture{pigment{rgb 1}finish {ambient 0.3}}
|
||||
#declare Blue_Texture=texture{pigment {rgb<0.85,0.9 ,1>}}
|
||||
|
||||
object {Thing(ER,CR,CX,CY, White_Texture)}//main object
|
||||
//loop through the buttons
|
||||
#declare R=-4.5;
|
||||
#while (R<5.5)
|
||||
#declare C=-1.5;
|
||||
#while (C<=1.5)
|
||||
object{Thing(0.1,0.2,(BX*0.8),(BY*0.8), Blue_Texture)
|
||||
translate <C*BX*4,R*BY*4,BZ>
|
||||
}
|
||||
#declare C=C+1;
|
||||
#end
|
||||
#declare R=R+1;
|
||||
#end
|
||||
|
||||
|
||||
light_source{<50,50,-100>*5 color 0.8
|
||||
#if (Area)area_light x*Area,y*Area,9,9#end
|
||||
}
|
||||
light_source{<0,0,-400>*3 rgb 1}
|
||||
|
||||
camera{orthographic location <0,0,-120> look_at <0,0,0> angle 11 }
|
||||
//That's all folks!
|
||||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 48 KiB |
@@ -0,0 +1,75 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.3 January 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
* "IRservo" Control a servo using an IR remote
|
||||
*/
|
||||
#include <IRLib.h>
|
||||
#include <Servo.h>
|
||||
/* Note: Servo library uses TIMER1. The default timer for IRLib on Arduino Uno
|
||||
* is TIMER2 so there is no conflict. However a default timer on Arduino Leonardo
|
||||
* is TIMER1 so you will have to modify the timer used to use TIMER3 or TIMER4
|
||||
* as specified in IRLibTimer.h. Also you will need to modify the input being used.
|
||||
*/
|
||||
// You will have to set these values depending on the protocol
|
||||
// and remote codes that you are using. These are from my Sony DVD/VCR
|
||||
#define MY_PROTOCOL SONY
|
||||
#define RIGHT_ARROW 0x86bca //Move several clockwise
|
||||
#define LEFT_ARROW 0x46bca //Move servo counterclockwise
|
||||
#define SELECT_BUTTON 0xd0bca //Center the servo
|
||||
#define UP_ARROW 0x42bca //Increased number of degrees servo moves
|
||||
#define DOWN_ARROW 0xc2bca //Decrease number of degrees servo moves
|
||||
#define BUTTON_0 0x90bca //Pushing buttons 0-9 moves to fix positions
|
||||
#define BUTTON_1 0x00bca // each 20 degrees greater
|
||||
#define BUTTON_2 0x80bca
|
||||
#define BUTTON_3 0x40bca
|
||||
#define BUTTON_4 0xc0bca
|
||||
#define BUTTON_5 0x20bca
|
||||
#define BUTTON_6 0xa0bca
|
||||
#define BUTTON_7 0x60bca
|
||||
#define BUTTON_8 0xe0bca
|
||||
#define BUTTON_9 0x10bca
|
||||
|
||||
IRrecv My_Receiver(11);//Receive on pin 11
|
||||
IRdecode My_Decoder;
|
||||
Servo My_Servo; // create servo object to control a servo
|
||||
int pos; // variable to store the servo position
|
||||
int Speed; // Number of degrees to move each time a left/right button is pressed
|
||||
|
||||
void setup()
|
||||
{
|
||||
My_Receiver.No_Output();//Turn off any unused IR LED output circuit
|
||||
My_Servo.attach(9); // attaches the servo on pin 9 to the servo object
|
||||
pos = 90; // start at midpoint 90 degrees
|
||||
Speed = 3; // servo moves 3 degrees each time left/right is pushed
|
||||
My_Servo.write(pos); // Set initial position
|
||||
My_Receiver.enableIRIn(); // Start the receiver
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (My_Receiver.GetResults(&My_Decoder)) {
|
||||
My_Decoder.decode();
|
||||
if(My_Decoder.decode_type==MY_PROTOCOL) {
|
||||
switch(My_Decoder.value) {
|
||||
case LEFT_ARROW: pos=min(180,pos+Speed); break;
|
||||
case RIGHT_ARROW: pos=max(0,pos-Speed); break;
|
||||
case SELECT_BUTTON: pos=90; break;
|
||||
case UP_ARROW: Speed=min(10, Speed+1); break;
|
||||
case DOWN_ARROW: Speed=max(1, Speed-1); break;
|
||||
case BUTTON_0: pos=0*20; break;
|
||||
case BUTTON_1: pos=1*20; break;
|
||||
case BUTTON_2: pos=2*20; break;
|
||||
case BUTTON_3: pos=3*20; break;
|
||||
case BUTTON_4: pos=4*20; break;
|
||||
case BUTTON_5: pos=5*20; break;
|
||||
case BUTTON_6: pos=6*20; break;
|
||||
case BUTTON_7: pos=7*20; break;
|
||||
case BUTTON_8: pos=8*20; break;
|
||||
case BUTTON_9: pos=9*20; break;
|
||||
}
|
||||
My_Servo.write(pos); // tell servo to go to position in variable 'pos'
|
||||
}
|
||||
My_Receiver.resume();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,258 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.4 March 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009I know prescription and no
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://www.righto.com/
|
||||
*/
|
||||
/*
|
||||
* This example demonstrates how to extend this library to add a new protocol
|
||||
* without actually modifying or recompiling the library itself. It implements a 36 bit
|
||||
* Samsung protocol that is used on a Blu-ray player that I own.
|
||||
* Because a 36 bit value will not fit in the value field (only 32 bits) we have to create
|
||||
* a second value field. This is a modified version of the IRecord example.
|
||||
*/
|
||||
#include <IRLib.h>
|
||||
#include <IRLibMatch.h>
|
||||
/* Although it is not necessary for this example to run, everything in this section
|
||||
* this section of the code could be moved to the actual IRLib.h file
|
||||
*/
|
||||
class IRdecodeSamsung36: public virtual IRdecodeBase
|
||||
{
|
||||
public:
|
||||
bool decode(void);
|
||||
unsigned int value2;
|
||||
void Reset(void);
|
||||
private:
|
||||
bool GetBit(void);
|
||||
int offset;
|
||||
unsigned long data;
|
||||
};
|
||||
|
||||
class IRsendSamsung36: public virtual IRsendBase
|
||||
{
|
||||
public:
|
||||
void send(unsigned long data, unsigned long data2);
|
||||
private:
|
||||
void PutBits (unsigned long data, int nbits);
|
||||
};
|
||||
/* If moving this code to IRLib.h instead of the line below at about
|
||||
line 60 you should search for the line that says...
|
||||
#define ADDITIONAL (number)
|
||||
and change the code to read as follows‘
|
||||
#define NECX 7
|
||||
#define SAMSUNG36 8
|
||||
#define HASH_CODE 9
|
||||
#define LAST_PROTOCOL HASH_CODE
|
||||
Also at approximately line 160 look for the line that says...
|
||||
, public virtual IRdecodeADDITIONAL
|
||||
and change it to read...
|
||||
public virtual IRdecodeNECx, //Be sure to add the comma
|
||||
public virtual IRdecodeSamsung36 //No comma here
|
||||
And at about line 238 change to read...
|
||||
public virtual IRsendNECx, //Be sure to add the comma
|
||||
public virtual IRsendSamsung36 //No comma here
|
||||
Which will add this protocol to the master send and decode classes
|
||||
*/
|
||||
#define SAMSUNG36 (LAST_PROTOCOL+1)
|
||||
|
||||
/* Although it is not necessary for this example to run, everything in this section
|
||||
* this section of the code could be moved to the actual IRLib.cpp file
|
||||
*/
|
||||
/*
|
||||
* According to http://www.hifi-remote.com/johnsfine/DecodeIR.html#Samsung36
|
||||
* The IRP notation for this protocol is:
|
||||
* {38k,500}<1,-1|1,-3>(9,-9,D:8,S:8,1,-9,E:4,F:8,-68u,~F:8,1,-118)+
|
||||
* This means it uses 38k frequency. Base timing is multiples of 500.
|
||||
* A "0" is mark(500) space(500). A "1" is mark (500) space(1500)
|
||||
* The header is mark(4500) space(4500).
|
||||
* The header is followed by 16 bits (8 device, 8 sub device)
|
||||
* This is followed by a mark(500) space(4500).
|
||||
* This is followed by 12 more bits (4+8)
|
||||
* This is followed by 68us ofspace. Followed by eight more bits
|
||||
* and a final stop bit.
|
||||
*/
|
||||
/* Because not all of the data bits are contiguous in the stream
|
||||
* we created this little routine to get one data bit.
|
||||
* We then call it in a loop as needed.
|
||||
*/
|
||||
bool IRdecodeSamsung36::GetBit(void) {
|
||||
if (!MATCH(rawbuf[offset],500)) return DATA_MARK_ERROR(500);
|
||||
offset++;
|
||||
if (MATCH(rawbuf[offset],1500))
|
||||
data = (data << 1) | 1;
|
||||
else if (MATCH(rawbuf[offset],500))
|
||||
data <<= 1;
|
||||
else return DATA_SPACE_ERROR(1500);
|
||||
offset++;
|
||||
return true;
|
||||
};
|
||||
bool IRdecodeSamsung36::decode(void) {
|
||||
IRLIB_ATTEMPT_MESSAGE(F("Samsung36"));
|
||||
if (rawlen != 78) return RAW_COUNT_ERROR;
|
||||
if (!MATCH(rawbuf[1],4500)) return HEADER_MARK_ERROR(4500);
|
||||
if (!MATCH(rawbuf[2],4500)) return HEADER_SPACE_ERROR(4500);
|
||||
offset=3; data=0;
|
||||
//Get first 16 bits
|
||||
while (offset < 16*2+2) if(!GetBit()) return false;
|
||||
//Skip middle header
|
||||
if (!MATCH(rawbuf[offset],500)) return DATA_MARK_ERROR(500);
|
||||
offset++;
|
||||
if (!MATCH(rawbuf[offset],4500)) return DATA_SPACE_ERROR(4400);
|
||||
//save first 16 bits in "value2" and reset data
|
||||
offset++; value2=data; data=0;
|
||||
//12 bits into this second segment there is a 68us space
|
||||
//so we find one of the raw values to eliminate that
|
||||
rawbuf[62]=rawbuf[62]-68;
|
||||
//this gets remaining 20 bits
|
||||
while(offset<77)if(!GetBit()) return false;
|
||||
bits =36;//set bit length
|
||||
value = data;//put remaining 12 bits in value
|
||||
decode_type= static_cast<IRTYPES>SAMSUNG36;
|
||||
return true;
|
||||
};
|
||||
//The Reset method clears out the data however we have extra data to clear
|
||||
void IRdecodeSamsung36::Reset(void) {
|
||||
IRdecodeBase::Reset();//respect your parents
|
||||
value2=0;
|
||||
};
|
||||
//Similar to GetBits, this routine sends just one bit of data.
|
||||
//Need this because data bits are not contiguous in the stream
|
||||
void IRsendSamsung36::PutBits (unsigned long data, int nbits){
|
||||
for (int i = 0; i < nbits; i++) {
|
||||
if (data & 0x80000000) {
|
||||
mark(500); space(1500);
|
||||
} else {
|
||||
mark(500); space(500);
|
||||
};
|
||||
data <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void IRsendSamsung36::send(unsigned long data, unsigned long data2) {
|
||||
data <<= 32-20;
|
||||
data2 <<= 32-16;
|
||||
enableIROut(38);
|
||||
mark(4500); space(4500);//Send header
|
||||
PutBits (data2, 16);//Send data2 16 bits
|
||||
mark (500); space (4500);//Send break
|
||||
PutBits (data, 12);//Send 12 bits
|
||||
space(68);//Send tiny break
|
||||
data <<= 12;
|
||||
PutBits (data, 8);mark(500); //Final eight bits and one stop bit
|
||||
space(118*500);//Lead out is 118 times the base time 500
|
||||
};
|
||||
/*
|
||||
* This concludes the portion that you could move to IRLib.cpp
|
||||
* Additionally at apprx. line 39 add F("Samsung36"), to the list
|
||||
* between NECx and hash code.
|
||||
* Also add "case SAMSUNG36:IRsendSamsung36::send(data,nbits); break;
|
||||
* at about line 238. Also at about 400 add
|
||||
* if (IRdecodeSamsung36::decode()) return true;
|
||||
*/
|
||||
|
||||
/*
|
||||
* The remaining code is unique to the example sketch.
|
||||
* We will create a custom class which is a combination
|
||||
* of all other protocols and our new protocol.
|
||||
*/
|
||||
|
||||
class MyCustomSend:
|
||||
public virtual IRsend,
|
||||
public virtual IRsendSamsung36
|
||||
{
|
||||
public:
|
||||
//Note: data2 is the number of bits for non-Samsung36 protocols
|
||||
void send(IRTYPES Type, unsigned long data, int data2);
|
||||
};
|
||||
void MyCustomSend::send(IRTYPES Type, unsigned long data, int data2) {
|
||||
if (Type==SAMSUNG36)
|
||||
IRsendSamsung36::send(data,data2);
|
||||
else
|
||||
IRsend::send(Type, data, data2);
|
||||
}
|
||||
class MyCustomDecode:
|
||||
public virtual IRdecode,
|
||||
public virtual IRdecodeSamsung36
|
||||
{
|
||||
public:
|
||||
virtual bool decode(void); // Calls each decode routine individually
|
||||
void DumpResults(void);
|
||||
};
|
||||
bool MyCustomDecode::decode(void) {
|
||||
if (IRdecodeSamsung36::decode()) return true;
|
||||
return IRdecode::decode ();
|
||||
}
|
||||
void MyCustomDecode::DumpResults(void){
|
||||
if(decode_type==SAMSUNG36) {
|
||||
Serial.print(F("Decoded Samsung36: Value:")); Serial.print(value, HEX);
|
||||
Serial.print(F(": Value2:")); Serial.print(value2, HEX);
|
||||
};
|
||||
IRdecode::DumpResults();
|
||||
};
|
||||
|
||||
MyCustomDecode My_Decoder;
|
||||
|
||||
MyCustomSend My_Sender;
|
||||
|
||||
int RECV_PIN = 11;
|
||||
|
||||
IRrecv My_Receiver(RECV_PIN);
|
||||
IRTYPES codeType; // The type of code
|
||||
unsigned long codeValue; // The data bits
|
||||
int codeBits; // The length of the code in bits or for Samsung is storage for data2
|
||||
bool GotOne;
|
||||
|
||||
void setup()
|
||||
{
|
||||
GotOne=false;
|
||||
codeType=UNKNOWN;
|
||||
codeValue=0;
|
||||
codeBits=0;//Stores data2 on Samsung36. Stores number of bits on another protocols
|
||||
Serial.begin(9600);
|
||||
delay(2000); while(!Serial);
|
||||
Serial.println(F("Send a code from your remote and we will record it."));
|
||||
Serial.println(F("Type any character and press enter. We will send the recorded code."));
|
||||
My_Receiver.enableIRIn(); // Start the receiver
|
||||
}
|
||||
void loop() {
|
||||
if (Serial.available()>0) {
|
||||
unsigned char c=Serial.read();
|
||||
if (c=='p') {//Send a test pattern
|
||||
GotOne= true; codeType=SAMSUNG36; codeValue=0x12345; codeBits=0x6789;
|
||||
}
|
||||
if(GotOne) {
|
||||
My_Sender.send(codeType,codeValue,codeBits);
|
||||
Serial.print(F("Sent "));
|
||||
if (codeType==SAMSUNG36) {
|
||||
Serial.print(F("Samsung36 Value:0x"));
|
||||
Serial.print(codeValue, HEX);
|
||||
Serial.print(F(" Value2:0x"));
|
||||
Serial.println(codeBits, HEX);
|
||||
} else {
|
||||
Serial.print(Pnames(codeType));
|
||||
Serial.print(F(" Value:0x"));
|
||||
Serial.print(codeValue, HEX);
|
||||
Serial.print(F(" Bits:"));
|
||||
Serial.println(codeBits, DEC);
|
||||
};
|
||||
My_Receiver.enableIRIn(); // Re-enable receiver
|
||||
}
|
||||
}
|
||||
else if (My_Receiver.GetResults(&My_Decoder)) {
|
||||
My_Decoder.decode();
|
||||
if(My_Decoder.decode_type == UNKNOWN) {
|
||||
Serial.println(F("Unknown type received. Ignoring."));
|
||||
} else {
|
||||
codeType= My_Decoder.decode_type;
|
||||
codeValue= My_Decoder.value;
|
||||
codeBits= My_Decoder.bits;
|
||||
GotOne=true;
|
||||
}
|
||||
My_Decoder.DumpResults();
|
||||
delay(1000);
|
||||
My_Receiver.resume();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
|
||||
* Version 1.4 March 2014
|
||||
* Copyright 2014 by Chris Young http://cyborg5.com
|
||||
* Based on original example sketch for IRremote library
|
||||
* Version 0.11 September, 2009I know prescription and no
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://www.righto.com/
|
||||
*/
|
||||
/*
|
||||
* This example demonstrates how to extend this library to add a new protocol
|
||||
* without actually modifying or recompiling the libnonstickrary itself. It implements the
|
||||
* Phillips RC-MM also known as Nokia Protocol. Is used by AT&T U-Verse cable boxes.
|
||||
* There are three different varieties that are 12, 24, or 32 bits.
|
||||
* This is a modified version of the IRecord example.
|
||||
* If you would like to make this a permanent part of your library you could copy the class
|
||||
* prototypes to IRLib.h and the code itself to IRLib.cpp. Search for the word "ADDITIONAL"
|
||||
* to see where to add various pieces of code. Also see the Samsung36 example for details.
|
||||
*/
|
||||
#include <IRLib.h>
|
||||
#include <IRLibMatch.h>
|
||||
|
||||
class IRdecodeRCMM: public virtual IRdecodeBase
|
||||
{
|
||||
public:
|
||||
bool decode(void);
|
||||
};
|
||||
|
||||
class IRsendRCMM: public virtual IRsendBase
|
||||
{
|
||||
public:
|
||||
void send(unsigned long data, unsigned char nbits);
|
||||
};
|
||||
|
||||
#define RCMM (LAST_PROTOCOL+1)
|
||||
#define RCMM_HEAD_MARK 417
|
||||
#define RCMM_DATA_MARK 167
|
||||
#define RCMM_ZERO 278
|
||||
#define RCMM_ONE 444
|
||||
#define RCMM_TWO 611
|
||||
#define RCMM_THREE 778
|
||||
|
||||
/*
|
||||
* According to http://www.hifi-remote.com/johnsfine/DecodeIR.html#Nokia
|
||||
* The IRP notation for these protocols are:
|
||||
* Nokia 12 bit: {36k,msb}<164,-276|164,-445|164,-614|164,-783>(412,-276,D:4,F:8,164,-???)+
|
||||
* Nokia 24-bit: {36k,msb}<164,-276|164,-445|164,-614|164,-783>(412,-276,D:8,S:8,F:8,164,-???)+
|
||||
* Nokia 32 bit: {36k,msb}<164,-276|164,-445|164,-614|164,-783>(412,-276,D:8,S:8,X:8,F:8,164,^100m)+
|
||||
* Slightly different timing values are documented at
|
||||
* http://www.sbprojects.com/knowledge/ir/rcmm.php
|
||||
* We will use the timing from the latter reference.
|
||||
* Unlike most protocols which defined sequences for a logical "0" and "1", this protocol
|
||||
* encodes 2 bits per pulse. Therefore it encodes a logical "2" and "3" as well.
|
||||
* The length of the mark is constant but the length of the space denotes the bit values.
|
||||
* Note the 32-bit version uses a toggle bit of 0x8000 and as usual it is up to the end-user
|
||||
* to implement it outside the library routines.
|
||||
*/
|
||||
/*
|
||||
* Normally IRLib uses a plus or minus percentage to determine if an interval matches the
|
||||
* desired value. However this protocol uses extremely long intervals of similar length.
|
||||
* For example using the default 25% tolerance the RCMM_TWO value 611 would be accepted for
|
||||
* anything between 458 and 763. The low end is actually closer to RCMM_ONE value of 444
|
||||
* and the upper range is closer to RCM_THREE value of 778. To implement this protocol
|
||||
* we created a new match routine ABS_MATCH which allows you to specify an absolute
|
||||
* number of microseconds of tolerance for comparison.
|
||||
*/
|
||||
#define RCMM_TOLERANCE 80
|
||||
bool IRdecodeRCMM::decode(void) {
|
||||
long data;
|
||||
IRLIB_ATTEMPT_MESSAGE(F("RCMM"));
|
||||
if ( (rawlen!=(12+2)) && (rawlen!=(24+2)) && (rawlen!=(32+4)) ) return RAW_COUNT_ERROR;
|
||||
if (!MATCH(rawbuf[1],RCMM_HEAD_MARK)) return HEADER_MARK_ERROR(RCMM_HEAD_MARK);
|
||||
if (!MATCH(rawbuf[2],RCMM_ZERO)) return HEADER_SPACE_ERROR(RCMM_ZERO);
|
||||
offset=3; data=0;
|
||||
while (offset < (rawlen-1)) {
|
||||
if (!ABS_MATCH(rawbuf[offset],RCMM_DATA_MARK, RCMM_TOLERANCE+50)) return DATA_MARK_ERROR(RCMM_DATA_MARK);
|
||||
offset++;
|
||||
if (ABS_MATCH(rawbuf[offset],RCMM_ZERO, RCMM_TOLERANCE) ) { //Logical "0"
|
||||
data <<= 2;
|
||||
}
|
||||
else if (ABS_MATCH(rawbuf[offset],RCMM_ONE, RCMM_TOLERANCE) ) { //Logical "1"
|
||||
data = (data<<2) + 1;
|
||||
}
|
||||
else if (ABS_MATCH(rawbuf[offset],RCMM_TWO, RCMM_TOLERANCE) ) { //Logical "2"
|
||||
data = (data<<2) + 2;
|
||||
}
|
||||
else if (ABS_MATCH(rawbuf[offset],RCMM_THREE, RCMM_TOLERANCE) ) { //Logical "3"
|
||||
data = (data<<2) + 3;
|
||||
}
|
||||
else return DATA_SPACE_ERROR(RCMM_ZERO);
|
||||
offset++;
|
||||
}
|
||||
if (!MATCH(rawbuf[offset],RCMM_DATA_MARK)) return DATA_MARK_ERROR(RCMM_DATA_MARK);
|
||||
bits = rawlen-4;//set bit length
|
||||
value = data;//put remaining bits in value
|
||||
decode_type= static_cast<IRTYPES>RCMM;
|
||||
return true;
|
||||
};
|
||||
|
||||
void IRsendRCMM::send(unsigned long data, unsigned char nbits) {
|
||||
Extent=0;
|
||||
data = data << (32 - nbits);
|
||||
nbits=nbits/2;
|
||||
enableIROut(36);
|
||||
mark(RCMM_HEAD_MARK); space(RCMM_ZERO);//Send header
|
||||
for (int i = 0; i < nbits; i++) {
|
||||
mark(RCMM_DATA_MARK);
|
||||
switch (data & 0xC0000000UL) {//use the leftmost two bits
|
||||
case 0x00000000UL: space(RCMM_ZERO); break;
|
||||
case 0x40000000UL: space(RCMM_ONE); break;
|
||||
case 0x80000000UL: space(RCMM_TWO); break;
|
||||
case 0xC0000000UL: space(RCMM_THREE); break;
|
||||
default: Serial.println("sending error");
|
||||
}
|
||||
data <<= 2;
|
||||
};
|
||||
mark(RCMM_DATA_MARK);
|
||||
space(27778-Extent);
|
||||
};
|
||||
|
||||
//Create a custom class that combines this new protocol with all the others
|
||||
class MyCustomSend:
|
||||
public virtual IRsend,
|
||||
public virtual IRsendRCMM
|
||||
{
|
||||
public:
|
||||
void send(IRTYPES Type, unsigned long data, int nbits);
|
||||
};
|
||||
void MyCustomSend::send(IRTYPES Type, unsigned long data, int nbits) {
|
||||
if (Type==RCMM)
|
||||
IRsendRCMM::send(data,nbits);
|
||||
else
|
||||
IRsend::send(Type, data, nbits);
|
||||
}
|
||||
class MyCustomDecode:
|
||||
public virtual IRdecode,
|
||||
public virtual IRdecodeRCMM
|
||||
{
|
||||
public:
|
||||
virtual bool decode(void); // Calls each decode routine individually
|
||||
void DumpResults(void);
|
||||
};
|
||||
bool MyCustomDecode::decode(void) {
|
||||
if (IRdecodeRCMM::decode()) return true;
|
||||
return IRdecode::decode ();
|
||||
}
|
||||
void MyCustomDecode::DumpResults(void){
|
||||
if(decode_type==RCMM) {
|
||||
Serial.print(F("Decoded RCMM: Value:")); Serial.print(value, HEX);
|
||||
};
|
||||
IRdecode::DumpResults();
|
||||
};
|
||||
|
||||
MyCustomDecode My_Decoder;
|
||||
|
||||
MyCustomSend My_Sender;
|
||||
|
||||
int RECV_PIN = 11;
|
||||
|
||||
IRrecv My_Receiver(RECV_PIN);
|
||||
IRTYPES codeType; // The type of code
|
||||
unsigned long codeValue; // The data bits
|
||||
int codeBits; // The length of the code in bits or for Samsung is storage for data2
|
||||
bool GotOne;
|
||||
char c;
|
||||
|
||||
void setup()
|
||||
{
|
||||
GotOne=false;
|
||||
codeType=UNKNOWN;
|
||||
codeValue=0;
|
||||
codeBits=0;
|
||||
Serial.begin(9600);while (! Serial) {};
|
||||
Serial.println(F("Send a code from your remote and we will record it."));
|
||||
Serial.println(F("Type any character and press enter. We will send the recorded code."));
|
||||
My_Receiver.enableIRIn(); // Start the receiver
|
||||
My_Receiver.Mark_Excess=40;
|
||||
}
|
||||
void loop() {
|
||||
if (Serial.available()>0) {
|
||||
c=Serial.read();
|
||||
if (c=='p') {//Send a test pattern
|
||||
GotOne= true; codeType=RCMM; codeValue=0x12345678; codeBits= 32;
|
||||
}
|
||||
if(GotOne) {
|
||||
My_Sender.send(codeType,codeValue,codeBits);
|
||||
Serial.print(F("Sent "));
|
||||
if (codeType== RCMM) Serial.print(F("RCMM")); else Serial.print(Pnames(codeType));
|
||||
Serial.print(F(" Value:0x"));
|
||||
Serial.print(codeValue, HEX);
|
||||
Serial.print(F(" Bits:"));
|
||||
Serial.println(codeBits, DEC);
|
||||
My_Receiver.enableIRIn(); // Re-enable receiver
|
||||
}
|
||||
}
|
||||
else if (My_Receiver.GetResults(&My_Decoder)) {
|
||||
My_Decoder.decode();
|
||||
if(My_Decoder.decode_type == UNKNOWN) {
|
||||
Serial.println(F("Unknown type received. Ignoring."));
|
||||
} else {
|
||||
codeType= My_Decoder.decode_type;
|
||||
codeValue= My_Decoder.value;
|
||||
codeBits= My_Decoder.bits;
|
||||
GotOne=true;
|
||||
}
|
||||
My_Decoder.DumpResults();
|
||||
delay(1000);
|
||||
My_Receiver.resume();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user