mirror of
https://github.com/Theaninova/Arduino-IRremote.git
synced 2025-12-21 05:46:15 +00:00
Compare commits
205 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
742f72fd0a | ||
|
|
3ab30887f4 | ||
|
|
bdb9f1c1f5 | ||
|
|
71f6daca4f | ||
|
|
2b3188e40a | ||
|
|
d719c27f95 | ||
|
|
20a4d97f61 | ||
|
|
d2939e2366 | ||
|
|
1154607b69 | ||
|
|
c6a2fcd8c9 | ||
|
|
e206e122e5 | ||
|
|
5bbd55c650 | ||
|
|
24dd940107 | ||
|
|
7245efd2f5 | ||
|
|
4eb95a3272 | ||
|
|
542516f116 | ||
|
|
563c82c6c4 | ||
|
|
a406f3b9f9 | ||
|
|
31968a4875 | ||
|
|
635e8a923d | ||
|
|
b0d15b6020 | ||
|
|
622e28bf69 | ||
|
|
e1768b4deb | ||
|
|
679348568d | ||
|
|
47aadf559d | ||
|
|
eb7a0bee7d | ||
|
|
18f12d3aff | ||
|
|
f0aa48a4d1 | ||
|
|
691ea5bc53 | ||
|
|
e0c2649b9f | ||
|
|
419c948c29 | ||
|
|
9133814e60 | ||
|
|
3875097df9 | ||
|
|
88b294a0cd | ||
|
|
ffdb6081ae | ||
|
|
6b8f2bdbfc | ||
|
|
eae9de4307 | ||
|
|
513e104515 | ||
|
|
ccc9d0135c | ||
|
|
257a15130f | ||
|
|
1b56da6cc7 | ||
|
|
aa8f7b31fe | ||
|
|
048efb23a2 | ||
|
|
4f24b696cf | ||
|
|
a4cf8bc43e | ||
|
|
3b41130ff9 | ||
|
|
96efb5930a | ||
|
|
9a74475c8d | ||
|
|
7c14514beb | ||
|
|
20b6e3b8a2 | ||
|
|
fe27a84d26 | ||
|
|
ccbaca5acc | ||
|
|
74594847b7 | ||
|
|
85f8aa1e25 | ||
|
|
9ae0239fb7 | ||
|
|
0d69a1a9ed | ||
|
|
05cc3e683c | ||
|
|
c0dda82685 | ||
|
|
0d398731b2 | ||
|
|
e72008adf6 | ||
|
|
2d1b0f4737 | ||
|
|
bb0323bd7c | ||
|
|
b26b64f871 | ||
|
|
13df9e5632 | ||
|
|
a9385b92d8 | ||
|
|
5bd251fa22 | ||
|
|
8a767328df | ||
|
|
1a05ac08a5 | ||
|
|
b27398de74 | ||
|
|
76e23159f2 | ||
|
|
75960b95f6 | ||
|
|
9bf00849b3 | ||
|
|
ec5a82bd93 | ||
|
|
d28b6f985c | ||
|
|
2343bee2fa | ||
|
|
e5dc3e108e | ||
|
|
de3d723574 | ||
|
|
978284d55f | ||
|
|
e6b839c34f | ||
|
|
bb1470a029 | ||
|
|
f9a41c99c8 | ||
|
|
bc15ded405 | ||
|
|
38c1e017a2 | ||
|
|
d5658f4488 | ||
|
|
e7e5465b74 | ||
|
|
44f801d55c | ||
|
|
92c7f00138 | ||
|
|
d0f1d0d33d | ||
|
|
34e5cd87ca | ||
|
|
d064c7dd5b | ||
|
|
33c2e36033 | ||
|
|
b8ef1c3e92 | ||
|
|
f04b014da5 | ||
|
|
fa2f5f9352 | ||
|
|
864ed3ad4d | ||
|
|
fc96667673 | ||
|
|
7d30c2ff78 | ||
|
|
ebbefa835f | ||
|
|
fba0ee0ae5 | ||
|
|
0221081f25 | ||
|
|
cf7b49389c | ||
|
|
3aebf42ca8 | ||
|
|
0486c4f25a | ||
|
|
25de5b79d6 | ||
|
|
17628525af | ||
|
|
cb01593db0 | ||
|
|
9e2c41230c | ||
|
|
3bdc6a65a6 | ||
|
|
841e77a642 | ||
|
|
bd1a2e05a0 | ||
|
|
3a906217d2 | ||
|
|
9697752f4e | ||
|
|
c471e2816d | ||
|
|
ec356c951b | ||
|
|
1c3275f228 | ||
|
|
376301228a | ||
|
|
96c40f63f0 | ||
|
|
86e20db36c | ||
|
|
e4933e809e | ||
|
|
92092df7a0 | ||
|
|
ed1a2a2153 | ||
|
|
e3ec11d696 | ||
|
|
8bde9ee628 | ||
|
|
711ebd7d92 | ||
|
|
a9706375c0 | ||
|
|
e1957629d3 | ||
|
|
9293d2fcba | ||
|
|
c41f506cc1 | ||
|
|
3c4fc7bf37 | ||
|
|
26560e5755 | ||
|
|
d7a4c4e0c8 | ||
|
|
9a57b2aead | ||
|
|
c90d6788a1 | ||
|
|
2da6aeaf27 | ||
|
|
2fd83bbb00 | ||
|
|
702a064251 | ||
|
|
f5071daac8 | ||
|
|
5b82539954 | ||
|
|
55f3e27866 | ||
|
|
f985c4b318 | ||
|
|
cdd783ce7e | ||
|
|
a237a0e393 | ||
|
|
27777e89b2 | ||
|
|
0ef30ed227 | ||
|
|
d87707d0ec | ||
|
|
d8bdbb1a44 | ||
|
|
3fcb071d36 | ||
|
|
b4c8e6b22c | ||
|
|
e6bcf89664 | ||
|
|
df34396969 | ||
|
|
bce86bf8ed | ||
|
|
0bf5993a5b | ||
|
|
77fd51e891 | ||
|
|
22e64f144c | ||
|
|
61f00b8dc5 | ||
|
|
bd72084b7f | ||
|
|
cd02daf27c | ||
|
|
339a7969c9 | ||
|
|
0abc9f0908 | ||
|
|
61d0263c5b | ||
|
|
e9d43f7751 | ||
|
|
79d951896d | ||
|
|
d433744ec7 | ||
|
|
ec371483ac | ||
|
|
072ab7f048 | ||
|
|
f83fe2b70f | ||
|
|
1fd88cd308 | ||
|
|
028cc2e649 | ||
|
|
9b21a7fdbd | ||
|
|
f1dc505249 | ||
|
|
1e72064557 | ||
|
|
24d20e3231 | ||
|
|
7aee7fcf89 | ||
|
|
11cb3fe442 | ||
|
|
c058f3f336 | ||
|
|
879b06b1c4 | ||
|
|
cd9fb53520 | ||
|
|
5c920bd31d | ||
|
|
c9e8ab555e | ||
|
|
a1a4538200 | ||
|
|
2efeef446e | ||
|
|
f1e1fd0a59 | ||
|
|
114fe2ccd6 | ||
|
|
295cdf2e15 | ||
|
|
6a10861a44 | ||
|
|
b6c04cde1a | ||
|
|
197ff26f68 | ||
|
|
e794c747db | ||
|
|
86a1e93b23 | ||
|
|
9fe9551705 | ||
|
|
b473429939 | ||
|
|
0c298aaf39 | ||
|
|
29826d01f4 | ||
|
|
e23aa5eb32 | ||
|
|
3cc9956f97 | ||
|
|
107b8c249c | ||
|
|
1e519b1bf3 | ||
|
|
dcd06fa0ef | ||
|
|
ee1b44de3f | ||
|
|
2280c963a7 | ||
|
|
b79c04f11c | ||
|
|
df6f2003ef | ||
|
|
66395a5daa | ||
|
|
8e043b5bb4 | ||
|
|
1c57c6a9b0 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1 +1,3 @@
|
||||
*.un~
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
30
.travis.yml
Normal file
30
.travis.yml
Normal file
@@ -0,0 +1,30 @@
|
||||
language: python
|
||||
python:
|
||||
- "2.7"
|
||||
|
||||
# Cache PlatformIO packages using Travis CI container-based infrastructure
|
||||
sudo: false
|
||||
cache:
|
||||
directories:
|
||||
- "~/.platformio"
|
||||
|
||||
env:
|
||||
- PLATFORMIO_CI_SRC=examples/AiwaRCT501SendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_AIWA_RC_T501"
|
||||
- PLATFORMIO_CI_SRC=examples/IRrecord PLATFORMIO_BUILD_FLAGS="-DSEND_NEC -DSEND_SONY -DSEND_RC5 -DSEND_RC6"
|
||||
- PLATFORMIO_CI_SRC=examples/IRrecvDemo
|
||||
- PLATFORMIO_CI_SRC=examples/IRrecvDump
|
||||
- PLATFORMIO_CI_SRC=examples/IRrecvDumpV2
|
||||
- PLATFORMIO_CI_SRC=examples/IRrelay
|
||||
- PLATFORMIO_CI_SRC=examples/IRsendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_SONY"
|
||||
- PLATFORMIO_CI_SRC=examples/IRtest PLATFORMIO_BUILD_FLAGS="-DSEND_NEC -DSEND_SONY -DSEND_RC5 -DSEND_RC6"
|
||||
- PLATFORMIO_CI_SRC=examples/IRtest2 PLATFORMIO_BUILD_FLAGS="-DSEND_NEC -DSEND_SONY -DSEND_RC5 -DSEND_RC6"
|
||||
- PLATFORMIO_CI_SRC=examples/JVCPanasonicSendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_JVC -DSEND_PANASONIC"
|
||||
- PLATFORMIO_CI_SRC=examples/LegoPowerFunctionsSendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_LEGO_PF"
|
||||
- PLATFORMIO_CI_SRC=examples/LegoPowerFunctionsTests PLATFORMIO_BUILD_FLAGS="-DSEND_LEGO_PF"
|
||||
- PLATFORMIO_CI_SRC=examples/IRremoteInfo
|
||||
|
||||
install:
|
||||
- pip install -U platformio
|
||||
|
||||
script:
|
||||
- platformio ci --lib="." --board=uno --board=leonardo --board=pro16MHzatmega168 --board=btatmega328
|
||||
11
Contributing.md
Normal file
11
Contributing.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Contribution Guidlines
|
||||
|
||||
This library is the culmination of the expertise of many members of the open source community who have dedicated their time and hard work. The best way to ask for help or propose a new idea is to [create a new issue](https://github.com/z3t0/Arduino-IRremote/issues/new) while creating a Pull Request with your code changes allows you to share your own innovations with the rest of the community.
|
||||
|
||||
The following are some guidelines to observe when creating issues or PRs:
|
||||
- Be friendly; it is important that we can all enjoy a safe space as we are all working on the same project and it is okay for people to have different ideas
|
||||
- [Use code blocks](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#code); it helps us help you when we can read your code! On that note also refrain from pasting more than 30 lines of code in a post, instead [create a gist](https://gist.github.com/) if you need to share large snippets
|
||||
- Use reasonable titles; refrain from using overly long or capitalized titles as they are usually annoying and do little to encourage others to help :smile:
|
||||
- Be detailed; refrain from mentioning code problems without sharing your source code and always give information regarding your board and version of the library
|
||||
|
||||
If there is any need to contact me then you can find my email on the README, I do not mind responding to emails but it would be in your own interests to create issues if you need help with the library as responses would be from a larger community with greater knowledge!
|
||||
@@ -1,18 +1,24 @@
|
||||
## Contributors
|
||||
These are the active contributors of this project that you may contact if there is anything you need help with or if you have suggestions.
|
||||
These are the active contributors of this project that you may contact if there is anything you need help with or if you have suggestions.
|
||||
|
||||
- [z3t0](https://github.com/z3t0) : Active Contributor and currently also the main contributor.
|
||||
* Email: zetoslab@gmail.com
|
||||
* Skype: polarised16
|
||||
- [shirriff](https://github.com/shirriff) : Owner of repository and creator of library.
|
||||
- [shirriff](https://github.com/shirriff) : An amazing person who worked to create this awesome library and provide unending support
|
||||
- [AnalysIR](https:/github.com/AnalysIR): Active contributor and is amazing with providing support!
|
||||
- [Informatic](https://github.com/Informatic) : Active contributor
|
||||
- [fmeschia](https://github.com/fmeschia) : Active contributor
|
||||
- [PaulStoffregen](https://github.com/paulstroffregen) : Active contributor
|
||||
- [crash7](https://github.com/crash7) : Active contributor
|
||||
- [Neco777](https://github.com/neco777) : Active contributor
|
||||
- [Lauszus](https://github.com/lauszus) : Active contributor
|
||||
- [csBlueChip](https://github.com/csbluechip) : Active contributor
|
||||
- [csBlueChip](https://github.com/csbluechip) : Active contributor, who contributed major and vital changes to the code base.
|
||||
- [Sebazzz](https://github.com/sebazz): Contributor
|
||||
- [lumbric](https://github.com/lumbric): Contributor
|
||||
- [ElectricRCAircraftGuy](https://github.com/electricrcaircraftguy): Active Contributor
|
||||
- [philipphenkel](https://github.com/philipphenkel): Active Contributor
|
||||
- [MCUdude](https://github.com/MCUdude): Contributor
|
||||
- [marcmerlin](https://github.com/marcmerlin): Contributor (ESP32 port)
|
||||
- [bengtmartensson](https://github.com/bengtmartensson): Active Contributor
|
||||
- [MrBryonMiller](https://github.com/MrBryonMiller): Contributor
|
||||
|
||||
Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed.
|
||||
|
||||
|
||||
|
||||
90
IRremote.cpp
90
IRremote.cpp
@@ -1,90 +0,0 @@
|
||||
//******************************************************************************
|
||||
// IRremote
|
||||
// Version 0.11 August, 2009
|
||||
// Copyright 2009 Ken Shirriff
|
||||
// For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
|
||||
//
|
||||
// Modified by Paul Stoffregen <paul@pjrc.com> to support other boards and timers
|
||||
// Modified by Mitra Ardron <mitra@mitra.biz>
|
||||
// Added Sanyo and Mitsubishi controllers
|
||||
// Modified Sony to spot the repeat codes that some Sony's send
|
||||
//
|
||||
// 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
|
||||
|
||||
//+=============================================================================
|
||||
// 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("Testing: ");
|
||||
DBG_PRINT(TICKS_LOW(desired), DEC);
|
||||
DBG_PRINT(" <= ");
|
||||
DBG_PRINT(measured, DEC);
|
||||
DBG_PRINT(" <= ");
|
||||
DBG_PRINTLN(TICKS_HIGH(desired), DEC);
|
||||
|
||||
return ((measured >= TICKS_LOW(desired)) && (measured <= TICKS_HIGH(desired)));
|
||||
}
|
||||
|
||||
//+========================================================
|
||||
// Due to sensor lag, when received, Marks tend to be 100us too long
|
||||
//
|
||||
int MATCH_MARK (int measured_ticks, int desired_us)
|
||||
{
|
||||
DBG_PRINT("Testing mark ");
|
||||
DBG_PRINT(measured_ticks * USECPERTICK, DEC);
|
||||
DBG_PRINT(" vs ");
|
||||
DBG_PRINT(desired_us, DEC);
|
||||
DBG_PRINT(": ");
|
||||
DBG_PRINT(TICKS_LOW(desired_us + MARK_EXCESS), DEC);
|
||||
DBG_PRINT(" <= ");
|
||||
DBG_PRINT(measured_ticks, DEC);
|
||||
DBG_PRINT(" <= ");
|
||||
DBG_PRINTLN(TICKS_HIGH(desired_us + MARK_EXCESS), DEC);
|
||||
|
||||
return ((measured_ticks >= TICKS_LOW (desired_us + MARK_EXCESS))
|
||||
&& (measured_ticks <= TICKS_HIGH(desired_us + MARK_EXCESS)));
|
||||
}
|
||||
|
||||
//+========================================================
|
||||
// Due to sensor lag, when received, Spaces tend to be 100us too short
|
||||
//
|
||||
int MATCH_SPACE (int measured_ticks, int desired_us)
|
||||
{
|
||||
DBG_PRINT("Testing space ");
|
||||
DBG_PRINT(measured_ticks * USECPERTICK, DEC);
|
||||
DBG_PRINT(" vs ");
|
||||
DBG_PRINT(desired_us, DEC);
|
||||
DBG_PRINT(": ");
|
||||
DBG_PRINT(TICKS_LOW(desired_us - MARK_EXCESS), DEC);
|
||||
DBG_PRINT(" <= ");
|
||||
DBG_PRINT(measured_ticks, DEC);
|
||||
DBG_PRINT(" <= ");
|
||||
DBG_PRINTLN(TICKS_HIGH(desired_us - MARK_EXCESS), DEC);
|
||||
|
||||
return ((measured_ticks >= TICKS_LOW (desired_us - MARK_EXCESS))
|
||||
&& (measured_ticks <= TICKS_HIGH(desired_us - MARK_EXCESS)));
|
||||
}
|
||||
25
ISSUE_TEMPLATE.md
Normal file
25
ISSUE_TEMPLATE.md
Normal file
@@ -0,0 +1,25 @@
|
||||
**Board:** ARDUINO UNO
|
||||
**Library Version:** 2.1.0
|
||||
**Protocol:** Sony (if any)
|
||||
|
||||
**Code Block:**
|
||||
```c
|
||||
|
||||
#include <IRremote.h>
|
||||
|
||||
.....
|
||||
|
||||
```
|
||||
|
||||
Use [a gist](gist.github.com) if the code exceeds 30 lines
|
||||
|
||||
**checklist:**
|
||||
- [] I have **read** the README.md file thoroughly
|
||||
- [] I have searched existing issues to see if there is anything I have missed.
|
||||
- [] The latest [release](https://github.com/z3t0/Arduino-IRremote/releases/latest) is used
|
||||
- [] Any code referenced is provided and if over 30 lines a gist is linked INSTEAD of it being pasted in here
|
||||
- [] The title of the issue is helpful and relevant
|
||||
|
||||
** We will start to close issues that do not follow these guidelines as it doesn't help the contributors who spend time trying to solve issues if the community ignores guidelines!**
|
||||
|
||||
The above is a short template allowing you to make detailed issues!
|
||||
82
README.md
82
README.md
@@ -1,28 +1,100 @@
|
||||
# IRremote Arduino Library
|
||||
|
||||
[](https://gitter.im/shirriff/Arduino-IRremote?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://travis-ci.org/z3t0/Arduino-IRremote)
|
||||
|
||||
This library enables you to send and receive using infra-red signals on an arduino.
|
||||
[](https://gitter.im/z3t0/Arduino-IRremote?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
Check [here](http://shirriff.github.io/Arduino-IRremote/) for tutorials and more information.
|
||||
This library enables you to send and receive using infra-red signals on an Arduino.
|
||||
|
||||
## Version - 22.00
|
||||
Tutorials and more information will be made available on [the official homepage](http://z3t0.github.io/Arduino-IRremote/).
|
||||
|
||||
## Version - 2.5.0b
|
||||
|
||||
## Installation
|
||||
1. Navigate to the [Releases](https://github.com/shirriff/Arduino-IRremote/releases) page.
|
||||
1. Navigate to the [Releases](https://github.com/z3t0/Arduino-IRremote/releases) page.
|
||||
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.
|
||||
|
||||
|
||||
## FAQ
|
||||
- IR does not work right when I use Neopixels (aka WS2811/WS2812/WS2812B)
|
||||
Whether you use the Adafruit Neopixel lib, or FastLED, interrupts get disabled on many lower end CPUs like the basic arduinos. In turn, this stops the IR interrupt handler from running when it needs to. There are some solutions to this on some processors, [see this page from Marc MERLIN](http://marc.merlins.org/perso/arduino/post_2017-04-03_Arduino-328P-Uno-Teensy3_1-ESP8266-ESP32-IR-and-Neopixels.html)
|
||||
|
||||
|
||||
## Supported Boards
|
||||
- Arduino Uno / Mega / Leonardo / Duemilanove / Diecimila / LilyPad / Mini / Fio / Nano etc.
|
||||
- Teensy 1.0 / 1.0++ / 2.0 / 2++ / 3.0 / 3.1 / Teensy-LC; Credits: @PaulStoffregen (Teensy Team)
|
||||
- Sanguino
|
||||
- ATmega8, 48, 88, 168, 328
|
||||
- ATmega8535, 16, 32, 164, 324, 644, 1284,
|
||||
- ATmega64, 128
|
||||
- ATtiny 84 / 85
|
||||
- ESP32 (receive only)
|
||||
- ESP8266 is supported in a fork based on an old codebase that isn't as recent, but it works reasonably well given that perfectly timed sub millisecond interrupts are different on that chip. See https://github.com/markszabo/IRremoteESP8266
|
||||
|
||||
We are open to suggestions for adding support to new boards, however we highly recommend you contact your supplier first and ask them to provide support from their side.
|
||||
|
||||
### Hardware specifications
|
||||
|
||||
| Board/CPU | Send Pin | Timers |
|
||||
|--------------------------------------------------------------------------|---------------------|-------------------|
|
||||
| [ATtiny84](https://github.com/SpenceKonde/ATTinyCore) | **6** | **1** |
|
||||
| [ATtiny85](https://github.com/SpenceKonde/ATTinyCore) | **1** | **TINY0** |
|
||||
| [ATmega8](https://github.com/MCUdude/MiniCore) | **9** | **1** |
|
||||
| Atmega32u4 | 5, **9**, 13 | 1, 3, **4** |
|
||||
| [ATmega48, ATmega88, ATmega168, ATmega328](https://github.com/MCUdude/MiniCore) | **3**, 9 | 1, **2** |
|
||||
| [ATmega1284](https://github.com/MCUdude/MightyCore) | 13, 14, 6 | 1, **2**, 3 |
|
||||
| [ATmega164, ATmega324, ATmega644](https://github.com/MCUdude/MightyCore) | 13, **14** | 1, **2** |
|
||||
| [ATmega8535 ATmega16, ATmega32](https://github.com/MCUdude/MightyCore) | **13** | **1** |
|
||||
| [ATmega64, ATmega128](https://github.com/MCUdude/MegaCore) | **13** | **1** |
|
||||
| ATmega1280, ATmega2560 | 5, 6, **9**, 11, 46 | 1, **2**, 3, 4, 5 |
|
||||
| [ESP32](http://esp32.net/) | N/A (not supported) | **1** |
|
||||
| [Teensy 1.0](https://www.pjrc.com/teensy/) | **17** | **1** |
|
||||
| [Teensy 2.0](https://www.pjrc.com/teensy/) | 9, **10**, 14 | 1, 3, **4_HS** |
|
||||
| [Teensy++ 1.0 / 2.0](https://www.pjrc.com/teensy/) | **1**, 16, 25 | 1, **2**, 3 |
|
||||
| [Teensy 3.0 / 3.1](https://www.pjrc.com/teensy/) | **5** | **CMT** |
|
||||
| [Teensy-LC](https://www.pjrc.com/teensy/) | **16** | **TPM1** |
|
||||
|
||||
|
||||
### Experimental patches
|
||||
The following are strictly community supported patches that have yet to make it into mainstream. If you have issues feel free to ask here. If it works well then let us know!
|
||||
|
||||
[Arduino 101](https://github.com/z3t0/Arduino-IRremote/pull/481#issuecomment-311243146)
|
||||
|
||||
The table above lists the currently supported timers and corresponding send pins, many of these can have additional pins opened up and we are open to requests if a need arises for other pins.
|
||||
|
||||
## Usage
|
||||
- TODO (Check examples for now)
|
||||
|
||||
## API documentation
|
||||
This project documents the library API using [Doxygen](http://www.doxygen.org).
|
||||
It is planned to make generated and up-to-date API documentation available online.
|
||||
|
||||
To generate the API documentation,
|
||||
Doxygen, as well as [Graphviz](http://www.graphviz.org/) should be installed.
|
||||
(Note that on Windows, it may be necessary to add the Graphviz binary directory
|
||||
(something like `C:\Program Files\Graphviz2.38\bin`)
|
||||
to the `PATH` variable manually.)
|
||||
With Doxygen and Graphviz installed, issue the command
|
||||
`doxygen` from the command line in the main project directory, which will
|
||||
generate the API documentation in HTML format.
|
||||
The just generated `api-doc/index.html` can now be opened in a browser.
|
||||
|
||||
## Contributing
|
||||
If you want to contribute to this project:
|
||||
- Report bugs and errors
|
||||
- Ask for enhancements
|
||||
- Create issues and pull requests
|
||||
- Tell other people about this library
|
||||
- Contribute new protocols
|
||||
|
||||
Check [here](Contributing.md) for some guidelines.
|
||||
|
||||
## Contact
|
||||
Email: zetoslab@gmail.com
|
||||
Please only email me if it is more appropriate than creating an Issue / PR. I **will** not respond to requests for adding support for particular boards, unless of course you are the creator of the board and would like to cooperate on the project. I will also **ignore** any emails asking me to tell you how to implement your ideas. However, if you have a private inquiry that you would only apply to you and you would prefer it to be via email, by all means.
|
||||
|
||||
## Contributors
|
||||
Check [here](Contributors.md)
|
||||
|
||||
87
changelog.md
87
changelog.md
@@ -1,5 +1,84 @@
|
||||
## 2.0.1 - 2015/06/26 - [Release](https://github.com/shirriff/Arduino-IRremote/releases/tag/BETA)
|
||||
- Separated protocols into individual files
|
||||
- Lots of code clean up
|
||||
- Possible bug fixes
|
||||
## 2.5.0
|
||||
- Added Philips Extended RC-5 protocol support [PR #522] (https://github.com/z3t0/Arduino-IRremote/pull/522)
|
||||
|
||||
## 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
|
||||
|
||||
@@ -80,6 +80,12 @@ void storeCode(decode_results *results) {
|
||||
else if (codeType == SONY) {
|
||||
Serial.print("Received SONY: ");
|
||||
}
|
||||
else if (codeType == PANASONIC) {
|
||||
Serial.print("Received PANASONIC: ");
|
||||
}
|
||||
else if (codeType == JVC) {
|
||||
Serial.print("Received JVC: ");
|
||||
}
|
||||
else if (codeType == RC5) {
|
||||
Serial.print("Received RC5: ");
|
||||
}
|
||||
@@ -114,6 +120,16 @@ void sendCode(int repeat) {
|
||||
Serial.print("Sent Sony ");
|
||||
Serial.println(codeValue, HEX);
|
||||
}
|
||||
else if (codeType == PANASONIC) {
|
||||
irsend.sendPanasonic(codeValue, codeLen);
|
||||
Serial.print("Sent Panasonic");
|
||||
Serial.println(codeValue, HEX);
|
||||
}
|
||||
else if (codeType == JVC) {
|
||||
irsend.sendJVC(codeValue, codeLen, false);
|
||||
Serial.print("Sent JVC");
|
||||
Serial.println(codeValue, HEX);
|
||||
}
|
||||
else if (codeType == RC5 || codeType == RC6) {
|
||||
if (!repeat) {
|
||||
// Flip the toggle bit for a new button press
|
||||
|
||||
@@ -17,7 +17,11 @@ decode_results results;
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
// In case the interrupt driver crashes on setup, give a clue
|
||||
// to the user what's going on.
|
||||
Serial.println("Enabling IRin");
|
||||
irrecv.enableIRIn(); // Start the receiver
|
||||
Serial.println("Enabled IRin");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
@@ -10,6 +10,11 @@
|
||||
|
||||
#include <IRremote.h>
|
||||
|
||||
/*
|
||||
* Default is Arduino pin D11.
|
||||
* You can change this to another available Arduino Pin.
|
||||
* Your IR receiver should be connected to the pin defined here
|
||||
*/
|
||||
int RECV_PIN = 11;
|
||||
|
||||
IRrecv irrecv(RECV_PIN);
|
||||
@@ -22,18 +27,17 @@ void setup()
|
||||
irrecv.enableIRIn(); // Start the receiver
|
||||
}
|
||||
|
||||
// Dumps out the decode_results structure.
|
||||
// Call this after IRrecv::decode()
|
||||
// void * to work around compiler issue
|
||||
//void dump(void *v) {
|
||||
// decode_results *results = (decode_results *)v
|
||||
|
||||
void dump(decode_results *results) {
|
||||
// Dumps out the decode_results structure.
|
||||
// Call this after IRrecv::decode()
|
||||
int count = results->rawlen;
|
||||
if (results->decode_type == UNKNOWN) {
|
||||
Serial.print("Unknown encoding: ");
|
||||
}
|
||||
else if (results->decode_type == NEC) {
|
||||
Serial.print("Decoded NEC: ");
|
||||
|
||||
}
|
||||
else if (results->decode_type == SONY) {
|
||||
Serial.print("Decoded SONY: ");
|
||||
@@ -46,21 +50,20 @@ void dump(decode_results *results) {
|
||||
}
|
||||
else if (results->decode_type == PANASONIC) {
|
||||
Serial.print("Decoded PANASONIC - Address: ");
|
||||
Serial.print(results->address,HEX);
|
||||
Serial.print(results->address, HEX);
|
||||
Serial.print(" Value: ");
|
||||
}
|
||||
else if (results->decode_type == LG) {
|
||||
Serial.print("Decoded LG: ");
|
||||
Serial.print("Decoded LG: ");
|
||||
}
|
||||
else if (results->decode_type == JVC) {
|
||||
Serial.print("Decoded JVC: ");
|
||||
|
||||
Serial.print("Decoded JVC: ");
|
||||
}
|
||||
else if (results->decode_type == AIWA_RC_T501) {
|
||||
Serial.print("Decoded AIWA RC T501: ");
|
||||
}
|
||||
else if (results->decode_type == WHYNTER) {
|
||||
Serial.print("Decoded Whynter: ");
|
||||
Serial.print("Decoded Whynter: ");
|
||||
}
|
||||
Serial.print(results->value, HEX);
|
||||
Serial.print(" (");
|
||||
@@ -70,19 +73,19 @@ void dump(decode_results *results) {
|
||||
Serial.print(count, DEC);
|
||||
Serial.print("): ");
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if ((i % 2) == 1) {
|
||||
for (int i = 1; i < count; i++) {
|
||||
if (i & 1) {
|
||||
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
else {
|
||||
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
|
||||
Serial.write('-');
|
||||
Serial.print((unsigned long) results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
if (irrecv.decode(&results)) {
|
||||
Serial.println(results.value, HEX);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Tell IRremote which Arduino pin is connected to the IR Receiver (TSOP4838)
|
||||
//
|
||||
int recvPin = 6;
|
||||
int recvPin = 11;
|
||||
IRrecv irrecv(recvPin);
|
||||
|
||||
//+=============================================================================
|
||||
@@ -66,7 +66,7 @@ void dumpInfo (decode_results *results)
|
||||
{
|
||||
// Check if the buffer overflowed
|
||||
if (results->overflow) {
|
||||
Serial.println("IR code too long. Edit IRremoteInt.h and increase RAWLEN");
|
||||
Serial.println("IR code too long. Edit IRremoteInt.h and increase RAWBUF");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -90,12 +90,11 @@ void dumpRaw (decode_results *results)
|
||||
{
|
||||
// Print Raw data
|
||||
Serial.print("Timing[");
|
||||
Serial.print(results->rawlen, DEC);
|
||||
Serial.print(results->rawlen-1, DEC);
|
||||
Serial.println("]: ");
|
||||
Serial.print(" -");
|
||||
Serial.println(results->rawbuf[0] * USECPERTICK, DEC);
|
||||
|
||||
for (int i = 1; i < results->rawlen; i++) {
|
||||
int x = results->rawbuf[i] * USECPERTICK;
|
||||
unsigned long x = results->rawbuf[i] * USECPERTICK;
|
||||
if (!(i & 1)) { // even
|
||||
Serial.print("-");
|
||||
if (x < 1000) Serial.print(" ") ;
|
||||
@@ -107,9 +106,9 @@ void dumpRaw (decode_results *results)
|
||||
if (x < 1000) Serial.print(" ") ;
|
||||
if (x < 100) Serial.print(" ") ;
|
||||
Serial.print(x, DEC);
|
||||
Serial.print(", ");
|
||||
if (i < results->rawlen-1) Serial.print(", "); //',' not needed for last one
|
||||
}
|
||||
if (!(i%8)) Serial.println("");
|
||||
if (!(i % 8)) Serial.println("");
|
||||
}
|
||||
Serial.println(""); // Newline
|
||||
}
|
||||
@@ -122,18 +121,18 @@ void dumpCode (decode_results *results)
|
||||
// Start declaration
|
||||
Serial.print("unsigned int "); // variable type
|
||||
Serial.print("rawData["); // array name
|
||||
Serial.print(results->rawlen + 1, DEC); // array size
|
||||
Serial.print(results->rawlen - 1, DEC); // array size
|
||||
Serial.print("] = {"); // Start declaration
|
||||
|
||||
// Dump data
|
||||
for (int i = 0; i < results->rawlen; i++) {
|
||||
Serial.print(results->rawbuf[i], DEC);
|
||||
Serial.print(",");
|
||||
if (!(i&1)) Serial.print(" ");
|
||||
for (int i = 1; i < results->rawlen; i++) {
|
||||
Serial.print(results->rawbuf[i] * USECPERTICK, DEC);
|
||||
if ( i < results->rawlen-1 ) Serial.print(","); // ',' not needed on last one
|
||||
if (!(i & 1)) Serial.print(" ");
|
||||
}
|
||||
|
||||
// End declaration
|
||||
Serial.print("0};"); // Turn LED off at the end
|
||||
Serial.print("};"); //
|
||||
|
||||
// Comment
|
||||
Serial.print(" // ");
|
||||
@@ -143,17 +142,17 @@ void dumpCode (decode_results *results)
|
||||
|
||||
// Newline
|
||||
Serial.println("");
|
||||
|
||||
|
||||
// Now dump "known" codes
|
||||
if (results->decode_type != UNKNOWN) {
|
||||
|
||||
|
||||
// Some protocols have an address
|
||||
if (results->decode_type == PANASONIC) {
|
||||
Serial.print("unsigned int addr = 0x");
|
||||
Serial.print(results->address, HEX);
|
||||
Serial.println(";");
|
||||
}
|
||||
|
||||
|
||||
// All protocols have data
|
||||
Serial.print("unsigned int data = 0x");
|
||||
Serial.print(results->value, HEX);
|
||||
@@ -166,14 +165,13 @@ void dumpCode (decode_results *results)
|
||||
//
|
||||
void loop ( )
|
||||
{
|
||||
decode_results results; // Somewhere to store the results
|
||||
decode_results results; // Somewhere to store the results
|
||||
|
||||
if (irrecv.decode(&results)) { // Grab an IR code
|
||||
dumpInfo(&results); // Output the results
|
||||
dumpRaw(&results); // Output the results in RAW format
|
||||
dumpCode(&results); // Output the results as source code
|
||||
Serial.println(""); // Blank line between entries
|
||||
irrecv.resume(); // Prepare for the next value
|
||||
}
|
||||
if (irrecv.decode(&results)) { // Grab an IR code
|
||||
dumpInfo(&results); // Output the results
|
||||
dumpRaw(&results); // Output the results in RAW format
|
||||
dumpCode(&results); // Output the results as source code
|
||||
Serial.println(""); // Blank line between entries
|
||||
irrecv.resume(); // Prepare for the next value
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
230
examples/IRremoteInfo/IRremoteInfo.ino
Normal file
230
examples/IRremoteInfo/IRremoteInfo.ino
Normal file
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* IRremote: IRremoteInfo - prints relevant config info & settings for IRremote over serial
|
||||
* Intended to help identify & troubleshoot the various settings of IRremote
|
||||
* For example, sometimes users are unsure of which pin is used for Tx or the RAWBUF values
|
||||
* This example can be used to assist the user directly or with support.
|
||||
* Intended to help identify & troubleshoot the various settings of IRremote
|
||||
* Hopefully this utility will be a useful tool for support & troubleshooting for IRremote
|
||||
* Check out the blog post describing the sketch via http://www.analysir.com/blog/2015/11/28/helper-utility-for-troubleshooting-irremote/
|
||||
* Version 1.0 November 2015
|
||||
* Original Author: AnalysIR - IR software & modules for Makers & Pros, visit http://www.AnalysIR.com
|
||||
*/
|
||||
|
||||
|
||||
#include <IRremote.h>
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200); //You may alter the BAUD rate here as needed
|
||||
while (!Serial); //wait until Serial is established - required on some Platforms
|
||||
|
||||
//Runs only once per restart of the Arduino.
|
||||
dumpHeader();
|
||||
dumpRAWBUF();
|
||||
dumpTIMER();
|
||||
dumpTimerPin();
|
||||
dumpClock();
|
||||
dumpPlatform();
|
||||
dumpPulseParams();
|
||||
dumpSignalParams();
|
||||
dumpArduinoIDE();
|
||||
dumpDebugMode();
|
||||
dumpProtocols();
|
||||
dumpFooter();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
//nothing to do!
|
||||
}
|
||||
|
||||
void dumpRAWBUF() {
|
||||
Serial.print(F("RAWBUF: "));
|
||||
Serial.println(RAWBUF);
|
||||
}
|
||||
|
||||
void dumpTIMER() {
|
||||
boolean flag = false;
|
||||
#ifdef IR_USE_TIMER1
|
||||
Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer1")); flag = true;
|
||||
#endif
|
||||
#ifdef IR_USE_TIMER2
|
||||
Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer2")); flag = true;
|
||||
#endif
|
||||
#ifdef IR_USE_TIMER3
|
||||
Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer3")); flag = true;
|
||||
#endif
|
||||
#ifdef IR_USE_TIMER4
|
||||
Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer4")); flag = true;
|
||||
#endif
|
||||
#ifdef IR_USE_TIMER5
|
||||
Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer5")); flag = true;
|
||||
#endif
|
||||
#ifdef IR_USE_TIMER4_HS
|
||||
Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer4_HS")); flag = true;
|
||||
#endif
|
||||
#ifdef IR_USE_TIMER_CMT
|
||||
Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer_CMT")); flag = true;
|
||||
#endif
|
||||
#ifdef IR_USE_TIMER_TPM1
|
||||
Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer_TPM1")); flag = true;
|
||||
#endif
|
||||
#ifdef IR_USE_TIMER_TINY0
|
||||
Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer_TINY0")); flag = true;
|
||||
#endif
|
||||
|
||||
if (!flag) {
|
||||
Serial.print(F("Timer Error: ")); Serial.println(F("not defined"));
|
||||
}
|
||||
}
|
||||
|
||||
void dumpTimerPin() {
|
||||
Serial.print(F("IR Tx Pin: "));
|
||||
Serial.println(SEND_PIN);
|
||||
}
|
||||
|
||||
void dumpClock() {
|
||||
Serial.print(F("MCU Clock: "));
|
||||
Serial.println(F_CPU);
|
||||
}
|
||||
|
||||
void dumpPlatform() {
|
||||
Serial.print(F("MCU Platform: "));
|
||||
|
||||
#if defined(__AVR_ATmega1280__)
|
||||
Serial.println(F("Arduino Mega1280"));
|
||||
#elif defined(__AVR_ATmega2560__)
|
||||
Serial.println(F("Arduino Mega2560"));
|
||||
#elif defined(__AVR_AT90USB162__)
|
||||
Serial.println(F("Teensy 1.0 / AT90USB162"));
|
||||
// Teensy 2.0
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
Serial.println(F("Arduino Leonardo / Yun / Teensy 1.0 / ATmega32U4"));
|
||||
#elif defined(__MK20DX128__) || defined(__MK20DX256__)
|
||||
Serial.println(F("Teensy 3.0 / Teensy 3.1 / MK20DX128 / MK20DX256"));
|
||||
#elif defined(__MKL26Z64__)
|
||||
Serial.println(F("Teensy-LC / MKL26Z64"));
|
||||
#elif defined(__AVR_AT90USB646__)
|
||||
Serial.println(F("Teensy++ 1.0 / AT90USB646"));
|
||||
#elif defined(__AVR_AT90USB1286__)
|
||||
Serial.println(F("Teensy++ 2.0 / AT90USB1286"));
|
||||
#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)
|
||||
Serial.println(F("ATmega1284"));
|
||||
#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__)
|
||||
Serial.println(F("ATmega644"));
|
||||
#elif defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) || defined(__AVR_ATmega324PA__)
|
||||
Serial.println(F("ATmega324"));
|
||||
#elif defined(__AVR_ATmega164A__) || defined(__AVR_ATmega164P__)
|
||||
Serial.println(F("ATmega164"));
|
||||
#elif defined(__AVR_ATmega128__)
|
||||
Serial.println(F("ATmega128"));
|
||||
#elif defined(__AVR_ATmega88__) || defined(__AVR_ATmega88P__)
|
||||
Serial.println(F("ATmega88"));
|
||||
#elif defined(__AVR_ATmega64__)
|
||||
Serial.println(F("ATmega64"));
|
||||
#elif defined(__AVR_ATmega48__) || defined(__AVR_ATmega48P__)
|
||||
Serial.println(F("ATmega48"));
|
||||
#elif defined(__AVR_ATmega32__)
|
||||
Serial.println(F("ATmega32"));
|
||||
#elif defined(__AVR_ATmega16__)
|
||||
Serial.println(F("ATmega16"));
|
||||
#elif defined(__AVR_ATmega8535__)
|
||||
Serial.println(F("ATmega8535"));
|
||||
#elif defined(__AVR_ATmega8__)
|
||||
Serial.println(F("Atmega8"));
|
||||
#elif defined(__AVR_ATtiny84__)
|
||||
Serial.println(F("ATtiny84"));
|
||||
#elif defined(__AVR_ATtiny85__)
|
||||
Serial.println(F("ATtiny85"));
|
||||
#else
|
||||
Serial.println(F("ATmega328(P) / (Duemilanove, Diecimila, LilyPad, Mini, Micro, Fio, Nano, etc)"));
|
||||
#endif
|
||||
}
|
||||
|
||||
void dumpPulseParams() {
|
||||
Serial.print(F("Mark Excess: ")); Serial.print(MARK_EXCESS);; Serial.println(F(" uSecs"));
|
||||
Serial.print(F("Microseconds per tick: ")); Serial.print(USECPERTICK);; Serial.println(F(" uSecs"));
|
||||
Serial.print(F("Measurement tolerance: ")); Serial.print(TOLERANCE); Serial.println(F("%"));
|
||||
}
|
||||
|
||||
void dumpSignalParams() {
|
||||
Serial.print(F("Minimum Gap between IR Signals: ")); Serial.print(_GAP); Serial.println(F(" uSecs"));
|
||||
}
|
||||
|
||||
void dumpDebugMode() {
|
||||
Serial.print(F("Debug Mode: "));
|
||||
#if DEBUG
|
||||
Serial.println(F("ON"));
|
||||
#else
|
||||
Serial.println(F("OFF (Normal)"));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void dumpArduinoIDE() {
|
||||
Serial.print(F("Arduino IDE version: "));
|
||||
Serial.print(ARDUINO / 10000);
|
||||
Serial.write('.');
|
||||
Serial.print((ARDUINO % 10000) / 100);
|
||||
Serial.write('.');
|
||||
Serial.println(ARDUINO % 100);
|
||||
}
|
||||
|
||||
void dumpProtocols() {
|
||||
|
||||
Serial.println(); Serial.print(F("IR PROTOCOLS ")); Serial.print(F("SEND ")); Serial.println(F("DECODE"));
|
||||
Serial.print(F("============= ")); Serial.print(F("======== ")); Serial.println(F("========"));
|
||||
Serial.print(F("RC5: ")); printSendEnabled(SEND_RC5); printDecodeEnabled(DECODE_RC6);
|
||||
Serial.print(F("RC6: ")); printSendEnabled(SEND_RC6); printDecodeEnabled(DECODE_RC5);
|
||||
Serial.print(F("NEC: ")); printSendEnabled(SEND_NEC); printDecodeEnabled(DECODE_NEC);
|
||||
Serial.print(F("SONY: ")); printSendEnabled(SEND_SONY); printDecodeEnabled(DECODE_SONY);
|
||||
Serial.print(F("PANASONIC: ")); printSendEnabled(SEND_PANASONIC); printDecodeEnabled(DECODE_PANASONIC);
|
||||
Serial.print(F("JVC: ")); printSendEnabled(SEND_JVC); printDecodeEnabled(DECODE_JVC);
|
||||
Serial.print(F("SAMSUNG: ")); printSendEnabled(SEND_SAMSUNG); printDecodeEnabled(DECODE_SAMSUNG);
|
||||
Serial.print(F("WHYNTER: ")); printSendEnabled(SEND_WHYNTER); printDecodeEnabled(DECODE_WHYNTER);
|
||||
Serial.print(F("AIWA_RC_T501: ")); printSendEnabled(SEND_AIWA_RC_T501); printDecodeEnabled(DECODE_AIWA_RC_T501);
|
||||
Serial.print(F("LG: ")); printSendEnabled(SEND_LG); printDecodeEnabled(DECODE_LG);
|
||||
Serial.print(F("SANYO: ")); printSendEnabled(SEND_SANYO); printDecodeEnabled(DECODE_SANYO);
|
||||
Serial.print(F("MITSUBISHI: ")); printSendEnabled(SEND_MITSUBISHI); printDecodeEnabled(DECODE_MITSUBISHI);
|
||||
Serial.print(F("DISH: ")); printSendEnabled(SEND_DISH); printDecodeEnabled(DECODE_DISH);
|
||||
Serial.print(F("SHARP: ")); printSendEnabled(SEND_SHARP); printDecodeEnabled(DECODE_SHARP);
|
||||
Serial.print(F("DENON: ")); printSendEnabled(SEND_DENON); printDecodeEnabled(DECODE_DENON);
|
||||
Serial.print(F("PRONTO: ")); printSendEnabled(SEND_PRONTO); Serial.println(F("(Not Applicable)"));
|
||||
}
|
||||
|
||||
void printSendEnabled(int flag) {
|
||||
if (flag) {
|
||||
Serial.print(F("Enabled "));
|
||||
}
|
||||
else {
|
||||
Serial.print(F("Disabled "));
|
||||
}
|
||||
}
|
||||
|
||||
void printDecodeEnabled(int flag) {
|
||||
if (flag) {
|
||||
Serial.println(F("Enabled"));
|
||||
}
|
||||
else {
|
||||
Serial.println(F("Disabled"));
|
||||
}
|
||||
}
|
||||
|
||||
void dumpHeader() {
|
||||
Serial.println(F("IRremoteInfo - by AnalysIR (http://www.AnalysIR.com/)"));
|
||||
Serial.println(F(" - A helper sketch to assist in troubleshooting issues with the library by reviewing the settings within the IRremote library"));
|
||||
Serial.println(F(" - Prints out the important settings within the library, which can be configured to suit the many supported platforms"));
|
||||
Serial.println(F(" - When seeking on-line support, please post or upload the output of this sketch, where appropriate"));
|
||||
Serial.println();
|
||||
Serial.println(F("IRremote Library Settings"));
|
||||
Serial.println(F("========================="));
|
||||
}
|
||||
|
||||
void dumpFooter() {
|
||||
Serial.println();
|
||||
Serial.println(F("Notes: "));
|
||||
Serial.println(F(" - Most of the seetings above can be configured in the following files included as part of the library"));
|
||||
Serial.println(F(" - IRremteInt.h"));
|
||||
Serial.println(F(" - IRremote.h"));
|
||||
Serial.println(F(" - You can save SRAM by disabling the Decode or Send features for any protocol (Near the top of IRremoteInt.h)"));
|
||||
Serial.println(F(" - Some Timer conflicts, with other libraries, can be easily resolved by configuring a differnt Timer for your platform"));
|
||||
}
|
||||
@@ -6,20 +6,19 @@
|
||||
* http://arcfn.com
|
||||
*/
|
||||
|
||||
|
||||
#include <IRremote.h>
|
||||
|
||||
IRsend irsend;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (Serial.read() != -1) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
irsend.sendSony(0xa90, 12); // Sony TV power code
|
||||
delay(40);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 3; i++) {
|
||||
irsend.sendSony(0xa90, 12);
|
||||
delay(40);
|
||||
}
|
||||
delay(5000); //5 second delay between each signal burst
|
||||
}
|
||||
|
||||
37
examples/IRsendRawDemo/IRsendRawDemo.ino
Normal file
37
examples/IRsendRawDemo/IRsendRawDemo.ino
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* IRremote: IRsendRawDemo - demonstrates sending IR codes with sendRaw
|
||||
* An IR LED must be connected to Arduino PWM pin 3.
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
*
|
||||
* IRsendRawDemo - added by AnalysIR (via www.AnalysIR.com), 24 August 2015
|
||||
*
|
||||
* This example shows how to send a RAW signal using the IRremote library.
|
||||
* The example signal is actually a 32 bit NEC signal.
|
||||
* Remote Control button: LGTV Power On/Off.
|
||||
* Hex Value: 0x20DF10EF, 32 bits
|
||||
*
|
||||
* It is more efficient to use the sendNEC function to send NEC signals.
|
||||
* Use of sendRaw here, serves only as an example of using the function.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <IRremote.h>
|
||||
|
||||
IRsend irsend;
|
||||
|
||||
void setup()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
int khz = 38; // 38kHz carrier frequency for the NEC protocol
|
||||
unsigned int irSignal[] = {9000, 4500, 560, 560, 560, 560, 560, 1690, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 1690, 560, 1690, 560, 560, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 560, 560, 560, 560, 560, 560, 1690, 560, 560, 560, 560, 560, 560, 560, 560, 560, 1690, 560, 1690, 560, 1690, 560, 560, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 39416, 9000, 2210, 560}; //AnalysIR Batch Export (IRremote) - RAW
|
||||
|
||||
irsend.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), khz); //Note the approach used to automatically calculate the size of the array.
|
||||
|
||||
delay(5000); //In this example, the signal will be repeated every 5 seconds, approximately.
|
||||
}
|
||||
@@ -10,7 +10,6 @@
|
||||
*/
|
||||
|
||||
#include <IRremote.h>
|
||||
#include <IRremoteInt.h>
|
||||
|
||||
// Dumps out the decode_results structure.
|
||||
// Call this after IRrecv::decode()
|
||||
|
||||
263
examples/LGACSendDemo/LGACSendDemo.ino
Normal file
263
examples/LGACSendDemo/LGACSendDemo.ino
Normal 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 ;
|
||||
}
|
||||
|
||||
|
||||
93
examples/LGACSendDemo/LGACSendDemo.md
Normal file
93
examples/LGACSendDemo/LGACSendDemo.md
Normal 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
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* LegoPowerFunctionsSendDemo: LEGO Power Functions
|
||||
* Copyright (c) 2016 Philipp Henkel
|
||||
*/
|
||||
|
||||
#include <IRremote.h>
|
||||
|
||||
IRsend irsend;
|
||||
|
||||
void setup() {
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Send repeated command "channel 1, blue forward, red backward"
|
||||
irsend.sendLegoPowerFunctions(0x197);
|
||||
delay(2000);
|
||||
|
||||
// Send single command "channel 1, blue forward, red backward"
|
||||
irsend.sendLegoPowerFunctions(0x197, false);
|
||||
delay(2000);
|
||||
}
|
||||
193
examples/LegoPowerFunctionsTests/LegoPowerFunctionsTests.ino
Normal file
193
examples/LegoPowerFunctionsTests/LegoPowerFunctionsTests.ino
Normal file
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* LegoPowerFunctionsTest: LEGO Power Functions Tests
|
||||
* Copyright (c) 2016, 2017 Philipp Henkel
|
||||
*/
|
||||
|
||||
#include <ir_Lego_PF_BitStreamEncoder.h>
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
delay(1000); // wait for reset triggered by serial connection
|
||||
runBitStreamEncoderTests();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
}
|
||||
|
||||
void runBitStreamEncoderTests() {
|
||||
Serial.println();
|
||||
Serial.println("BitStreamEncoder Tests");
|
||||
static LegoPfBitStreamEncoder bitStreamEncoder;
|
||||
testStartBit(bitStreamEncoder);
|
||||
testLowBit(bitStreamEncoder);
|
||||
testHighBit(bitStreamEncoder);
|
||||
testMessageBitCount(bitStreamEncoder);
|
||||
testMessageBitCountRepeat(bitStreamEncoder);
|
||||
testMessage407(bitStreamEncoder);
|
||||
testMessage407Repeated(bitStreamEncoder);
|
||||
testGetChannelId1(bitStreamEncoder);
|
||||
testGetChannelId2(bitStreamEncoder);
|
||||
testGetChannelId3(bitStreamEncoder);
|
||||
testGetChannelId4(bitStreamEncoder);
|
||||
testGetMessageLengthAllHigh(bitStreamEncoder);
|
||||
testGetMessageLengthAllLow(bitStreamEncoder);
|
||||
}
|
||||
|
||||
void logTestResult(bool testPassed) {
|
||||
if (testPassed) {
|
||||
Serial.println("OK");
|
||||
}
|
||||
else {
|
||||
Serial.println("FAIL ############");
|
||||
}
|
||||
}
|
||||
|
||||
void testStartBit(LegoPfBitStreamEncoder& bitStreamEncoder) {
|
||||
Serial.print(" testStartBit ");
|
||||
bitStreamEncoder.reset(0, false);
|
||||
int startMark = bitStreamEncoder.getMarkDuration();
|
||||
int startPause = bitStreamEncoder.getPauseDuration();
|
||||
logTestResult(startMark == 158 && startPause == 1184-158);
|
||||
}
|
||||
|
||||
void testLowBit(LegoPfBitStreamEncoder& bitStreamEncoder) {
|
||||
Serial.print(" testLowBit ");
|
||||
bitStreamEncoder.reset(0, false);
|
||||
bitStreamEncoder.next();
|
||||
int lowMark = bitStreamEncoder.getMarkDuration();
|
||||
int lowPause = bitStreamEncoder.getPauseDuration();
|
||||
logTestResult(lowMark == 158 && lowPause == 421-158);
|
||||
}
|
||||
|
||||
void testHighBit(LegoPfBitStreamEncoder& bitStreamEncoder) {
|
||||
Serial.print(" testHighBit ");
|
||||
bitStreamEncoder.reset(0xFFFF, false);
|
||||
bitStreamEncoder.next();
|
||||
int highMark = bitStreamEncoder.getMarkDuration();
|
||||
int highPause = bitStreamEncoder.getPauseDuration();
|
||||
logTestResult(highMark == 158 && highPause == 711-158);
|
||||
}
|
||||
|
||||
void testMessageBitCount(LegoPfBitStreamEncoder& bitStreamEncoder) {
|
||||
Serial.print(" testMessageBitCount ");
|
||||
bitStreamEncoder.reset(0xFFFF, false);
|
||||
int bitCount = 1;
|
||||
while (bitStreamEncoder.next()) {
|
||||
bitCount++;
|
||||
}
|
||||
logTestResult(bitCount == 18);
|
||||
}
|
||||
|
||||
boolean check(LegoPfBitStreamEncoder& bitStreamEncoder, unsigned long markDuration, unsigned long pauseDuration) {
|
||||
bool result = true;
|
||||
result = result && bitStreamEncoder.getMarkDuration() == markDuration;
|
||||
result = result && bitStreamEncoder.getPauseDuration() == pauseDuration;
|
||||
return result;
|
||||
}
|
||||
|
||||
boolean checkNext(LegoPfBitStreamEncoder& bitStreamEncoder, unsigned long markDuration, unsigned long pauseDuration) {
|
||||
bool result = bitStreamEncoder.next();
|
||||
result = result && check(bitStreamEncoder, markDuration, pauseDuration);
|
||||
return result;
|
||||
}
|
||||
|
||||
boolean checkDataBitsOfMessage407(LegoPfBitStreamEncoder& bitStreamEncoder) {
|
||||
bool result = true;
|
||||
result = result && checkNext(bitStreamEncoder, 158, 263);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 263);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 263);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 263);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 263);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 263);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 263);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 553);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 553);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 263);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 263);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 553);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 263);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 553);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 553);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 553);
|
||||
return result;
|
||||
}
|
||||
|
||||
void testMessage407(LegoPfBitStreamEncoder& bitStreamEncoder) {
|
||||
Serial.print(" testMessage407 ");
|
||||
bitStreamEncoder.reset(407, false);
|
||||
bool result = true;
|
||||
result = result && check(bitStreamEncoder, 158, 1026);
|
||||
result = result && checkDataBitsOfMessage407(bitStreamEncoder);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 1026);
|
||||
result = result && !bitStreamEncoder.next();
|
||||
logTestResult(result);
|
||||
}
|
||||
|
||||
void testMessage407Repeated(LegoPfBitStreamEncoder& bitStreamEncoder) {
|
||||
Serial.print(" testMessage407Repeated ");
|
||||
bitStreamEncoder.reset(407, true);
|
||||
bool result = true;
|
||||
result = result && check(bitStreamEncoder, 158, 1026);
|
||||
result = result && checkDataBitsOfMessage407(bitStreamEncoder);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 1026L + 5L * 16000L - 10844L);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 1026);
|
||||
result = result && checkDataBitsOfMessage407(bitStreamEncoder);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 1026L + 5L * 16000L - 10844L);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 1026);
|
||||
result = result && checkDataBitsOfMessage407(bitStreamEncoder);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 1026L + 8L * 16000L - 10844L);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 1026);
|
||||
result = result && checkDataBitsOfMessage407(bitStreamEncoder);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 1026L + 8L * 16000L - 10844L);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 1026);
|
||||
result = result && checkDataBitsOfMessage407(bitStreamEncoder);
|
||||
result = result && checkNext(bitStreamEncoder, 158, 1026);
|
||||
result = result && !bitStreamEncoder.next();
|
||||
logTestResult(result);
|
||||
}
|
||||
|
||||
void testMessageBitCountRepeat(LegoPfBitStreamEncoder& bitStreamEncoder) {
|
||||
Serial.print(" testMessageBitCountRepeat ");
|
||||
bitStreamEncoder.reset(0xFFFF, true);
|
||||
int bitCount = 1;
|
||||
while (bitStreamEncoder.next()) {
|
||||
bitCount++;
|
||||
}
|
||||
logTestResult(bitCount == 5*18);
|
||||
}
|
||||
|
||||
void testGetChannelId1(LegoPfBitStreamEncoder& bitStreamEncoder) {
|
||||
Serial.print(" testGetChannelId1 ");
|
||||
bitStreamEncoder.reset(407, false);
|
||||
logTestResult(bitStreamEncoder.getChannelId() == 1);
|
||||
}
|
||||
|
||||
void testGetChannelId2(LegoPfBitStreamEncoder& bitStreamEncoder) {
|
||||
Serial.print(" testGetChannelId2 ");
|
||||
bitStreamEncoder.reset(4502, false);
|
||||
logTestResult(bitStreamEncoder.getChannelId() == 2);
|
||||
}
|
||||
|
||||
void testGetChannelId3(LegoPfBitStreamEncoder& bitStreamEncoder) {
|
||||
Serial.print(" testGetChannelId3 ");
|
||||
bitStreamEncoder.reset(8597, false);
|
||||
logTestResult(bitStreamEncoder.getChannelId() == 3);
|
||||
}
|
||||
|
||||
void testGetChannelId4(LegoPfBitStreamEncoder& bitStreamEncoder) {
|
||||
Serial.print(" testGetChannelId4 ");
|
||||
bitStreamEncoder.reset(12692, false);
|
||||
logTestResult(bitStreamEncoder.getChannelId() == 4);
|
||||
}
|
||||
|
||||
void testGetMessageLengthAllHigh(LegoPfBitStreamEncoder& bitStreamEncoder) {
|
||||
Serial.print(" testGetMessageLengthAllHigh ");
|
||||
bitStreamEncoder.reset(0xFFFF, false);
|
||||
logTestResult(bitStreamEncoder.getMessageLength() == 13744);
|
||||
}
|
||||
|
||||
void testGetMessageLengthAllLow(LegoPfBitStreamEncoder& bitStreamEncoder) {
|
||||
Serial.print(" testGetMessageLengthAllLow ");
|
||||
bitStreamEncoder.reset(0x0, false);
|
||||
logTestResult(bitStreamEncoder.getMessageLength() == 9104);
|
||||
}
|
||||
85
irISR.cpp
85
irISR.cpp
@@ -1,85 +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 L (D13) while receiving IR data
|
||||
if (irparams.blinkflag) {
|
||||
if (irdata == MARK) BLINKLED_ON() ; // turn pin 13 LED on
|
||||
else BLINKLED_OFF() ; // turn pin 13 LED off
|
||||
}
|
||||
}
|
||||
66
irSend.cpp
66
irSend.cpp
@@ -1,66 +0,0 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//+=============================================================================
|
||||
void IRsend::sendRaw (unsigned int buf[], int len, int hz)
|
||||
{
|
||||
// Set IR carrier frequency
|
||||
enableIROut(hz);
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (i & 1) space(buf[i]) ;
|
||||
else mark (buf[i]) ;
|
||||
}
|
||||
|
||||
space(0); // Always end with the LED off
|
||||
}
|
||||
|
||||
//+=============================================================================
|
||||
// Sends an IR mark for the specified number of microseconds.
|
||||
// The mark output is modulated at the PWM frequency.
|
||||
//
|
||||
void IRsend::mark (int time)
|
||||
{
|
||||
TIMER_ENABLE_PWM; // Enable pin 3 PWM output
|
||||
if (time > 0) delayMicroseconds(time);
|
||||
}
|
||||
|
||||
//+=============================================================================
|
||||
// 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 (int time)
|
||||
{
|
||||
TIMER_DISABLE_PWM; // Disable pin 3 PWM output
|
||||
if (time > 0) delayMicroseconds(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)
|
||||
{
|
||||
// Disable the Timer2 Interrupt (which is used for receiving IR)
|
||||
TIMER_DISABLE_INTR; //Timer2 Overflow Interrupt
|
||||
|
||||
pinMode(TIMER_PWM_PIN, OUTPUT);
|
||||
digitalWrite(TIMER_PWM_PIN, LOW); // When not sending PWM, we want it low
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ sendSharp KEYWORD2
|
||||
sendSharpRaw KEYWORD2
|
||||
sendPanasonic KEYWORD2
|
||||
sendJVC KEYWORD2
|
||||
sendLG KEYWORD2
|
||||
|
||||
#
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
|
||||
16
library.json
16
library.json
@@ -5,8 +5,20 @@
|
||||
"repository":
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/shirriff/Arduino-IRremote.git"
|
||||
"url": "https://github.com/z3t0/Arduino-IRremote.git"
|
||||
},
|
||||
"version": "2.4.0",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "atmelavr"
|
||||
"platforms": "atmelavr",
|
||||
"authors" :
|
||||
[
|
||||
{
|
||||
"name":"Rafi Khan",
|
||||
"email":"zetoslab@gmail.com"
|
||||
},
|
||||
{
|
||||
"name":"Ken Shirriff",
|
||||
"email":"ken.shirriff@gmail.com"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
name=IRremote
|
||||
version=1.0
|
||||
author=shirriff
|
||||
maintainer=shirriff
|
||||
version=2.4.0
|
||||
author=shirriff, z3t0
|
||||
maintainer=z3t0
|
||||
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
|
||||
paragraph=Find more information at https://github.com/z3t0/Arduino-IRremote
|
||||
category=Communication
|
||||
url=https://github.com/z3t0/Arduino-IRremote
|
||||
architectures=*
|
||||
|
||||
200
src/IRremote.cpp
Normal file
200
src/IRremote.cpp
Normal file
@@ -0,0 +1,200 @@
|
||||
//******************************************************************************
|
||||
// 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"
|
||||
#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
|
||||
}
|
||||
@@ -1,7 +1,11 @@
|
||||
/**
|
||||
* @file IRremote.h
|
||||
* @brief Public API to the library.
|
||||
*/
|
||||
|
||||
//******************************************************************************
|
||||
// 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
|
||||
@@ -21,7 +25,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// The ISR header contains several useful macros the user may wish to use
|
||||
//
|
||||
#include "IRremoteInt.h"
|
||||
#include "private/IRremoteInt.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Supported IR protocols
|
||||
@@ -56,7 +60,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
|
||||
@@ -76,6 +80,9 @@
|
||||
#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
|
||||
@@ -91,10 +98,10 @@
|
||||
#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!
|
||||
//
|
||||
/**
|
||||
* An enum consisting of all supported formats.
|
||||
* You do NOT need to remove entries from this list when disabling protocols!
|
||||
*/
|
||||
typedef
|
||||
enum {
|
||||
UNKNOWN = -1,
|
||||
@@ -115,12 +122,13 @@ typedef
|
||||
SHARP,
|
||||
DENON,
|
||||
PRONTO,
|
||||
LEGO_PF,
|
||||
}
|
||||
decode_type_t;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Set DEBUG to 1 for lots of lovely debug output
|
||||
//
|
||||
/**
|
||||
* Set DEBUG to 1 for lots of lovely debug output.
|
||||
*/
|
||||
#define DEBUG 0
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -130,7 +138,13 @@ decode_type_t;
|
||||
# define DBG_PRINT(...) Serial.print(__VA_ARGS__)
|
||||
# define DBG_PRINTLN(...) Serial.println(__VA_ARGS__)
|
||||
#else
|
||||
/**
|
||||
* If DEBUG, print the arguments, otherwise do nothing.
|
||||
*/
|
||||
# define DBG_PRINT(...)
|
||||
/**
|
||||
* If DEBUG, print the arguments as a line, otherwise do nothing.
|
||||
*/
|
||||
# define DBG_PRINTLN(...)
|
||||
#endif
|
||||
|
||||
@@ -141,37 +155,71 @@ 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
|
||||
//
|
||||
/**
|
||||
* 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
|
||||
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
|
||||
//
|
||||
/**
|
||||
* Decoded value for NEC when a repeat code is received
|
||||
*/
|
||||
#define REPEAT 0xFFFFFFFF
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Main class for receiving IR
|
||||
//
|
||||
/**
|
||||
* Main class for receiving IR
|
||||
*/
|
||||
class IRrecv
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Instantiate the IRrecv class. Multiple instantiation is not supported.
|
||||
* @param recvpin Arduino pin to use. No sanity check is made.
|
||||
*/
|
||||
IRrecv (int recvpin) ;
|
||||
/**
|
||||
* Instantiate the IRrecv class. Multiple instantiation is not supported.
|
||||
* @param recvpin Arduino pin to use, where a demodulating IR receiver is connected.
|
||||
* @param blinkpin pin to blink when receiving IR. Not supported by all hardware. No sanity check is made.
|
||||
*/
|
||||
IRrecv (int recvpin, int blinkpin);
|
||||
|
||||
/**
|
||||
* TODO: Why is this public???
|
||||
* @param blinkflag
|
||||
*/
|
||||
void blink13 (int blinkflag) ;
|
||||
|
||||
/**
|
||||
* Attempt to decode the recently receive IR signal
|
||||
* @param results decode_results instance returning the decode, if any.
|
||||
* @return success of operation. TODO: convert to bool
|
||||
*/
|
||||
int decode (decode_results *results) ;
|
||||
|
||||
/**
|
||||
* Enable IR reception.
|
||||
*/
|
||||
void enableIRIn ( ) ;
|
||||
|
||||
/**
|
||||
* Returns status of reception
|
||||
* @return true if no reception is on-going.
|
||||
*/
|
||||
bool isIdle ( ) ;
|
||||
|
||||
/**
|
||||
* Called to re-enable IR reception.
|
||||
*/
|
||||
void resume ( ) ;
|
||||
|
||||
private:
|
||||
@@ -180,10 +228,17 @@ class IRrecv
|
||||
|
||||
//......................................................................
|
||||
# if (DECODE_RC5 || DECODE_RC6)
|
||||
// This helper function is shared by RC5 and 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
|
||||
/**
|
||||
* Try to decode the recently received IR signal as an RC5 signal-
|
||||
* @param results decode_results instance returning the decode, if any.
|
||||
* @return Success of the operation.
|
||||
*/
|
||||
bool decodeRC5 (decode_results *results) ;
|
||||
# endif
|
||||
# if DECODE_RC6
|
||||
@@ -241,24 +296,41 @@ class IRrecv
|
||||
# if DECODE_DENON
|
||||
bool decodeDenon (decode_results *results) ;
|
||||
# endif
|
||||
//......................................................................
|
||||
# if DECODE_LEGO_PF
|
||||
bool decodeLegoPowerFunctions (decode_results *results) ;
|
||||
# endif
|
||||
} ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Main class for sending IR
|
||||
//
|
||||
/**
|
||||
* Main class for sending IR
|
||||
*/
|
||||
class IRsend
|
||||
{
|
||||
public:
|
||||
IRsend () { }
|
||||
#ifdef USE_SOFT_CARRIER
|
||||
|
||||
void enableIROut (int khz) ;
|
||||
void mark (int usec) ;
|
||||
void space (int usec) ;
|
||||
void sendRaw (unsigned int buf[], int len, int hz) ;
|
||||
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) ;
|
||||
void sendRC5ext (unsigned long addr, unsigned long cmd, boolean toggle);
|
||||
# endif
|
||||
# if SEND_RC6
|
||||
void sendRC6 (unsigned long data, int nbits) ;
|
||||
@@ -297,7 +369,7 @@ class IRsend
|
||||
# endif
|
||||
//......................................................................
|
||||
# if SEND_LG
|
||||
void sendLG ( ) ; // NOT WRITTEN
|
||||
void sendLG (unsigned long data, int nbits) ;
|
||||
# endif
|
||||
//......................................................................
|
||||
# if SEND_SANYO
|
||||
@@ -321,9 +393,27 @@ 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
|
||||
//......................................................................
|
||||
# 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
|
||||
38
src/esp32.cpp
Normal file
38
src/esp32.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#ifdef ESP32
|
||||
|
||||
// This file contains functions specific to the ESP32.
|
||||
|
||||
#include "IRremote.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
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//+=============================================================================
|
||||
// Decodes the received IR message
|
||||
@@ -15,71 +14,76 @@ int IRrecv::decode (decode_results *results)
|
||||
|
||||
if (irparams.rcvstate != STATE_STOP) return false ;
|
||||
|
||||
#ifdef DECODE_NEC
|
||||
#if DECODE_NEC
|
||||
DBG_PRINTLN("Attempting NEC decode");
|
||||
if (decodeNEC(results)) return true ;
|
||||
#endif
|
||||
|
||||
#ifdef DECODE_SONY
|
||||
#if DECODE_SONY
|
||||
DBG_PRINTLN("Attempting Sony decode");
|
||||
if (decodeSony(results)) return true ;
|
||||
#endif
|
||||
|
||||
#ifdef DECODE_SANYO
|
||||
#if DECODE_SANYO
|
||||
DBG_PRINTLN("Attempting Sanyo decode");
|
||||
if (decodeSanyo(results)) return true ;
|
||||
#endif
|
||||
|
||||
#ifdef DECODE_MITSUBISHI
|
||||
#if DECODE_MITSUBISHI
|
||||
DBG_PRINTLN("Attempting Mitsubishi decode");
|
||||
if (decodeMitsubishi(results)) return true ;
|
||||
#endif
|
||||
|
||||
#ifdef DECODE_RC5
|
||||
#if DECODE_RC5
|
||||
DBG_PRINTLN("Attempting RC5 decode");
|
||||
if (decodeRC5(results)) return true ;
|
||||
#endif
|
||||
|
||||
#ifdef DECODE_RC6
|
||||
#if DECODE_RC6
|
||||
DBG_PRINTLN("Attempting RC6 decode");
|
||||
if (decodeRC6(results)) return true ;
|
||||
#endif
|
||||
|
||||
#ifdef DECODE_PANASONIC
|
||||
#if DECODE_PANASONIC
|
||||
DBG_PRINTLN("Attempting Panasonic decode");
|
||||
if (decodePanasonic(results)) return true ;
|
||||
#endif
|
||||
|
||||
#ifdef DECODE_LG
|
||||
#if DECODE_LG
|
||||
DBG_PRINTLN("Attempting LG decode");
|
||||
if (decodeLG(results)) return true ;
|
||||
#endif
|
||||
|
||||
#ifdef DECODE_JVC
|
||||
#if DECODE_JVC
|
||||
DBG_PRINTLN("Attempting JVC decode");
|
||||
if (decodeJVC(results)) return true ;
|
||||
#endif
|
||||
|
||||
#ifdef DECODE_SAMSUNG
|
||||
#if DECODE_SAMSUNG
|
||||
DBG_PRINTLN("Attempting SAMSUNG decode");
|
||||
if (decodeSAMSUNG(results)) return true ;
|
||||
#endif
|
||||
|
||||
#ifdef DECODE_WHYNTER
|
||||
#if DECODE_WHYNTER
|
||||
DBG_PRINTLN("Attempting Whynter decode");
|
||||
if (decodeWhynter(results)) return true ;
|
||||
#endif
|
||||
|
||||
#ifdef DECODE_AIWA_RC_T501
|
||||
#if DECODE_AIWA_RC_T501
|
||||
DBG_PRINTLN("Attempting Aiwa RC-T501 decode");
|
||||
if (decodeAiwaRCT501(results)) return true ;
|
||||
#endif
|
||||
|
||||
#ifdef DECODE_DENON
|
||||
#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.
|
||||
@@ -97,11 +101,23 @@ IRrecv::IRrecv (int 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)
|
||||
@@ -123,16 +139,26 @@ void IRrecv::enableIRIn ( )
|
||||
// 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
|
||||
//
|
||||
138
src/irSend.cpp
Normal file
138
src/irSend.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
#include "IRremote.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
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// AAA IIIII W W AAA
|
||||
@@ -9,7 +8,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 +27,6 @@
|
||||
void IRsend::sendAiwaRCT501 (int code)
|
||||
{
|
||||
unsigned long pre = 0x0227EEC0; // 26-bits
|
||||
int mask;
|
||||
|
||||
// Set IR carrier frequency
|
||||
enableIROut(AIWA_RC_T501_HZ);
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
// Reverse Engineered by looking at RAW dumps generated by IRremote
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// DDDD IIIII SSSS H H
|
||||
@@ -48,6 +47,7 @@ void IRsend::sendDISH (unsigned long data, int nbits)
|
||||
space(DISH_ZERO_SPACE);
|
||||
}
|
||||
}
|
||||
mark(DISH_HDR_MARK); //added 26th March 2016, by AnalysIR ( https://www.AnalysIR.com )
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// JJJJJ V V CCCC
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// L GGGG
|
||||
@@ -52,3 +51,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
|
||||
|
||||
45
src/ir_Lego_PF.cpp
Normal file
45
src/ir_Lego_PF.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#include "IRremote.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
src/ir_Lego_PF_BitStreamEncoder.h
Normal file
115
src/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;
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// MMMMM IIIII TTTTT SSSS U U BBBB IIIII SSSS H H IIIII
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// N N EEEEE CCCC
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// PPPP AAA N N AAA SSSS OOO N N IIIII CCCC
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//+=============================================================================
|
||||
// Gets one undecoded level at a time from the raw buffer.
|
||||
@@ -10,6 +9,7 @@
|
||||
// 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;
|
||||
@@ -37,6 +37,7 @@ int IRrecv::getRClevel (decode_results *results, int *offset, int *used, int
|
||||
|
||||
return val;
|
||||
}
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// RRRR CCCC 55555
|
||||
@@ -76,6 +77,73 @@ void IRsend::sendRC5 (unsigned long data, int nbits)
|
||||
|
||||
space(0); // Always end with the LED off
|
||||
}
|
||||
|
||||
void IRsend::sendRC5ext (unsigned long addr, unsigned long cmd, boolean toggle)
|
||||
{
|
||||
// Set IR carrier frequency
|
||||
enableIROut(36);
|
||||
|
||||
unsigned long addressBits = 5;
|
||||
unsigned long commandBits = 7;
|
||||
unsigned long nbits = addressBits + commandBits;
|
||||
|
||||
// Start
|
||||
mark(RC5_T1);
|
||||
|
||||
// Bit #6 of the command part, but inverted!
|
||||
unsigned long cmdBit6 = (1UL << (commandBits-1)) & cmd;
|
||||
if (cmdBit6) {
|
||||
// Inverted (1 -> 0 = mark-to-space)
|
||||
mark(RC5_T1);
|
||||
space(RC5_T1);
|
||||
} else {
|
||||
space(RC5_T1);
|
||||
mark(RC5_T1);
|
||||
}
|
||||
commandBits--;
|
||||
|
||||
// Toggle bit
|
||||
static int toggleBit = 1;
|
||||
if (toggle) {
|
||||
if (toggleBit == 0) {
|
||||
toggleBit = 1;
|
||||
} else {
|
||||
toggleBit = 0;
|
||||
}
|
||||
}
|
||||
if (toggleBit) {
|
||||
space(RC5_T1);
|
||||
mark(RC5_T1);
|
||||
} else {
|
||||
mark(RC5_T1);
|
||||
space(RC5_T1);
|
||||
}
|
||||
|
||||
// Address
|
||||
for (unsigned long mask = 1UL << (addressBits - 1); mask; mask >>= 1) {
|
||||
if (addr & mask) {
|
||||
space(RC5_T1); // 1 is space, then mark
|
||||
mark(RC5_T1);
|
||||
} else {
|
||||
mark(RC5_T1);
|
||||
space(RC5_T1);
|
||||
}
|
||||
}
|
||||
|
||||
// Command
|
||||
for (unsigned long mask = 1UL << (commandBits - 1); mask; mask >>= 1) {
|
||||
if (cmd & 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
|
||||
|
||||
//+=============================================================================
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// SSSS AAA MMM SSSS U U N N GGGG
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// SSSS AAA N N Y Y OOO
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// SSSS H H AAA RRRR PPPP
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// SSSS OOO N N Y Y
|
||||
@@ -92,7 +92,6 @@ Regards,
|
||||
*/
|
||||
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
//
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// W W H H Y Y N N TTTTT EEEEE RRRRR
|
||||
116
src/private/IRremoteInt.h
Normal file
116
src/private/IRremoteInt.h
Normal file
@@ -0,0 +1,116 @@
|
||||
//******************************************************************************
|
||||
// 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 Arduino header
|
||||
//
|
||||
#include <Arduino.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// 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. Must be odd.
|
||||
|
||||
/**
|
||||
* This struct is used to communicate with the ISR (interrupt service routine).
|
||||
*/
|
||||
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
|
||||
//
|
||||
|
||||
/**
|
||||
* When received, marks tend to be too long and
|
||||
* spaces tend to be too short.
|
||||
* To compensate for this, MARK_EXCESS is subtracted from all marks,
|
||||
* and added to all spaces.
|
||||
*/
|
||||
#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
|
||||
@@ -1,9 +1,12 @@
|
||||
//******************************************************************************
|
||||
// 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
|
||||
//
|
||||
|
||||
// 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
|
||||
@@ -14,62 +17,39 @@
|
||||
// Whynter A/C ARC-110WD added by Francesco Meschia
|
||||
//******************************************************************************
|
||||
|
||||
#ifndef IRremoteint_h
|
||||
#define IRremoteint_h
|
||||
#ifndef boarddefs_h
|
||||
#define boarddefs_h
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Include the right Arduino header
|
||||
//
|
||||
#if defined(ARDUINO) && (ARDUINO >= 100)
|
||||
# include <Arduino.h>
|
||||
#else
|
||||
# if !defined(IRPRONTO)
|
||||
# include <WProgram.h>
|
||||
# endif
|
||||
#endif
|
||||
// Define some defaults, that some boards may like to override
|
||||
// (This is to avoid negative logic, ! DONT_... is just awkward.)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// This handles definition and access to global variables
|
||||
//
|
||||
#ifdef IR_GLOBAL
|
||||
# define EXTERN
|
||||
#else
|
||||
# define EXTERN extern
|
||||
#endif
|
||||
// This board has/needs the avr/interrupt.h
|
||||
#define HAS_AVR_INTERRUPT_H
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Information for the Interrupt Service Routine
|
||||
//
|
||||
#define RAWBUF 101 // Maximum length of raw duration buffer
|
||||
// Define if sending is supported
|
||||
#define SENDING_SUPPORTED
|
||||
|
||||
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 blinkflag; // true -> enable blinking of pin 13 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;
|
||||
// If defined, a standard enableIRIn function will be define.
|
||||
// Undefine for boards supplying their own.
|
||||
#define USE_DEFAULT_ENABLE_IR_IN
|
||||
|
||||
// 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
|
||||
// Duty cycle in percent for sent signals. Presently takes effect only with USE_SOFT_CARRIER
|
||||
#define DUTY_CYCLE 50
|
||||
|
||||
// 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;
|
||||
// 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))
|
||||
@@ -85,9 +65,34 @@ EXTERN volatile irparams_t irparams;
|
||||
# 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_ON() (PORTB |= B00100000)
|
||||
# define BLINKLED_OFF() (PORTB &= B11011111)
|
||||
#endif
|
||||
|
||||
@@ -100,48 +105,9 @@ EXTERN volatile irparams_t irparams;
|
||||
# define SYSCLOCK 16000000 // main Arduino clock
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// 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
|
||||
|
||||
// microseconds per clock interrupt tick
|
||||
#define USECPERTICK 50
|
||||
|
||||
// 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
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Define which timer to use
|
||||
//
|
||||
@@ -165,11 +131,11 @@ EXTERN volatile irparams_t irparams;
|
||||
// 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
|
||||
#define IR_USE_TIMER3 // tx = pin 9
|
||||
//#define IR_USE_TIMER4_HS // tx = pin 10
|
||||
|
||||
// Teensy 3.0
|
||||
#elif defined(__MK20DX128__) || defined(__MK20DX256__)
|
||||
// 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
|
||||
@@ -182,17 +148,49 @@ EXTERN volatile irparams_t irparams;
|
||||
#define IR_USE_TIMER2 // tx = pin 1
|
||||
//#define IR_USE_TIMER3 // tx = pin 16
|
||||
|
||||
// Sanguino
|
||||
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||
// 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_ATmega8P__) || defined(__AVR_ATmega8__)
|
||||
#elif defined(__AVR_ATmega8__)
|
||||
#define IR_USE_TIMER1 // tx = pin 9
|
||||
|
||||
// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc
|
||||
// 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
|
||||
|
||||
@@ -242,14 +240,18 @@ EXTERN volatile irparams_t irparams;
|
||||
|
||||
//-----------------
|
||||
#if defined(CORE_OC2B_PIN)
|
||||
# define TIMER_PWM_PIN CORE_OC2B_PIN // Teensy
|
||||
# define SEND_PIN CORE_OC2B_PIN // Teensy
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
# define TIMER_PWM_PIN 9 // Arduino Mega
|
||||
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||
# define TIMER_PWM_PIN 14 // Sanguino
|
||||
# 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 TIMER_PWM_PIN 3 // Arduino Duemilanove, Diecimila, LilyPad, etc
|
||||
#endif
|
||||
# define SEND_PIN 3 // Arduino Duemilanove, Diecimila, LilyPad, etc
|
||||
#endif // ATmega48, ATmega88, ATmega168, ATmega328
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Timer1 (16 bits)
|
||||
@@ -261,7 +263,9 @@ EXTERN volatile irparams_t irparams;
|
||||
#define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1)))
|
||||
|
||||
//-----------------
|
||||
#if defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__)
|
||||
#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
|
||||
@@ -289,14 +293,23 @@ EXTERN volatile irparams_t irparams;
|
||||
|
||||
//-----------------
|
||||
#if defined(CORE_OC1A_PIN)
|
||||
# define TIMER_PWM_PIN CORE_OC1A_PIN // Teensy
|
||||
# define SEND_PIN CORE_OC1A_PIN // Teensy
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
# define TIMER_PWM_PIN 11 // Arduino Mega
|
||||
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||
# define TIMER_PWM_PIN 13 // Sanguino
|
||||
# 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 TIMER_PWM_PIN 9 // Arduino Duemilanove, Diecimila, LilyPad, etc
|
||||
#endif
|
||||
# define SEND_PIN 9 // Arduino Duemilanove, Diecimila, LilyPad, etc
|
||||
#endif // ATmega48, ATmega88, ATmega168, ATmega328
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Timer3 (16 bits)
|
||||
@@ -327,9 +340,11 @@ EXTERN volatile irparams_t irparams;
|
||||
|
||||
//-----------------
|
||||
#if defined(CORE_OC3A_PIN)
|
||||
# define TIMER_PWM_PIN CORE_OC3A_PIN // Teensy
|
||||
# define SEND_PIN CORE_OC3A_PIN // Teensy
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
# define TIMER_PWM_PIN 5 // Arduino Mega
|
||||
# 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
|
||||
@@ -373,9 +388,9 @@ EXTERN volatile irparams_t irparams;
|
||||
|
||||
//-----------------
|
||||
#if defined(CORE_OC4A_PIN)
|
||||
# define TIMER_PWM_PIN CORE_OC4A_PIN // Teensy
|
||||
# define SEND_PIN CORE_OC4A_PIN // Teensy
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
# define TIMER_PWM_PIN 13 // Leonardo
|
||||
# define SEND_PIN 13 // Leonardo
|
||||
#else
|
||||
# error "Please add OC4A pin number here\n"
|
||||
#endif
|
||||
@@ -409,9 +424,9 @@ EXTERN volatile irparams_t irparams;
|
||||
|
||||
//-----------------
|
||||
#if defined(CORE_OC4A_PIN)
|
||||
# define TIMER_PWM_PIN CORE_OC4A_PIN
|
||||
# define SEND_PIN CORE_OC4A_PIN
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
# define TIMER_PWM_PIN 6 // Arduino Mega
|
||||
# define SEND_PIN 6 // Arduino Mega
|
||||
#else
|
||||
# error "Please add OC4A pin number here\n"
|
||||
#endif
|
||||
@@ -445,9 +460,9 @@ EXTERN volatile irparams_t irparams;
|
||||
|
||||
//-----------------
|
||||
#if defined(CORE_OC5A_PIN)
|
||||
# define TIMER_PWM_PIN CORE_OC5A_PIN
|
||||
# define SEND_PIN CORE_OC5A_PIN
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
# define TIMER_PWM_PIN 46 // Arduino Mega
|
||||
# define SEND_PIN 46 // Arduino Mega
|
||||
#else
|
||||
# error "Please add OC5A pin number here\n"
|
||||
#endif
|
||||
@@ -458,7 +473,7 @@ EXTERN volatile irparams_t irparams;
|
||||
#elif defined(IR_USE_TIMER_CMT)
|
||||
|
||||
#define TIMER_RESET ({ \
|
||||
uint8_t tmp = CMT_MSC; \
|
||||
uint8_t tmp __attribute__((unused)) = CMT_MSC; \
|
||||
CMT_CMD2 = 30; \
|
||||
})
|
||||
|
||||
@@ -481,19 +496,18 @@ EXTERN volatile irparams_t irparams;
|
||||
#define ISR(f) void f(void)
|
||||
|
||||
//-----------------
|
||||
#if (F_BUS == 48000000)
|
||||
# define CMT_PPS_VAL 5
|
||||
#else
|
||||
# define CMT_PPS_VAL 2
|
||||
#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_VAL; \
|
||||
CMT_CGH1 = 2667 / val; \
|
||||
CMT_CGL1 = 5333 / val; \
|
||||
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; \
|
||||
@@ -504,18 +518,18 @@ EXTERN volatile irparams_t irparams;
|
||||
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
SIM_SCGC4 |= SIM_SCGC4_CMT; \
|
||||
CMT_PPS = CMT_PPS_VAL; \
|
||||
CMT_PPS = CMT_PPS_DIV - 1; \
|
||||
CMT_CGH1 = 1; \
|
||||
CMT_CGL1 = 1; \
|
||||
CMT_CMD1 = 0; \
|
||||
CMT_CMD2 = 30 \
|
||||
CMT_CMD2 = 30; \
|
||||
CMT_CMD3 = 0; \
|
||||
CMT_CMD4 = 19; \
|
||||
CMT_CMD4 = (F_BUS / 160000 + CMT_PPS_DIV / 2) / CMT_PPS_DIV - 31; \
|
||||
CMT_OC = 0; \
|
||||
CMT_MSC = 0x03; \
|
||||
})
|
||||
|
||||
#define TIMER_PWM_PIN 5
|
||||
#define SEND_PIN 5
|
||||
|
||||
// defines for TPM1 timer on Teensy-LC
|
||||
#elif defined(IR_USE_TIMER_TPM1)
|
||||
@@ -545,9 +559,80 @@ EXTERN volatile irparams_t irparams;
|
||||
FTM1_C0V = 0; \
|
||||
FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0) | FTM_SC_TOF | FTM_SC_TOIE; \
|
||||
})
|
||||
#define TIMER_PWM_PIN 16
|
||||
#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
|
||||
@@ -555,4 +640,14 @@ EXTERN volatile irparams_t irparams;
|
||||
#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
|
||||
101
src/sam.cpp
Normal file
101
src/sam.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
// Support routines for SAM processor boards
|
||||
|
||||
#include "IRremote.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)
|
||||
Reference in New Issue
Block a user