Merge pull request #2 from z3t0/master

Update from Original
This commit is contained in:
AnalysIR
2015-11-28 14:01:01 +00:00
11 changed files with 482 additions and 98 deletions

View File

@@ -1,6 +1,6 @@
//******************************************************************************
// IRremote
// Version 0.11 August, 2009
// Version 2.0.1 June, 2015
// Copyright 2009 Ken Shirriff
// For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
//
@@ -18,6 +18,8 @@
// Whynter A/C ARC-110WD added by Francesco Meschia
//******************************************************************************
#include <avr/interrupt.h>
// Defining IR_GLOBAL here allows us to declare the instantiation of global variables
#define IR_GLOBAL
# include "IRremote.h"
@@ -88,3 +90,87 @@ int MATCH_SPACE (int measured_ticks, int desired_us)
return ((measured_ticks >= TICKS_LOW (desired_us - MARK_EXCESS))
&& (measured_ticks <= TICKS_HIGH(desired_us - MARK_EXCESS)));
}
//+=============================================================================
// 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;
}
// 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
}
}

View File

@@ -1,7 +1,7 @@
//******************************************************************************
// IRremote
// Version 0.1 July, 2009
// 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
@@ -56,7 +56,7 @@
#define SEND_AIWA_RC_T501 1
#define DECODE_LG 1
#define SEND_LG 0 // NOT WRITTEN
#define SEND_LG 1
#define DECODE_SANYO 1
#define SEND_SANYO 0 // NOT WRITTEN
@@ -300,7 +300,7 @@ class IRsend
# endif
//......................................................................
# if SEND_LG
void sendLG ( ) ; // NOT WRITTEN
void sendLG (unsigned long data, int nbits) ;
# endif
//......................................................................
# if SEND_SANYO
@@ -324,7 +324,7 @@ class IRsend
void sendDenon (unsigned long data, int nbits) ;
# endif
//......................................................................
# if SEND_Pronto
# if SEND_PRONTO
void sendPronto (char* code, bool repeat, bool fallback) ;
# endif
} ;

View File

@@ -1,6 +1,6 @@
//******************************************************************************
// IRremote
// Version 0.1 July, 2009
// Version 2.0.1 June, 2015
// Copyright 2009 Ken Shirriff
// For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
//

View File

@@ -15,6 +15,7 @@ Check [here](http://z3t0.github.io/Arduino-IRremote/) for tutorials and more inf
2. Download the latest release.
3. Extract the zip file
4. Move the "IRremote" folder that has been extracted to your libraries directory.
5. Make sure to delete Arduino_Root/libraries/RobotIRremote. Where Arduino_Root refers to the install directory of Arduino. The library RobotIRremote has similar definitions to IRremote and causes errors.
## Usage
- TODO (Check examples for now)
@@ -26,6 +27,11 @@ If you want to contribute to this project:
- Create issues and pull requests
- Tell other people about this library
- Contribute new protocols
-
## Contact
The only way to contact me at the moment is by email: zetoslab@gmail.com
I am not currently monitoring any PRs or Issues due to other issues but will respond to all emails. If anyone wants contributor access, feel free to email me. Or if you find any Issues/PRs to be of importance that my attention is needed please email me.
## Contributors
Check [here](Contributors.md)

View File

@@ -0,0 +1,263 @@
#include <IRremote.h>
#include <Wire.h>
IRsend irsend;
// not used
int RECV_PIN = 11;
IRrecv irrecv (RECV_PIN);
const int AC_TYPE = 0;
// 0 : TOWER
// 1 : WALL
//
int AC_HEAT = 0;
// 0 : cooling
// 1 : heating
int AC_POWER_ON = 0;
// 0 : off
// 1 : on
int AC_AIR_ACLEAN = 0;
// 0 : off
// 1 : on --> power on
int AC_TEMPERATURE = 27;
// temperature : 18 ~ 30
int AC_FLOW = 1;
// 0 : low
// 1 : mid
// 2 : high
// if AC_TYPE =1, 3 : change
//
const int AC_FLOW_TOWER[3] = {0, 4, 6};
const int AC_FLOW_WALL[4] = {0, 2, 4, 5};
unsigned long AC_CODE_TO_SEND;
int r = LOW;
int o_r = LOW;
byte a, b;
void ac_send_code(unsigned long code)
{
Serial.print("code to send : ");
Serial.print(code, BIN);
Serial.print(" : ");
Serial.println(code, HEX);
irsend.sendLG(code, 28);
}
void ac_activate(int temperature, int air_flow)
{
int AC_MSBITS1 = 8;
int AC_MSBITS2 = 8;
int AC_MSBITS3 = 0;
int AC_MSBITS4 ;
if ( AC_HEAT == 1 ) {
// heating
AC_MSBITS4 = 4;
} else {
// cooling
AC_MSBITS4 = 0;
}
int AC_MSBITS5 = temperature - 15;
int AC_MSBITS6 ;
if ( AC_TYPE == 0) {
AC_MSBITS6 = AC_FLOW_TOWER[air_flow];
} else {
AC_MSBITS6 = AC_FLOW_WALL[air_flow];
}
int AC_MSBITS7 = (AC_MSBITS3 + AC_MSBITS4 + AC_MSBITS5 + AC_MSBITS6) & B00001111;
AC_CODE_TO_SEND = AC_MSBITS1 << 4 ;
AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS2) << 4;
AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS3) << 4;
AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS4) << 4;
AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS5) << 4;
AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS6) << 4;
AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS7);
ac_send_code(AC_CODE_TO_SEND);
AC_POWER_ON = 1;
AC_TEMPERATURE = temperature;
AC_FLOW = air_flow;
}
void ac_change_air_swing(int air_swing)
{
if ( AC_TYPE == 0) {
if ( air_swing == 1) {
AC_CODE_TO_SEND = 0x881316B;
} else {
AC_CODE_TO_SEND = 0x881317C;
}
} else {
if ( air_swing == 1) {
AC_CODE_TO_SEND = 0x8813149;
} else {
AC_CODE_TO_SEND = 0x881315A;
}
}
ac_send_code(AC_CODE_TO_SEND);
}
void ac_power_down()
{
AC_CODE_TO_SEND = 0x88C0051;
ac_send_code(AC_CODE_TO_SEND);
AC_POWER_ON = 0;
}
void ac_air_clean(int air_clean)
{
if ( air_clean == 1) {
AC_CODE_TO_SEND = 0x88C000C;
} else {
AC_CODE_TO_SEND = 0x88C0084;
}
ac_send_code(AC_CODE_TO_SEND);
AC_AIR_ACLEAN = air_clean;
}
void setup()
{
Serial.begin(38400);
delay(1000);
Wire.begin(7);
Wire.onReceive(receiveEvent);
Serial.println(" - - - T E S T - - - ");
/* test
ac_activate(25, 1);
delay(5000);
ac_activate(27, 2);
delay(5000);
*/
}
void loop()
{
ac_activate(25, 1);
delay(5000);
ac_activate(27, 0);
delay(5000);
if ( r != o_r) {
/*
# a : mode or temp b : air_flow, temp, swing, clean, cooling/heating
# 18 ~ 30 : temp 0 ~ 2 : flow // on
# 0 : off 0
# 1 : on 0
# 2 : air_swing 0 or 1
# 3 : air_clean 0 or 1
# 4 : air_flow 0 ~ 2 : flow
# 5 : temp 18 ~ 30
# + : temp + 1
# - : temp - 1
# m : change cooling to air clean, air clean to cooling
*/
Serial.print("a : ");
Serial.print(a);
Serial.print(" b : ");
Serial.println(b);
switch (a) {
case 0: // off
ac_power_down();
break;
case 1: // on
ac_activate(AC_TEMPERATURE, AC_FLOW);
break;
case 2:
if ( b == 0 | b == 1 ) {
ac_change_air_swing(b);
}
break;
case 3: // 1 : clean on, power on
if ( b == 0 | b == 1 ) {
ac_air_clean(b);
}
break;
case 4:
if ( 0 <= b && b <= 2 ) {
ac_activate(AC_TEMPERATURE, b);
}
break;
case 5:
if (18 <= b && b <= 30 ) {
ac_activate(b, AC_FLOW);
}
break;
case '+':
if ( 18 <= AC_TEMPERATURE && AC_TEMPERATURE <= 29 ) {
ac_activate((AC_TEMPERATURE + 1), AC_FLOW);
}
break;
case '-':
if ( 19 <= AC_TEMPERATURE && AC_TEMPERATURE <= 30 ) {
ac_activate((AC_TEMPERATURE - 1), AC_FLOW);
}
break;
case 'm':
/*
if ac is on, 1) turn off, 2) turn on ac_air_clean(1)
if ac is off, 1) turn on, 2) turn off ac_air_clean(0)
*/
if ( AC_POWER_ON == 1 ) {
ac_power_down();
delay(100);
ac_air_clean(1);
} else {
if ( AC_AIR_ACLEAN == 1) {
ac_air_clean(0);
delay(100);
}
ac_activate(AC_TEMPERATURE, AC_FLOW);
}
break;
default:
if ( 18 <= a && a <= 30 ) {
if ( 0 <= b && b <= 2 ) {
ac_activate(a, b);
}
}
}
o_r = r ;
}
delay(100);
}
void receiveEvent(int howMany)
{
a = Wire.read();
b = Wire.read();
r = !r ;
}

View File

@@ -0,0 +1,93 @@
=== decoding for LG A/C ====
- 1) remote of LG AC has two type of HDR mark/space, 8000/4000 and 3100/10000
- 2) HDR 8000/4000 is decoded using decodeLG(IRrecvDumpV2) without problem
- 3) for HDR 3100/10000, use AnalysIR's code : http://www.analysir.com/blog/2014/03/19/air-conditioners-problems-recording-long-infrared-remote-control-signals-arduino/
- 4) for bin output based on AnalysIR's code : https://gist.github.com/chaeplin/a3a4b4b6b887c663bfe8
- 5) remove first two byte(11)
- 6) sample rawcode with bin output : https://gist.github.com/chaeplin/134d232e0b8cfb898860
=== *** ===
- 1) Sample raw code : https://gist.github.com/chaeplin/ab2a7ad1533c41260f0d
- 2) send raw code : https://gist.github.com/chaeplin/7c800d3166463bb51be4
=== *** ===
- (0) : Cooling or Heating
- (1) : fixed
- (2) : fixed
- (3) : special(power, swing, air clean)
- (4) : change air flow, temperature, cooling(0)/heating(4)
- (5) : temperature ( 15 + (5) = )
- (6) : air flow
- (7) : crc ( 3 + 4 + 5 + 6 ) & B00001111
°F = °C × 1.8 + 32
°C = (°F 32) / 1.8
=== *** ===
* remote / Korea / without heating
| status |(0)| (1)| (2)| (3)| (4)| (5)| (6)| (7)
|----------------|---|----|----|----|----|----|----|----
| on / 25 / mid | C |1000|1000|0000|0000|1010|0010|1100
| on / 26 / mid | C |1000|1000|0000|0000|1011|0010|1101
| on / 27 / mid | C |1000|1000|0000|0000|1100|0010|1110
| on / 28 / mid | C |1000|1000|0000|0000|1101|0010|1111
| on / 25 / high | C |1000|1000|0000|0000|1010|0100|1110
| on / 26 / high | C |1000|1000|0000|0000|1011|0100|1111
| on / 27 / high | C |1000|1000|0000|0000|1100|0100|0000
| on / 28 / high | C |1000|1000|0000|0000|1101|0100|0001
|----------------|---|----|----|----|----|----|----|----
| 1 up | C |1000|1000|0000|1000|1101|0100|1001
|----------------|---|----|----|----|----|----|----|----
| Cool power | C |1000|1000|0001|0000|0000|1100|1101
| energy saving | C |1000|1000|0001|0000|0000|0100|0101
| power | C |1000|1000|0001|0000|0000|1000|1001
| flow/up/down | C |1000|1000|0001|0011|0001|0100|1001
| up/down off | C |1000|1000|0001|0011|0001|0101|1010
| flow/left/right| C |1000|1000|0001|0011|0001|0110|1011
| left/right off | C |1000|1000|0001|0011|0001|0111|1100
|----------------|---|----|----|----|----|----|----|----
| Air clean | C |1000|1000|1100|0000|0000|0000|1100
|----------------|---|----|----|----|----|----|----|----
| off | C |1000|1000|1100|0000|0000|0101|0001
* remote / with heating
* converted using raw code at https://github.com/chaeplin/RaspAC/blob/master/lircd.conf
| status |(0)| (1)| (2)| (3)| (4)| (5)| (6)| (7)
|----------------|---|----|----|----|----|----|----|----
| on | C |1000|1000|0000|0000|1011|0010|1101
|----------------|---|----|----|----|----|----|----|----
| off | C |1000|1000|1100|0000|0000|0101|0001
|----------------|---|----|----|----|----|----|----|----
| 64 / 18 | C |1000|1000|0000|0000|0011|0100|0111
| 66 / 19 | C |1000|1000|0000|0000|0100|0100|1000
| 68 / 20 | C |1000|1000|0000|0000|0101|0100|1001
| 70 / 21 | C |1000|1000|0000|0000|0110|0100|1010
| 72 / 22 | C |1000|1000|0000|0000|0111|0100|1011
| 74 / 23 | C |1000|1000|0000|0000|1000|0100|1100
| 76 / 25 | C |1000|1000|0000|0000|1010|0100|1110
| 78 / 26 | C |1000|1000|0000|0000|1011|0100|1111
| 80 / 27 | C |1000|1000|0000|0000|1100|0100|0000
| 82 / 28 | C |1000|1000|0000|0000|1101|0100|0001
| 84 / 29 | C |1000|1000|0000|0000|1110|0100|0010
| 86 / 30 | C |1000|1000|0000|0000|1111|0100|0011
|----------------|---|----|----|----|----|----|----|----
| heat64 | H |1000|1000|0000|0100|0011|0100|1011
| heat66 | H |1000|1000|0000|0100|0100|0100|1100
| heat68 | H |1000|1000|0000|0100|0101|0100|1101
| heat70 | H |1000|1000|0000|0100|0110|0100|1110
| heat72 | H |1000|1000|0000|0100|0111|0100|1111
| heat74 | H |1000|1000|0000|0100|1000|0100|0000
| heat76 | H |1000|1000|0000|0100|1001|0100|0001
| heat78 | H |1000|1000|0000|0100|1011|0100|0011
| heat80 | H |1000|1000|0000|0100|1100|0100|0100
| heat82 | H |1000|1000|0000|0100|1101|0100|0101
| heat84 | H |1000|1000|0000|0100|1110|0100|0110
| heat86 | H |1000|1000|0000|0100|1111|0100|0111

View File

@@ -1,88 +0,0 @@
#include <avr/interrupt.h>
#include "IRremote.h"
#include "IRremoteInt.h"
//+=============================================================================
// 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;
}
// 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
}
}

View File

@@ -9,7 +9,7 @@
// A A IIIII WWW A A
//==============================================================================
// Baszed off the RC-T501 RCU
// Based off the RC-T501 RCU
// Lirc file http://lirc.sourceforge.net/remotes/aiwa/RC-T501
#define AIWA_RC_T501_HZ 38
@@ -28,7 +28,6 @@
void IRsend::sendAiwaRCT501 (int code)
{
unsigned long pre = 0x0227EEC0; // 26-bits
int mask;
// Set IR carrier frequency
enableIROut(AIWA_RC_T501_HZ);

View File

@@ -52,3 +52,29 @@ bool IRrecv::decodeLG (decode_results *results)
}
#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

View File

@@ -32,7 +32,6 @@ sendSharpRaw KEYWORD2
sendPanasonic KEYWORD2
sendJVC KEYWORD2
#
#######################################
# Constants (LITERAL1)
#######################################

View File

@@ -1,5 +1,5 @@
name=IRremote
version=1.0
version=2.0.1
author=shirriff
maintainer=shirriff
sentence=Send and receive infrared signals with multiple protocols