Hallo
This commit is contained in:
		
							
								
								
									
										198
									
								
								IRremote/IRremote.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								IRremote/IRremote.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,198 @@
 | 
				
			|||||||
 | 
					//******************************************************************************
 | 
				
			||||||
 | 
					// IRremote
 | 
				
			||||||
 | 
					// Version 2.0.1 June, 2015
 | 
				
			||||||
 | 
					// 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
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 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)
 | 
				
			||||||
 | 
					// LG added by Darryl Smith (based on the JVC protocol)
 | 
				
			||||||
 | 
					// Whynter A/C ARC-110WD added by Francesco Meschia
 | 
				
			||||||
 | 
					//******************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Defining IR_GLOBAL here allows us to declare the instantiation of global variables
 | 
				
			||||||
 | 
					#define IR_GLOBAL
 | 
				
			||||||
 | 
					#	include "IRremote.h"
 | 
				
			||||||
 | 
					#	include "IRremoteInt.h"
 | 
				
			||||||
 | 
					#undef IR_GLOBAL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAS_AVR_INTERRUPT_H
 | 
				
			||||||
 | 
					#include <avr/interrupt.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// The match functions were (apparently) originally MACROs to improve code speed
 | 
				
			||||||
 | 
					//   (although this would have bloated the code) hence the names being CAPS
 | 
				
			||||||
 | 
					// A later release implemented debug output and so they needed to be converted
 | 
				
			||||||
 | 
					//   to functions.
 | 
				
			||||||
 | 
					// I tried to implement a dual-compile mode (DEBUG/non-DEBUG) but for some
 | 
				
			||||||
 | 
					//   reason, no matter what I did I could not get them to function as macros again.
 | 
				
			||||||
 | 
					// I have found a *lot* of bugs in the Arduino compiler over the last few weeks,
 | 
				
			||||||
 | 
					//   and I am currently assuming that one of these bugs is my problem.
 | 
				
			||||||
 | 
					// I may revisit this code at a later date and look at the assembler produced
 | 
				
			||||||
 | 
					//   in a hope of finding out what is going on, but for now they will remain as
 | 
				
			||||||
 | 
					//   functions even in non-DEBUG mode
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					int  MATCH (int measured,  int desired)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					 	DBG_PRINT(F("Testing: "));
 | 
				
			||||||
 | 
					 	DBG_PRINT(TICKS_LOW(desired), DEC);
 | 
				
			||||||
 | 
					 	DBG_PRINT(F(" <= "));
 | 
				
			||||||
 | 
					 	DBG_PRINT(measured, DEC);
 | 
				
			||||||
 | 
					 	DBG_PRINT(F(" <= "));
 | 
				
			||||||
 | 
					 	DBG_PRINT(TICKS_HIGH(desired), DEC);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool passed = ((measured >= TICKS_LOW(desired)) && (measured <= TICKS_HIGH(desired)));
 | 
				
			||||||
 | 
					  if (passed)
 | 
				
			||||||
 | 
					    DBG_PRINTLN(F("?; passed"));
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    DBG_PRINTLN(F("?; FAILED")); 
 | 
				
			||||||
 | 
					 	return passed;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+========================================================
 | 
				
			||||||
 | 
					// Due to sensor lag, when received, Marks tend to be 100us too long
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					int  MATCH_MARK (int measured_ticks,  int desired_us)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						DBG_PRINT(F("Testing mark (actual vs desired): "));
 | 
				
			||||||
 | 
						DBG_PRINT(measured_ticks * USECPERTICK, DEC);
 | 
				
			||||||
 | 
						DBG_PRINT(F("us vs "));
 | 
				
			||||||
 | 
						DBG_PRINT(desired_us, DEC);
 | 
				
			||||||
 | 
						DBG_PRINT("us"); 
 | 
				
			||||||
 | 
						DBG_PRINT(": ");
 | 
				
			||||||
 | 
						DBG_PRINT(TICKS_LOW(desired_us + MARK_EXCESS) * USECPERTICK, DEC);
 | 
				
			||||||
 | 
						DBG_PRINT(F(" <= "));
 | 
				
			||||||
 | 
						DBG_PRINT(measured_ticks * USECPERTICK, DEC);
 | 
				
			||||||
 | 
						DBG_PRINT(F(" <= "));
 | 
				
			||||||
 | 
						DBG_PRINT(TICKS_HIGH(desired_us + MARK_EXCESS) * USECPERTICK, DEC);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool passed = ((measured_ticks >= TICKS_LOW (desired_us + MARK_EXCESS))
 | 
				
			||||||
 | 
					                && (measured_ticks <= TICKS_HIGH(desired_us + MARK_EXCESS)));
 | 
				
			||||||
 | 
					  if (passed)
 | 
				
			||||||
 | 
					    DBG_PRINTLN(F("?; passed"));
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    DBG_PRINTLN(F("?; FAILED")); 
 | 
				
			||||||
 | 
					 	return passed;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+========================================================
 | 
				
			||||||
 | 
					// Due to sensor lag, when received, Spaces tend to be 100us too short
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					int  MATCH_SPACE (int measured_ticks,  int desired_us)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						DBG_PRINT(F("Testing space (actual vs desired): "));
 | 
				
			||||||
 | 
						DBG_PRINT(measured_ticks * USECPERTICK, DEC);
 | 
				
			||||||
 | 
						DBG_PRINT(F("us vs "));
 | 
				
			||||||
 | 
						DBG_PRINT(desired_us, DEC);
 | 
				
			||||||
 | 
						DBG_PRINT("us"); 
 | 
				
			||||||
 | 
						DBG_PRINT(": ");
 | 
				
			||||||
 | 
						DBG_PRINT(TICKS_LOW(desired_us - MARK_EXCESS) * USECPERTICK, DEC);
 | 
				
			||||||
 | 
						DBG_PRINT(F(" <= "));
 | 
				
			||||||
 | 
						DBG_PRINT(measured_ticks * USECPERTICK, DEC);
 | 
				
			||||||
 | 
						DBG_PRINT(F(" <= "));
 | 
				
			||||||
 | 
						DBG_PRINT(TICKS_HIGH(desired_us - MARK_EXCESS) * USECPERTICK, DEC);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool passed = ((measured_ticks >= TICKS_LOW (desired_us - MARK_EXCESS))
 | 
				
			||||||
 | 
					                && (measured_ticks <= TICKS_HIGH(desired_us - MARK_EXCESS)));
 | 
				
			||||||
 | 
					  if (passed)
 | 
				
			||||||
 | 
					    DBG_PRINTLN(F("?; passed"));
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    DBG_PRINTLN(F("?; FAILED")); 
 | 
				
			||||||
 | 
					 	return passed;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// Interrupt Service Routine - Fires every 50uS
 | 
				
			||||||
 | 
					// TIMER2 interrupt code to collect raw data.
 | 
				
			||||||
 | 
					// Widths of alternating SPACE, MARK are recorded in rawbuf.
 | 
				
			||||||
 | 
					// Recorded in ticks of 50uS [microseconds, 0.000050 seconds]
 | 
				
			||||||
 | 
					// 'rawlen' counts the number of entries recorded so far.
 | 
				
			||||||
 | 
					// First entry is the SPACE between transmissions.
 | 
				
			||||||
 | 
					// As soon as a the first [SPACE] entry 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; New logging starts
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					ISR (TIMER_INTR_NAME)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						TIMER_RESET;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Read if IR Receiver -> SPACE [xmt LED off] or a MARK [xmt LED on]
 | 
				
			||||||
 | 
						// digitalRead() is very slow. Optimisation is possible, but makes the code unportable
 | 
				
			||||||
 | 
						uint8_t  irdata = (uint8_t)digitalRead(irparams.recvpin);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						irparams.timer++;  // One more 50uS tick
 | 
				
			||||||
 | 
						if (irparams.rawlen >= RAWBUF)  irparams.rcvstate = STATE_OVERFLOW ;  // Buffer overflow
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						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; Start recording transmission
 | 
				
			||||||
 | 
										irparams.overflow                  = false;
 | 
				
			||||||
 | 
										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 time
 | 
				
			||||||
 | 
									irparams.rawbuf[irparams.rawlen++] = irparams.timer;
 | 
				
			||||||
 | 
									irparams.timer                     = 0;
 | 
				
			||||||
 | 
									irparams.rcvstate                  = STATE_MARK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								} else if (irparams.timer > GAP_TICKS) {  // Space
 | 
				
			||||||
 | 
										// A long Space, indicates gap between codes
 | 
				
			||||||
 | 
										// Flag the 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)  irparams.timer = 0 ;  // Reset gap timer
 | 
				
			||||||
 | 
							 	break;
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
							case STATE_OVERFLOW:  // Flag up a read overflow; Stop the State Machine
 | 
				
			||||||
 | 
								irparams.overflow = true;
 | 
				
			||||||
 | 
								irparams.rcvstate = STATE_STOP;
 | 
				
			||||||
 | 
							 	break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef BLINKLED
 | 
				
			||||||
 | 
						// If requested, flash LED while receiving IR data
 | 
				
			||||||
 | 
						if (irparams.blinkflag) {
 | 
				
			||||||
 | 
							if (irdata == MARK)
 | 
				
			||||||
 | 
								if (irparams.blinkpin) digitalWrite(irparams.blinkpin, HIGH); // Turn user defined pin LED on
 | 
				
			||||||
 | 
									else BLINKLED_ON() ;   // if no user defined LED pin, turn default LED pin for the hardware on
 | 
				
			||||||
 | 
							else if (irparams.blinkpin) digitalWrite(irparams.blinkpin, LOW); // Turn user defined pin LED on
 | 
				
			||||||
 | 
									else BLINKLED_OFF() ;   // if no user defined LED pin, turn default LED pin for the hardware on
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif // BLINKLED
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										371
									
								
								IRremote/IRremote.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										371
									
								
								IRremote/IRremote.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,371 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					//******************************************************************************
 | 
				
			||||||
 | 
					// IRremote
 | 
				
			||||||
 | 
					// Version 2.0.1 June, 2015
 | 
				
			||||||
 | 
					// Copyright 2009 Ken Shirriff
 | 
				
			||||||
 | 
					// For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
 | 
				
			||||||
 | 
					// Edited by Mitra to add new controller SANYO
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Interrupt code based on NECIRrcv by Joe Knapp
 | 
				
			||||||
 | 
					// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
 | 
				
			||||||
 | 
					// Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
 | 
				
			||||||
 | 
					// LG added by Darryl Smith (based on the JVC protocol)
 | 
				
			||||||
 | 
					// Whynter A/C ARC-110WD added by Francesco Meschia
 | 
				
			||||||
 | 
					//******************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef IRremote_h
 | 
				
			||||||
 | 
					#define IRremote_h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VERSION_IRREMOTE "2.4.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// The ISR header contains several useful macros the user may wish to use
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#include "IRremoteInt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Supported IR protocols
 | 
				
			||||||
 | 
					// Each protocol you include costs memory and, during decode, costs time
 | 
				
			||||||
 | 
					// Disable (set to 0) all the protocols you do not need/want!
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#define DECODE_RC5           1
 | 
				
			||||||
 | 
					#define SEND_RC5             1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DECODE_RC6           1
 | 
				
			||||||
 | 
					#define SEND_RC6             1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DECODE_NEC           1
 | 
				
			||||||
 | 
					#define SEND_NEC             1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DECODE_SONY          1
 | 
				
			||||||
 | 
					#define SEND_SONY            1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DECODE_PANASONIC     1
 | 
				
			||||||
 | 
					#define SEND_PANASONIC       1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DECODE_JVC           1
 | 
				
			||||||
 | 
					#define SEND_JVC             1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DECODE_SAMSUNG       1
 | 
				
			||||||
 | 
					#define SEND_SAMSUNG         1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DECODE_WHYNTER       1
 | 
				
			||||||
 | 
					#define SEND_WHYNTER         1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DECODE_AIWA_RC_T501  1
 | 
				
			||||||
 | 
					#define SEND_AIWA_RC_T501    1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DECODE_LG            1
 | 
				
			||||||
 | 
					#define SEND_LG              1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DECODE_SANYO         1
 | 
				
			||||||
 | 
					#define SEND_SANYO           0 // NOT WRITTEN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DECODE_MITSUBISHI    1
 | 
				
			||||||
 | 
					#define SEND_MITSUBISHI      0 // NOT WRITTEN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DECODE_DISH          0 // NOT WRITTEN
 | 
				
			||||||
 | 
					#define SEND_DISH            1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DECODE_SHARP         0 // NOT WRITTEN
 | 
				
			||||||
 | 
					#define SEND_SHARP           1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DECODE_DENON         1
 | 
				
			||||||
 | 
					#define SEND_DENON           1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DECODE_PRONTO        0 // This function doe not logically make sense
 | 
				
			||||||
 | 
					#define SEND_PRONTO          1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DECODE_LEGO_PF       0 // NOT WRITTEN
 | 
				
			||||||
 | 
					#define SEND_LEGO_PF         1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// When sending a Pronto code we request to send either the "once" code
 | 
				
			||||||
 | 
					//                                                   or the "repeat" code
 | 
				
			||||||
 | 
					// If the code requested does not exist we can request to fallback on the
 | 
				
			||||||
 | 
					// other code (the one we did not explicitly request)
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// I would suggest that "fallback" will be the standard calling method
 | 
				
			||||||
 | 
					// The last paragraph on this page discusses the rationale of this idea:
 | 
				
			||||||
 | 
					//   http://www.remotecentral.com/features/irdisp2.htm
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#define PRONTO_ONCE        false
 | 
				
			||||||
 | 
					#define PRONTO_REPEAT      true
 | 
				
			||||||
 | 
					#define PRONTO_FALLBACK    true
 | 
				
			||||||
 | 
					#define PRONTO_NOFALLBACK  false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// An enumerated list of all supported formats
 | 
				
			||||||
 | 
					// You do NOT need to remove entries from this list when disabling protocols!
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					typedef
 | 
				
			||||||
 | 
						enum {
 | 
				
			||||||
 | 
							UNKNOWN      = -1,
 | 
				
			||||||
 | 
							UNUSED       =  0,
 | 
				
			||||||
 | 
							RC5,
 | 
				
			||||||
 | 
							RC6,
 | 
				
			||||||
 | 
							NEC,
 | 
				
			||||||
 | 
							SONY,
 | 
				
			||||||
 | 
							PANASONIC,
 | 
				
			||||||
 | 
							JVC,
 | 
				
			||||||
 | 
							SAMSUNG,
 | 
				
			||||||
 | 
							WHYNTER,
 | 
				
			||||||
 | 
							AIWA_RC_T501,
 | 
				
			||||||
 | 
							LG,
 | 
				
			||||||
 | 
							SANYO,
 | 
				
			||||||
 | 
							MITSUBISHI,
 | 
				
			||||||
 | 
							DISH,
 | 
				
			||||||
 | 
							SHARP,
 | 
				
			||||||
 | 
							DENON,
 | 
				
			||||||
 | 
							PRONTO,
 | 
				
			||||||
 | 
							LEGO_PF,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					decode_type_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Set DEBUG to 1 for lots of lovely debug output
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#define DEBUG  0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Debug directives
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#if DEBUG
 | 
				
			||||||
 | 
					#	define DBG_PRINT(...)    Serial.print(__VA_ARGS__)
 | 
				
			||||||
 | 
					#	define DBG_PRINTLN(...)  Serial.println(__VA_ARGS__)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#	define DBG_PRINT(...)
 | 
				
			||||||
 | 
					#	define DBG_PRINTLN(...)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Mark & Space matching functions
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					int  MATCH       (int measured, int desired) ;
 | 
				
			||||||
 | 
					int  MATCH_MARK  (int measured_ticks, int desired_us) ;
 | 
				
			||||||
 | 
					int  MATCH_SPACE (int measured_ticks, int desired_us) ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Results returned from the decoder
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					class decode_results
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						public:
 | 
				
			||||||
 | 
							decode_type_t          decode_type;  // UNKNOWN, NEC, SONY, RC5, ...
 | 
				
			||||||
 | 
							unsigned int           address;      // Used by Panasonic & Sharp [16-bits]
 | 
				
			||||||
 | 
							unsigned long          value;        // Decoded value [max 32-bits]
 | 
				
			||||||
 | 
							int                    bits;         // Number of bits in decoded value
 | 
				
			||||||
 | 
							volatile unsigned int  *rawbuf;      // Raw intervals in 50uS ticks
 | 
				
			||||||
 | 
							int                    rawlen;       // Number of records in rawbuf
 | 
				
			||||||
 | 
							int                    overflow;     // true iff IR raw code too long
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Decoded value for NEC when a repeat code is received
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#define REPEAT 0xFFFFFFFF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Main class for receiving IR
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					class IRrecv
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						public:
 | 
				
			||||||
 | 
							IRrecv (int recvpin) ;
 | 
				
			||||||
 | 
							IRrecv (int recvpin, int blinkpin);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							void  blink13    (int blinkflag) ;
 | 
				
			||||||
 | 
							int   decode     (decode_results *results) ;
 | 
				
			||||||
 | 
							void  enableIRIn ( ) ;
 | 
				
			||||||
 | 
							bool  isIdle     ( ) ;
 | 
				
			||||||
 | 
							void  resume     ( ) ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private:
 | 
				
			||||||
 | 
							long  decodeHash (decode_results *results) ;
 | 
				
			||||||
 | 
							int   compare    (unsigned int oldval, unsigned int newval) ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if (DECODE_RC5 || DECODE_RC6)
 | 
				
			||||||
 | 
								// This helper function is shared by RC5 and RC6
 | 
				
			||||||
 | 
								int  getRClevel (decode_results *results,  int *offset,  int *used,  int t1) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
					#		if DECODE_RC5
 | 
				
			||||||
 | 
								bool  decodeRC5        (decode_results *results) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
					#		if DECODE_RC6
 | 
				
			||||||
 | 
								bool  decodeRC6        (decode_results *results) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if DECODE_NEC
 | 
				
			||||||
 | 
								bool  decodeNEC        (decode_results *results) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if DECODE_SONY
 | 
				
			||||||
 | 
								bool  decodeSony       (decode_results *results) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if DECODE_PANASONIC
 | 
				
			||||||
 | 
								bool  decodePanasonic  (decode_results *results) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if DECODE_JVC
 | 
				
			||||||
 | 
								bool  decodeJVC        (decode_results *results) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if DECODE_SAMSUNG
 | 
				
			||||||
 | 
								bool  decodeSAMSUNG    (decode_results *results) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if DECODE_WHYNTER
 | 
				
			||||||
 | 
								bool  decodeWhynter    (decode_results *results) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if DECODE_AIWA_RC_T501
 | 
				
			||||||
 | 
								bool  decodeAiwaRCT501 (decode_results *results) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if DECODE_LG
 | 
				
			||||||
 | 
								bool  decodeLG         (decode_results *results) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if DECODE_SANYO
 | 
				
			||||||
 | 
								bool  decodeSanyo      (decode_results *results) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if DECODE_MITSUBISHI
 | 
				
			||||||
 | 
								bool  decodeMitsubishi (decode_results *results) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if DECODE_DISH
 | 
				
			||||||
 | 
								bool  decodeDish (decode_results *results) ; // NOT WRITTEN
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if DECODE_SHARP
 | 
				
			||||||
 | 
								bool  decodeSharp (decode_results *results) ; // NOT WRITTEN
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if DECODE_DENON
 | 
				
			||||||
 | 
								bool  decodeDenon (decode_results *results) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
					//......................................................................
 | 
				
			||||||
 | 
					#		if DECODE_LEGO_PF
 | 
				
			||||||
 | 
								bool  decodeLegoPowerFunctions (decode_results *results) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
					} ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Main class for sending IR
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					class IRsend
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						public:
 | 
				
			||||||
 | 
					#ifdef USE_SOFT_CARRIER
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							IRsend(int pin = SEND_PIN)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								sendPin = pin;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							IRsend()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							void  custom_delay_usec (unsigned long uSecs);
 | 
				
			||||||
 | 
							void  enableIROut 		(int khz) ;
 | 
				
			||||||
 | 
							void  mark        		(unsigned int usec) ;
 | 
				
			||||||
 | 
							void  space       		(unsigned int usec) ;
 | 
				
			||||||
 | 
							void  sendRaw     		(const unsigned int buf[],  unsigned int len,  unsigned int hz) ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if SEND_RC5
 | 
				
			||||||
 | 
								void  sendRC5        (unsigned long data,  int nbits) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
					#		if SEND_RC6
 | 
				
			||||||
 | 
								void  sendRC6        (unsigned long data,  int nbits) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if SEND_NEC
 | 
				
			||||||
 | 
								void  sendNEC        (unsigned long data,  int nbits) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if SEND_SONY
 | 
				
			||||||
 | 
								void  sendSony       (unsigned long data,  int nbits) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if SEND_PANASONIC
 | 
				
			||||||
 | 
								void  sendPanasonic  (unsigned int address,  unsigned long data) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if SEND_JVC
 | 
				
			||||||
 | 
								// JVC does NOT repeat by sending a separate code (like NEC does).
 | 
				
			||||||
 | 
								// The JVC protocol repeats by skipping the header.
 | 
				
			||||||
 | 
								// To send a JVC repeat signal, send the original code value
 | 
				
			||||||
 | 
								//   and set 'repeat' to true
 | 
				
			||||||
 | 
								void  sendJVC        (unsigned long data,  int nbits,  bool repeat) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if SEND_SAMSUNG
 | 
				
			||||||
 | 
								void  sendSAMSUNG    (unsigned long data,  int nbits) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if SEND_WHYNTER
 | 
				
			||||||
 | 
								void  sendWhynter    (unsigned long data,  int nbits) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if SEND_AIWA_RC_T501
 | 
				
			||||||
 | 
								void  sendAiwaRCT501 (int code) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if SEND_LG
 | 
				
			||||||
 | 
								void  sendLG         (unsigned long data,  int nbits) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if SEND_SANYO
 | 
				
			||||||
 | 
								void  sendSanyo      ( ) ; // NOT WRITTEN
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if SEND_MISUBISHI
 | 
				
			||||||
 | 
								void  sendMitsubishi ( ) ; // NOT WRITTEN
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if SEND_DISH
 | 
				
			||||||
 | 
								void  sendDISH       (unsigned long data,  int nbits) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if SEND_SHARP
 | 
				
			||||||
 | 
								void  sendSharpRaw   (unsigned long data,  int nbits) ;
 | 
				
			||||||
 | 
								void  sendSharp      (unsigned int address,  unsigned int command) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if SEND_DENON
 | 
				
			||||||
 | 
								void  sendDenon      (unsigned long data,  int nbits) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
							//......................................................................
 | 
				
			||||||
 | 
					#		if SEND_PRONTO
 | 
				
			||||||
 | 
								void  sendPronto     (char* code,  bool repeat,  bool fallback) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
					//......................................................................
 | 
				
			||||||
 | 
					#		if SEND_LEGO_PF
 | 
				
			||||||
 | 
								void  sendLegoPowerFunctions (uint16_t data, bool repeat = true) ;
 | 
				
			||||||
 | 
					#		endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef USE_SOFT_CARRIER
 | 
				
			||||||
 | 
						private:
 | 
				
			||||||
 | 
							int sendPin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							unsigned int periodTime;
 | 
				
			||||||
 | 
							unsigned int periodOnTime;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							void sleepMicros(unsigned long us);
 | 
				
			||||||
 | 
							void sleepUntilMicros(unsigned long targetTime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
							const int sendPin = SEND_PIN;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					} ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										113
									
								
								IRremote/IRremoteInt.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								IRremote/IRremoteInt.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,113 @@
 | 
				
			|||||||
 | 
					//******************************************************************************
 | 
				
			||||||
 | 
					// IRremote
 | 
				
			||||||
 | 
					// Version 2.0.1 June, 2015
 | 
				
			||||||
 | 
					// 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)
 | 
				
			||||||
 | 
					// Whynter A/C ARC-110WD added by Francesco Meschia
 | 
				
			||||||
 | 
					//******************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef IRremoteint_h
 | 
				
			||||||
 | 
					#define IRremoteint_h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Include the right Arduino header
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#if defined(ARDUINO) && (ARDUINO >= 100)
 | 
				
			||||||
 | 
					#	include <Arduino.h>
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#	if !defined(IRPRONTO)
 | 
				
			||||||
 | 
					#		include <WProgram.h>
 | 
				
			||||||
 | 
					#	endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// This handles definition and access to global variables
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#ifdef IR_GLOBAL
 | 
				
			||||||
 | 
					#	define EXTERN
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#	define EXTERN extern
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Information for the Interrupt Service Routine
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#define RAWBUF  101  // Maximum length of raw duration buffer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							// The fields are ordered to reduce memory over caused by struct-padding
 | 
				
			||||||
 | 
							uint8_t       rcvstate;        // State Machine state
 | 
				
			||||||
 | 
							uint8_t       recvpin;         // Pin connected to IR data from detector
 | 
				
			||||||
 | 
							uint8_t       blinkpin;
 | 
				
			||||||
 | 
							uint8_t       blinkflag;       // true -> enable blinking of pin on IR processing
 | 
				
			||||||
 | 
							uint8_t       rawlen;          // counter of entries in rawbuf
 | 
				
			||||||
 | 
							unsigned int  timer;           // State timer, counts 50uS ticks.
 | 
				
			||||||
 | 
							unsigned int  rawbuf[RAWBUF];  // raw data
 | 
				
			||||||
 | 
							uint8_t       overflow;        // Raw buffer overflow occurred
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					irparams_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ISR State-Machine : Receiver States
 | 
				
			||||||
 | 
					#define STATE_IDLE      2
 | 
				
			||||||
 | 
					#define STATE_MARK      3
 | 
				
			||||||
 | 
					#define STATE_SPACE     4
 | 
				
			||||||
 | 
					#define STATE_STOP      5
 | 
				
			||||||
 | 
					#define STATE_OVERFLOW  6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Allow all parts of the code access to the ISR data
 | 
				
			||||||
 | 
					// NB. The data can be changed by the ISR at any time, even mid-function
 | 
				
			||||||
 | 
					// Therefore we declare it as "volatile" to stop the compiler/CPU caching it
 | 
				
			||||||
 | 
					EXTERN  volatile irparams_t  irparams;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Defines for setting and clearing register bits
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#ifndef cbi
 | 
				
			||||||
 | 
					#	define cbi(sfr, bit)  (_SFR_BYTE(sfr) &= ~_BV(bit))
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef sbi
 | 
				
			||||||
 | 
					#	define sbi(sfr, bit)  (_SFR_BYTE(sfr) |= _BV(bit))
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Pulse parms are ((X*50)-100) for the Mark and ((X*50)+100) for the Space.
 | 
				
			||||||
 | 
					// First MARK is the one after the long gap
 | 
				
			||||||
 | 
					// Pulse parameters in uSec
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Due to sensor lag, when received, Marks  tend to be 100us too long and
 | 
				
			||||||
 | 
					//                                   Spaces tend to be 100us too short
 | 
				
			||||||
 | 
					#define MARK_EXCESS    100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Upper and Lower percentage tolerances in measurements
 | 
				
			||||||
 | 
					#define TOLERANCE       25
 | 
				
			||||||
 | 
					#define LTOL            (1.0 - (TOLERANCE/100.))
 | 
				
			||||||
 | 
					#define UTOL            (1.0 + (TOLERANCE/100.))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Minimum gap between IR transmissions
 | 
				
			||||||
 | 
					#define _GAP            5000
 | 
				
			||||||
 | 
					#define GAP_TICKS       (_GAP/USECPERTICK)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TICKS_LOW(us)   ((int)(((us)*LTOL/USECPERTICK)))
 | 
				
			||||||
 | 
					#define TICKS_HIGH(us)  ((int)(((us)*UTOL/USECPERTICK + 1)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// IR detector output is active low
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#define MARK   0
 | 
				
			||||||
 | 
					#define SPACE  1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// All board specific stuff has been moved to its own file, included here.
 | 
				
			||||||
 | 
					#include "boarddefs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										653
									
								
								IRremote/boarddefs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										653
									
								
								IRremote/boarddefs.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,653 @@
 | 
				
			|||||||
 | 
					//******************************************************************************
 | 
				
			||||||
 | 
					// IRremote
 | 
				
			||||||
 | 
					// Version 2.0.1 June, 2015
 | 
				
			||||||
 | 
					// Copyright 2009 Ken Shirriff
 | 
				
			||||||
 | 
					// For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This file contains all board specific information. It was previously contained within
 | 
				
			||||||
 | 
					// IRremoteInt.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 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)
 | 
				
			||||||
 | 
					// Whynter A/C ARC-110WD added by Francesco Meschia
 | 
				
			||||||
 | 
					//******************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef boarddefs_h
 | 
				
			||||||
 | 
					#define boarddefs_h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Define some defaults, that some boards may like to override
 | 
				
			||||||
 | 
					// (This is to avoid negative logic, ! DONT_... is just awkward.)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This board has/needs the avr/interrupt.h
 | 
				
			||||||
 | 
					#define HAS_AVR_INTERRUPT_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Define if sending is supported
 | 
				
			||||||
 | 
					#define SENDING_SUPPORTED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// If defined, a standard enableIRIn function will be define.
 | 
				
			||||||
 | 
					// Undefine for boards supplying their own.
 | 
				
			||||||
 | 
					#define USE_DEFAULT_ENABLE_IR_IN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Duty cycle in percent for sent signals. Presently takes effect only with USE_SOFT_CARRIER
 | 
				
			||||||
 | 
					#define DUTY_CYCLE 50
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// If USE_SOFT_CARRIER, this amount (in micro seconds) is subtracted from the
 | 
				
			||||||
 | 
					// on-time of the pulses.
 | 
				
			||||||
 | 
					#define PULSE_CORRECTION 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// digitalWrite is supposed to be slow. If this is an issue, define faster,
 | 
				
			||||||
 | 
					// board-dependent versions of these macros SENDPIN_ON(pin) and SENDPIN_OFF(pin).
 | 
				
			||||||
 | 
					// Portable, possibly slow, default definitions are given at the end of this file.
 | 
				
			||||||
 | 
					// If defining new versions, feel free to ignore the pin argument if it
 | 
				
			||||||
 | 
					// is not configurable on the current board.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Defines for blinking the LED
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CORE_LED0_PIN)
 | 
				
			||||||
 | 
					#	define BLINKLED        CORE_LED0_PIN
 | 
				
			||||||
 | 
					#	define BLINKLED_ON()   (digitalWrite(CORE_LED0_PIN, HIGH))
 | 
				
			||||||
 | 
					#	define BLINKLED_OFF()  (digitalWrite(CORE_LED0_PIN, LOW))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
 | 
				
			||||||
 | 
					#	define BLINKLED        13
 | 
				
			||||||
 | 
					#	define BLINKLED_ON()   (PORTB |= B10000000)
 | 
				
			||||||
 | 
					#	define BLINKLED_OFF()  (PORTB &= B01111111)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
 | 
				
			||||||
 | 
					#	define BLINKLED        0
 | 
				
			||||||
 | 
					#	define BLINKLED_ON()   (PORTD |= B00000001)
 | 
				
			||||||
 | 
					#	define BLINKLED_OFF()  (PORTD &= B11111110)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#elif defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD)
 | 
				
			||||||
 | 
					#	define BLINKLED        LED_BUILTIN
 | 
				
			||||||
 | 
					#	define BLINKLED_ON()   (digitalWrite(LED_BUILTIN, HIGH))
 | 
				
			||||||
 | 
					#	define BLINKLED_OFF()  (digitalWrite(LED_BUILTIN, LOW))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#	define USE_SOFT_CARRIER
 | 
				
			||||||
 | 
						// Define to use spin wait instead of delayMicros()
 | 
				
			||||||
 | 
					//#	define USE_SPIN_WAIT
 | 
				
			||||||
 | 
					#       undef USE_DEFAULT_ENABLE_IR_IN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // The default pin used used for sending.
 | 
				
			||||||
 | 
					#	define SEND_PIN 9
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#elif defined(ESP32)
 | 
				
			||||||
 | 
					        // No system LED on ESP32, disable blinking by NOT defining BLINKLED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // avr/interrupt.h is not present
 | 
				
			||||||
 | 
					#       undef HAS_AVR_INTERRUPT_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Sending not implemented
 | 
				
			||||||
 | 
					#       undef SENDING_SUPPORTED#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Supply own enbleIRIn
 | 
				
			||||||
 | 
					#       undef USE_DEFAULT_ENABLE_IR_IN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#	define BLINKLED        13
 | 
				
			||||||
 | 
					#	define BLINKLED_ON()  (PORTB |= B00100000)
 | 
				
			||||||
 | 
					#	define BLINKLED_OFF()  (PORTB &= B11011111)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// CPU Frequency
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#ifdef F_CPU
 | 
				
			||||||
 | 
					#	define SYSCLOCK  F_CPU     // main Arduino clock
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#	define SYSCLOCK  16000000  // main Arduino clock
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// microseconds per clock interrupt tick
 | 
				
			||||||
 | 
					#define USECPERTICK    50
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// 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 3.0 / Teensy 3.1
 | 
				
			||||||
 | 
					#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
 | 
				
			||||||
 | 
						#define IR_USE_TIMER_CMT  // tx = pin 5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Teensy-LC
 | 
				
			||||||
 | 
					#elif defined(__MKL26Z64__)
 | 
				
			||||||
 | 
					  #define IR_USE_TIMER_TPM1 // tx = pin 16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// MightyCore - ATmega1284
 | 
				
			||||||
 | 
					#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)
 | 
				
			||||||
 | 
						//#define IR_USE_TIMER1   // tx = pin 13
 | 
				
			||||||
 | 
						#define IR_USE_TIMER2     // tx = pin 14
 | 
				
			||||||
 | 
						//#define IR_USE_TIMER3   // tx = pin 6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// MightyCore - ATmega164, ATmega324, ATmega644
 | 
				
			||||||
 | 
					#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \
 | 
				
			||||||
 | 
					|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \
 | 
				
			||||||
 | 
					|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \
 | 
				
			||||||
 | 
					|| defined(__AVR_ATmega164P__)
 | 
				
			||||||
 | 
						//#define IR_USE_TIMER1   // tx = pin 13
 | 
				
			||||||
 | 
						#define IR_USE_TIMER2     // tx = pin 14
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					//MegaCore - ATmega64, ATmega128
 | 
				
			||||||
 | 
					#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
 | 
				
			||||||
 | 
					 	#define IR_USE_TIMER1     // tx = pin 13
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// MightyCore - ATmega8535, ATmega16, ATmega32
 | 
				
			||||||
 | 
					#elif defined(__AVR_ATmega8535__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__)
 | 
				
			||||||
 | 
					 	#define IR_USE_TIMER1     // tx = pin 13
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Atmega8
 | 
				
			||||||
 | 
					#elif defined(__AVR_ATmega8__)
 | 
				
			||||||
 | 
						#define IR_USE_TIMER1     // tx = pin 9
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ATtiny84
 | 
				
			||||||
 | 
					#elif defined(__AVR_ATtiny84__)
 | 
				
			||||||
 | 
						#define IR_USE_TIMER1     // tx = pin 6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//ATtiny85
 | 
				
			||||||
 | 
					#elif defined(__AVR_ATtiny85__)
 | 
				
			||||||
 | 
						#define IR_USE_TIMER_TINY0   // tx = pin 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#elif defined(ESP32)
 | 
				
			||||||
 | 
						#define IR_TIMER_USE_ESP32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#elif defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD)
 | 
				
			||||||
 | 
						#define TIMER_PRESCALER_DIV 64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc
 | 
				
			||||||
 | 
					// ATmega48, ATmega88, ATmega168, ATmega328
 | 
				
			||||||
 | 
						//#define IR_USE_TIMER1   // tx = pin 9
 | 
				
			||||||
 | 
						#define IR_USE_TIMER2     // tx = pin 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Defines for Timer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//---------------------------------------------------------
 | 
				
			||||||
 | 
					// Timer2 (8 bits)
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#if defined(IR_USE_TIMER2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TIMER_RESET
 | 
				
			||||||
 | 
					#define TIMER_ENABLE_PWM    (TCCR2A |= _BV(COM2B1))
 | 
				
			||||||
 | 
					#define TIMER_DISABLE_PWM   (TCCR2A &= ~(_BV(COM2B1)))
 | 
				
			||||||
 | 
					#define TIMER_ENABLE_INTR   (TIMSK2 = _BV(OCIE2A))
 | 
				
			||||||
 | 
					#define TIMER_DISABLE_INTR  (TIMSK2 = 0)
 | 
				
			||||||
 | 
					#define TIMER_INTR_NAME     TIMER2_COMPA_vect
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TIMER_CONFIG_KHZ(val) ({ \
 | 
				
			||||||
 | 
						const uint8_t pwmval = SYSCLOCK / 2000 / (val); \
 | 
				
			||||||
 | 
						TCCR2A               = _BV(WGM20); \
 | 
				
			||||||
 | 
						TCCR2B               = _BV(WGM22) | _BV(CS20); \
 | 
				
			||||||
 | 
						OCR2A                = pwmval; \
 | 
				
			||||||
 | 
						OCR2B                = pwmval / 3; \
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TIMER_COUNT_TOP  (SYSCLOCK * USECPERTICK / 1000000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------
 | 
				
			||||||
 | 
					#if (TIMER_COUNT_TOP < 256)
 | 
				
			||||||
 | 
					#	define TIMER_CONFIG_NORMAL() ({ \
 | 
				
			||||||
 | 
							TCCR2A = _BV(WGM21); \
 | 
				
			||||||
 | 
							TCCR2B = _BV(CS20); \
 | 
				
			||||||
 | 
							OCR2A  = TIMER_COUNT_TOP; \
 | 
				
			||||||
 | 
							TCNT2  = 0; \
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#	define TIMER_CONFIG_NORMAL() ({ \
 | 
				
			||||||
 | 
							TCCR2A = _BV(WGM21); \
 | 
				
			||||||
 | 
							TCCR2B = _BV(CS21); \
 | 
				
			||||||
 | 
							OCR2A  = TIMER_COUNT_TOP / 8; \
 | 
				
			||||||
 | 
							TCNT2  = 0; \
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------
 | 
				
			||||||
 | 
					#if defined(CORE_OC2B_PIN)
 | 
				
			||||||
 | 
					#	define SEND_PIN  CORE_OC2B_PIN  // Teensy
 | 
				
			||||||
 | 
					#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
 | 
				
			||||||
 | 
					#	define SEND_PIN  9              // Arduino Mega
 | 
				
			||||||
 | 
					#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \
 | 
				
			||||||
 | 
					|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \
 | 
				
			||||||
 | 
					|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \
 | 
				
			||||||
 | 
					|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \
 | 
				
			||||||
 | 
					|| defined(__AVR_ATmega164P__)
 | 
				
			||||||
 | 
					#	define SEND_PIN  14             // MightyCore
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#	define SEND_PIN  3              // Arduino Duemilanove, Diecimila, LilyPad, etc
 | 
				
			||||||
 | 
					#endif					     // ATmega48, ATmega88, ATmega168, ATmega328
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//---------------------------------------------------------
 | 
				
			||||||
 | 
					// 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_ATmega8__) || defined(__AVR_ATmega8535__) \
 | 
				
			||||||
 | 
					|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \
 | 
				
			||||||
 | 
					|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
 | 
				
			||||||
 | 
					#	define TIMER_ENABLE_INTR   (TIMSK |= _BV(OCIE1A))
 | 
				
			||||||
 | 
					#	define TIMER_DISABLE_INTR  (TIMSK &= ~_BV(OCIE1A))
 | 
				
			||||||
 | 
					#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 SEND_PIN  CORE_OC1A_PIN  // Teensy
 | 
				
			||||||
 | 
					#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
 | 
				
			||||||
 | 
					#	define SEND_PIN  11             // Arduino Mega
 | 
				
			||||||
 | 
					#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
 | 
				
			||||||
 | 
					#	define SEND_PIN  13	     // MegaCore
 | 
				
			||||||
 | 
					#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \
 | 
				
			||||||
 | 
					|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \
 | 
				
			||||||
 | 
					|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \
 | 
				
			||||||
 | 
					|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \
 | 
				
			||||||
 | 
					|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \
 | 
				
			||||||
 | 
					|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__)
 | 
				
			||||||
 | 
					#	define SEND_PIN  13             // MightyCore
 | 
				
			||||||
 | 
					#elif defined(__AVR_ATtiny84__)
 | 
				
			||||||
 | 
					# 	define SEND_PIN  6
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#	define SEND_PIN  9              // Arduino Duemilanove, Diecimila, LilyPad, etc
 | 
				
			||||||
 | 
					#endif					     // ATmega48, ATmega88, ATmega168, ATmega328
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//---------------------------------------------------------
 | 
				
			||||||
 | 
					// 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 SEND_PIN  CORE_OC3A_PIN  // Teensy
 | 
				
			||||||
 | 
					#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
 | 
				
			||||||
 | 
					#	define SEND_PIN  5              // Arduino Mega
 | 
				
			||||||
 | 
					#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)
 | 
				
			||||||
 | 
					#	define SEND_PIN  6              // MightyCore
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#	error "Please add OC3A pin number here\n"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//---------------------------------------------------------
 | 
				
			||||||
 | 
					// 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 SEND_PIN  CORE_OC4A_PIN  // Teensy
 | 
				
			||||||
 | 
					#elif defined(__AVR_ATmega32U4__)
 | 
				
			||||||
 | 
					#	define SEND_PIN  13             // Leonardo
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#	error "Please add OC4A pin number here\n"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//---------------------------------------------------------
 | 
				
			||||||
 | 
					// 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 SEND_PIN  CORE_OC4A_PIN
 | 
				
			||||||
 | 
					#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
 | 
				
			||||||
 | 
					#	define SEND_PIN  6  // Arduino Mega
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#	error "Please add OC4A pin number here\n"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//---------------------------------------------------------
 | 
				
			||||||
 | 
					// 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 SEND_PIN  CORE_OC5A_PIN
 | 
				
			||||||
 | 
					#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
 | 
				
			||||||
 | 
					#	define SEND_PIN  46  // Arduino Mega
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#	error "Please add OC5A pin number here\n"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//---------------------------------------------------------
 | 
				
			||||||
 | 
					// Special carrier modulator timer
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#elif defined(IR_USE_TIMER_CMT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TIMER_RESET ({     \
 | 
				
			||||||
 | 
						uint8_t tmp __attribute__((unused)) = CMT_MSC; \
 | 
				
			||||||
 | 
						CMT_CMD2 = 30;         \
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TIMER_ENABLE_PWM  do {                                         \
 | 
				
			||||||
 | 
						CORE_PIN5_CONFIG = PORT_PCR_MUX(2) | PORT_PCR_DSE | PORT_PCR_SRE;  \
 | 
				
			||||||
 | 
					} while(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TIMER_DISABLE_PWM  do {                                        \
 | 
				
			||||||
 | 
						CORE_PIN5_CONFIG = PORT_PCR_MUX(1) | PORT_PCR_DSE | PORT_PCR_SRE;  \
 | 
				
			||||||
 | 
					} while(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TIMER_ENABLE_INTR   NVIC_ENABLE_IRQ(IRQ_CMT)
 | 
				
			||||||
 | 
					#define TIMER_DISABLE_INTR  NVIC_DISABLE_IRQ(IRQ_CMT)
 | 
				
			||||||
 | 
					#define TIMER_INTR_NAME     cmt_isr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------
 | 
				
			||||||
 | 
					#ifdef ISR
 | 
				
			||||||
 | 
					#	undef ISR
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#define  ISR(f)  void f(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------
 | 
				
			||||||
 | 
					#define CMT_PPS_DIV  ((F_BUS + 7999999) / 8000000)
 | 
				
			||||||
 | 
					#if F_BUS < 8000000
 | 
				
			||||||
 | 
					#error IRremote requires at least 8 MHz on Teensy 3.x
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------
 | 
				
			||||||
 | 
					#define TIMER_CONFIG_KHZ(val) ({ 	 \
 | 
				
			||||||
 | 
						SIM_SCGC4 |= SIM_SCGC4_CMT;      \
 | 
				
			||||||
 | 
						SIM_SOPT2 |= SIM_SOPT2_PTD7PAD;  \
 | 
				
			||||||
 | 
						CMT_PPS    = CMT_PPS_DIV - 1;    \
 | 
				
			||||||
 | 
						CMT_CGH1   = ((F_BUS / CMT_PPS_DIV / 3000) + ((val)/2)) / (val); \
 | 
				
			||||||
 | 
						CMT_CGL1   = ((F_BUS / CMT_PPS_DIV / 1500) + ((val)/2)) / (val); \
 | 
				
			||||||
 | 
						CMT_CMD1   = 0;                  \
 | 
				
			||||||
 | 
						CMT_CMD2   = 30;                 \
 | 
				
			||||||
 | 
						CMT_CMD3   = 0;                  \
 | 
				
			||||||
 | 
						CMT_CMD4   = 0;                  \
 | 
				
			||||||
 | 
						CMT_OC     = 0x60;               \
 | 
				
			||||||
 | 
						CMT_MSC    = 0x01;               \
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TIMER_CONFIG_NORMAL() ({  \
 | 
				
			||||||
 | 
						SIM_SCGC4 |= SIM_SCGC4_CMT;   \
 | 
				
			||||||
 | 
						CMT_PPS    = CMT_PPS_DIV - 1; \
 | 
				
			||||||
 | 
						CMT_CGH1   = 1;               \
 | 
				
			||||||
 | 
						CMT_CGL1   = 1;               \
 | 
				
			||||||
 | 
						CMT_CMD1   = 0;               \
 | 
				
			||||||
 | 
						CMT_CMD2   = 30;              \
 | 
				
			||||||
 | 
						CMT_CMD3   = 0;               \
 | 
				
			||||||
 | 
						CMT_CMD4   = (F_BUS / 160000 + CMT_PPS_DIV / 2) / CMT_PPS_DIV - 31; \
 | 
				
			||||||
 | 
						CMT_OC     = 0;               \
 | 
				
			||||||
 | 
						CMT_MSC    = 0x03;            \
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SEND_PIN  5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// defines for TPM1 timer on Teensy-LC
 | 
				
			||||||
 | 
					#elif defined(IR_USE_TIMER_TPM1)
 | 
				
			||||||
 | 
					#define TIMER_RESET          FTM1_SC |= FTM_SC_TOF;
 | 
				
			||||||
 | 
					#define TIMER_ENABLE_PWM     CORE_PIN16_CONFIG = PORT_PCR_MUX(3)|PORT_PCR_DSE|PORT_PCR_SRE
 | 
				
			||||||
 | 
					#define TIMER_DISABLE_PWM    CORE_PIN16_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_SRE
 | 
				
			||||||
 | 
					#define TIMER_ENABLE_INTR    NVIC_ENABLE_IRQ(IRQ_FTM1)
 | 
				
			||||||
 | 
					#define TIMER_DISABLE_INTR   NVIC_DISABLE_IRQ(IRQ_FTM1)
 | 
				
			||||||
 | 
					#define TIMER_INTR_NAME      ftm1_isr
 | 
				
			||||||
 | 
					#ifdef ISR
 | 
				
			||||||
 | 
					#undef ISR
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#define ISR(f) void f(void)
 | 
				
			||||||
 | 
					#define TIMER_CONFIG_KHZ(val) ({                     \
 | 
				
			||||||
 | 
						SIM_SCGC6 |= SIM_SCGC6_TPM1;                 \
 | 
				
			||||||
 | 
						FTM1_SC = 0;                                 \
 | 
				
			||||||
 | 
						FTM1_CNT = 0;                                \
 | 
				
			||||||
 | 
						FTM1_MOD = (F_PLL/2000) / val - 1;           \
 | 
				
			||||||
 | 
						FTM1_C0V = (F_PLL/6000) / val - 1;           \
 | 
				
			||||||
 | 
						FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0);     \
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					#define TIMER_CONFIG_NORMAL() ({                     \
 | 
				
			||||||
 | 
						SIM_SCGC6 |= SIM_SCGC6_TPM1;                 \
 | 
				
			||||||
 | 
						FTM1_SC = 0;                                 \
 | 
				
			||||||
 | 
						FTM1_CNT = 0;                                \
 | 
				
			||||||
 | 
						FTM1_MOD = (F_PLL/40000) - 1;                \
 | 
				
			||||||
 | 
						FTM1_C0V = 0;                                \
 | 
				
			||||||
 | 
						FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0) | FTM_SC_TOF | FTM_SC_TOIE; \
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					#define SEND_PIN        16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// defines for timer_tiny0 (8 bits)
 | 
				
			||||||
 | 
					#elif defined(IR_USE_TIMER_TINY0)
 | 
				
			||||||
 | 
					#define TIMER_RESET
 | 
				
			||||||
 | 
					#define TIMER_ENABLE_PWM     (TCCR0A |= _BV(COM0B1))
 | 
				
			||||||
 | 
					#define TIMER_DISABLE_PWM    (TCCR0A &= ~(_BV(COM0B1)))
 | 
				
			||||||
 | 
					#define TIMER_ENABLE_INTR    (TIMSK |= _BV(OCIE0A))
 | 
				
			||||||
 | 
					#define TIMER_DISABLE_INTR   (TIMSK &= ~(_BV(OCIE0A)))
 | 
				
			||||||
 | 
					#define TIMER_INTR_NAME      TIMER0_COMPA_vect
 | 
				
			||||||
 | 
					#define TIMER_CONFIG_KHZ(val) ({ \
 | 
				
			||||||
 | 
					  const uint8_t pwmval = SYSCLOCK / 2000 / (val); \
 | 
				
			||||||
 | 
					  TCCR0A = _BV(WGM00); \
 | 
				
			||||||
 | 
					  TCCR0B = _BV(WGM02) | _BV(CS00); \
 | 
				
			||||||
 | 
					  OCR0A = pwmval; \
 | 
				
			||||||
 | 
					  OCR0B = pwmval / 3; \
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					#define TIMER_COUNT_TOP      (SYSCLOCK * USECPERTICK / 1000000)
 | 
				
			||||||
 | 
					#if (TIMER_COUNT_TOP < 256)
 | 
				
			||||||
 | 
					#define TIMER_CONFIG_NORMAL() ({ \
 | 
				
			||||||
 | 
					  TCCR0A = _BV(WGM01); \
 | 
				
			||||||
 | 
					  TCCR0B = _BV(CS00); \
 | 
				
			||||||
 | 
					  OCR0A = TIMER_COUNT_TOP; \
 | 
				
			||||||
 | 
					  TCNT0 = 0; \
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define TIMER_CONFIG_NORMAL() ({ \
 | 
				
			||||||
 | 
					  TCCR0A = _BV(WGM01); \
 | 
				
			||||||
 | 
					  TCCR0B = _BV(CS01); \
 | 
				
			||||||
 | 
					  OCR0A = TIMER_COUNT_TOP / 8; \
 | 
				
			||||||
 | 
					  TCNT0 = 0; \
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SEND_PIN        1  /* ATtiny85 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//---------------------------------------------------------
 | 
				
			||||||
 | 
					// ESP32 (ESP8266 should likely be added here too)
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ESP32 has it own timer API and does not use these macros, but to avoid ifdef'ing
 | 
				
			||||||
 | 
					// them out in the common code, they are defined to no-op. This allows the code to compile
 | 
				
			||||||
 | 
					// (which it wouldn't otherwise) but irsend will not work until ESP32 specific code is written
 | 
				
			||||||
 | 
					// for that -- merlin
 | 
				
			||||||
 | 
					// As a warning, sending timing specific code from an ESP32 can be challenging if you need 100%
 | 
				
			||||||
 | 
					// reliability because the arduino code may be interrupted and cause your sent waveform to be the
 | 
				
			||||||
 | 
					// wrong length. This is specifically an issue for neopixels which require 800Khz resolution.
 | 
				
			||||||
 | 
					// IR may just work as is with the common code since it's lower frequency, but if not, the other
 | 
				
			||||||
 | 
					// way to do this on ESP32 is using the RMT built in driver like in this incomplete library below
 | 
				
			||||||
 | 
					// https://github.com/ExploreEmbedded/ESP32_RMT
 | 
				
			||||||
 | 
					#elif defined(IR_TIMER_USE_ESP32)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TIMER_RESET
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef ISR
 | 
				
			||||||
 | 
					#	undef ISR
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#define  ISR(f)  void IRTimer()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#elif defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD)
 | 
				
			||||||
 | 
					// use timer 3 hardcoded at this time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TIMER_RESET
 | 
				
			||||||
 | 
					#define TIMER_ENABLE_PWM     // Not presently used
 | 
				
			||||||
 | 
					#define TIMER_DISABLE_PWM
 | 
				
			||||||
 | 
					#define TIMER_ENABLE_INTR    NVIC_EnableIRQ(TC3_IRQn) // Not presently used    
 | 
				
			||||||
 | 
					#define TIMER_DISABLE_INTR   NVIC_DisableIRQ(TC3_IRQn)
 | 
				
			||||||
 | 
					#define TIMER_INTR_NAME      TC3_Handler // Not presently used
 | 
				
			||||||
 | 
					#define TIMER_CONFIG_KHZ(f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef ISR
 | 
				
			||||||
 | 
					#	undef ISR
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#define  ISR(f)  void irs()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//---------------------------------------------------------
 | 
				
			||||||
 | 
					// Unknown Timer
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#	error "Internal code configuration error, no known IR_USE_TIMER# defined\n"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Provide default definitions, portable but possibly slower than necessary.
 | 
				
			||||||
 | 
					#ifndef SENDPIN_ON
 | 
				
			||||||
 | 
					#define SENDPIN_ON(pin)  digitalWrite(pin, HIGH)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					#ifndef SENDPIN_OFF
 | 
				
			||||||
 | 
					#define SENDPIN_OFF(pin) digitalWrite(pin, LOW)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // ! boarddefs_h
 | 
				
			||||||
							
								
								
									
										81
									
								
								IRremote/changelog.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								IRremote/changelog.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
				
			|||||||
 | 
					## 2.4.0 - 2017/08/10
 | 
				
			||||||
 | 
					 - Cleanup of hardware dependencies. Merge in SAM support [PR #437](https://github.com/z3t0/Arduino-IRremote/pull/437)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 2.3.3 - 2017/03/31
 | 
				
			||||||
 | 
					- Added ESP32 IR receive support [PR #427](https://github.com/z3t0/Arduino-IRremote/pull/425)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 2.2.3 - 2017/03/27
 | 
				
			||||||
 | 
					- Fix calculation of pause length in LEGO PF protocol [PR #427](https://github.com/z3t0/Arduino-IRremote/pull/427)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 2.2.2 - 2017/01/20
 | 
				
			||||||
 | 
					- Fixed naming bug [PR #398](https://github.com/z3t0/Arduino-IRremote/pull/398)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 2.2.1 - 2016/07/27
 | 
				
			||||||
 | 
					- Added tests for Lego Power Functions Protocol [PR #336](https://github.com/z3t0/Arduino-IRremote/pull/336)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 2.2.0 - 2016/06/28
 | 
				
			||||||
 | 
					- Added support for ATmega8535
 | 
				
			||||||
 | 
					- Added support for ATmega16
 | 
				
			||||||
 | 
					- Added support for ATmega32
 | 
				
			||||||
 | 
					- Added support for ATmega164
 | 
				
			||||||
 | 
					- Added support for ATmega324
 | 
				
			||||||
 | 
					- Added support for ATmega644
 | 
				
			||||||
 | 
					- Added support for ATmega1284
 | 
				
			||||||
 | 
					- Added support for ATmega64
 | 
				
			||||||
 | 
					- Added support for ATmega128
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[PR](https://github.com/z3t0/Arduino-IRremote/pull/324)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 2.1.1 - 2016/05/04
 | 
				
			||||||
 | 
					- Added Lego Power Functions Protocol [PR #309](https://github.com/z3t0/Arduino-IRremote/pull/309)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 2.1.0 - 2016/02/20
 | 
				
			||||||
 | 
					- Improved Debugging [PR #258](https://github.com/z3t0/Arduino-IRremote/pull/258)
 | 
				
			||||||
 | 
					- Display TIME instead of TICKS [PR #258](https://github.com/z3t0/Arduino-IRremote/pull/258)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 2.0.4 - 2016/02/20
 | 
				
			||||||
 | 
					- Add Panasonic and JVC to IRrecord example [PR](https://github.com/z3t0/Arduino-IRremote/pull/54)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 2.0.3 - 2016/02/20
 | 
				
			||||||
 | 
					- Change IRSend Raw parameter to const [PR](https://github.com/z3t0/Arduino-IRremote/pull/227)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 2.0.2 - 2015/12/02
 | 
				
			||||||
 | 
					- Added IRremoteInfo Sketch - [PR](https://github.com/z3t0/Arduino-IRremote/pull/241)
 | 
				
			||||||
 | 
					- Enforcing changelog.md
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 2.0.1 - 2015/07/26 - [Release](https://github.com/shirriff/Arduino-IRremote/releases/tag/BETA)
 | 
				
			||||||
 | 
					### Changes
 | 
				
			||||||
 | 
					- Updated README
 | 
				
			||||||
 | 
					- Updated Contributors
 | 
				
			||||||
 | 
					- Fixed #110 Mess
 | 
				
			||||||
 | 
					- Created Gitter Room
 | 
				
			||||||
 | 
					- Added Gitter Badge
 | 
				
			||||||
 | 
					- Standardised Code Base
 | 
				
			||||||
 | 
					- Clean Debug Output
 | 
				
			||||||
 | 
					- Optimized Send Loops
 | 
				
			||||||
 | 
					- Modularized Design
 | 
				
			||||||
 | 
					- Optimized and Updated Examples
 | 
				
			||||||
 | 
					- Improved Documentation
 | 
				
			||||||
 | 
					- Fixed and Improved many coding errors
 | 
				
			||||||
 | 
					- Fixed Aiwa RC-T501 Decoding
 | 
				
			||||||
 | 
					- Fixed Interrupt on ATmega8
 | 
				
			||||||
 | 
					- Switched to Stable Release of @PlatformIO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Additions
 | 
				
			||||||
 | 
					- Added Aiwa RC-T501 Protocol
 | 
				
			||||||
 | 
					- Added Denon Protocol
 | 
				
			||||||
 | 
					- Added Pronto Support
 | 
				
			||||||
 | 
					- Added Library Properties
 | 
				
			||||||
 | 
					- Added Template For New Protocols
 | 
				
			||||||
 | 
					- Added this changelog
 | 
				
			||||||
 | 
					- Added Teensy LC Support
 | 
				
			||||||
 | 
					- Added ATtiny84 Support
 | 
				
			||||||
 | 
					- Added ATtiny85 Support
 | 
				
			||||||
 | 
					- Added isIdle method
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Deletions
 | 
				
			||||||
 | 
					- Removed (Fixed) #110
 | 
				
			||||||
 | 
					- Broke Teensy 3 / 3.1 Support
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Not Working
 | 
				
			||||||
 | 
					- Teensy 3 / 3.1 Support is in Development
 | 
				
			||||||
							
								
								
									
										39
									
								
								IRremote/esp32.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								IRremote/esp32.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
				
			|||||||
 | 
					#ifdef ESP32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This file contains functions specific to the ESP32.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "IRremote.h"
 | 
				
			||||||
 | 
					#include "IRremoteInt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// "Idiot check"
 | 
				
			||||||
 | 
					#ifdef USE_DEFAULT_ENABLE_IR_IN
 | 
				
			||||||
 | 
					#error Must undef USE_DEFAULT_ENABLE_IR_IN
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					hw_timer_t *timer;
 | 
				
			||||||
 | 
					void IRTimer(); // defined in IRremote.cpp, masqueraded as ISR(TIMER_INTR_NAME)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// initialization
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					void  IRrecv::enableIRIn ( )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					// Interrupt Service Routine - Fires every 50uS
 | 
				
			||||||
 | 
						// ESP32 has a proper API to setup timers, no weird chip macros needed
 | 
				
			||||||
 | 
						// simply call the readable API versions :)
 | 
				
			||||||
 | 
						// 3 timers, choose #1, 80 divider nanosecond precision, 1 to count up
 | 
				
			||||||
 | 
						timer = timerBegin(1, 80, 1);
 | 
				
			||||||
 | 
						timerAttachInterrupt(timer, &IRTimer, 1);
 | 
				
			||||||
 | 
						// every 50ns, autoreload = true
 | 
				
			||||||
 | 
						timerAlarmWrite(timer, 50, true);
 | 
				
			||||||
 | 
						timerAlarmEnable(timer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Initialize state machine variables
 | 
				
			||||||
 | 
						irparams.rcvstate = STATE_IDLE;
 | 
				
			||||||
 | 
						irparams.rawlen = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Set pin modes
 | 
				
			||||||
 | 
						pinMode(irparams.recvpin, INPUT);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // ESP32
 | 
				
			||||||
							
								
								
									
										513
									
								
								IRremote/irPronto.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										513
									
								
								IRremote/irPronto.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,513 @@
 | 
				
			|||||||
 | 
					#define TEST 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if TEST
 | 
				
			||||||
 | 
					#	define SEND_PRONTO        1
 | 
				
			||||||
 | 
					#	define PRONTO_ONCE        false
 | 
				
			||||||
 | 
					#	define PRONTO_REPEAT      true
 | 
				
			||||||
 | 
					#	define PRONTO_FALLBACK    true
 | 
				
			||||||
 | 
					#	define PRONTO_NOFALLBACK  false
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if SEND_PRONTO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//******************************************************************************
 | 
				
			||||||
 | 
					#if TEST
 | 
				
			||||||
 | 
					#	include <stdio.h>
 | 
				
			||||||
 | 
						void  enableIROut (int freq)  { printf("\nFreq = %d KHz\n", freq); }
 | 
				
			||||||
 | 
						void  mark        (int t)     { printf("+%d," , t); }
 | 
				
			||||||
 | 
						void  space       (int t)     { printf("-%d, ", t); }
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#	include "IRremote.h"
 | 
				
			||||||
 | 
					#endif // TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// Check for a valid hex digit
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					bool  ishex (char ch)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return ( ((ch >= '0') && (ch <= '9')) ||
 | 
				
			||||||
 | 
					             ((ch >= 'A') && (ch <= 'F')) ||
 | 
				
			||||||
 | 
					             ((ch >= 'a') && (ch <= 'f'))   ) ? true : false ;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// Check for a valid "blank" ... '\0' is a valid "blank"
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					bool  isblank (char ch)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return ((ch == ' ') || (ch == '\t') || (ch == '\0')) ? true : false ;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// Bypass spaces
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					bool  byp (char** pcp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						while (isblank(**pcp))  (*pcp)++ ;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// Hex-to-Byte : Decode a hex digit
 | 
				
			||||||
 | 
					// We assume the character has already been validated
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					uint8_t  htob (char ch)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if ((ch >= '0') && (ch <= '9'))  return ch - '0' ;
 | 
				
			||||||
 | 
						if ((ch >= 'A') && (ch <= 'F'))  return ch - 'A' + 10 ;
 | 
				
			||||||
 | 
						if ((ch >= 'a') && (ch <= 'f'))  return ch - 'a' + 10 ;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// Hex-to-Word : Decode a block of 4 hex digits
 | 
				
			||||||
 | 
					// We assume the string has already been validated
 | 
				
			||||||
 | 
					//   and the pointer being passed points at the start of a block of 4 hex digits
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					uint16_t  htow (char* cp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return ( (htob(cp[0]) << 12) | (htob(cp[1]) <<  8) |
 | 
				
			||||||
 | 
					             (htob(cp[2]) <<  4) | (htob(cp[3])      )  ) ;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					bool sendPronto (char* s,  bool repeat,  bool fallback)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int       i;
 | 
				
			||||||
 | 
						int       len;
 | 
				
			||||||
 | 
						int       skip;
 | 
				
			||||||
 | 
						char*     cp;
 | 
				
			||||||
 | 
						uint16_t  freq;  // Frequency in KHz
 | 
				
			||||||
 | 
						uint8_t   usec;  // pronto uSec/tick
 | 
				
			||||||
 | 
						uint8_t   once;
 | 
				
			||||||
 | 
						uint8_t   rpt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Validate the string
 | 
				
			||||||
 | 
						for (cp = s;  *cp;  cp += 4) {
 | 
				
			||||||
 | 
							byp(&cp);
 | 
				
			||||||
 | 
							if ( !ishex(cp[0]) || !ishex(cp[1]) ||
 | 
				
			||||||
 | 
							     !ishex(cp[2]) || !ishex(cp[3]) || !isblank(cp[4]) )  return false ;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// We will use cp to traverse the string
 | 
				
			||||||
 | 
						cp = s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check mode = Oscillated/Learned
 | 
				
			||||||
 | 
						byp(&cp);
 | 
				
			||||||
 | 
						if (htow(cp) != 0000)  return false;
 | 
				
			||||||
 | 
						cp += 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Extract & set frequency
 | 
				
			||||||
 | 
						byp(&cp);
 | 
				
			||||||
 | 
						freq = (int)(1000000 / (htow(cp) * 0.241246));  // Rounding errors will occur, tolerance is +/- 10%
 | 
				
			||||||
 | 
						usec = (int)(((1.0 / freq) * 1000000) + 0.5);  // Another rounding error, thank Cod for analogue electronics
 | 
				
			||||||
 | 
						freq /= 1000;  // This will introduce a(nother) rounding error which we do not want in the usec calcualtion
 | 
				
			||||||
 | 
						cp += 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Get length of "once" code
 | 
				
			||||||
 | 
						byp(&cp);
 | 
				
			||||||
 | 
						once = htow(cp);
 | 
				
			||||||
 | 
						cp += 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Get length of "repeat" code
 | 
				
			||||||
 | 
						byp(&cp);
 | 
				
			||||||
 | 
						rpt = htow(cp);
 | 
				
			||||||
 | 
						cp += 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Which code are we sending?
 | 
				
			||||||
 | 
						if (fallback) { // fallback on the "other" code if "this" code is not present
 | 
				
			||||||
 | 
							if (!repeat) { // requested 'once'
 | 
				
			||||||
 | 
								if (once)  len = once * 2,  skip = 0 ;  // if once exists send it
 | 
				
			||||||
 | 
								else       len = rpt  * 2,  skip = 0 ;  // else send repeat code
 | 
				
			||||||
 | 
							} else { // requested 'repeat'
 | 
				
			||||||
 | 
								if (rpt)   len = rpt  * 2,  skip = 0 ;  // if rpt exists send it
 | 
				
			||||||
 | 
								else       len = once * 2,  skip = 0 ;  // else send once code
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {  // Send what we asked for, do not fallback if the code is empty!
 | 
				
			||||||
 | 
							if (!repeat)  len = once * 2,  skip = 0 ;     // 'once' starts at 0
 | 
				
			||||||
 | 
							else          len = rpt  * 2,  skip = once ;  // 'repeat' starts where 'once' ends
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Skip to start of code
 | 
				
			||||||
 | 
						for (i = 0;  i < skip;  i++, cp += 4)  byp(&cp) ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Send code
 | 
				
			||||||
 | 
						enableIROut(freq);
 | 
				
			||||||
 | 
						for (i = 0;  i < len;  i++) {
 | 
				
			||||||
 | 
							byp(&cp);
 | 
				
			||||||
 | 
							if (i & 1)  space(htow(cp) * usec);
 | 
				
			||||||
 | 
							else        mark (htow(cp) * usec);
 | 
				
			||||||
 | 
							cp += 4;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					#if TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int  main ( )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char  prontoTest[] =
 | 
				
			||||||
 | 
							"0000 0070 0000 0032 0080 0040 0010 0010 0010 0030 " //  10
 | 
				
			||||||
 | 
							"0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " //  20
 | 
				
			||||||
 | 
							"0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " //  30
 | 
				
			||||||
 | 
							"0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " //  40
 | 
				
			||||||
 | 
							"0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " //  50
 | 
				
			||||||
 | 
							"0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " //  60
 | 
				
			||||||
 | 
							"0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " //  70
 | 
				
			||||||
 | 
							"0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 " //  80
 | 
				
			||||||
 | 
							"0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " //  90
 | 
				
			||||||
 | 
							"0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 100
 | 
				
			||||||
 | 
							"0010 0030 0010 0aa6";                               // 104
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sendPronto(prontoTest, PRONTO_ONCE,   PRONTO_FALLBACK);    // once code
 | 
				
			||||||
 | 
						sendPronto(prontoTest, PRONTO_REPEAT, PRONTO_FALLBACK);    // repeat code
 | 
				
			||||||
 | 
						sendPronto(prontoTest, PRONTO_ONCE,   PRONTO_NOFALLBACK);  // once code
 | 
				
			||||||
 | 
						sendPronto(prontoTest, PRONTO_REPEAT, PRONTO_NOFALLBACK);  // repeat code
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // SEND_PRONTO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
					//******************************************************************************
 | 
				
			||||||
 | 
					// Sources:
 | 
				
			||||||
 | 
					//   http://www.remotecentral.com/features/irdisp2.htm
 | 
				
			||||||
 | 
					//   http://www.hifi-remote.com/wiki/index.php?title=Working_With_Pronto_Hex
 | 
				
			||||||
 | 
					//******************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define IRPRONTO
 | 
				
			||||||
 | 
					#include "IRremoteInt.h"  // The Arduino IRremote library defines USECPERTICK
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Source: https://www.google.co.uk/search?q=DENON+MASTER+IR+Hex+Command+Sheet
 | 
				
			||||||
 | 
					//         -> http://assets.denon.com/documentmaster/us/denon%20master%20ir%20hex.xls
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					char  prontoTest[] =
 | 
				
			||||||
 | 
						"0000 0070 0000 0032 0080 0040 0010 0010 0010 0030 " //  10
 | 
				
			||||||
 | 
						"0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " //  20
 | 
				
			||||||
 | 
						"0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " //  30
 | 
				
			||||||
 | 
						"0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " //  40
 | 
				
			||||||
 | 
						"0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " //  50
 | 
				
			||||||
 | 
						"0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " //  60
 | 
				
			||||||
 | 
						"0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " //  70
 | 
				
			||||||
 | 
						"0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 " //  80
 | 
				
			||||||
 | 
						"0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " //  90
 | 
				
			||||||
 | 
						"0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 100
 | 
				
			||||||
 | 
						"0010 0030 0010 0aa6";                               // 104
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// This is the longest code we can support
 | 
				
			||||||
 | 
					#define CODEMAX  200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// This is the data we pull out of the pronto code
 | 
				
			||||||
 | 
					typedef
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							int        freq;           // Carrier frequency (in Hz)
 | 
				
			||||||
 | 
							int        usec;           // uSec per tick (based on freq)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							int        codeLen;        // Length of code
 | 
				
			||||||
 | 
							uint16_t   code[CODEMAX];  // Code in hex
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							int        onceLen;        // Length of "once" transmit
 | 
				
			||||||
 | 
							uint16_t*  once;           // Pointer to start within 'code'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							int        rptLen;         // Length of "repeat" transmit
 | 
				
			||||||
 | 
							uint16_t*  rpt;            // Pointer to start within 'code'
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					pronto_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// From what I have seen, the only time we go over 8-bits is the 'space'
 | 
				
			||||||
 | 
					// on the end which creates the lead-out/inter-code gap.  Assuming I'm right,
 | 
				
			||||||
 | 
					// we can code this up as a special case and otherwise halve the size of our
 | 
				
			||||||
 | 
					// data!
 | 
				
			||||||
 | 
					// Ignoring the first four values (the config data) and the last value
 | 
				
			||||||
 | 
					// (the lead-out), if you find a protocol that uses values greater than 00fe
 | 
				
			||||||
 | 
					// we are going to have to revisit this code!
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// So, the 0th byte will be the carrier frequency in Khz (NOT Hz)
 | 
				
			||||||
 | 
					//      "  1st  "    "   "   "  length of the "once" code
 | 
				
			||||||
 | 
					//      "  2nd  "    "   "   "  length of the "repeat" code
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Thereafter, odd  bytes will be Mark  lengths as a multiple of USECPERTICK uS
 | 
				
			||||||
 | 
					//             even   "     "  "  Space    "    "  "    "     "       "      "
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Any occurence of "FF" in either a Mark or a Space will indicate
 | 
				
			||||||
 | 
					//   "Use the 16-bit FF value" which will also be a multiple of USECPERTICK uS
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// As a point of comparison, the test code (prontoTest[]) is 520 bytes
 | 
				
			||||||
 | 
					// (yes, more than 0.5KB of our Arduino's precious 32KB) ... after conversion
 | 
				
			||||||
 | 
					// to pronto hex that goes down to ((520/5)*2) = 208 bytes ... once converted to
 | 
				
			||||||
 | 
					// our format we are down to ((208/2) -1 -1 +2) = 104 bytes
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// In fariness this is still very memory-hungry
 | 
				
			||||||
 | 
					// ...As a rough guide:
 | 
				
			||||||
 | 
					//   10 codes cost 1K of memory (this will vary depending on the protocol).
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// So if you're building a complex remote control, you will probably need to
 | 
				
			||||||
 | 
					// keep the codes on an external memory device (not in the Arduino sketch) and
 | 
				
			||||||
 | 
					// load them as you need them.  Hmmm.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This dictates that "Oscillated Pronto Codes" are probably NOT the way forward
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// For example, prontoTest[] happens to be: A 48-bit IR code in Denon format
 | 
				
			||||||
 | 
					// So we know it starts with 80/40                           (Denon header)
 | 
				
			||||||
 | 
					//             and ends with 10/aa6                          (Denon leadout)
 | 
				
			||||||
 | 
					//             and all (48) bits in between are either 10/10 (Denon 0)
 | 
				
			||||||
 | 
					//                                                  or 10/30 (Denon 1)
 | 
				
			||||||
 | 
					// So we could easily store this data in 1-byte  ("Denon")
 | 
				
			||||||
 | 
					//                                     + 1-byte  (Length=48)
 | 
				
			||||||
 | 
					//                                     + 6-bytes (IR code)
 | 
				
			||||||
 | 
					// At 8-bytes per code, we can store 128 codes in 1KB or memory - that's a lot
 | 
				
			||||||
 | 
					// better than the 2 (two) we started off with!
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// And serendipitously, by reducing the amount of data, our program will run
 | 
				
			||||||
 | 
					// a LOT faster!
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Again, I repeat, even after you have spent time converting the "Oscillated
 | 
				
			||||||
 | 
					// Pronto Codes" in to IRremote format, it will be a LOT more memory-hungry
 | 
				
			||||||
 | 
					// than using sendDenon() (or whichever) ...BUT these codes are easily
 | 
				
			||||||
 | 
					// available on the internet, so we'll support them!
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					typedef
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							uint16_t   FF;
 | 
				
			||||||
 | 
							uint8_t    code[CODEMAX];
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					irCode_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					#define DEBUGF(...)  printf(__VA_ARGS__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// String must be block of 4 hex digits separated with blanks
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					bool  validate (char* cp,  int* len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						for (*len = 0;  *cp;  (*len)++, cp += 4) {
 | 
				
			||||||
 | 
							byp(&cp);
 | 
				
			||||||
 | 
							if ( !ishex(cp[0]) || !ishex(cp[1]) ||
 | 
				
			||||||
 | 
							     !ishex(cp[2]) || !ishex(cp[3]) || !isblank(cp[4]) )  return false ;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// Hex-to-Byte : Decode a hex digit
 | 
				
			||||||
 | 
					// We assume the character has already been validated
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					uint8_t  htob (char ch)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if ((ch >= '0') && (ch <= '9'))  return ch - '0' ;
 | 
				
			||||||
 | 
						if ((ch >= 'A') && (ch <= 'F'))  return ch - 'A' + 10 ;
 | 
				
			||||||
 | 
						if ((ch >= 'a') && (ch <= 'f'))  return ch - 'a' + 10 ;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// Hex-to-Word : Decode a block of 4 hex digits
 | 
				
			||||||
 | 
					// We assume the string has already been validated
 | 
				
			||||||
 | 
					//   and the pointer being passed points at the start of a block of 4 hex digits
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					uint16_t  htow (char* cp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return ( (htob(cp[0]) << 12) | (htob(cp[1]) <<  8) |
 | 
				
			||||||
 | 
					             (htob(cp[2]) <<  4) | (htob(cp[3])      )  ) ;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// Convert the pronto string in to data
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					bool  decode (char* s,  pronto_t* p,  irCode_t* ir)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int    i, len;
 | 
				
			||||||
 | 
						char*  cp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Validate the Pronto string
 | 
				
			||||||
 | 
						if (!validate(s, &p->codeLen)) {
 | 
				
			||||||
 | 
							DEBUGF("Invalid pronto string\n");
 | 
				
			||||||
 | 
							return false ;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
						DEBUGF("Found %d hex codes\n", p->codeLen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Allocate memory to store the decoded string
 | 
				
			||||||
 | 
						//if (!(p->code = malloc(p->len))) {
 | 
				
			||||||
 | 
						//	DEBUGF("Memory allocation failed\n");
 | 
				
			||||||
 | 
						//	return false ;
 | 
				
			||||||
 | 
						//}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check in case our code is too long
 | 
				
			||||||
 | 
						if (p->codeLen > CODEMAX) {
 | 
				
			||||||
 | 
							DEBUGF("Code too long, edit CODEMAX and recompile\n");
 | 
				
			||||||
 | 
							return false ;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Decode the string
 | 
				
			||||||
 | 
						cp = s;
 | 
				
			||||||
 | 
						for (i = 0;  i < p->codeLen;  i++, cp += 4) {
 | 
				
			||||||
 | 
							byp(&cp);
 | 
				
			||||||
 | 
							p->code[i] = htow(cp);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Announce our findings
 | 
				
			||||||
 | 
						DEBUGF("Input: |%s|\n", s);
 | 
				
			||||||
 | 
						DEBUGF("Found: |");
 | 
				
			||||||
 | 
					    for (i = 0;  i < p->codeLen;  i++)  DEBUGF("%04x ", p->code[i]) ;
 | 
				
			||||||
 | 
						DEBUGF("|\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DEBUGF("Form [%04X] : ", p->code[0]);
 | 
				
			||||||
 | 
						if      (p->code[0] == 0x0000)  DEBUGF("Oscillated (Learned)\n");
 | 
				
			||||||
 | 
						else if (p->code[0] == 0x0100)  DEBUGF("Unmodulated\n");
 | 
				
			||||||
 | 
						else                            DEBUGF("Unknown\n");
 | 
				
			||||||
 | 
					    if (p->code[0] != 0x0000)  return false ;  // Can only handle Oscillated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Calculate the carrier frequency (+/- 10%) & uSecs per pulse
 | 
				
			||||||
 | 
						// Pronto uses a crystal which generates a timeabse of 0.241246
 | 
				
			||||||
 | 
						p->freq     = (int)(1000000 / (p->code[1] * 0.241246));
 | 
				
			||||||
 | 
						p->usec     = (int)(((1.0 / p->freq) * 1000000) + 0.5);
 | 
				
			||||||
 | 
						ir->code[0] = p->freq / 1000;
 | 
				
			||||||
 | 
					    DEBUGF("Freq [%04X] : %d Hz  (%d uS/pluse) -> %d KHz\n",
 | 
				
			||||||
 | 
						       p->code[1], p->freq, p->usec, ir->code[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Set the length & start pointer for the "once" code
 | 
				
			||||||
 | 
						p->onceLen  = p->code[2];
 | 
				
			||||||
 | 
						p->once     = &p->code[4];
 | 
				
			||||||
 | 
						ir->code[1] = p->onceLen;
 | 
				
			||||||
 | 
						DEBUGF("Once [%04X] : %d\n", p->code[2], p->onceLen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Set the length & start pointer for the "repeat" code
 | 
				
			||||||
 | 
						p->rptLen = p->code[3];
 | 
				
			||||||
 | 
						p->rpt    = &p->code[4 + p->onceLen];
 | 
				
			||||||
 | 
						ir->code[2] = p->rptLen;
 | 
				
			||||||
 | 
						DEBUGF("Rpt  [%04X] : %d\n", p->code[3], p->rptLen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check everything tallies
 | 
				
			||||||
 | 
						if (1 + 1 + 1 + 1 + (p->onceLen * 2) + (p->rptLen * 2) != p->codeLen) {
 | 
				
			||||||
 | 
							DEBUGF("Bad code length\n");
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Convert the IR data to our new format
 | 
				
			||||||
 | 
						ir->FF = p->code[p->codeLen - 1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						len = (p->onceLen * 2) + (p->rptLen * 2);
 | 
				
			||||||
 | 
						DEBUGF("Encoded: |");
 | 
				
			||||||
 | 
						for (i = 0;  i < len;  i++) {
 | 
				
			||||||
 | 
							if (p->code[i+4] == ir->FF) {
 | 
				
			||||||
 | 
								ir->code[i+3] = 0xFF;
 | 
				
			||||||
 | 
							} else if (p->code[i+4] > 0xFE) {
 | 
				
			||||||
 | 
								DEBUGF("\n%04X : Mark/Space overflow\n", p->code[i+4]);
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								ir->code[i+3] = (p->code[i+4] * p->usec) / USECPERTICK;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							DEBUGF("%s%d", !i ? "" : (i&1 ? "," : ", "), ir->code[i+3]);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						DEBUGF("|\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ir->FF = (ir->FF * p->usec) / USECPERTICK;
 | 
				
			||||||
 | 
						DEBUGF("FF -> %d\n", ir->FF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					void  irDump (irCode_t* ir)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int  i, len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printf("uint8_t  buttonName[%d] = {", len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printf("%d,%d, ", (ir->FF >> 8), ir->FF & 0xFF);
 | 
				
			||||||
 | 
						printf("%d,%d,%d, ", ir->code[0], ir->code[1], ir->code[2]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						len = (ir->code[1] * 2) + (ir->code[2] * 2);
 | 
				
			||||||
 | 
						for (i = 0;  i < len;  i++) {
 | 
				
			||||||
 | 
							printf("%s%d", !i ? "" : (i&1 ? "," : ", "), ir->code[i+3]);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printf("};\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					int  main ( )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						pronto_t  pCode;
 | 
				
			||||||
 | 
						irCode_t  irCode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						decode(prontoTest, &pCode, &irCode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						irDump(&irCode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //0
 | 
				
			||||||
							
								
								
									
										223
									
								
								IRremote/irRecv.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										223
									
								
								IRremote/irRecv.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,223 @@
 | 
				
			|||||||
 | 
					#include "IRremote.h"
 | 
				
			||||||
 | 
					#include "IRremoteInt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// Decodes the received IR message
 | 
				
			||||||
 | 
					// Returns 0 if no data ready, 1 if data ready.
 | 
				
			||||||
 | 
					// Results of decoding are stored in results
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					int  IRrecv::decode (decode_results *results)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						results->rawbuf   = irparams.rawbuf;
 | 
				
			||||||
 | 
						results->rawlen   = irparams.rawlen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						results->overflow = irparams.overflow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (irparams.rcvstate != STATE_STOP)  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if DECODE_NEC
 | 
				
			||||||
 | 
						DBG_PRINTLN("Attempting NEC decode");
 | 
				
			||||||
 | 
						if (decodeNEC(results))  return true ;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if DECODE_SONY
 | 
				
			||||||
 | 
						DBG_PRINTLN("Attempting Sony decode");
 | 
				
			||||||
 | 
						if (decodeSony(results))  return true ;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if DECODE_SANYO
 | 
				
			||||||
 | 
						DBG_PRINTLN("Attempting Sanyo decode");
 | 
				
			||||||
 | 
						if (decodeSanyo(results))  return true ;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if DECODE_MITSUBISHI
 | 
				
			||||||
 | 
						DBG_PRINTLN("Attempting Mitsubishi decode");
 | 
				
			||||||
 | 
						if (decodeMitsubishi(results))  return true ;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if DECODE_RC5
 | 
				
			||||||
 | 
						DBG_PRINTLN("Attempting RC5 decode");
 | 
				
			||||||
 | 
						if (decodeRC5(results))  return true ;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if DECODE_RC6
 | 
				
			||||||
 | 
						DBG_PRINTLN("Attempting RC6 decode");
 | 
				
			||||||
 | 
						if (decodeRC6(results))  return true ;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if DECODE_PANASONIC
 | 
				
			||||||
 | 
						DBG_PRINTLN("Attempting Panasonic decode");
 | 
				
			||||||
 | 
						if (decodePanasonic(results))  return true ;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if DECODE_LG
 | 
				
			||||||
 | 
						DBG_PRINTLN("Attempting LG decode");
 | 
				
			||||||
 | 
						if (decodeLG(results))  return true ;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if DECODE_JVC
 | 
				
			||||||
 | 
						DBG_PRINTLN("Attempting JVC decode");
 | 
				
			||||||
 | 
						if (decodeJVC(results))  return true ;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if DECODE_SAMSUNG
 | 
				
			||||||
 | 
						DBG_PRINTLN("Attempting SAMSUNG decode");
 | 
				
			||||||
 | 
						if (decodeSAMSUNG(results))  return true ;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if DECODE_WHYNTER
 | 
				
			||||||
 | 
						DBG_PRINTLN("Attempting Whynter decode");
 | 
				
			||||||
 | 
						if (decodeWhynter(results))  return true ;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if DECODE_AIWA_RC_T501
 | 
				
			||||||
 | 
						DBG_PRINTLN("Attempting Aiwa RC-T501 decode");
 | 
				
			||||||
 | 
						if (decodeAiwaRCT501(results))  return true ;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if DECODE_DENON
 | 
				
			||||||
 | 
						DBG_PRINTLN("Attempting Denon decode");
 | 
				
			||||||
 | 
						if (decodeDenon(results))  return true ;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if DECODE_LEGO_PF
 | 
				
			||||||
 | 
						DBG_PRINTLN("Attempting Lego Power Functions");
 | 
				
			||||||
 | 
						if (decodeLegoPowerFunctions(results))  return true ;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// decodeHash returns a hash on any input.
 | 
				
			||||||
 | 
						// Thus, it needs to be last in the list.
 | 
				
			||||||
 | 
						// If you add any decodes, add them before this.
 | 
				
			||||||
 | 
						if (decodeHash(results))  return true ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Throw away and start over
 | 
				
			||||||
 | 
						resume();
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					IRrecv::IRrecv (int recvpin)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						irparams.recvpin = recvpin;
 | 
				
			||||||
 | 
						irparams.blinkflag = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					IRrecv::IRrecv (int recvpin, int blinkpin)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						irparams.recvpin = recvpin;
 | 
				
			||||||
 | 
						irparams.blinkpin = blinkpin;
 | 
				
			||||||
 | 
						pinMode(blinkpin, OUTPUT);
 | 
				
			||||||
 | 
						irparams.blinkflag = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// initialization
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#ifdef USE_DEFAULT_ENABLE_IR_IN
 | 
				
			||||||
 | 
					void  IRrecv::enableIRIn ( )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					// Interrupt Service Routine - Fires every 50uS
 | 
				
			||||||
 | 
						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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif // USE_DEFAULT_ENABLE_IR_IN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// Enable/disable blinking of pin 13 on IR processing
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					void  IRrecv::blink13 (int blinkflag)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef BLINKLED
 | 
				
			||||||
 | 
						irparams.blinkflag = blinkflag;
 | 
				
			||||||
 | 
						if (blinkflag)  pinMode(BLINKLED, OUTPUT) ;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// Return if receiving new IR signals
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					bool  IRrecv::isIdle ( )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					 return (irparams.rcvstate == STATE_IDLE || irparams.rcvstate == STATE_STOP) ? true : false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// Restart the ISR state machine
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					void  IRrecv::resume ( )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						irparams.rcvstate = STATE_IDLE;
 | 
				
			||||||
 | 
						irparams.rawlen = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// hashdecode - 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.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The algorithm: look at the sequence of MARK signals, and see if each one
 | 
				
			||||||
 | 
					// is shorter (0), the same length (1), or longer (2) than the previous.
 | 
				
			||||||
 | 
					// Do the same with the SPACE signals.  Hash the resulting sequence of 0's,
 | 
				
			||||||
 | 
					// 1's, and 2's to a 32-bit value.  This will give a unique value for each
 | 
				
			||||||
 | 
					// different code (probably), for most code systems.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// http://arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Compare two tick values, returning 0 if newval is shorter,
 | 
				
			||||||
 | 
					// 1 if newval is equal, and 2 if newval is longer
 | 
				
			||||||
 | 
					// Use a tolerance of 20%
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					int  IRrecv::compare (unsigned int oldval,  unsigned int newval)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if      (newval < oldval * .8)  return 0 ;
 | 
				
			||||||
 | 
						else if (oldval < newval * .8)  return 2 ;
 | 
				
			||||||
 | 
						else                            return 1 ;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param
 | 
				
			||||||
 | 
					// Converts the raw code values into a 32-bit hash code.
 | 
				
			||||||
 | 
					// Hopefully this code is unique for each button.
 | 
				
			||||||
 | 
					// This isn't a "real" decoding, just an arbitrary value.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#define FNV_PRIME_32 16777619
 | 
				
			||||||
 | 
					#define FNV_BASIS_32 2166136261
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					long  IRrecv::decodeHash (decode_results *results)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						long  hash = FNV_BASIS_32;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Require at least 6 samples to prevent triggering on noise
 | 
				
			||||||
 | 
						if (results->rawlen < 6)  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (int i = 1;  (i + 2) < results->rawlen;  i++) {
 | 
				
			||||||
 | 
							int value =  compare(results->rawbuf[i], results->rawbuf[i+2]);
 | 
				
			||||||
 | 
							// Add value into the hash
 | 
				
			||||||
 | 
							hash = (hash * FNV_PRIME_32) ^ value;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						results->value       = hash;
 | 
				
			||||||
 | 
						results->bits        = 32;
 | 
				
			||||||
 | 
						results->decode_type = UNKNOWN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										139
									
								
								IRremote/irSend.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								IRremote/irSend.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,139 @@
 | 
				
			|||||||
 | 
					#include "IRremote.h"
 | 
				
			||||||
 | 
					#include "IRremoteInt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef SENDING_SUPPORTED
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					void  IRsend::sendRaw (const unsigned int buf[],  unsigned int len,  unsigned int hz)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// Set IR carrier frequency
 | 
				
			||||||
 | 
						enableIROut(hz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (unsigned int i = 0;  i < len;  i++) {
 | 
				
			||||||
 | 
							if (i & 1)  space(buf[i]) ;
 | 
				
			||||||
 | 
							else        mark (buf[i]) ;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						space(0);  // Always end with the LED off
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef USE_SOFT_CARRIER
 | 
				
			||||||
 | 
					void inline IRsend::sleepMicros(unsigned long us)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef USE_SPIN_WAIT
 | 
				
			||||||
 | 
						sleepUntilMicros(micros() + us);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						if (us > 0U) // Is this necessary? (Official docu https://www.arduino.cc/en/Reference/DelayMicroseconds does not tell.)
 | 
				
			||||||
 | 
							delayMicroseconds((unsigned int) us);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void inline IRsend::sleepUntilMicros(unsigned long targetTime)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef USE_SPIN_WAIT
 | 
				
			||||||
 | 
						while (micros() < targetTime)
 | 
				
			||||||
 | 
							;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					        unsigned long now = micros();
 | 
				
			||||||
 | 
					        if (now < targetTime)
 | 
				
			||||||
 | 
					                sleepMicros(targetTime - now);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif // USE_SOFT_CARRIER
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// Sends an IR mark for the specified number of microseconds.
 | 
				
			||||||
 | 
					// The mark output is modulated at the PWM frequency.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void IRsend::mark(unsigned int time)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef USE_SOFT_CARRIER
 | 
				
			||||||
 | 
						unsigned long start = micros();
 | 
				
			||||||
 | 
						unsigned long stop = start + time;
 | 
				
			||||||
 | 
						if (stop + periodTime < start)
 | 
				
			||||||
 | 
							// Counter wrap-around, happens very seldomly, but CAN happen.
 | 
				
			||||||
 | 
							// Just give up instead of possibly damaging the hardware.
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						unsigned long nextPeriodEnding = start;
 | 
				
			||||||
 | 
						unsigned long now = micros();
 | 
				
			||||||
 | 
						while (now < stop) {
 | 
				
			||||||
 | 
							SENDPIN_ON(sendPin);
 | 
				
			||||||
 | 
							sleepMicros(periodOnTime);
 | 
				
			||||||
 | 
							SENDPIN_OFF(sendPin);
 | 
				
			||||||
 | 
							nextPeriodEnding += periodTime;
 | 
				
			||||||
 | 
							sleepUntilMicros(nextPeriodEnding);
 | 
				
			||||||
 | 
							now = micros();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						TIMER_ENABLE_PWM; // Enable pin 3 PWM output
 | 
				
			||||||
 | 
						if (time > 0) custom_delay_usec(time);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// Leave pin off for time (given in microseconds)
 | 
				
			||||||
 | 
					// Sends an IR space for the specified number of microseconds.
 | 
				
			||||||
 | 
					// A space is no output, so the PWM output is disabled.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					void  IRsend::space (unsigned int time)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						TIMER_DISABLE_PWM; // Disable pin 3 PWM output
 | 
				
			||||||
 | 
						if (time > 0) IRsend::custom_delay_usec(time);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// 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.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					void  IRsend::enableIROut (int khz)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef USE_SOFT_CARRIER
 | 
				
			||||||
 | 
						periodTime = (1000U + khz/2) / khz; // = 1000/khz + 1/2 = round(1000.0/khz)
 | 
				
			||||||
 | 
						periodOnTime = periodTime * DUTY_CYCLE / 100U - PULSE_CORRECTION;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						// Disable the Timer2 Interrupt (which is used for receiving IR)
 | 
				
			||||||
 | 
						TIMER_DISABLE_INTR; //Timer2 Overflow Interrupt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pinMode(sendPin, OUTPUT);
 | 
				
			||||||
 | 
						SENDPIN_OFF(sendPin); // When not sending, we want it low
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// COM2A = 00: disconnect OC2A
 | 
				
			||||||
 | 
						// COM2B = 00: disconnect OC2B; to send signal set to 10: OC2B non-inverted
 | 
				
			||||||
 | 
						// WGM2 = 101: phase-correct PWM with OCRA as top
 | 
				
			||||||
 | 
						// CS2  = 000: no prescaling
 | 
				
			||||||
 | 
						// The top value for the timer.  The modulation frequency will be SYSCLOCK / 2 / OCR2A.
 | 
				
			||||||
 | 
						TIMER_CONFIG_KHZ(khz);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// Custom delay function that circumvents Arduino's delayMicroseconds limit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void IRsend::custom_delay_usec(unsigned long uSecs) {
 | 
				
			||||||
 | 
					  if (uSecs > 4) {
 | 
				
			||||||
 | 
					    unsigned long start = micros();
 | 
				
			||||||
 | 
					    unsigned long endMicros = start + uSecs - 4;
 | 
				
			||||||
 | 
					    if (endMicros < start) { // Check if overflow
 | 
				
			||||||
 | 
					      while ( micros() > start ) {} // wait until overflow
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    while ( micros() < endMicros ) {} // normal wait
 | 
				
			||||||
 | 
					  } 
 | 
				
			||||||
 | 
					  //else {
 | 
				
			||||||
 | 
					  //  __asm__("nop\n\t"); // must have or compiler optimizes out
 | 
				
			||||||
 | 
					  //}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // SENDING_SUPPORTED
 | 
				
			||||||
							
								
								
									
										105
									
								
								IRremote/ir_Aiwa.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								IRremote/ir_Aiwa.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,105 @@
 | 
				
			|||||||
 | 
					#include "IRremote.h"
 | 
				
			||||||
 | 
					#include "IRremoteInt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					//                         AAA   IIIII  W   W   AAA
 | 
				
			||||||
 | 
					//                        A   A    I    W   W  A   A
 | 
				
			||||||
 | 
					//                        AAAAA    I    W W W  AAAAA
 | 
				
			||||||
 | 
					//                        A   A    I    W W W  A   A
 | 
				
			||||||
 | 
					//                        A   A  IIIII   WWW   A   A
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Based off the RC-T501 RCU
 | 
				
			||||||
 | 
					// Lirc file http://lirc.sourceforge.net/remotes/aiwa/RC-T501
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AIWA_RC_T501_HZ            38
 | 
				
			||||||
 | 
					#define AIWA_RC_T501_BITS          15
 | 
				
			||||||
 | 
					#define AIWA_RC_T501_PRE_BITS      26
 | 
				
			||||||
 | 
					#define AIWA_RC_T501_POST_BITS      1
 | 
				
			||||||
 | 
					#define AIWA_RC_T501_SUM_BITS    (AIWA_RC_T501_PRE_BITS + AIWA_RC_T501_BITS + AIWA_RC_T501_POST_BITS)
 | 
				
			||||||
 | 
					#define AIWA_RC_T501_HDR_MARK    8800
 | 
				
			||||||
 | 
					#define AIWA_RC_T501_HDR_SPACE   4500
 | 
				
			||||||
 | 
					#define AIWA_RC_T501_BIT_MARK     500
 | 
				
			||||||
 | 
					#define AIWA_RC_T501_ONE_SPACE    600
 | 
				
			||||||
 | 
					#define AIWA_RC_T501_ZERO_SPACE  1700
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					#if SEND_AIWA_RC_T501
 | 
				
			||||||
 | 
					void  IRsend::sendAiwaRCT501 (int code)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned long  pre = 0x0227EEC0;  // 26-bits
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Set IR carrier frequency
 | 
				
			||||||
 | 
						enableIROut(AIWA_RC_T501_HZ);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Header
 | 
				
			||||||
 | 
						mark(AIWA_RC_T501_HDR_MARK);
 | 
				
			||||||
 | 
						space(AIWA_RC_T501_HDR_SPACE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Send "pre" data
 | 
				
			||||||
 | 
						for (unsigned long  mask = 1UL << (26 - 1);  mask;  mask >>= 1) {
 | 
				
			||||||
 | 
							mark(AIWA_RC_T501_BIT_MARK);
 | 
				
			||||||
 | 
							if (pre & mask)  space(AIWA_RC_T501_ONE_SPACE) ;
 | 
				
			||||||
 | 
							else             space(AIWA_RC_T501_ZERO_SPACE) ;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-v- THIS CODE LOOKS LIKE IT MIGHT BE WRONG - CHECK!
 | 
				
			||||||
 | 
					//    it only send 15bits and ignores the top bit
 | 
				
			||||||
 | 
					//    then uses TOPBIT which is 0x80000000 to check the bit code
 | 
				
			||||||
 | 
					//    I suspect TOPBIT should be changed to 0x00008000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Skip first code bit
 | 
				
			||||||
 | 
						code <<= 1;
 | 
				
			||||||
 | 
						// Send code
 | 
				
			||||||
 | 
						for (int  i = 0;  i < 15;  i++) {
 | 
				
			||||||
 | 
							mark(AIWA_RC_T501_BIT_MARK);
 | 
				
			||||||
 | 
							if (code & 0x80000000)  space(AIWA_RC_T501_ONE_SPACE) ;
 | 
				
			||||||
 | 
							else                    space(AIWA_RC_T501_ZERO_SPACE) ;
 | 
				
			||||||
 | 
							code <<= 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-^- THIS CODE LOOKS LIKE IT MIGHT BE WRONG - CHECK!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// POST-DATA, 1 bit, 0x0
 | 
				
			||||||
 | 
						mark(AIWA_RC_T501_BIT_MARK);
 | 
				
			||||||
 | 
						space(AIWA_RC_T501_ZERO_SPACE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mark(AIWA_RC_T501_BIT_MARK);
 | 
				
			||||||
 | 
						space(0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					#if DECODE_AIWA_RC_T501
 | 
				
			||||||
 | 
					bool  IRrecv::decodeAiwaRCT501 (decode_results *results)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int  data   = 0;
 | 
				
			||||||
 | 
						int  offset = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check SIZE
 | 
				
			||||||
 | 
						if (irparams.rawlen < 2 * (AIWA_RC_T501_SUM_BITS) + 4)  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check HDR Mark/Space
 | 
				
			||||||
 | 
						if (!MATCH_MARK (results->rawbuf[offset++], AIWA_RC_T501_HDR_MARK ))  return false ;
 | 
				
			||||||
 | 
						if (!MATCH_SPACE(results->rawbuf[offset++], AIWA_RC_T501_HDR_SPACE))  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						offset += 26;  // skip pre-data - optional
 | 
				
			||||||
 | 
						while(offset < irparams.rawlen - 4) {
 | 
				
			||||||
 | 
							if (MATCH_MARK(results->rawbuf[offset], AIWA_RC_T501_BIT_MARK))  offset++ ;
 | 
				
			||||||
 | 
							else                                                             return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// ONE & ZERO
 | 
				
			||||||
 | 
							if      (MATCH_SPACE(results->rawbuf[offset], AIWA_RC_T501_ONE_SPACE))   data = (data << 1) | 1 ;
 | 
				
			||||||
 | 
							else if (MATCH_SPACE(results->rawbuf[offset], AIWA_RC_T501_ZERO_SPACE))  data = (data << 1) | 0 ;
 | 
				
			||||||
 | 
							else                                                                     break ;  // End of one & zero detected
 | 
				
			||||||
 | 
							offset++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						results->bits = (offset - 1) / 2;
 | 
				
			||||||
 | 
						if (results->bits < 42)  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						results->value       = data;
 | 
				
			||||||
 | 
						results->decode_type = AIWA_RC_T501;
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										94
									
								
								IRremote/ir_Denon.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								IRremote/ir_Denon.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,94 @@
 | 
				
			|||||||
 | 
					#include "IRremote.h"
 | 
				
			||||||
 | 
					#include "IRremoteInt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Reverse Engineered by looking at RAW dumps generated by IRremote
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// I have since discovered that Denon publish all their IR codes:
 | 
				
			||||||
 | 
					//  https://www.google.co.uk/search?q=DENON+MASTER+IR+Hex+Command+Sheet
 | 
				
			||||||
 | 
					//  -> http://assets.denon.com/documentmaster/us/denon%20master%20ir%20hex.xls
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Having looked at the official Denon Pronto sheet and reverse engineered
 | 
				
			||||||
 | 
					// the timing values from it, it is obvious that Denon have a range of
 | 
				
			||||||
 | 
					// different timings and protocols ...the values here work for my AVR-3801 Amp!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					//                    DDDD   EEEEE  N   N   OOO   N   N
 | 
				
			||||||
 | 
					//                     D  D  E      NN  N  O   O  NN  N
 | 
				
			||||||
 | 
					//                     D  D  EEE    N N N  O   O  N N N
 | 
				
			||||||
 | 
					//                     D  D  E      N  NN  O   O  N  NN
 | 
				
			||||||
 | 
					//                    DDDD   EEEEE  N   N   OOO   N   N
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BITS          14  // The number of bits in the command
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HDR_MARK     300  // The length of the Header:Mark
 | 
				
			||||||
 | 
					#define HDR_SPACE    750  // The lenght of the Header:Space
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BIT_MARK     300  // The length of a Bit:Mark
 | 
				
			||||||
 | 
					#define ONE_SPACE   1800  // The length of a Bit:Space for 1's
 | 
				
			||||||
 | 
					#define ZERO_SPACE   750  // The length of a Bit:Space for 0's
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#if SEND_DENON
 | 
				
			||||||
 | 
					void  IRsend::sendDenon (unsigned long data,  int nbits)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// Set IR carrier frequency
 | 
				
			||||||
 | 
						enableIROut(38);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Header
 | 
				
			||||||
 | 
						mark (HDR_MARK);
 | 
				
			||||||
 | 
						space(HDR_SPACE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Data
 | 
				
			||||||
 | 
						for (unsigned long  mask = 1UL << (nbits - 1);  mask;  mask >>= 1) {
 | 
				
			||||||
 | 
							if (data & mask) {
 | 
				
			||||||
 | 
								mark (BIT_MARK);
 | 
				
			||||||
 | 
								space(ONE_SPACE);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								mark (BIT_MARK);
 | 
				
			||||||
 | 
								space(ZERO_SPACE);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Footer
 | 
				
			||||||
 | 
						mark(BIT_MARK);
 | 
				
			||||||
 | 
					    space(0);  // Always end with the LED off
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#if DECODE_DENON
 | 
				
			||||||
 | 
					bool  IRrecv::decodeDenon (decode_results *results)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned long  data   = 0;  // Somewhere to build our code
 | 
				
			||||||
 | 
						int            offset = 1;  // Skip the Gap reading
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check we have the right amount of data
 | 
				
			||||||
 | 
						if (irparams.rawlen != 1 + 2 + (2 * BITS) + 1)  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check initial Mark+Space match
 | 
				
			||||||
 | 
						if (!MATCH_MARK (results->rawbuf[offset++], HDR_MARK ))  return false ;
 | 
				
			||||||
 | 
						if (!MATCH_SPACE(results->rawbuf[offset++], HDR_SPACE))  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Read the bits in
 | 
				
			||||||
 | 
						for (int i = 0;  i < BITS;  i++) {
 | 
				
			||||||
 | 
							// Each bit looks like: MARK + SPACE_1 -> 1
 | 
				
			||||||
 | 
							//                 or : MARK + SPACE_0 -> 0
 | 
				
			||||||
 | 
							if (!MATCH_MARK(results->rawbuf[offset++], BIT_MARK))  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// IR data is big-endian, so we shuffle it in from the right:
 | 
				
			||||||
 | 
							if      (MATCH_SPACE(results->rawbuf[offset], ONE_SPACE))   data = (data << 1) | 1 ;
 | 
				
			||||||
 | 
							else if (MATCH_SPACE(results->rawbuf[offset], ZERO_SPACE))  data = (data << 1) | 0 ;
 | 
				
			||||||
 | 
							else                                                        return false ;
 | 
				
			||||||
 | 
							offset++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Success
 | 
				
			||||||
 | 
						results->bits        = BITS;
 | 
				
			||||||
 | 
						results->value       = data;
 | 
				
			||||||
 | 
						results->decode_type = DENON;
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										54
									
								
								IRremote/ir_Dish.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								IRremote/ir_Dish.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					#include "IRremote.h"
 | 
				
			||||||
 | 
					#include "IRremoteInt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					//                       DDDD   IIIII   SSSS  H   H
 | 
				
			||||||
 | 
					//                        D  D    I    S      H   H
 | 
				
			||||||
 | 
					//                        D  D    I     SSS   HHHHH
 | 
				
			||||||
 | 
					//                        D  D    I        S  H   H
 | 
				
			||||||
 | 
					//                       DDDD   IIIII  SSSS   H   H
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Sharp and DISH support by Todd Treece ( http://unionbridge.org/design/ircommand )
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The sned function needs to be repeated 4 times
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Only send the last for characters of the hex.
 | 
				
			||||||
 | 
					// I.E.  Use 0x1C10 instead of 0x0000000000001C10 as listed in the LIRC file.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Here is the LIRC file I found that seems to match the remote codes from the
 | 
				
			||||||
 | 
					// oscilloscope:
 | 
				
			||||||
 | 
					//   DISH NETWORK (echostar 301):
 | 
				
			||||||
 | 
					//   http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DISH_BITS          16
 | 
				
			||||||
 | 
					#define DISH_HDR_MARK     400
 | 
				
			||||||
 | 
					#define DISH_HDR_SPACE   6100
 | 
				
			||||||
 | 
					#define DISH_BIT_MARK     400
 | 
				
			||||||
 | 
					#define DISH_ONE_SPACE   1700
 | 
				
			||||||
 | 
					#define DISH_ZERO_SPACE  2800
 | 
				
			||||||
 | 
					#define DISH_RPT_SPACE   6200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					#if SEND_DISH
 | 
				
			||||||
 | 
					void  IRsend::sendDISH (unsigned long data,  int nbits)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// Set IR carrier frequency
 | 
				
			||||||
 | 
						enableIROut(56);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mark(DISH_HDR_MARK);
 | 
				
			||||||
 | 
						space(DISH_HDR_SPACE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (unsigned long  mask = 1UL << (nbits - 1);  mask;  mask >>= 1) {
 | 
				
			||||||
 | 
							if (data & mask) {
 | 
				
			||||||
 | 
								mark(DISH_BIT_MARK);
 | 
				
			||||||
 | 
								space(DISH_ONE_SPACE);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								mark(DISH_BIT_MARK);
 | 
				
			||||||
 | 
								space(DISH_ZERO_SPACE);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						mark(DISH_HDR_MARK); //added 26th March 2016, by AnalysIR ( https://www.AnalysIR.com )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										101
									
								
								IRremote/ir_JVC.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								IRremote/ir_JVC.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,101 @@
 | 
				
			|||||||
 | 
					#include "IRremote.h"
 | 
				
			||||||
 | 
					#include "IRremoteInt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					//                             JJJJJ  V   V   CCCC
 | 
				
			||||||
 | 
					//                               J    V   V  C
 | 
				
			||||||
 | 
					//                               J     V V   C
 | 
				
			||||||
 | 
					//                             J J     V V   C
 | 
				
			||||||
 | 
					//                              J       V     CCCC
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define JVC_BITS           16
 | 
				
			||||||
 | 
					#define JVC_HDR_MARK     8000
 | 
				
			||||||
 | 
					#define JVC_HDR_SPACE    4000
 | 
				
			||||||
 | 
					#define JVC_BIT_MARK      600
 | 
				
			||||||
 | 
					#define JVC_ONE_SPACE    1600
 | 
				
			||||||
 | 
					#define JVC_ZERO_SPACE    550
 | 
				
			||||||
 | 
					#define JVC_RPT_LENGTH  60000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// JVC does NOT repeat by sending a separate code (like NEC does).
 | 
				
			||||||
 | 
					// The JVC protocol repeats by skipping the header.
 | 
				
			||||||
 | 
					// To send a JVC repeat signal, send the original code value
 | 
				
			||||||
 | 
					//   and set 'repeat' to true
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#if SEND_JVC
 | 
				
			||||||
 | 
					void  IRsend::sendJVC (unsigned long data,  int nbits,  bool repeat)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// Set IR carrier frequency
 | 
				
			||||||
 | 
						enableIROut(38);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Only send the Header if this is NOT a repeat command
 | 
				
			||||||
 | 
						if (!repeat){
 | 
				
			||||||
 | 
							mark(JVC_HDR_MARK);
 | 
				
			||||||
 | 
							space(JVC_HDR_SPACE);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Data
 | 
				
			||||||
 | 
						for (unsigned long  mask = 1UL << (nbits - 1);  mask;  mask >>= 1) {
 | 
				
			||||||
 | 
							if (data & mask) {
 | 
				
			||||||
 | 
								mark(JVC_BIT_MARK);
 | 
				
			||||||
 | 
								space(JVC_ONE_SPACE);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								mark(JVC_BIT_MARK);
 | 
				
			||||||
 | 
								space(JVC_ZERO_SPACE);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Footer
 | 
				
			||||||
 | 
					    mark(JVC_BIT_MARK);
 | 
				
			||||||
 | 
					    space(0);  // Always end with the LED off
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					#if DECODE_JVC
 | 
				
			||||||
 | 
					bool  IRrecv::decodeJVC (decode_results *results)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						long  data   = 0;
 | 
				
			||||||
 | 
						int   offset = 1; // Skip first space
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check for repeat
 | 
				
			||||||
 | 
						if (  (irparams.rawlen - 1 == 33)
 | 
				
			||||||
 | 
						    && MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK)
 | 
				
			||||||
 | 
						    && MATCH_MARK(results->rawbuf[irparams.rawlen-1], JVC_BIT_MARK)
 | 
				
			||||||
 | 
						   ) {
 | 
				
			||||||
 | 
							results->bits        = 0;
 | 
				
			||||||
 | 
							results->value       = REPEAT;
 | 
				
			||||||
 | 
							results->decode_type = JVC;
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Initial mark
 | 
				
			||||||
 | 
						if (!MATCH_MARK(results->rawbuf[offset++], JVC_HDR_MARK))  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (irparams.rawlen < (2 * JVC_BITS) + 1 )  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Initial space
 | 
				
			||||||
 | 
						if (!MATCH_SPACE(results->rawbuf[offset++], JVC_HDR_SPACE))  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (int i = 0;  i < JVC_BITS;  i++) {
 | 
				
			||||||
 | 
							if (!MATCH_MARK(results->rawbuf[offset++], JVC_BIT_MARK))  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if      (MATCH_SPACE(results->rawbuf[offset], JVC_ONE_SPACE))   data = (data << 1) | 1 ;
 | 
				
			||||||
 | 
							else if (MATCH_SPACE(results->rawbuf[offset], JVC_ZERO_SPACE))  data = (data << 1) | 0 ;
 | 
				
			||||||
 | 
							else                                                            return false ;
 | 
				
			||||||
 | 
							offset++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Stop bit
 | 
				
			||||||
 | 
						if (!MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK))  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Success
 | 
				
			||||||
 | 
						results->bits        = JVC_BITS;
 | 
				
			||||||
 | 
						results->value       = data;
 | 
				
			||||||
 | 
						results->decode_type = JVC;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										80
									
								
								IRremote/ir_LG.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								IRremote/ir_LG.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
				
			|||||||
 | 
					#include "IRremote.h"
 | 
				
			||||||
 | 
					#include "IRremoteInt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					//                               L       GGGG
 | 
				
			||||||
 | 
					//                               L      G
 | 
				
			||||||
 | 
					//                               L      G  GG
 | 
				
			||||||
 | 
					//                               L      G   G
 | 
				
			||||||
 | 
					//                               LLLLL   GGG
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define LG_BITS 28
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define LG_HDR_MARK 8000
 | 
				
			||||||
 | 
					#define LG_HDR_SPACE 4000
 | 
				
			||||||
 | 
					#define LG_BIT_MARK 600
 | 
				
			||||||
 | 
					#define LG_ONE_SPACE 1600
 | 
				
			||||||
 | 
					#define LG_ZERO_SPACE 550
 | 
				
			||||||
 | 
					#define LG_RPT_LENGTH 60000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					#if DECODE_LG
 | 
				
			||||||
 | 
					bool  IRrecv::decodeLG (decode_results *results)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    long  data   = 0;
 | 
				
			||||||
 | 
					    int   offset = 1; // Skip first space
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check we have the right amount of data
 | 
				
			||||||
 | 
					    if (irparams.rawlen < (2 * LG_BITS) + 1 )  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Initial mark/space
 | 
				
			||||||
 | 
					    if (!MATCH_MARK(results->rawbuf[offset++], LG_HDR_MARK))  return false ;
 | 
				
			||||||
 | 
					    if (!MATCH_SPACE(results->rawbuf[offset++], LG_HDR_SPACE))  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int i = 0;  i < LG_BITS;  i++) {
 | 
				
			||||||
 | 
					        if (!MATCH_MARK(results->rawbuf[offset++], LG_BIT_MARK))  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if      (MATCH_SPACE(results->rawbuf[offset], LG_ONE_SPACE))   data = (data << 1) | 1 ;
 | 
				
			||||||
 | 
					        else if (MATCH_SPACE(results->rawbuf[offset], LG_ZERO_SPACE))  data = (data << 1) | 0 ;
 | 
				
			||||||
 | 
					        else                                                           return false ;
 | 
				
			||||||
 | 
					        offset++;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Stop bit
 | 
				
			||||||
 | 
					    if (!MATCH_MARK(results->rawbuf[offset], LG_BIT_MARK))   return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Success
 | 
				
			||||||
 | 
					    results->bits        = LG_BITS;
 | 
				
			||||||
 | 
					    results->value       = data;
 | 
				
			||||||
 | 
					    results->decode_type = LG;
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					#if SEND_LG
 | 
				
			||||||
 | 
					void  IRsend::sendLG (unsigned long data,  int nbits)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // Set IR carrier frequency
 | 
				
			||||||
 | 
					    enableIROut(38);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Header
 | 
				
			||||||
 | 
					    mark(LG_HDR_MARK);
 | 
				
			||||||
 | 
					    space(LG_HDR_SPACE);
 | 
				
			||||||
 | 
					    mark(LG_BIT_MARK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Data
 | 
				
			||||||
 | 
					    for (unsigned long  mask = 1UL << (nbits - 1);  mask;  mask >>= 1) {
 | 
				
			||||||
 | 
					        if (data & mask) {
 | 
				
			||||||
 | 
					            space(LG_ONE_SPACE);
 | 
				
			||||||
 | 
					            mark(LG_BIT_MARK);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            space(LG_ZERO_SPACE);
 | 
				
			||||||
 | 
					            mark(LG_BIT_MARK);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    space(0);  // Always end with the LED off
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										46
									
								
								IRremote/ir_Lego_PF.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								IRremote/ir_Lego_PF.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
				
			|||||||
 | 
					#include "IRremote.h"
 | 
				
			||||||
 | 
					#include "IRremoteInt.h"
 | 
				
			||||||
 | 
					#include "ir_Lego_PF_BitStreamEncoder.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					//    L       EEEEEE   EEEE    OOOO
 | 
				
			||||||
 | 
					//    L       E       E       O    O
 | 
				
			||||||
 | 
					//    L       EEEE    E  EEE  O    O
 | 
				
			||||||
 | 
					//    L       E       E    E  O    O    LEGO Power Functions
 | 
				
			||||||
 | 
					//    LLLLLL  EEEEEE   EEEE    OOOO     Copyright (c) 2016 Philipp Henkel
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Supported Devices
 | 
				
			||||||
 | 
					// LEGO® Power Functions IR Receiver 8884
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#if SEND_LEGO_PF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if DEBUG
 | 
				
			||||||
 | 
					namespace {
 | 
				
			||||||
 | 
					void logFunctionParameters(uint16_t data, bool repeat) {
 | 
				
			||||||
 | 
					  DBG_PRINT("sendLegoPowerFunctions(data=");
 | 
				
			||||||
 | 
					  DBG_PRINT(data);
 | 
				
			||||||
 | 
					  DBG_PRINT(", repeat=");
 | 
				
			||||||
 | 
					  DBG_PRINTLN(repeat?"true)" : "false)");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					} // anonymous namespace
 | 
				
			||||||
 | 
					#endif // DEBUG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void IRsend::sendLegoPowerFunctions(uint16_t data, bool repeat)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if DEBUG
 | 
				
			||||||
 | 
					  ::logFunctionParameters(data, repeat);
 | 
				
			||||||
 | 
					#endif // DEBUG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  enableIROut(38);
 | 
				
			||||||
 | 
					  static LegoPfBitStreamEncoder bitStreamEncoder;
 | 
				
			||||||
 | 
					  bitStreamEncoder.reset(data, repeat);
 | 
				
			||||||
 | 
					  do {
 | 
				
			||||||
 | 
					    mark(bitStreamEncoder.getMarkDuration());
 | 
				
			||||||
 | 
					    space(bitStreamEncoder.getPauseDuration());
 | 
				
			||||||
 | 
					  } while (bitStreamEncoder.next());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // SEND_LEGO_PF
 | 
				
			||||||
							
								
								
									
										115
									
								
								IRremote/ir_Lego_PF_BitStreamEncoder.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								IRremote/ir_Lego_PF_BitStreamEncoder.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,115 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					//    L       EEEEEE   EEEE    OOOO
 | 
				
			||||||
 | 
					//    L       E       E       O    O
 | 
				
			||||||
 | 
					//    L       EEEE    E  EEE  O    O
 | 
				
			||||||
 | 
					//    L       E       E    E  O    O    LEGO Power Functions
 | 
				
			||||||
 | 
					//    LLLLLL  EEEEEE   EEEE    OOOO     Copyright (c) 2016, 2017 Philipp Henkel
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class LegoPfBitStreamEncoder {
 | 
				
			||||||
 | 
					 private:
 | 
				
			||||||
 | 
					  uint16_t data;
 | 
				
			||||||
 | 
					  bool repeatMessage;
 | 
				
			||||||
 | 
					  uint8_t messageBitIdx;
 | 
				
			||||||
 | 
					  uint8_t repeatCount;
 | 
				
			||||||
 | 
					  uint16_t messageLength;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  // HIGH data bit = IR mark + high pause
 | 
				
			||||||
 | 
					  // LOW data bit = IR mark + low pause
 | 
				
			||||||
 | 
					  static const uint16_t LOW_BIT_DURATION = 421;
 | 
				
			||||||
 | 
					  static const uint16_t HIGH_BIT_DURATION = 711;
 | 
				
			||||||
 | 
					  static const uint16_t START_BIT_DURATION = 1184;
 | 
				
			||||||
 | 
					  static const uint16_t STOP_BIT_DURATION = 1184;
 | 
				
			||||||
 | 
					  static const uint8_t IR_MARK_DURATION = 158;
 | 
				
			||||||
 | 
					  static const uint16_t HIGH_PAUSE_DURATION = HIGH_BIT_DURATION - IR_MARK_DURATION;
 | 
				
			||||||
 | 
					  static const uint16_t LOW_PAUSE_DURATION = LOW_BIT_DURATION - IR_MARK_DURATION;
 | 
				
			||||||
 | 
					  static const uint16_t START_PAUSE_DURATION = START_BIT_DURATION - IR_MARK_DURATION;
 | 
				
			||||||
 | 
					  static const uint16_t STOP_PAUSE_DURATION = STOP_BIT_DURATION - IR_MARK_DURATION;
 | 
				
			||||||
 | 
					  static const uint8_t MESSAGE_BITS = 18;
 | 
				
			||||||
 | 
					  static const uint16_t MAX_MESSAGE_LENGTH = 16000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void reset(uint16_t data, bool repeatMessage) {
 | 
				
			||||||
 | 
					    this->data = data;
 | 
				
			||||||
 | 
					    this->repeatMessage = repeatMessage;
 | 
				
			||||||
 | 
					    messageBitIdx = 0;
 | 
				
			||||||
 | 
					    repeatCount = 0;
 | 
				
			||||||
 | 
					    messageLength = getMessageLength();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int getChannelId() const { return 1 + ((data >> 12) & 0x3); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  uint16_t getMessageLength() const {
 | 
				
			||||||
 | 
					    // Sum up all marks
 | 
				
			||||||
 | 
					    uint16_t length = MESSAGE_BITS * IR_MARK_DURATION;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Sum up all pauses
 | 
				
			||||||
 | 
					    length += START_PAUSE_DURATION;
 | 
				
			||||||
 | 
					    for (unsigned long mask = 1UL << 15; mask; mask >>= 1) {
 | 
				
			||||||
 | 
					      if (data & mask) {
 | 
				
			||||||
 | 
					        length += HIGH_PAUSE_DURATION;
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        length += LOW_PAUSE_DURATION;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    length += STOP_PAUSE_DURATION;
 | 
				
			||||||
 | 
					    return length;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  boolean next() {
 | 
				
			||||||
 | 
					    messageBitIdx++;
 | 
				
			||||||
 | 
					    if (messageBitIdx >= MESSAGE_BITS) {
 | 
				
			||||||
 | 
					      repeatCount++;
 | 
				
			||||||
 | 
					      messageBitIdx = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (repeatCount >= 1 && !repeatMessage) {
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    } else if (repeatCount >= 5) {
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  uint8_t getMarkDuration() const { return IR_MARK_DURATION; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  uint32_t getPauseDuration() const {
 | 
				
			||||||
 | 
					    if (messageBitIdx == 0)
 | 
				
			||||||
 | 
					      return START_PAUSE_DURATION;
 | 
				
			||||||
 | 
					    else if (messageBitIdx < MESSAGE_BITS - 1) {
 | 
				
			||||||
 | 
					      return getDataBitPause();
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      return getStopPause();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 private:
 | 
				
			||||||
 | 
					  uint16_t getDataBitPause() const {
 | 
				
			||||||
 | 
					    const int pos = MESSAGE_BITS - 2 - messageBitIdx;
 | 
				
			||||||
 | 
					    const bool isHigh = data & (1 << pos);
 | 
				
			||||||
 | 
					    return isHigh ? HIGH_PAUSE_DURATION : LOW_PAUSE_DURATION;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  uint32_t getStopPause() const {
 | 
				
			||||||
 | 
					    if (repeatMessage) {
 | 
				
			||||||
 | 
					      return getRepeatStopPause();
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      return STOP_PAUSE_DURATION;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  uint32_t getRepeatStopPause() const {
 | 
				
			||||||
 | 
					    if (repeatCount == 0 || repeatCount == 1) {
 | 
				
			||||||
 | 
					      return STOP_PAUSE_DURATION + (uint32_t)5 * MAX_MESSAGE_LENGTH - messageLength;
 | 
				
			||||||
 | 
					    } else if (repeatCount == 2 || repeatCount == 3) {
 | 
				
			||||||
 | 
					      return STOP_PAUSE_DURATION
 | 
				
			||||||
 | 
					             + (uint32_t)(6 + 2 * getChannelId()) * MAX_MESSAGE_LENGTH - messageLength;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      return STOP_PAUSE_DURATION;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										85
									
								
								IRremote/ir_Mitsubishi.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								IRremote/ir_Mitsubishi.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,85 @@
 | 
				
			|||||||
 | 
					#include "IRremote.h"
 | 
				
			||||||
 | 
					#include "IRremoteInt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					//    MMMMM  IIIII TTTTT   SSSS  U   U  BBBB   IIIII   SSSS  H   H  IIIII
 | 
				
			||||||
 | 
					//    M M M    I     T    S      U   U  B   B    I    S      H   H    I
 | 
				
			||||||
 | 
					//    M M M    I     T     SSS   U   U  BBBB     I     SSS   HHHHH    I
 | 
				
			||||||
 | 
					//    M   M    I     T        S  U   U  B   B    I        S  H   H    I
 | 
				
			||||||
 | 
					//    M   M  IIIII   T    SSSS    UUU   BBBBB  IIIII  SSSS   H   H  IIIII
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Looks like Sony except for timings, 48 chars of data and time/space different
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MITSUBISHI_BITS 16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Mitsubishi RM 75501
 | 
				
			||||||
 | 
					// 14200 7 41 7 42 7 42 7 17 7 17 7 18 7 41 7 18 7 17 7 17 7 18 7 41 8 17 7 17 7 18 7 17 7
 | 
				
			||||||
 | 
					// #define MITSUBISHI_HDR_MARK	250  // seen range 3500
 | 
				
			||||||
 | 
					#define MITSUBISHI_HDR_SPACE	350 //  7*50+100
 | 
				
			||||||
 | 
					#define MITSUBISHI_ONE_MARK	1950 // 41*50-100
 | 
				
			||||||
 | 
					#define MITSUBISHI_ZERO_MARK  750 // 17*50-100
 | 
				
			||||||
 | 
					// #define MITSUBISHI_DOUBLE_SPACE_USECS  800  // usually ssee 713 - not using ticks as get number wrapround
 | 
				
			||||||
 | 
					// #define MITSUBISHI_RPT_LENGTH 45000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					#if DECODE_MITSUBISHI
 | 
				
			||||||
 | 
					bool  IRrecv::decodeMitsubishi (decode_results *results)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  // Serial.print("?!? decoding Mitsubishi:");Serial.print(irparams.rawlen); Serial.print(" want "); Serial.println( 2 * MITSUBISHI_BITS + 2);
 | 
				
			||||||
 | 
					  long data = 0;
 | 
				
			||||||
 | 
					  if (irparams.rawlen < 2 * MITSUBISHI_BITS + 2)  return false ;
 | 
				
			||||||
 | 
					  int offset = 0; // Skip first space
 | 
				
			||||||
 | 
					  // Initial space
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
					  // Put this back in for debugging - note can't use #DEBUG as if Debug on we don't see the repeat cos of the delay
 | 
				
			||||||
 | 
					  Serial.print("IR Gap: ");
 | 
				
			||||||
 | 
					  Serial.println( results->rawbuf[offset]);
 | 
				
			||||||
 | 
					  Serial.println( "test against:");
 | 
				
			||||||
 | 
					  Serial.println(results->rawbuf[offset]);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
					  // Not seeing double keys from Mitsubishi
 | 
				
			||||||
 | 
					  if (results->rawbuf[offset] < MITSUBISHI_DOUBLE_SPACE_USECS) {
 | 
				
			||||||
 | 
					    // Serial.print("IR Gap found: ");
 | 
				
			||||||
 | 
					    results->bits = 0;
 | 
				
			||||||
 | 
					    results->value = REPEAT;
 | 
				
			||||||
 | 
					    results->decode_type = MITSUBISHI;
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  offset++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Typical
 | 
				
			||||||
 | 
					  // 14200 7 41 7 42 7 42 7 17 7 17 7 18 7 41 7 18 7 17 7 17 7 18 7 41 8 17 7 17 7 18 7 17 7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Initial Space
 | 
				
			||||||
 | 
					  if (!MATCH_MARK(results->rawbuf[offset], MITSUBISHI_HDR_SPACE))  return false ;
 | 
				
			||||||
 | 
					  offset++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  while (offset + 1 < irparams.rawlen) {
 | 
				
			||||||
 | 
					    if      (MATCH_MARK(results->rawbuf[offset], MITSUBISHI_ONE_MARK))   data = (data << 1) | 1 ;
 | 
				
			||||||
 | 
					    else if (MATCH_MARK(results->rawbuf[offset], MITSUBISHI_ZERO_MARK))  data <<= 1 ;
 | 
				
			||||||
 | 
					    else                                                                 return false ;
 | 
				
			||||||
 | 
					    offset++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!MATCH_SPACE(results->rawbuf[offset], MITSUBISHI_HDR_SPACE))  break ;
 | 
				
			||||||
 | 
					    offset++;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Success
 | 
				
			||||||
 | 
					  results->bits = (offset - 1) / 2;
 | 
				
			||||||
 | 
					  if (results->bits < MITSUBISHI_BITS) {
 | 
				
			||||||
 | 
					    results->bits = 0;
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  results->value       = data;
 | 
				
			||||||
 | 
					  results->decode_type = MITSUBISHI;
 | 
				
			||||||
 | 
					  return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										98
									
								
								IRremote/ir_NEC.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								IRremote/ir_NEC.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,98 @@
 | 
				
			|||||||
 | 
					#include "IRremote.h"
 | 
				
			||||||
 | 
					#include "IRremoteInt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					//                           N   N  EEEEE   CCCC
 | 
				
			||||||
 | 
					//                           NN  N  E      C
 | 
				
			||||||
 | 
					//                           N N N  EEE    C
 | 
				
			||||||
 | 
					//                           N  NN  E      C
 | 
				
			||||||
 | 
					//                           N   N  EEEEE   CCCC
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NEC_BITS          32
 | 
				
			||||||
 | 
					#define NEC_HDR_MARK    9000
 | 
				
			||||||
 | 
					#define NEC_HDR_SPACE   4500
 | 
				
			||||||
 | 
					#define NEC_BIT_MARK     560
 | 
				
			||||||
 | 
					#define NEC_ONE_SPACE   1690
 | 
				
			||||||
 | 
					#define NEC_ZERO_SPACE   560
 | 
				
			||||||
 | 
					#define NEC_RPT_SPACE   2250
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					#if SEND_NEC
 | 
				
			||||||
 | 
					void  IRsend::sendNEC (unsigned long data,  int nbits)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// Set IR carrier frequency
 | 
				
			||||||
 | 
						enableIROut(38);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Header
 | 
				
			||||||
 | 
						mark(NEC_HDR_MARK);
 | 
				
			||||||
 | 
						space(NEC_HDR_SPACE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Data
 | 
				
			||||||
 | 
						for (unsigned long  mask = 1UL << (nbits - 1);  mask;  mask >>= 1) {
 | 
				
			||||||
 | 
							if (data & mask) {
 | 
				
			||||||
 | 
								mark(NEC_BIT_MARK);
 | 
				
			||||||
 | 
								space(NEC_ONE_SPACE);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								mark(NEC_BIT_MARK);
 | 
				
			||||||
 | 
								space(NEC_ZERO_SPACE);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Footer
 | 
				
			||||||
 | 
						mark(NEC_BIT_MARK);
 | 
				
			||||||
 | 
						space(0);  // Always end with the LED off
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// NECs have a repeat only 4 items long
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#if DECODE_NEC
 | 
				
			||||||
 | 
					bool  IRrecv::decodeNEC (decode_results *results)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						long  data   = 0;  // We decode in to here; Start with nothing
 | 
				
			||||||
 | 
						int   offset = 1;  // Index in to results; Skip first entry!?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check header "mark"
 | 
				
			||||||
 | 
						if (!MATCH_MARK(results->rawbuf[offset], NEC_HDR_MARK))  return false ;
 | 
				
			||||||
 | 
						offset++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check for repeat
 | 
				
			||||||
 | 
						if ( (irparams.rawlen == 4)
 | 
				
			||||||
 | 
						    && MATCH_SPACE(results->rawbuf[offset  ], NEC_RPT_SPACE)
 | 
				
			||||||
 | 
						    && MATCH_MARK (results->rawbuf[offset+1], NEC_BIT_MARK )
 | 
				
			||||||
 | 
						   ) {
 | 
				
			||||||
 | 
							results->bits        = 0;
 | 
				
			||||||
 | 
							results->value       = REPEAT;
 | 
				
			||||||
 | 
							results->decode_type = NEC;
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check we have enough data
 | 
				
			||||||
 | 
						if (irparams.rawlen < (2 * NEC_BITS) + 4)  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check header "space"
 | 
				
			||||||
 | 
						if (!MATCH_SPACE(results->rawbuf[offset], NEC_HDR_SPACE))  return false ;
 | 
				
			||||||
 | 
						offset++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Build the data
 | 
				
			||||||
 | 
						for (int i = 0;  i < NEC_BITS;  i++) {
 | 
				
			||||||
 | 
							// Check data "mark"
 | 
				
			||||||
 | 
							if (!MATCH_MARK(results->rawbuf[offset], NEC_BIT_MARK))  return false ;
 | 
				
			||||||
 | 
							offset++;
 | 
				
			||||||
 | 
					        // Suppend this bit
 | 
				
			||||||
 | 
							if      (MATCH_SPACE(results->rawbuf[offset], NEC_ONE_SPACE ))  data = (data << 1) | 1 ;
 | 
				
			||||||
 | 
							else if (MATCH_SPACE(results->rawbuf[offset], NEC_ZERO_SPACE))  data = (data << 1) | 0 ;
 | 
				
			||||||
 | 
							else                                                            return false ;
 | 
				
			||||||
 | 
							offset++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Success
 | 
				
			||||||
 | 
						results->bits        = NEC_BITS;
 | 
				
			||||||
 | 
						results->value       = data;
 | 
				
			||||||
 | 
						results->decode_type = NEC;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										78
									
								
								IRremote/ir_Panasonic.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								IRremote/ir_Panasonic.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
				
			|||||||
 | 
					#include "IRremote.h"
 | 
				
			||||||
 | 
					#include "IRremoteInt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					//       PPPP    AAA   N   N   AAA    SSSS   OOO   N   N  IIIII   CCCC
 | 
				
			||||||
 | 
					//       P   P  A   A  NN  N  A   A  S      O   O  NN  N    I    C
 | 
				
			||||||
 | 
					//       PPPP   AAAAA  N N N  AAAAA   SSS   O   O  N N N    I    C
 | 
				
			||||||
 | 
					//       P      A   A  N  NN  A   A      S  O   O  N  NN    I    C
 | 
				
			||||||
 | 
					//       P      A   A  N   N  A   A  SSSS    OOO   N   N  IIIII   CCCC
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PANASONIC_BITS          48
 | 
				
			||||||
 | 
					#define PANASONIC_HDR_MARK    3502
 | 
				
			||||||
 | 
					#define PANASONIC_HDR_SPACE   1750
 | 
				
			||||||
 | 
					#define PANASONIC_BIT_MARK     502
 | 
				
			||||||
 | 
					#define PANASONIC_ONE_SPACE   1244
 | 
				
			||||||
 | 
					#define PANASONIC_ZERO_SPACE   400
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					#if SEND_PANASONIC
 | 
				
			||||||
 | 
					void  IRsend::sendPanasonic (unsigned int address,  unsigned long data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// Set IR carrier frequency
 | 
				
			||||||
 | 
						enableIROut(35);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Header
 | 
				
			||||||
 | 
						mark(PANASONIC_HDR_MARK);
 | 
				
			||||||
 | 
						space(PANASONIC_HDR_SPACE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Address
 | 
				
			||||||
 | 
						for (unsigned long  mask = 1UL << (16 - 1);  mask;  mask >>= 1) {
 | 
				
			||||||
 | 
							mark(PANASONIC_BIT_MARK);
 | 
				
			||||||
 | 
							if (address & mask)  space(PANASONIC_ONE_SPACE) ;
 | 
				
			||||||
 | 
							else                 space(PANASONIC_ZERO_SPACE) ;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Data
 | 
				
			||||||
 | 
						for (unsigned long  mask = 1UL << (32 - 1);  mask;  mask >>= 1) {
 | 
				
			||||||
 | 
					        mark(PANASONIC_BIT_MARK);
 | 
				
			||||||
 | 
					        if (data & mask)  space(PANASONIC_ONE_SPACE) ;
 | 
				
			||||||
 | 
					        else              space(PANASONIC_ZERO_SPACE) ;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Footer
 | 
				
			||||||
 | 
					    mark(PANASONIC_BIT_MARK);
 | 
				
			||||||
 | 
					    space(0);  // Always end with the LED off
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					#if DECODE_PANASONIC
 | 
				
			||||||
 | 
					bool  IRrecv::decodePanasonic (decode_results *results)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    unsigned long long  data   = 0;
 | 
				
			||||||
 | 
					    int                 offset = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!MATCH_MARK(results->rawbuf[offset++], PANASONIC_HDR_MARK ))  return false ;
 | 
				
			||||||
 | 
					    if (!MATCH_MARK(results->rawbuf[offset++], PANASONIC_HDR_SPACE))  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // decode address
 | 
				
			||||||
 | 
					    for (int i = 0;  i < PANASONIC_BITS;  i++) {
 | 
				
			||||||
 | 
					        if (!MATCH_MARK(results->rawbuf[offset++], PANASONIC_BIT_MARK))  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if      (MATCH_SPACE(results->rawbuf[offset],PANASONIC_ONE_SPACE ))  data = (data << 1) | 1 ;
 | 
				
			||||||
 | 
					        else if (MATCH_SPACE(results->rawbuf[offset],PANASONIC_ZERO_SPACE))  data = (data << 1) | 0 ;
 | 
				
			||||||
 | 
					        else                                                                 return false ;
 | 
				
			||||||
 | 
					        offset++;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    results->value       = (unsigned long)data;
 | 
				
			||||||
 | 
					    results->address     = (unsigned int)(data >> 32);
 | 
				
			||||||
 | 
					    results->decode_type = PANASONIC;
 | 
				
			||||||
 | 
					    results->bits        = PANASONIC_BITS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										207
									
								
								IRremote/ir_RC5_RC6.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										207
									
								
								IRremote/ir_RC5_RC6.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,207 @@
 | 
				
			|||||||
 | 
					#include "IRremote.h"
 | 
				
			||||||
 | 
					#include "IRremoteInt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// Gets one undecoded level at a time from the raw buffer.
 | 
				
			||||||
 | 
					// The RC5/6 decoding is easier if the data is broken into time intervals.
 | 
				
			||||||
 | 
					// E.g. if the buffer has MARK for 2 time intervals and SPACE for 1,
 | 
				
			||||||
 | 
					// successive calls to getRClevel will return MARK, MARK, SPACE.
 | 
				
			||||||
 | 
					// offset and used are updated to keep track of the current position.
 | 
				
			||||||
 | 
					// t1 is the time interval for a single bit in microseconds.
 | 
				
			||||||
 | 
					// Returns -1 for error (measured time interval is not a multiple of t1).
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#if (DECODE_RC5 || DECODE_RC6)
 | 
				
			||||||
 | 
					int  IRrecv::getRClevel (decode_results *results,  int *offset,  int *used,  int t1)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int  width;
 | 
				
			||||||
 | 
						int  val;
 | 
				
			||||||
 | 
						int  correction;
 | 
				
			||||||
 | 
						int  avail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (*offset >= results->rawlen)  return SPACE ;  // After end of recorded buffer, assume SPACE.
 | 
				
			||||||
 | 
						width      = results->rawbuf[*offset];
 | 
				
			||||||
 | 
						val        = ((*offset) % 2) ? MARK : SPACE;
 | 
				
			||||||
 | 
						correction = (val == MARK) ? MARK_EXCESS : - MARK_EXCESS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if      (MATCH(width, (  t1) + correction))  avail = 1 ;
 | 
				
			||||||
 | 
						else if (MATCH(width, (2*t1) + correction))  avail = 2 ;
 | 
				
			||||||
 | 
						else if (MATCH(width, (3*t1) + correction))  avail = 3 ;
 | 
				
			||||||
 | 
						else                                         return -1 ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(*used)++;
 | 
				
			||||||
 | 
						if (*used >= avail) {
 | 
				
			||||||
 | 
							*used = 0;
 | 
				
			||||||
 | 
							(*offset)++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DBG_PRINTLN( (val == MARK) ? "MARK" : "SPACE" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return val;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					// RRRR    CCCC  55555
 | 
				
			||||||
 | 
					// R   R  C      5
 | 
				
			||||||
 | 
					// RRRR   C      5555
 | 
				
			||||||
 | 
					// R  R   C          5
 | 
				
			||||||
 | 
					// R   R   CCCC  5555
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// NB: First bit must be a one (start bit)
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#define MIN_RC5_SAMPLES     11
 | 
				
			||||||
 | 
					#define RC5_T1             889
 | 
				
			||||||
 | 
					#define RC5_RPT_LENGTH   46000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					#if SEND_RC5
 | 
				
			||||||
 | 
					void  IRsend::sendRC5 (unsigned long data,  int nbits)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// Set IR carrier frequency
 | 
				
			||||||
 | 
						enableIROut(36);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Start
 | 
				
			||||||
 | 
						mark(RC5_T1);
 | 
				
			||||||
 | 
						space(RC5_T1);
 | 
				
			||||||
 | 
						mark(RC5_T1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Data
 | 
				
			||||||
 | 
						for (unsigned long  mask = 1UL << (nbits - 1);  mask;  mask >>= 1) {
 | 
				
			||||||
 | 
							if (data & mask) {
 | 
				
			||||||
 | 
								space(RC5_T1); // 1 is space, then mark
 | 
				
			||||||
 | 
								mark(RC5_T1);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								mark(RC5_T1);
 | 
				
			||||||
 | 
								space(RC5_T1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						space(0);  // Always end with the LED off
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					#if DECODE_RC5
 | 
				
			||||||
 | 
					bool  IRrecv::decodeRC5 (decode_results *results)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int   nbits;
 | 
				
			||||||
 | 
						long  data   = 0;
 | 
				
			||||||
 | 
						int   used   = 0;
 | 
				
			||||||
 | 
						int   offset = 1;  // Skip gap space
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (irparams.rawlen < MIN_RC5_SAMPLES + 2)  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Get start bits
 | 
				
			||||||
 | 
						if (getRClevel(results, &offset, &used, RC5_T1) != MARK)   return false ;
 | 
				
			||||||
 | 
						if (getRClevel(results, &offset, &used, RC5_T1) != SPACE)  return false ;
 | 
				
			||||||
 | 
						if (getRClevel(results, &offset, &used, RC5_T1) != MARK)   return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (nbits = 0;  offset < irparams.rawlen;  nbits++) {
 | 
				
			||||||
 | 
							int  levelA = getRClevel(results, &offset, &used, RC5_T1);
 | 
				
			||||||
 | 
							int  levelB = getRClevel(results, &offset, &used, RC5_T1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if      ((levelA == SPACE) && (levelB == MARK ))  data = (data << 1) | 1 ;
 | 
				
			||||||
 | 
							else if ((levelA == MARK ) && (levelB == SPACE))  data = (data << 1) | 0 ;
 | 
				
			||||||
 | 
							else                                              return false ;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Success
 | 
				
			||||||
 | 
						results->bits        = nbits;
 | 
				
			||||||
 | 
						results->value       = data;
 | 
				
			||||||
 | 
						results->decode_type = RC5;
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// RRRR    CCCC   6666
 | 
				
			||||||
 | 
					// R   R  C      6
 | 
				
			||||||
 | 
					// RRRR   C      6666
 | 
				
			||||||
 | 
					// R  R   C      6   6
 | 
				
			||||||
 | 
					// R   R   CCCC   666
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// NB : Caller needs to take care of flipping the toggle bit
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#define MIN_RC6_SAMPLES      1
 | 
				
			||||||
 | 
					#define RC6_HDR_MARK      2666
 | 
				
			||||||
 | 
					#define RC6_HDR_SPACE      889
 | 
				
			||||||
 | 
					#define RC6_T1             444
 | 
				
			||||||
 | 
					#define RC6_RPT_LENGTH   46000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if SEND_RC6
 | 
				
			||||||
 | 
					void  IRsend::sendRC6 (unsigned long data,  int nbits)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// Set IR carrier frequency
 | 
				
			||||||
 | 
						enableIROut(36);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Header
 | 
				
			||||||
 | 
						mark(RC6_HDR_MARK);
 | 
				
			||||||
 | 
						space(RC6_HDR_SPACE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Start bit
 | 
				
			||||||
 | 
						mark(RC6_T1);
 | 
				
			||||||
 | 
						space(RC6_T1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Data
 | 
				
			||||||
 | 
						for (unsigned long  i = 1, mask = 1UL << (nbits - 1);  mask;  i++, mask >>= 1) {
 | 
				
			||||||
 | 
							// The fourth bit we send is a "double width trailer bit"
 | 
				
			||||||
 | 
							int  t = (i == 4) ? (RC6_T1 * 2) : (RC6_T1) ;
 | 
				
			||||||
 | 
							if (data & mask) {
 | 
				
			||||||
 | 
								mark(t);
 | 
				
			||||||
 | 
								space(t);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								space(t);
 | 
				
			||||||
 | 
								mark(t);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						space(0);  // Always end with the LED off
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					#if DECODE_RC6
 | 
				
			||||||
 | 
					bool  IRrecv::decodeRC6 (decode_results *results)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int   nbits;
 | 
				
			||||||
 | 
						long  data   = 0;
 | 
				
			||||||
 | 
						int   used   = 0;
 | 
				
			||||||
 | 
						int   offset = 1;  // Skip first space
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (results->rawlen < MIN_RC6_SAMPLES)  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Initial mark
 | 
				
			||||||
 | 
						if (!MATCH_MARK(results->rawbuf[offset++],  RC6_HDR_MARK))   return false ;
 | 
				
			||||||
 | 
						if (!MATCH_SPACE(results->rawbuf[offset++], RC6_HDR_SPACE))  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Get start bit (1)
 | 
				
			||||||
 | 
						if (getRClevel(results, &offset, &used, RC6_T1) != MARK)   return false ;
 | 
				
			||||||
 | 
						if (getRClevel(results, &offset, &used, RC6_T1) != SPACE)  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (nbits = 0;  offset < results->rawlen;  nbits++) {
 | 
				
			||||||
 | 
							int  levelA, levelB;  // Next two levels
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							levelA = getRClevel(results, &offset, &used, RC6_T1);
 | 
				
			||||||
 | 
							if (nbits == 3) {
 | 
				
			||||||
 | 
								// T bit is double wide; make sure second half matches
 | 
				
			||||||
 | 
								if (levelA != getRClevel(results, &offset, &used, RC6_T1)) return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							levelB = getRClevel(results, &offset, &used, RC6_T1);
 | 
				
			||||||
 | 
							if (nbits == 3) {
 | 
				
			||||||
 | 
								// T bit is double wide; make sure second half matches
 | 
				
			||||||
 | 
								if (levelB != getRClevel(results, &offset, &used, RC6_T1)) return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if      ((levelA == MARK ) && (levelB == SPACE))  data = (data << 1) | 1 ;  // inverted compared to RC5
 | 
				
			||||||
 | 
							else if ((levelA == SPACE) && (levelB == MARK ))  data = (data << 1) | 0 ;  // ...
 | 
				
			||||||
 | 
							else                                              return false ;            // Error
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Success
 | 
				
			||||||
 | 
						results->bits        = nbits;
 | 
				
			||||||
 | 
						results->value       = data;
 | 
				
			||||||
 | 
						results->decode_type = RC6;
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										92
									
								
								IRremote/ir_Samsung.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								IRremote/ir_Samsung.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
				
			|||||||
 | 
					#include "IRremote.h"
 | 
				
			||||||
 | 
					#include "IRremoteInt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					//              SSSS   AAA    MMM    SSSS  U   U  N   N   GGGG
 | 
				
			||||||
 | 
					//             S      A   A  M M M  S      U   U  NN  N  G
 | 
				
			||||||
 | 
					//              SSS   AAAAA  M M M   SSS   U   U  N N N  G  GG
 | 
				
			||||||
 | 
					//                 S  A   A  M   M      S  U   U  N  NN  G   G
 | 
				
			||||||
 | 
					//             SSSS   A   A  M   M  SSSS    UUU   N   N   GGG
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SAMSUNG_BITS          32
 | 
				
			||||||
 | 
					#define SAMSUNG_HDR_MARK    5000
 | 
				
			||||||
 | 
					#define SAMSUNG_HDR_SPACE   5000
 | 
				
			||||||
 | 
					#define SAMSUNG_BIT_MARK     560
 | 
				
			||||||
 | 
					#define SAMSUNG_ONE_SPACE   1600
 | 
				
			||||||
 | 
					#define SAMSUNG_ZERO_SPACE   560
 | 
				
			||||||
 | 
					#define SAMSUNG_RPT_SPACE   2250
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					#if SEND_SAMSUNG
 | 
				
			||||||
 | 
					void  IRsend::sendSAMSUNG (unsigned long data,  int nbits)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// Set IR carrier frequency
 | 
				
			||||||
 | 
						enableIROut(38);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Header
 | 
				
			||||||
 | 
						mark(SAMSUNG_HDR_MARK);
 | 
				
			||||||
 | 
						space(SAMSUNG_HDR_SPACE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Data
 | 
				
			||||||
 | 
						for (unsigned long  mask = 1UL << (nbits - 1);  mask;  mask >>= 1) {
 | 
				
			||||||
 | 
							if (data & mask) {
 | 
				
			||||||
 | 
								mark(SAMSUNG_BIT_MARK);
 | 
				
			||||||
 | 
								space(SAMSUNG_ONE_SPACE);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								mark(SAMSUNG_BIT_MARK);
 | 
				
			||||||
 | 
								space(SAMSUNG_ZERO_SPACE);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Footer
 | 
				
			||||||
 | 
						mark(SAMSUNG_BIT_MARK);
 | 
				
			||||||
 | 
					    space(0);  // Always end with the LED off
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// SAMSUNGs have a repeat only 4 items long
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#if DECODE_SAMSUNG
 | 
				
			||||||
 | 
					bool  IRrecv::decodeSAMSUNG (decode_results *results)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						long  data   = 0;
 | 
				
			||||||
 | 
						int   offset = 1;  // Skip first space
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Initial mark
 | 
				
			||||||
 | 
						if (!MATCH_MARK(results->rawbuf[offset], SAMSUNG_HDR_MARK))   return false ;
 | 
				
			||||||
 | 
						offset++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check for repeat
 | 
				
			||||||
 | 
						if (    (irparams.rawlen == 4)
 | 
				
			||||||
 | 
						     && MATCH_SPACE(results->rawbuf[offset], SAMSUNG_RPT_SPACE)
 | 
				
			||||||
 | 
						     && MATCH_MARK(results->rawbuf[offset+1], SAMSUNG_BIT_MARK)
 | 
				
			||||||
 | 
						   ) {
 | 
				
			||||||
 | 
							results->bits        = 0;
 | 
				
			||||||
 | 
							results->value       = REPEAT;
 | 
				
			||||||
 | 
							results->decode_type = SAMSUNG;
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (irparams.rawlen < (2 * SAMSUNG_BITS) + 4)  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Initial space
 | 
				
			||||||
 | 
						if (!MATCH_SPACE(results->rawbuf[offset++], SAMSUNG_HDR_SPACE))  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (int i = 0;  i < SAMSUNG_BITS;   i++) {
 | 
				
			||||||
 | 
							if (!MATCH_MARK(results->rawbuf[offset++], SAMSUNG_BIT_MARK))  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if      (MATCH_SPACE(results->rawbuf[offset], SAMSUNG_ONE_SPACE))   data = (data << 1) | 1 ;
 | 
				
			||||||
 | 
							else if (MATCH_SPACE(results->rawbuf[offset], SAMSUNG_ZERO_SPACE))  data = (data << 1) | 0 ;
 | 
				
			||||||
 | 
							else                                                                return false ;
 | 
				
			||||||
 | 
							offset++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Success
 | 
				
			||||||
 | 
						results->bits        = SAMSUNG_BITS;
 | 
				
			||||||
 | 
						results->value       = data;
 | 
				
			||||||
 | 
						results->decode_type = SAMSUNG;
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										76
									
								
								IRremote/ir_Sanyo.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								IRremote/ir_Sanyo.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
				
			|||||||
 | 
					#include "IRremote.h"
 | 
				
			||||||
 | 
					#include "IRremoteInt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					//                      SSSS   AAA   N   N  Y   Y   OOO
 | 
				
			||||||
 | 
					//                     S      A   A  NN  N   Y Y   O   O
 | 
				
			||||||
 | 
					//                      SSS   AAAAA  N N N    Y    O   O
 | 
				
			||||||
 | 
					//                         S  A   A  N  NN    Y    O   O
 | 
				
			||||||
 | 
					//                     SSSS   A   A  N   N    Y     OOO
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// I think this is a Sanyo decoder:  Serial = SA 8650B
 | 
				
			||||||
 | 
					// Looks like Sony except for timings, 48 chars of data and time/space different
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SANYO_BITS                   12
 | 
				
			||||||
 | 
					#define SANYO_HDR_MARK	           3500  // seen range 3500
 | 
				
			||||||
 | 
					#define SANYO_HDR_SPACE	            950  // seen 950
 | 
				
			||||||
 | 
					#define SANYO_ONE_MARK	           2400  // seen 2400
 | 
				
			||||||
 | 
					#define SANYO_ZERO_MARK             700  // seen 700
 | 
				
			||||||
 | 
					#define SANYO_DOUBLE_SPACE_USECS    800  // usually ssee 713 - not using ticks as get number wrapround
 | 
				
			||||||
 | 
					#define SANYO_RPT_LENGTH          45000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					#if DECODE_SANYO
 | 
				
			||||||
 | 
					bool  IRrecv::decodeSanyo (decode_results *results)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						long  data   = 0;
 | 
				
			||||||
 | 
						int   offset = 0;  // Skip first space  <-- CHECK THIS!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (irparams.rawlen < (2 * SANYO_BITS) + 2)  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
						// Put this back in for debugging - note can't use #DEBUG as if Debug on we don't see the repeat cos of the delay
 | 
				
			||||||
 | 
						Serial.print("IR Gap: ");
 | 
				
			||||||
 | 
						Serial.println( results->rawbuf[offset]);
 | 
				
			||||||
 | 
						Serial.println( "test against:");
 | 
				
			||||||
 | 
						Serial.println(results->rawbuf[offset]);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Initial space
 | 
				
			||||||
 | 
						if (results->rawbuf[offset] < SANYO_DOUBLE_SPACE_USECS) {
 | 
				
			||||||
 | 
							//Serial.print("IR Gap found: ");
 | 
				
			||||||
 | 
							results->bits        = 0;
 | 
				
			||||||
 | 
							results->value       = REPEAT;
 | 
				
			||||||
 | 
							results->decode_type = SANYO;
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						offset++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Initial mark
 | 
				
			||||||
 | 
						if (!MATCH_MARK(results->rawbuf[offset++], SANYO_HDR_MARK))  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Skip Second Mark
 | 
				
			||||||
 | 
						if (!MATCH_MARK(results->rawbuf[offset++], SANYO_HDR_MARK))  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (offset + 1 < irparams.rawlen) {
 | 
				
			||||||
 | 
							if (!MATCH_SPACE(results->rawbuf[offset++], SANYO_HDR_SPACE))  break ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if      (MATCH_MARK(results->rawbuf[offset], SANYO_ONE_MARK))   data = (data << 1) | 1 ;
 | 
				
			||||||
 | 
							else if (MATCH_MARK(results->rawbuf[offset], SANYO_ZERO_MARK))  data = (data << 1) | 0 ;
 | 
				
			||||||
 | 
							else                                                            return false ;
 | 
				
			||||||
 | 
							offset++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Success
 | 
				
			||||||
 | 
						results->bits = (offset - 1) / 2;
 | 
				
			||||||
 | 
						if (results->bits < 12) {
 | 
				
			||||||
 | 
							results->bits = 0;
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						results->value       = data;
 | 
				
			||||||
 | 
						results->decode_type = SANYO;
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										71
									
								
								IRremote/ir_Sharp.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								IRremote/ir_Sharp.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
				
			|||||||
 | 
					#include "IRremote.h"
 | 
				
			||||||
 | 
					#include "IRremoteInt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					//                       SSSS  H   H   AAA   RRRR   PPPP
 | 
				
			||||||
 | 
					//                      S      H   H  A   A  R   R  P   P
 | 
				
			||||||
 | 
					//                       SSS   HHHHH  AAAAA  RRRR   PPPP
 | 
				
			||||||
 | 
					//                          S  H   H  A   A  R  R   P
 | 
				
			||||||
 | 
					//                      SSSS   H   H  A   A  R   R  P
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Sharp and DISH support by Todd Treece: http://unionbridge.org/design/ircommand
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The send function has the necessary repeat built in because of the need to
 | 
				
			||||||
 | 
					// invert the signal.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Sharp protocol documentation:
 | 
				
			||||||
 | 
					//   http://www.sbprojects.com/knowledge/ir/sharp.htm
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Here is the LIRC file I found that seems to match the remote codes from the
 | 
				
			||||||
 | 
					// oscilloscope:
 | 
				
			||||||
 | 
					//   Sharp LCD TV:
 | 
				
			||||||
 | 
					//   http://lirc.sourceforge.net/remotes/sharp/GA538WJSA
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SHARP_BITS             15
 | 
				
			||||||
 | 
					#define SHARP_BIT_MARK        245
 | 
				
			||||||
 | 
					#define SHARP_ONE_SPACE      1805
 | 
				
			||||||
 | 
					#define SHARP_ZERO_SPACE      795
 | 
				
			||||||
 | 
					#define SHARP_GAP          600000
 | 
				
			||||||
 | 
					#define SHARP_RPT_SPACE      3000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SHARP_TOGGLE_MASK  0x3FF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					#if SEND_SHARP
 | 
				
			||||||
 | 
					void  IRsend::sendSharpRaw (unsigned long data,  int nbits)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						enableIROut(38);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Sending codes in bursts of 3 (normal, inverted, normal) makes transmission
 | 
				
			||||||
 | 
						// much more reliable. That's the exact behaviour of CD-S6470 remote control.
 | 
				
			||||||
 | 
						for (int n = 0;  n < 3;  n++) {
 | 
				
			||||||
 | 
							for (unsigned long  mask = 1UL << (nbits - 1);  mask;  mask >>= 1) {
 | 
				
			||||||
 | 
								if (data & mask) {
 | 
				
			||||||
 | 
									mark(SHARP_BIT_MARK);
 | 
				
			||||||
 | 
									space(SHARP_ONE_SPACE);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									mark(SHARP_BIT_MARK);
 | 
				
			||||||
 | 
									space(SHARP_ZERO_SPACE);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							mark(SHARP_BIT_MARK);
 | 
				
			||||||
 | 
							space(SHARP_ZERO_SPACE);
 | 
				
			||||||
 | 
							delay(40);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							data = data ^ SHARP_TOGGLE_MASK;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// Sharp send compatible with data obtained through decodeSharp()
 | 
				
			||||||
 | 
					//                                                  ^^^^^^^^^^^^^ FUNCTION MISSING!
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#if SEND_SHARP
 | 
				
			||||||
 | 
					void  IRsend::sendSharp (unsigned int address,  unsigned int command)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						sendSharpRaw((address << 10) | (command << 2) | 2, SHARP_BITS);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										95
									
								
								IRremote/ir_Sony.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								IRremote/ir_Sony.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,95 @@
 | 
				
			|||||||
 | 
					#include "IRremote.h"
 | 
				
			||||||
 | 
					#include "IRremoteInt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					//                           SSSS   OOO   N   N  Y   Y
 | 
				
			||||||
 | 
					//                          S      O   O  NN  N   Y Y
 | 
				
			||||||
 | 
					//                           SSS   O   O  N N N    Y
 | 
				
			||||||
 | 
					//                              S  O   O  N  NN    Y
 | 
				
			||||||
 | 
					//                          SSSS    OOO   N   N    Y
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SONY_BITS                   12
 | 
				
			||||||
 | 
					#define SONY_HDR_MARK             2400
 | 
				
			||||||
 | 
					#define SONY_HDR_SPACE             600
 | 
				
			||||||
 | 
					#define SONY_ONE_MARK             1200
 | 
				
			||||||
 | 
					#define SONY_ZERO_MARK             600
 | 
				
			||||||
 | 
					#define SONY_RPT_LENGTH          45000
 | 
				
			||||||
 | 
					#define SONY_DOUBLE_SPACE_USECS    500  // usually ssee 713 - not using ticks as get number wrapround
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					#if SEND_SONY
 | 
				
			||||||
 | 
					void  IRsend::sendSony (unsigned long data,  int nbits)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// Set IR carrier frequency
 | 
				
			||||||
 | 
						enableIROut(40);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Header
 | 
				
			||||||
 | 
						mark(SONY_HDR_MARK);
 | 
				
			||||||
 | 
						space(SONY_HDR_SPACE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Data
 | 
				
			||||||
 | 
						for (unsigned long  mask = 1UL << (nbits - 1);  mask;  mask >>= 1) {
 | 
				
			||||||
 | 
							if (data & mask) {
 | 
				
			||||||
 | 
								mark(SONY_ONE_MARK);
 | 
				
			||||||
 | 
								space(SONY_HDR_SPACE);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								mark(SONY_ZERO_MARK);
 | 
				
			||||||
 | 
								space(SONY_HDR_SPACE);
 | 
				
			||||||
 | 
					    	}
 | 
				
			||||||
 | 
					  	}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// We will have ended with LED off
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					#if DECODE_SONY
 | 
				
			||||||
 | 
					bool  IRrecv::decodeSony (decode_results *results)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						long  data   = 0;
 | 
				
			||||||
 | 
						int   offset = 0;  // Dont skip first space, check its size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (irparams.rawlen < (2 * SONY_BITS) + 2)  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Some Sony's deliver repeats fast after first
 | 
				
			||||||
 | 
						// unfortunately can't spot difference from of repeat from two fast clicks
 | 
				
			||||||
 | 
						if (results->rawbuf[offset] < SONY_DOUBLE_SPACE_USECS) {
 | 
				
			||||||
 | 
							// Serial.print("IR Gap found: ");
 | 
				
			||||||
 | 
							results->bits = 0;
 | 
				
			||||||
 | 
							results->value = REPEAT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#	ifdef DECODE_SANYO
 | 
				
			||||||
 | 
							results->decode_type = SANYO;
 | 
				
			||||||
 | 
					#	else
 | 
				
			||||||
 | 
							results->decode_type = UNKNOWN;
 | 
				
			||||||
 | 
					#	endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						    return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						offset++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Initial mark
 | 
				
			||||||
 | 
						if (!MATCH_MARK(results->rawbuf[offset++], SONY_HDR_MARK))  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (offset + 1 < irparams.rawlen) {
 | 
				
			||||||
 | 
							if (!MATCH_SPACE(results->rawbuf[offset++], SONY_HDR_SPACE))  break ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if      (MATCH_MARK(results->rawbuf[offset], SONY_ONE_MARK))   data = (data << 1) | 1 ;
 | 
				
			||||||
 | 
							else if (MATCH_MARK(results->rawbuf[offset], SONY_ZERO_MARK))  data = (data << 1) | 0 ;
 | 
				
			||||||
 | 
							else                                                           return false ;
 | 
				
			||||||
 | 
							offset++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Success
 | 
				
			||||||
 | 
						results->bits = (offset - 1) / 2;
 | 
				
			||||||
 | 
						if (results->bits < 12) {
 | 
				
			||||||
 | 
							results->bits = 0;
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						results->value       = data;
 | 
				
			||||||
 | 
						results->decode_type = SONY;
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										179
									
								
								IRremote/ir_Template.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								IRremote/ir_Template.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,179 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Assuming the protocol we are adding is for the (imaginary) manufacturer:  Shuzu
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Our fantasy protocol is a standard protocol, so we can use this standard
 | 
				
			||||||
 | 
					template without too much work. Some protocols are quite unique and will require
 | 
				
			||||||
 | 
					considerably more work in this file! It is way beyond the scope of this text to
 | 
				
			||||||
 | 
					explain how to reverse engineer "unusual" IR protocols. But, unless you own an
 | 
				
			||||||
 | 
					oscilloscope, the starting point is probably to use the rawDump.ino sketch and
 | 
				
			||||||
 | 
					try to spot the pattern!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Before you start, make sure the IR library is working OK:
 | 
				
			||||||
 | 
					  # Open up the Arduino IDE
 | 
				
			||||||
 | 
					  # Load up the rawDump.ino example sketch
 | 
				
			||||||
 | 
					  # Run it
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Now we can start to add our new protocol...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Copy this file to : ir_Shuzu.cpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2. Replace all occurrences of "Shuzu" with the name of your protocol.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					3. Tweak the #defines to suit your protocol.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					4. If you're lucky, tweaking the #defines will make the default send() function
 | 
				
			||||||
 | 
					   work.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					5. Again, if you're lucky, tweaking the #defines will have made the default
 | 
				
			||||||
 | 
					   decode() function work.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You have written the code to support your new protocol!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Now you must do a few things to add it to the IRremote system:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Open IRremote.h and make the following changes:
 | 
				
			||||||
 | 
					   REMEMEBER to change occurences of "SHUZU" with the name of your protocol
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   A. At the top, in the section "Supported Protocols", add:
 | 
				
			||||||
 | 
					      #define DECODE_SHUZU  1
 | 
				
			||||||
 | 
					      #define SEND_SHUZU    1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   B. In the section "enumerated list of all supported formats", add:
 | 
				
			||||||
 | 
					      SHUZU,
 | 
				
			||||||
 | 
					      to the end of the list (notice there is a comma after the protocol name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   C. Further down in "Main class for receiving IR", add:
 | 
				
			||||||
 | 
					      //......................................................................
 | 
				
			||||||
 | 
					      #if DECODE_SHUZU
 | 
				
			||||||
 | 
					          bool  decodeShuzu (decode_results *results) ;
 | 
				
			||||||
 | 
					      #endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   D. Further down in "Main class for sending IR", add:
 | 
				
			||||||
 | 
					      //......................................................................
 | 
				
			||||||
 | 
					      #if SEND_SHUZU
 | 
				
			||||||
 | 
					          void  sendShuzu (unsigned long data,  int nbits) ;
 | 
				
			||||||
 | 
					      #endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   E. Save your changes and close the file
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2. Now open irRecv.cpp and make the following change:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   A. In the function IRrecv::decode(), add:
 | 
				
			||||||
 | 
					      #ifdef DECODE_NEC
 | 
				
			||||||
 | 
					          DBG_PRINTLN("Attempting Shuzu decode");
 | 
				
			||||||
 | 
					          if (decodeShuzu(results))  return true ;
 | 
				
			||||||
 | 
					      #endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   B. Save your changes and close the file
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You will probably want to add your new protocol to the example sketch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					3. Open MyDocuments\Arduino\libraries\IRremote\examples\IRrecvDumpV2.ino
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   A. In the encoding() function, add:
 | 
				
			||||||
 | 
					      case SHUZU:    Serial.print("SHUZU");     break ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Now open the Arduino IDE, load up the rawDump.ino sketch, and run it.
 | 
				
			||||||
 | 
					Hopefully it will compile and upload.
 | 
				
			||||||
 | 
					If it doesn't, you've done something wrong. Check your work.
 | 
				
			||||||
 | 
					If you can't get it to work - seek help from somewhere.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you get this far, I will assume you have successfully added your new protocol
 | 
				
			||||||
 | 
					There is one last thing to do.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Delete this giant instructional comment.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2. Send a copy of your work to us so we can include it in the library and
 | 
				
			||||||
 | 
					   others may benefit from your hard work and maybe even write a song about how
 | 
				
			||||||
 | 
					   great you are for helping them! :)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Regards,
 | 
				
			||||||
 | 
					  BlueChip
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "IRremote.h"
 | 
				
			||||||
 | 
					#include "IRremoteInt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//                              S H U Z U
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BITS          32  // The number of bits in the command
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HDR_MARK    1000  // The length of the Header:Mark
 | 
				
			||||||
 | 
					#define HDR_SPACE   2000  // The lenght of the Header:Space
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BIT_MARK    3000  // The length of a Bit:Mark
 | 
				
			||||||
 | 
					#define ONE_SPACE   4000  // The length of a Bit:Space for 1's
 | 
				
			||||||
 | 
					#define ZERO_SPACE  5000  // The length of a Bit:Space for 0's
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define OTHER       1234  // Other things you may need to define
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#if SEND_SHUZU
 | 
				
			||||||
 | 
					void  IRsend::sendShuzu (unsigned long data,  int nbits)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// Set IR carrier frequency
 | 
				
			||||||
 | 
						enableIROut(38);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Header
 | 
				
			||||||
 | 
						mark (HDR_MARK);
 | 
				
			||||||
 | 
						space(HDR_SPACE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Data
 | 
				
			||||||
 | 
						for (unsigned long  mask = 1UL << (nbits - 1);  mask;  mask >>= 1) {
 | 
				
			||||||
 | 
							if (data & mask) {
 | 
				
			||||||
 | 
								mark (BIT_MARK);
 | 
				
			||||||
 | 
								space(ONE_SPACE);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								mark (BIT_MARK);
 | 
				
			||||||
 | 
								space(ZERO_SPACE);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Footer
 | 
				
			||||||
 | 
						mark(BIT_MARK);
 | 
				
			||||||
 | 
					    space(0);  // Always end with the LED off
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#if DECODE_SHUZU
 | 
				
			||||||
 | 
					bool  IRrecv::decodeShuzu (decode_results *results)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned long  data   = 0;  // Somewhere to build our code
 | 
				
			||||||
 | 
						int            offset = 1;  // Skip the Gap reading
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check we have the right amount of data
 | 
				
			||||||
 | 
						if (irparams.rawlen != 1 + 2 + (2 * BITS) + 1)  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check initial Mark+Space match
 | 
				
			||||||
 | 
						if (!MATCH_MARK (results->rawbuf[offset++], HDR_MARK ))  return false ;
 | 
				
			||||||
 | 
						if (!MATCH_SPACE(results->rawbuf[offset++], HDR_SPACE))  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Read the bits in
 | 
				
			||||||
 | 
						for (int i = 0;  i < SHUZU_BITS;  i++) {
 | 
				
			||||||
 | 
							// Each bit looks like: MARK + SPACE_1 -> 1
 | 
				
			||||||
 | 
							//                 or : MARK + SPACE_0 -> 0
 | 
				
			||||||
 | 
							if (!MATCH_MARK(results->rawbuf[offset++], BIT_MARK))  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// IR data is big-endian, so we shuffle it in from the right:
 | 
				
			||||||
 | 
							if      (MATCH_SPACE(results->rawbuf[offset], ONE_SPACE))   data = (data << 1) | 1 ;
 | 
				
			||||||
 | 
							else if (MATCH_SPACE(results->rawbuf[offset], ZERO_SPACE))  data = (data << 1) | 0 ;
 | 
				
			||||||
 | 
							else                                                        return false ;
 | 
				
			||||||
 | 
							offset++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Success
 | 
				
			||||||
 | 
						results->bits        = BITS;
 | 
				
			||||||
 | 
						results->value       = data;
 | 
				
			||||||
 | 
						results->decode_type = SHUZU;
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										91
									
								
								IRremote/ir_Whynter.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								IRremote/ir_Whynter.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,91 @@
 | 
				
			|||||||
 | 
					#include "IRremote.h"
 | 
				
			||||||
 | 
					#include "IRremoteInt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					//               W   W  H   H  Y   Y N   N TTTTT EEEEE  RRRRR
 | 
				
			||||||
 | 
					//               W   W  H   H   Y Y  NN  N   T   E      R   R
 | 
				
			||||||
 | 
					//               W W W  HHHHH    Y   N N N   T   EEE    RRRR
 | 
				
			||||||
 | 
					//               W W W  H   H    Y   N  NN   T   E      R  R
 | 
				
			||||||
 | 
					//                WWW   H   H    Y   N   N   T   EEEEE  R   R
 | 
				
			||||||
 | 
					//==============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define WHYNTER_BITS          32
 | 
				
			||||||
 | 
					#define WHYNTER_HDR_MARK    2850
 | 
				
			||||||
 | 
					#define WHYNTER_HDR_SPACE   2850
 | 
				
			||||||
 | 
					#define WHYNTER_BIT_MARK     750
 | 
				
			||||||
 | 
					#define WHYNTER_ONE_MARK     750
 | 
				
			||||||
 | 
					#define WHYNTER_ONE_SPACE   2150
 | 
				
			||||||
 | 
					#define WHYNTER_ZERO_MARK    750
 | 
				
			||||||
 | 
					#define WHYNTER_ZERO_SPACE   750
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					#if SEND_WHYNTER
 | 
				
			||||||
 | 
					void  IRsend::sendWhynter (unsigned long data,  int nbits)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// Set IR carrier frequency
 | 
				
			||||||
 | 
						enableIROut(38);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Start
 | 
				
			||||||
 | 
						mark(WHYNTER_ZERO_MARK);
 | 
				
			||||||
 | 
						space(WHYNTER_ZERO_SPACE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Header
 | 
				
			||||||
 | 
						mark(WHYNTER_HDR_MARK);
 | 
				
			||||||
 | 
						space(WHYNTER_HDR_SPACE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Data
 | 
				
			||||||
 | 
						for (unsigned long  mask = 1UL << (nbits - 1);  mask;  mask >>= 1) {
 | 
				
			||||||
 | 
							if (data & mask) {
 | 
				
			||||||
 | 
								mark(WHYNTER_ONE_MARK);
 | 
				
			||||||
 | 
								space(WHYNTER_ONE_SPACE);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								mark(WHYNTER_ZERO_MARK);
 | 
				
			||||||
 | 
								space(WHYNTER_ZERO_SPACE);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Footer
 | 
				
			||||||
 | 
						mark(WHYNTER_ZERO_MARK);
 | 
				
			||||||
 | 
						space(WHYNTER_ZERO_SPACE);  // Always end with the LED off
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					#if DECODE_WHYNTER
 | 
				
			||||||
 | 
					bool  IRrecv::decodeWhynter (decode_results *results)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						long  data   = 0;
 | 
				
			||||||
 | 
						int   offset = 1;  // skip initial space
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check we have the right amount of data
 | 
				
			||||||
 | 
						if (irparams.rawlen < (2 * WHYNTER_BITS) + 6)  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Sequence begins with a bit mark and a zero space
 | 
				
			||||||
 | 
						if (!MATCH_MARK (results->rawbuf[offset++], WHYNTER_BIT_MARK  ))  return false ;
 | 
				
			||||||
 | 
						if (!MATCH_SPACE(results->rawbuf[offset++], WHYNTER_ZERO_SPACE))  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// header mark and space
 | 
				
			||||||
 | 
						if (!MATCH_MARK (results->rawbuf[offset++], WHYNTER_HDR_MARK ))  return false ;
 | 
				
			||||||
 | 
						if (!MATCH_SPACE(results->rawbuf[offset++], WHYNTER_HDR_SPACE))  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// data bits
 | 
				
			||||||
 | 
						for (int i = 0;  i < WHYNTER_BITS;  i++) {
 | 
				
			||||||
 | 
							if (!MATCH_MARK(results->rawbuf[offset++], WHYNTER_BIT_MARK))  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if      (MATCH_SPACE(results->rawbuf[offset], WHYNTER_ONE_SPACE ))  data = (data << 1) | 1 ;
 | 
				
			||||||
 | 
							else if (MATCH_SPACE(results->rawbuf[offset], WHYNTER_ZERO_SPACE))  data = (data << 1) | 0 ;
 | 
				
			||||||
 | 
							else                                                                return false ;
 | 
				
			||||||
 | 
							offset++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// trailing mark
 | 
				
			||||||
 | 
						if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_BIT_MARK))  return false ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Success
 | 
				
			||||||
 | 
						results->bits = WHYNTER_BITS;
 | 
				
			||||||
 | 
						results->value = data;
 | 
				
			||||||
 | 
						results->decode_type = WHYNTER;
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										24
									
								
								IRremote/library.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								IRremote/library.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "name": "IRremote",
 | 
				
			||||||
 | 
					  "keywords": "infrared, ir, remote",
 | 
				
			||||||
 | 
					  "description": "Send and receive infrared signals with multiple protocols",
 | 
				
			||||||
 | 
					  "repository":
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "type": "git",
 | 
				
			||||||
 | 
					    "url": "https://github.com/z3t0/Arduino-IRremote.git"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "version": "2.3.3",
 | 
				
			||||||
 | 
					  "frameworks": "arduino",
 | 
				
			||||||
 | 
					  "platforms": "atmelavr",
 | 
				
			||||||
 | 
					  "authors" :
 | 
				
			||||||
 | 
					  [
 | 
				
			||||||
 | 
					     {
 | 
				
			||||||
 | 
					       "name":"Rafi Khan",
 | 
				
			||||||
 | 
					       "email":"zetoslab@gmail.com"
 | 
				
			||||||
 | 
					     },
 | 
				
			||||||
 | 
					     {
 | 
				
			||||||
 | 
					       "name":"Ken Shirriff",
 | 
				
			||||||
 | 
					       "email":"ken.shirriff@gmail.com"
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					  ]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										9
									
								
								IRremote/library.properties
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								IRremote/library.properties
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					name=IRremote
 | 
				
			||||||
 | 
					version=2.2.3
 | 
				
			||||||
 | 
					author=shirriff
 | 
				
			||||||
 | 
					maintainer=shirriff
 | 
				
			||||||
 | 
					sentence=Send and receive infrared signals with multiple protocols
 | 
				
			||||||
 | 
					paragraph=Send and receive infrared signals with multiple protocols
 | 
				
			||||||
 | 
					category=Signal Input/Output
 | 
				
			||||||
 | 
					url=https://github.com/shirriff/Arduino-IRremote.git
 | 
				
			||||||
 | 
					architectures=*
 | 
				
			||||||
							
								
								
									
										102
									
								
								IRremote/sam.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								IRremote/sam.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,102 @@
 | 
				
			|||||||
 | 
					// Support routines for SAM processor boards
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "IRremote.h"
 | 
				
			||||||
 | 
					#include "IRremoteInt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// "Idiot check"
 | 
				
			||||||
 | 
					#ifdef USE_DEFAULT_ENABLE_IR_IN
 | 
				
			||||||
 | 
					#error Must undef USE_DEFAULT_ENABLE_IR_IN
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// ATSAMD Timer setup & IRQ functions
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// following based on setup from GitHub jdneo/timerInterrupt.ino
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void setTimerFrequency(int frequencyHz)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int compareValue = (SYSCLOCK / (TIMER_PRESCALER_DIV * frequencyHz)) - 1;
 | 
				
			||||||
 | 
						//Serial.println(compareValue);
 | 
				
			||||||
 | 
						TcCount16* TC = (TcCount16*) TC3;
 | 
				
			||||||
 | 
						// Make sure the count is in a proportional position to where it was
 | 
				
			||||||
 | 
						// to prevent any jitter or disconnect when changing the compare value.
 | 
				
			||||||
 | 
						TC->COUNT.reg = map(TC->COUNT.reg, 0, TC->CC[0].reg, 0, compareValue);
 | 
				
			||||||
 | 
						TC->CC[0].reg = compareValue;
 | 
				
			||||||
 | 
						//Serial.print("COUNT.reg ");
 | 
				
			||||||
 | 
						//Serial.println(TC->COUNT.reg);
 | 
				
			||||||
 | 
						//Serial.print("CC[0].reg ");
 | 
				
			||||||
 | 
						//Serial.println(TC->CC[0].reg);
 | 
				
			||||||
 | 
						while (TC->STATUS.bit.SYNCBUSY == 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void startTimer()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						REG_GCLK_CLKCTRL = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID_TCC2_TC3);
 | 
				
			||||||
 | 
						while (GCLK->STATUS.bit.SYNCBUSY == 1); // wait for sync
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TcCount16* TC = (TcCount16*) TC3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TC->CTRLA.reg &= ~TC_CTRLA_ENABLE;
 | 
				
			||||||
 | 
						while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Use the 16-bit timer
 | 
				
			||||||
 | 
						TC->CTRLA.reg |= TC_CTRLA_MODE_COUNT16;
 | 
				
			||||||
 | 
						while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Use match mode so that the timer counter resets when the count matches the compare register
 | 
				
			||||||
 | 
						TC->CTRLA.reg |= TC_CTRLA_WAVEGEN_MFRQ;
 | 
				
			||||||
 | 
						while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Set prescaler to 1024
 | 
				
			||||||
 | 
						//TC->CTRLA.reg |= TC_CTRLA_PRESCALER_DIV1024;
 | 
				
			||||||
 | 
						TC->CTRLA.reg |= TC_CTRLA_PRESCALER_DIV64;
 | 
				
			||||||
 | 
						while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setTimerFrequency(1000000 / USECPERTICK);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						// Enable the compare interrupt
 | 
				
			||||||
 | 
						TC->INTENSET.reg = 0;
 | 
				
			||||||
 | 
						TC->INTENSET.bit.MC0 = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NVIC_EnableIRQ(TC3_IRQn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TC->CTRLA.reg |= TC_CTRLA_ENABLE;
 | 
				
			||||||
 | 
						while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//+=============================================================================
 | 
				
			||||||
 | 
					// initialization
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void IRrecv::enableIRIn()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// Interrupt Service Routine - Fires every 50uS
 | 
				
			||||||
 | 
						//Serial.println("Starting timer");
 | 
				
			||||||
 | 
						startTimer();
 | 
				
			||||||
 | 
						//Serial.println("Started timer");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Initialize state machine variables
 | 
				
			||||||
 | 
						irparams.rcvstate = STATE_IDLE;
 | 
				
			||||||
 | 
						irparams.rawlen = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Set pin modes
 | 
				
			||||||
 | 
						pinMode(irparams.recvpin, INPUT);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void irs(); // Defined in IRRemote as ISR(TIMER_INTR_NAME)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TC3_Handler(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						TcCount16* TC = (TcCount16*) TC3;
 | 
				
			||||||
 | 
						// If this interrupt is due to the compare register matching the timer count
 | 
				
			||||||
 | 
						// we toggle the LED.
 | 
				
			||||||
 | 
						if (TC->INTFLAG.bit.MC0 == 1) {
 | 
				
			||||||
 | 
							TC->INTFLAG.bit.MC0 = 1;
 | 
				
			||||||
 | 
							irs();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD)
 | 
				
			||||||
							
								
								
									
										211
									
								
								mecanum.ino
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								mecanum.ino
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,211 @@
 | 
				
			|||||||
 | 
					#include <boarddefs.h>
 | 
				
			||||||
 | 
					#include <IRremote.h>
 | 
				
			||||||
 | 
					#include <IRremoteInt.h>
 | 
				
			||||||
 | 
					#include <ir_Lego_PF_BitStreamEncoder.h>
 | 
				
			||||||
 | 
					#define IR 4
 | 
				
			||||||
 | 
					IRrecv irrecv(IR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define WHEEL_FRONT_LEFT_F A0
 | 
				
			||||||
 | 
					#define WHEEL_REAR_LEFT_R A1
 | 
				
			||||||
 | 
					#define WHEEL_REAR_RIGHT_F A2
 | 
				
			||||||
 | 
					#define WHEEL_FRONT_RIGHT_R A3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define WHEEL_FRONT_LEFT_R 10
 | 
				
			||||||
 | 
					#define WHEEL_REAR_LEFT_F 9
 | 
				
			||||||
 | 
					#define WHEEL_FRONT_RIGHT_F 8
 | 
				
			||||||
 | 
					#define WHEEL_REAR_RIGHT_R 7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 4060792887 ^
 | 
				
			||||||
 | 
					 * 4060752087 v
 | 
				
			||||||
 | 
					 * 4060768407 <
 | 
				
			||||||
 | 
					 * 4060784727 >
 | 
				
			||||||
 | 
					 * 4060801047 enter
 | 
				
			||||||
 | 
					 * 4060776567 menu
 | 
				
			||||||
 | 
					 * 4060774527 aspect
 | 
				
			||||||
 | 
					 * 4060745967 vol+
 | 
				
			||||||
 | 
					 * 4060794927 vol-
 | 
				
			||||||
 | 
					 * 4060803087 mute
 | 
				
			||||||
 | 
					 * 4060750047 source
 | 
				
			||||||
 | 
					 * 4060790847 video mode
 | 
				
			||||||
 | 
					 * 4060786767 keystone +
 | 
				
			||||||
 | 
					 * 4060778607 keystone -
 | 
				
			||||||
 | 
					 * 4060782687 mouse +
 | 
				
			||||||
 | 
					 * 4060766367 mouse -
 | 
				
			||||||
 | 
					 * 4060748007 auto adj
 | 
				
			||||||
 | 
					 * 4060743927 freeze
 | 
				
			||||||
 | 
					 * 4060754127 blank
 | 
				
			||||||
 | 
					 * 4060762287 zoom +
 | 
				
			||||||
 | 
					 * 4060770447 zoom -
 | 
				
			||||||
 | 
					 * 4060759227 info
 | 
				
			||||||
 | 
					 * 4060780647 vga
 | 
				
			||||||
 | 
					 * 4060742907 video
 | 
				
			||||||
 | 
					 * 4060775547 s-video
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void setup() {
 | 
				
			||||||
 | 
					  Serial.begin(115200);
 | 
				
			||||||
 | 
					  irrecv.enableIRIn();
 | 
				
			||||||
 | 
					  pinMode(WHEEL_REAR_RIGHT_R, OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(WHEEL_REAR_RIGHT_F, OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(WHEEL_REAR_LEFT_R, OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(WHEEL_REAR_LEFT_F, OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(WHEEL_FRONT_RIGHT_R, OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(WHEEL_FRONT_RIGHT_F, OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(WHEEL_FRONT_LEFT_R, OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(WHEEL_FRONT_LEFT_F, OUTPUT);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void stop(){
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_REAR_RIGHT_R, HIGH);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_REAR_RIGHT_F, HIGH);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_REAR_LEFT_R, HIGH);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_REAR_LEFT_F, HIGH);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_FRONT_RIGHT_R, HIGH);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_FRONT_RIGHT_F, HIGH);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_FRONT_LEFT_R, HIGH);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_FRONT_LEFT_F, HIGH);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void forward(){
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_REAR_RIGHT_F, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_REAR_LEFT_F, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_FRONT_RIGHT_F, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_FRONT_LEFT_F, LOW);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void backward(){
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_REAR_RIGHT_R, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_REAR_LEFT_R, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_FRONT_RIGHT_R, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_FRONT_LEFT_R, LOW);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void strafe_l(){
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_REAR_RIGHT_R, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_REAR_LEFT_F, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_FRONT_RIGHT_F, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_FRONT_LEFT_R, LOW);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void strafe_r(){
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_REAR_RIGHT_F, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_REAR_LEFT_R, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_FRONT_RIGHT_R, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_FRONT_LEFT_F, LOW);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void diag_l_f(){
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_REAR_LEFT_F, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_FRONT_RIGHT_F, LOW);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void diag_r_r(){
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_REAR_LEFT_R, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_FRONT_RIGHT_R, LOW);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void diag_r_f(){
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_REAR_RIGHT_F, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_FRONT_LEFT_F, LOW);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void diag_l_r(){
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_REAR_RIGHT_R, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_FRONT_LEFT_R, LOW);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void turn_l(){
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_REAR_RIGHT_R, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_REAR_LEFT_F, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_FRONT_RIGHT_R, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_FRONT_LEFT_F, LOW);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void turn_r(){
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_REAR_RIGHT_F, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_REAR_LEFT_R, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_FRONT_RIGHT_F, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(WHEEL_FRONT_LEFT_R, LOW);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned long getIRremote(){
 | 
				
			||||||
 | 
					  static unsigned long lastValue = 0;
 | 
				
			||||||
 | 
					  decode_results irResults;
 | 
				
			||||||
 | 
					  if(irrecv.decode(&irResults) == 0){
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if(!(irResults.decode_type == NEC && irResults.value == REPEAT)){
 | 
				
			||||||
 | 
					    lastValue = irResults.value;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  irrecv.resume();
 | 
				
			||||||
 | 
					  return lastValue;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void loop() {
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  unsigned long remote = getIRremote();
 | 
				
			||||||
 | 
					  static unsigned long modus;
 | 
				
			||||||
 | 
					  if(remote){
 | 
				
			||||||
 | 
					    Serial.println(remote);
 | 
				
			||||||
 | 
					    modus = remote;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if(modus == 4060792887){
 | 
				
			||||||
 | 
					      forward();
 | 
				
			||||||
 | 
					  }else if(modus == 4060801047){
 | 
				
			||||||
 | 
					    stop();
 | 
				
			||||||
 | 
					  }else if(modus == 4060752087){
 | 
				
			||||||
 | 
					    backward();
 | 
				
			||||||
 | 
					  }else if(modus == 4060768407){
 | 
				
			||||||
 | 
					    strafe_l();
 | 
				
			||||||
 | 
					  }else if(modus == 4060784727){
 | 
				
			||||||
 | 
					    strafe_r();
 | 
				
			||||||
 | 
					  }else if(modus == 4060750047){
 | 
				
			||||||
 | 
					    turn_l();
 | 
				
			||||||
 | 
					  }else if(modus == 4060790847){
 | 
				
			||||||
 | 
					    turn_r();
 | 
				
			||||||
 | 
					  }else if(modus == 4060786767){
 | 
				
			||||||
 | 
					    diag_l_f();
 | 
				
			||||||
 | 
					  }else if(modus == 4060778607){
 | 
				
			||||||
 | 
					    diag_r_r();
 | 
				
			||||||
 | 
					  }else if(modus == 4060782687){
 | 
				
			||||||
 | 
					    diag_r_f();
 | 
				
			||||||
 | 
					  }else if(modus == 4060766367){
 | 
				
			||||||
 | 
					    diag_l_r();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					  stop();
 | 
				
			||||||
 | 
					  forward();
 | 
				
			||||||
 | 
					  delay(1000);
 | 
				
			||||||
 | 
					  stop();
 | 
				
			||||||
 | 
					  backward();
 | 
				
			||||||
 | 
					  delay(1000);
 | 
				
			||||||
 | 
					  stop();
 | 
				
			||||||
 | 
					  strafe_l();
 | 
				
			||||||
 | 
					  delay(1000);
 | 
				
			||||||
 | 
					  stop();
 | 
				
			||||||
 | 
					  strafe_r();
 | 
				
			||||||
 | 
					  delay(1000);
 | 
				
			||||||
 | 
					  stop();
 | 
				
			||||||
 | 
					  diag_l_f();
 | 
				
			||||||
 | 
					  delay(1000);
 | 
				
			||||||
 | 
					  stop();
 | 
				
			||||||
 | 
					  diag_l_r();
 | 
				
			||||||
 | 
					  delay(1000);
 | 
				
			||||||
 | 
					  stop();
 | 
				
			||||||
 | 
					  diag_r_f();
 | 
				
			||||||
 | 
					  delay(1000);
 | 
				
			||||||
 | 
					  stop();
 | 
				
			||||||
 | 
					  diag_r_r();
 | 
				
			||||||
 | 
					  delay(1000);
 | 
				
			||||||
 | 
					  stop();
 | 
				
			||||||
 | 
					  turn_l();
 | 
				
			||||||
 | 
					  delay(1000);
 | 
				
			||||||
 | 
					  stop();
 | 
				
			||||||
 | 
					  turn_r();
 | 
				
			||||||
 | 
					  delay(1000);
 | 
				
			||||||
 | 
					  stop();
 | 
				
			||||||
 | 
					  */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user