added example for arduino
This commit is contained in:
370
arduino-example/IRSendRev.cpp
Normal file
370
arduino-example/IRSendRev.cpp
Normal file
@@ -0,0 +1,370 @@
|
|||||||
|
/*
|
||||||
|
* IRremote
|
||||||
|
* Version 0.11 August, 2009
|
||||||
|
* Copyright 2009 Ken Shirriff
|
||||||
|
* For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
|
||||||
|
*
|
||||||
|
* Modified by Paul Stoffregen <paul@pjrc.com> to support other boards and timers
|
||||||
|
* Modified by Mitra Ardron <mitra@mitra.biz>
|
||||||
|
* Added Sanyo and Mitsubishi controllers
|
||||||
|
* Modified Sony to spot the repeat codes that some Sony's send
|
||||||
|
*
|
||||||
|
* Modifier by
|
||||||
|
* 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 "IRSendrev.h"
|
||||||
|
#include "IRsendRevInt.h"
|
||||||
|
|
||||||
|
// Provides ISR
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
|
volatile irparams_t irparams;
|
||||||
|
|
||||||
|
void IRSendRev::sendRaw(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
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRSendRev::mark(int time) {
|
||||||
|
// Sends an IR mark for the specified number of microseconds.
|
||||||
|
// The mark output is modulated at the PWM frequency.
|
||||||
|
TIMER_ENABLE_PWM; // Enable pin 3 PWM output
|
||||||
|
delayMicroseconds(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Leave pin off for time (given in microseconds) */
|
||||||
|
void IRSendRev::space(int time) {
|
||||||
|
// Sends an IR space for the specified number of microseconds.
|
||||||
|
// A space is no output, so the PWM output is disabled.
|
||||||
|
TIMER_DISABLE_PWM; // Disable pin 3 PWM output
|
||||||
|
delayMicroseconds(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRSendRev::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);
|
||||||
|
TIMER_ENABLE_PWM;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRSendRev::Init(int revPin)
|
||||||
|
{
|
||||||
|
irparams.recvpin = revPin;
|
||||||
|
|
||||||
|
enableIRIn(); // Start the receiver
|
||||||
|
delay(20);
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRSendRev::Init()
|
||||||
|
{
|
||||||
|
delay(20);
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
// initialization
|
||||||
|
void IRSendRev::enableIRIn() {
|
||||||
|
cli();
|
||||||
|
// setup pulse clock timer interrupt
|
||||||
|
//Prescale /8 (16M/8 = 0.5 microseconds per tick)
|
||||||
|
// Therefore, the timer interval can range from 0.5 to 128 microseconds
|
||||||
|
// depending on the reset value (255 to 0)
|
||||||
|
TIMER_CONFIG_NORMAL();
|
||||||
|
|
||||||
|
//Timer2 Overflow Interrupt Enable
|
||||||
|
TIMER_ENABLE_INTR;
|
||||||
|
|
||||||
|
TIMER_RESET;
|
||||||
|
|
||||||
|
sei(); // enable interrupts
|
||||||
|
|
||||||
|
// initialize state machine variables
|
||||||
|
irparams.rcvstate = STATE_IDLE;
|
||||||
|
irparams.rawlen = 0;
|
||||||
|
|
||||||
|
// set pin modes
|
||||||
|
pinMode(irparams.recvpin, INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
uint8_t irdata = (uint8_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 == 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 == SPACE) { // MARK ended, record time
|
||||||
|
irparams.rawbuf[irparams.rawlen++] = irparams.timer;
|
||||||
|
irparams.timer = 0;
|
||||||
|
irparams.rcvstate = STATE_SPACE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case STATE_SPACE: // timing SPACE
|
||||||
|
if (irdata == MARK) { // SPACE just ended, record 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 == MARK) { // reset gap timer
|
||||||
|
irparams.timer = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRSendRev::Clear() {
|
||||||
|
irparams.rcvstate = STATE_IDLE;
|
||||||
|
irparams.rawlen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decodes the received IR message
|
||||||
|
// Returns 0 if no data ready, 1 if data ready.
|
||||||
|
// Results of decoding are stored in results
|
||||||
|
int IRSendRev::decode(decode_results *results) {
|
||||||
|
results->rawbuf = irparams.rawbuf;
|
||||||
|
results->rawlen = irparams.rawlen;
|
||||||
|
if (irparams.rcvstate != STATE_STOP) {
|
||||||
|
return ERR;
|
||||||
|
}
|
||||||
|
// Throw away and start over
|
||||||
|
Clear();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char IRSendRev::Recv(unsigned char *revData)
|
||||||
|
{
|
||||||
|
int count = results.rawlen;
|
||||||
|
int nshort = 0;
|
||||||
|
int nlong = 0;
|
||||||
|
int count_data = 0;
|
||||||
|
|
||||||
|
count_data = (count-4)/16;
|
||||||
|
|
||||||
|
for(int i = 0; i<10; i++) // count nshort
|
||||||
|
{
|
||||||
|
nshort += results.rawbuf[3+2*i];
|
||||||
|
}
|
||||||
|
nshort /= 10;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
while(1) // count nlong
|
||||||
|
{
|
||||||
|
if(results.rawbuf[4+2*i] > (2*nshort))
|
||||||
|
{
|
||||||
|
nlong += results.rawbuf[4+2*i];
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
if(j==10)break;
|
||||||
|
if((4+2*i)>(count-10))break;
|
||||||
|
}
|
||||||
|
nlong /= j;
|
||||||
|
|
||||||
|
int doubleshort = 2*nshort;
|
||||||
|
for(i = 0; i<count_data; i++)
|
||||||
|
{
|
||||||
|
revData[i+D_DATA] = 0x00;
|
||||||
|
for(j = 0; j<8; j++)
|
||||||
|
{
|
||||||
|
if(results.rawbuf[4 + 16*i + j*2] > doubleshort) // 1
|
||||||
|
{
|
||||||
|
revData[i+D_DATA] |= 0x01<< (7-j);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
revData[i+D_DATA] &= ~(0x01<<(7-j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
revData[D_LEN] = count_data+5;
|
||||||
|
revData[D_STARTH] = results.rawbuf[1];
|
||||||
|
revData[D_STARTL] = results.rawbuf[2];
|
||||||
|
revData[D_SHORT] = nshort;
|
||||||
|
revData[D_LONG] = nlong;
|
||||||
|
revData[D_DATALEN] = count_data;
|
||||||
|
|
||||||
|
#if __DEBUG
|
||||||
|
Serial.print("\r\n*************************************************************\r\n");
|
||||||
|
Serial.print("len\t = ");Serial.println(revData[D_LEN]);
|
||||||
|
Serial.print("start_h\t = ");Serial.println(revData[D_STARTH]);
|
||||||
|
Serial.print("start_l\t = ");Serial.println(revData[D_STARTL]);
|
||||||
|
Serial.print("short\t = ");Serial.println(revData[D_SHORT]);
|
||||||
|
Serial.print("long\t = ");Serial.println(revData[D_LONG]);
|
||||||
|
Serial.print("data_len = ");Serial.println(revData[D_DATALEN]);
|
||||||
|
for(int i = 0; i<revData[D_DATALEN]; i++)
|
||||||
|
{
|
||||||
|
Serial.print(revData[D_DATA+i]);Serial.print("\t");
|
||||||
|
}
|
||||||
|
Serial.print("\r\n*************************************************************\r\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Clear(); // Receive the next value
|
||||||
|
return revData[D_LEN]+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if get some data from IR
|
||||||
|
unsigned char IRSendRev::IsDta()
|
||||||
|
{
|
||||||
|
|
||||||
|
if(decode(&results))
|
||||||
|
{
|
||||||
|
int count = results.rawlen;
|
||||||
|
if(count < 64 || (count -4)%8 != 0)
|
||||||
|
{
|
||||||
|
#if __DEBUG
|
||||||
|
Serial.print("IR GET BAD DATA!\r\n");
|
||||||
|
#endif
|
||||||
|
Clear(); // Receive the next value
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int count_data = (count-4) / 16;
|
||||||
|
#if __DEBUG
|
||||||
|
Serial.print("ir get data! count_data = ");
|
||||||
|
Serial.println(count_data);
|
||||||
|
#endif
|
||||||
|
return (unsigned char)(count_data+6);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRSendRev::Send(unsigned char *idata, unsigned char ifreq)
|
||||||
|
{
|
||||||
|
int len = idata[0];
|
||||||
|
unsigned char start_high = idata[1];
|
||||||
|
unsigned char start_low = idata[2];
|
||||||
|
unsigned char nshort = idata[3];
|
||||||
|
unsigned char nlong = idata[4];
|
||||||
|
unsigned char datalen = idata[5];
|
||||||
|
|
||||||
|
unsigned int *pSt = (unsigned int *)malloc((4+datalen*16)*sizeof(unsigned int));
|
||||||
|
|
||||||
|
if(NULL == pSt)
|
||||||
|
{
|
||||||
|
#if __DEBUG
|
||||||
|
Serial.println("not enough place!!\r\n");
|
||||||
|
#endif
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __DEBUG
|
||||||
|
Serial.println("begin to send ir:\r\n");
|
||||||
|
Serial.print("ifreq = ");Serial.println(ifreq);
|
||||||
|
Serial.print("len = ");Serial.println(len);
|
||||||
|
Serial.print("start_high = ");Serial.println(start_high);
|
||||||
|
Serial.print("start_low = ");Serial.println(start_low);
|
||||||
|
Serial.print("nshort = ");Serial.println(nshort);
|
||||||
|
Serial.print("nlong = ");Serial.println(nlong);
|
||||||
|
Serial.print("datalen = ");Serial.println(datalen);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pSt[0] = start_high*50;
|
||||||
|
pSt[1] = start_low*50;
|
||||||
|
|
||||||
|
for(int i = 0; i<datalen; i++)
|
||||||
|
{
|
||||||
|
for(int j = 0; j<8; j++)
|
||||||
|
{
|
||||||
|
if(idata[6+i] & 0x01<<(7-j))
|
||||||
|
{
|
||||||
|
pSt[16*i + 2*j + 2] = nshort*50;
|
||||||
|
pSt[16*i + 2*j+3] = nlong*50;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pSt[16*i + 2*j+2] = nshort*50;
|
||||||
|
pSt[16*i + 2*j+3] = nshort*50;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pSt[2+datalen*16] = nshort*50;
|
||||||
|
pSt[2+datalen*16+1] = nshort*50;
|
||||||
|
|
||||||
|
#if __DEBUG
|
||||||
|
for(int i = 0; i<4+datalen*16; i++)
|
||||||
|
{
|
||||||
|
Serial.print(pSt[i]);Serial.print("\t");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
#endif
|
||||||
|
sendRaw(pSt, 4+datalen*16, ifreq);
|
||||||
|
free(pSt);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
IRSendRev IR;
|
||||||
87
arduino-example/IRSendRev.h
Normal file
87
arduino-example/IRSendRev.h
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* IRremote
|
||||||
|
* Version 0.11 August, 2009
|
||||||
|
* Copyright 2009 Ken Shirriff
|
||||||
|
* For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
|
||||||
|
*
|
||||||
|
* Modified by Paul Stoffregen <paul@pjrc.com> to support other boards and timers
|
||||||
|
* Modified by Mitra Ardron <mitra@mitra.biz>
|
||||||
|
* Added Sanyo and Mitsubishi controllers
|
||||||
|
* Modified Sony to spot the repeat codes that some Sony's send
|
||||||
|
*
|
||||||
|
* Modifier by
|
||||||
|
* 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 _IRSENDREV_H_
|
||||||
|
#define _IRSENDREV_H_
|
||||||
|
|
||||||
|
// len, start_H, start_L, nshort, nlong, data_len, data[data_len]....
|
||||||
|
#define D_LEN 0
|
||||||
|
#define D_STARTH 1
|
||||||
|
#define D_STARTL 2
|
||||||
|
#define D_SHORT 3
|
||||||
|
#define D_LONG 4
|
||||||
|
#define D_DATALEN 5
|
||||||
|
#define D_DATA 6
|
||||||
|
|
||||||
|
|
||||||
|
#define USECPERTICK 50 // microseconds per clock interrupt tick
|
||||||
|
#define RAWBUF 300 // Length of raw duration buffer
|
||||||
|
|
||||||
|
// Marks tend to be 100us too long, and spaces 100us too short
|
||||||
|
// when received due to sensor lag.
|
||||||
|
#define MARK_EXCESS 100
|
||||||
|
|
||||||
|
#define __DEBUG 0
|
||||||
|
|
||||||
|
// Results returned from the decoder
|
||||||
|
class decode_results {
|
||||||
|
|
||||||
|
public:
|
||||||
|
volatile unsigned int *rawbuf; // Raw intervals in .5 us ticks
|
||||||
|
int rawlen; // Number of records in rawbuf.
|
||||||
|
};
|
||||||
|
|
||||||
|
// main class for receiving IR
|
||||||
|
class IRSendRev
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
decode_results results;
|
||||||
|
//**************************rev**********************************
|
||||||
|
|
||||||
|
private:
|
||||||
|
int decode(decode_results *results);
|
||||||
|
void enableIRIn();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void Init(int revPin); // init
|
||||||
|
void Init();
|
||||||
|
unsigned char Recv(unsigned char *revData); //
|
||||||
|
unsigned char IsDta(); // if IR get data
|
||||||
|
void Clear(); // clear IR data
|
||||||
|
|
||||||
|
//**************************send*********************************
|
||||||
|
private:
|
||||||
|
|
||||||
|
void sendRaw(unsigned int buf[], int len, int hz);
|
||||||
|
|
||||||
|
// private:
|
||||||
|
|
||||||
|
void mark(int usec);
|
||||||
|
void space(int usec);
|
||||||
|
void enableIROut(int khz);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void Send(unsigned char *idata, unsigned char ifreq);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
extern IRSendRev IR;
|
||||||
|
|
||||||
|
#endif
|
||||||
341
arduino-example/IRSendRevInt.h
Normal file
341
arduino-example/IRSendRevInt.h
Normal file
@@ -0,0 +1,341 @@
|
|||||||
|
/*
|
||||||
|
* IRremote
|
||||||
|
* Version 0.1 July, 2009
|
||||||
|
* Copyright 2009 Ken Shirriff
|
||||||
|
* For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
|
||||||
|
*
|
||||||
|
* Modified by Paul Stoffregen <paul@pjrc.com> to support other boards and timers
|
||||||
|
*
|
||||||
|
* Interrupt code based on NECIRrcv by Joe Knapp
|
||||||
|
* http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
|
||||||
|
* Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
|
||||||
|
*
|
||||||
|
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _IRSENDREVINT_H_
|
||||||
|
#define _IRSENDREVINT_H_
|
||||||
|
|
||||||
|
#if defined(ARDUINO) && ARDUINO >= 100
|
||||||
|
#include <Arduino.h>
|
||||||
|
#else
|
||||||
|
#include <WProgram.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// define which timer to use
|
||||||
|
//
|
||||||
|
// Uncomment the timer you wish to use on your board. If you
|
||||||
|
// are using another library which uses timer2, you have options
|
||||||
|
// to switch IRremote to use a different timer.
|
||||||
|
|
||||||
|
// Arduino Mega
|
||||||
|
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||||
|
//#define IR_USE_TIMER1 // tx = pin 11
|
||||||
|
#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
|
||||||
|
#elif defined(__AVR_ATmega32U4__)
|
||||||
|
//#define IR_USE_TIMER1 // tx = pin 14
|
||||||
|
//#define IR_USE_TIMER3 // tx = pin 9
|
||||||
|
#define IR_USE_TIMER4_HS // tx = pin 10
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// Atmega8
|
||||||
|
#elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__)
|
||||||
|
#define IR_USE_TIMER1 // tx = pin 9
|
||||||
|
|
||||||
|
// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, etc
|
||||||
|
#else
|
||||||
|
//#define IR_USE_TIMER1 // tx = pin 9
|
||||||
|
#define IR_USE_TIMER2 // tx = pin 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef F_CPU
|
||||||
|
#define SYSCLOCK F_CPU // main Arduino clock
|
||||||
|
#else
|
||||||
|
#define SYSCLOCK 16000000 // main Arduino clock
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ERR 0
|
||||||
|
#define DECODED 1
|
||||||
|
|
||||||
|
|
||||||
|
// defines for setting and clearing register bits
|
||||||
|
#ifndef cbi
|
||||||
|
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
|
||||||
|
#endif
|
||||||
|
#ifndef sbi
|
||||||
|
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define TOLERANCE 25 // percent tolerance in measurements
|
||||||
|
#define LTOL (1.0 - TOLERANCE/100.)
|
||||||
|
#define UTOL (1.0 + TOLERANCE/100.)
|
||||||
|
|
||||||
|
#define _GAP 5000 // Minimum map between transmissions
|
||||||
|
#define GAP_TICKS (_GAP/USECPERTICK)
|
||||||
|
|
||||||
|
#define TICKS_LOW(us) (int) (((us)*LTOL/USECPERTICK))
|
||||||
|
#define TICKS_HIGH(us) (int) (((us)*UTOL/USECPERTICK + 1))
|
||||||
|
|
||||||
|
|
||||||
|
// receiver states
|
||||||
|
#define STATE_IDLE 2
|
||||||
|
#define STATE_MARK 3
|
||||||
|
#define STATE_SPACE 4
|
||||||
|
#define STATE_STOP 5
|
||||||
|
|
||||||
|
// information for the interrupt handler
|
||||||
|
typedef struct {
|
||||||
|
uint8_t recvpin; // pin for IR data from detector
|
||||||
|
uint8_t rcvstate; // state machine
|
||||||
|
unsigned int timer; // state timer, counts 50uS ticks.
|
||||||
|
unsigned int rawbuf[RAWBUF]; // raw data
|
||||||
|
uint8_t rawlen; // counter of entries in rawbuf
|
||||||
|
} irparams_t;
|
||||||
|
|
||||||
|
// Defined in IRremote.cpp
|
||||||
|
extern volatile irparams_t irparams;
|
||||||
|
|
||||||
|
// IR detector output is active low
|
||||||
|
#define MARK 0
|
||||||
|
#define SPACE 1
|
||||||
|
|
||||||
|
#define TOPBIT 0x80000000
|
||||||
|
|
||||||
|
// defines for timer2 (8 bits)
|
||||||
|
#if defined(IR_USE_TIMER2)
|
||||||
|
#define TIMER_RESET
|
||||||
|
#define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1))
|
||||||
|
#define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1)))
|
||||||
|
#define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A))
|
||||||
|
#define TIMER_DISABLE_INTR (TIMSK2 = 0)
|
||||||
|
#define TIMER_INTR_NAME TIMER2_COMPA_vect
|
||||||
|
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||||
|
const uint8_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||||
|
TCCR2A = _BV(WGM20); \
|
||||||
|
TCCR2B = _BV(WGM22) | _BV(CS20); \
|
||||||
|
OCR2A = pwmval; \
|
||||||
|
OCR2B = pwmval / (100/10); \
|
||||||
|
})
|
||||||
|
#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, Diecimi */
|
||||||
|
/* la, 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)))
|
||||||
|
#if defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__)
|
||||||
|
#define TIMER_ENABLE_INTR (TIMSK = _BV(OCIE1A))
|
||||||
|
#define TIMER_DISABLE_INTR (TIMSK = 0)
|
||||||
|
#else
|
||||||
|
#define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A))
|
||||||
|
#define TIMER_DISABLE_INTR (TIMSK1 = 0)
|
||||||
|
#endif
|
||||||
|
#define TIMER_INTR_NAME TIMER1_COMPA_vect
|
||||||
|
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||||
|
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||||
|
TCCR1A = _BV(WGM11); \
|
||||||
|
TCCR1B = _BV(WGM13) | _BV(CS10); \
|
||||||
|
ICR1 = pwmval; \
|
||||||
|
OCR1A = pwmval / 3; \
|
||||||
|
})
|
||||||
|
#define TIMER_CONFIG_NORMAL() ({ \
|
||||||
|
TCCR1A = 0; \
|
||||||
|
TCCR1B = _BV(WGM12) | _BV(CS10); \
|
||||||
|
OCR1A = SYSCLOCK * USECPERTICK / 1000000; \
|
||||||
|
TCNT1 = 0; \
|
||||||
|
})
|
||||||
|
#if defined(CORE_OC1A_PIN)
|
||||||
|
#define TIMER_PWM_PIN CORE_OC1A_PIN /* Teensy */
|
||||||
|
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||||
|
#define TIMER_PWM_PIN 11 /* Arduino Mega */
|
||||||
|
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||||
|
#define TIMER_PWM_PIN 13 /* Sanguino */
|
||||||
|
#else
|
||||||
|
#define TIMER_PWM_PIN 9 /* Arduino Duemilanove, Diecimi */
|
||||||
|
/* la, 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 */
|
||||||
|
#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 */
|
||||||
|
#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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
34
arduino-example/examples/revTest/revTest.ino
Normal file
34
arduino-example/examples/revTest/revTest.ino
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
//**************
|
||||||
|
//IR receive demo v1.0
|
||||||
|
//******************************
|
||||||
|
#include <IRSendRev.h>
|
||||||
|
//#include <IRSendRevInt.h>
|
||||||
|
#define IR_OUT_PIN 2//The OUT pin of the Infrared Receiver is connected to D2 of Arduino/Catduino
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(38400);
|
||||||
|
IR.Init(IR_OUT_PIN);
|
||||||
|
Serial.println("init over");
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char dta[20];
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
if(IR.IsDta())
|
||||||
|
{
|
||||||
|
// IR.Recv(dta);
|
||||||
|
int length= IR.Recv(dta);
|
||||||
|
for (int i =0;i<length;i++)
|
||||||
|
{
|
||||||
|
Serial.print(dta[i]);
|
||||||
|
Serial.print("\t");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
// Very Important:
|
||||||
|
// the received data is comprised of the trsmission parameters , please refer to
|
||||||
|
// the sendTest.ino in the library ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
24
arduino-example/examples/sendTest/sendTest.ino
Normal file
24
arduino-example/examples/sendTest/sendTest.ino
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
//**************
|
||||||
|
//IR sent demo v1.0
|
||||||
|
//******************************
|
||||||
|
#include <IRSendRev.h>
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
//enableIROut(38);
|
||||||
|
}
|
||||||
|
//unsigned char d[] = {9, 90, 91, 11, 31, 4, 1, 2, 3, 4};
|
||||||
|
unsigned char d[] = {15, 70, 70, 20, 60, 10, 1, 2, 3, 4,5,6,7,8,9,10};
|
||||||
|
//Very Important:
|
||||||
|
//the first parameter(15): the length of data that needs to be sent;15 = 15Bytes
|
||||||
|
//the next 2 parameter(70,70): the logic high and low duration of "Start";
|
||||||
|
//the next 2 parameter(20,60): the logic "short" and "long"duration in the communication
|
||||||
|
// that to say: if "0", the high duration is 20ms and low is 20 ms; while logic "1",
|
||||||
|
// the high duration is 20 ms and low is 60 ms;
|
||||||
|
//the next 2 parameter(10): number of data you will sent;
|
||||||
|
//the next parameter(1, 2, 3, 4,5,6,7,8,9,10): data you will sent ;
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
IR.Send(d, 38);//sent the data via 38Kz IR
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
29
arduino-example/keywords.txt
Normal file
29
arduino-example/keywords.txt
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#######################################
|
||||||
|
# IRSendRev
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Datatypes (KEYWORD1)
|
||||||
|
#######################################
|
||||||
|
IRSendRev KEYWORD1
|
||||||
|
IRSendRevInt KEYWORD1
|
||||||
|
IR KEYWORD1
|
||||||
|
#######################################
|
||||||
|
# Methods and Functions (KEYWORD2)
|
||||||
|
#######################################
|
||||||
|
Init KEYWORD2
|
||||||
|
Recv KEYWORD2
|
||||||
|
IsDta KEYWORD2
|
||||||
|
Clear KEYWORD2
|
||||||
|
Send KEYWORD2
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Constants (LITERAL1)
|
||||||
|
#######################################
|
||||||
|
D_LEN LITERAL1
|
||||||
|
D_STARTH LITERAL1
|
||||||
|
D_STARTL LITERAL1
|
||||||
|
D_SHORT LITERAL1
|
||||||
|
D_LONG LITERAL1
|
||||||
|
D_DATALEN LITERAL1
|
||||||
|
D_DATA LITERAL1
|
||||||
Reference in New Issue
Block a user