Merge branch 'release-7.1'

This commit is contained in:
Theo Arends 2019-11-29 16:17:07 +01:00
commit c9b02896ce
537 changed files with 31873 additions and 27474 deletions

View File

@ -1,34 +1,35 @@
---
name: Bug report
name: Problem report
about: Create a report to help us improve
---
> **GUIDE**
>
> This BUG issue template is meant to REPORT Tasmota software BUGS ONLY>
>
> Please DO NOT OPEN AN ISSUE:
> - If your Tasmota version is not the latest from the development branch, please update your device before submitting your issue. Your problem might already be solved. The latest precompiled binaries of Tasmota can be downloaded from http://thehackbox.org/tasmota/
> - If you have a issue when flashing was done via Tuya Convert
> - If your issue is a flashing issue, please address it to the [Tasmota Support Chat](https://discord.gg/Ks2Kzd4)
> - If your issue is compilation problem, please address it to the [Tasmota Support Chat](https://discord.gg/Ks2Kzd4)
> - If your issue has been addressed before (i.e., duplicated issue), please ask in the original issue
> - If your issue is a Wi-Fi problem or MQTT problem, please try the steps provided in the [FAQ](https://github.com/arendst/Sonoff-Tasmota/wiki/FAQ) and troubleshooting wiki articles
>
> Please take a few minutes to complete the requested information below. Our ability to provide assistance is greatly hampered without it. The details requested potentially affect which options to pursue. The small amount of time you spend completing the template will also help the volunteers providing the assistance to you to reduce the time required to help you.
<!-- Thanks for reporting a problem for this project. READ THIS FIRST:
### BUG DESCRIPTION
_A clear and concise description of what the bug is._
This issue template is meant to REPORT Tasmota software PROBLEMS ONLY
Please DO NOT OPEN AN ISSUE:
- If your Tasmota version is not the latest from the development branch, please update your device before submitting your issue. Your problem might already be solved. The latest precompiled binaries of Tasmota can be downloaded from http://thehackbox.org/tasmota/
- If you have an issue when flashing was done via Tuya Convert, please address it to Tuya Convert Team
- If your issue is a flashing issue, please address it to the [Tasmota Support Chat](https://discord.gg/Ks2Kzd4)
- If your issue is compilation problem, please address it to the [Tasmota Support Chat](https://discord.gg/Ks2Kzd4)
- If your issue has been addressed before (i.e., duplicated issue), please ask in the original issue
- If your issue is a Wi-Fi problem or MQTT problem, please try the steps provided in the [FAQ](https://tasmota.github.io/docs/#/help/FAQ) and [Troubleshooting](https://tasmota.github.io/docs/#/help/Troubleshooting)
Please take a few minutes to complete the requested information below. Our ability to provide assistance is greatly hampered without it. The details requested potentially affect which options to pursue. The small amount of time you spend completing the template will also help the volunteers providing the assistance to you to reduce the time required to help you.
DO NOT DELETE ANY TEXT from this template! Otherwise the issue will be auto-closed.
-->
### PROBLEM DESCRIPTION
_A clear and concise description of what the problem is._
### REQUESTED INFORMATION
_Make sure your have performed every step and checked the applicable boxes before submitting your issue. Thank you!_
**FAILURE TO COMPLETE THE REQUESTED INFORMATION WILL RESULT IN YOUR ISSUE BEING CLOSED**
- [ ] Read the [Contributing Guide and Policy](https://github.com/arendst/Sonoff-Tasmota/blob/development/CONTRIBUTING.md) and [the Code of Conduct](https://github.com/arendst/Sonoff-Tasmota/blob/development/CODE_OF_CONDUCT.md)
- [ ] Searched the problem in [issues](https://github.com/arendst/Sonoff-Tasmota/issues)
- [ ] Searched the problem in the [wiki](https://github.com/arendst/Sonoff-Tasmota/wiki/Troubleshooting)
- [ ] Read the [Contributing Guide and Policy](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md) and [the Code of Conduct](https://github.com/arendst/Tasmota/blob/development/CODE_OF_CONDUCT.md)
- [ ] Searched the problem in [issues](https://github.com/arendst/Tasmota/issues)
- [ ] Searched the problem in the [wiki](https://github.com/arendst/Tasmota/wiki/Troubleshooting)
- [ ] Searched the problem in the [forum](https://groups.google.com/d/forum/sonoffusers)
- [ ] Searched the problem in the [chat](https://discord.gg/Ks2Kzd4)
- [ ] Device used (e.g., Sonoff Basic): _____
@ -40,27 +41,27 @@ _Make sure your have performed every step and checked the applicable boxes befor
- [ ] Provide the output of command: ``Backlog Template; Module; GPIO``:
```
Configuration output here:
```
- [ ] If using rules, provide the output of this command: ``Backlog Rule1; Rule2; Rule3``:
```
Rules output here:
```
- [ ] Provide the output of this command: ``Status 0``:
```
STATUS 0 output here:
```
- [ ] Provide the output of the Console log output when you experience your issue; if applicable:
_(Please use_ ``weblog 4`` _for more debug information)_
```
Console output here:
```
### TO REPRODUCE

View File

@ -1,67 +0,0 @@
---
name: Troubleshooting
about: Users Troubleshooting Help
---
> **GUIDE**
>
> This troubleshooting issue template is meant to help Tasmota users with difficult problems. It is aimed to be opened if using the wiki and the support chat could not solve the issue. The Github Issue tracker is NOT a general discussion forum!
>
> Please DO NOT OPEN AN ISSUE:
> - If you have general questions or you need help on Tasmota usage, go to the [Tasmota Support Chat](https://discord.gg/Ks2Kzd4)
> - If your Tasmota version is not the latest from the development branch, please update your device before submitting your issue. Your problem might already be solved. The latest precompiled binaries of Tasmota can be downloaded from http://thehackbox.org/tasmota/
> - If your issue is about a new device, please use the Tasmota [Template](../wiki/Templates) feature.
> - If your issue is a flashing issue, please address it to the [Tasmota Support Chat](https://discord.gg/Ks2Kzd4)
> - If your issue is compilation problem, please address it to the [Tasmota Support Chat](https://discord.gg/Ks2Kzd4)
> - If your issue has been addressed before (i.e., duplicated issue), please ask in the original issue
> - If your issue is a Wi-Fi problem or MQTT problem, please try the steps provided in the [FAQ](https://github.com/arendst/Sonoff-Tasmota/wiki/FAQ) and troubleshooting wiki articles
>
> Please take a few minutes to complete the requested information below. Our ability to provide assistance is greatly hampered without it. The details requested potentially affect which options to pursue. The small amount of time you spend completing the template will also help the volunteers providing the assistance to you to reduce the time required to help you.
### ISSUE DESCRIPTION - TROUBLESHOOTING
_A clear description of what the issue is and be as extensive as possible_
### REQUESTED INFORMATION
_Make sure these boxes are checked before submitting your issue. Thank you_
**FAILURE TO COMPLETE THE REQUESTED INFORMATION WILL RESULT IN YOUR ISSUE BEING CLOSED**
- [ ] Read the [Contributing Guide and Policy](https://github.com/arendst/Sonoff-Tasmota/blob/development/CONTRIBUTING.md) and [the Code of Conduct](https://github.com/arendst/Sonoff-Tasmota/blob/development/CODE_OF_CONDUCT.md)
- [ ] Searched the problem in issues (https://github.com/arendst/Sonoff-Tasmota/issues)
- [ ] Searched the problem in the wiki (https://github.com/arendst/Sonoff-Tasmota/wiki/Troubleshooting)
- [ ] Searched the problem in the forum (https://groups.google.com/d/forum/sonoffusers)
- [ ] Searched the problem in the chat (https://discord.gg/Ks2Kzd4)
- [ ] Device used (e.g., Sonoff Basic): _____
- [ ] Tasmota binary firmware version number used: _____
- [ ] Pre-compiled
- [ ] Self-compiled
- [ ] IDE / Compiler used: _____
- [ ] Flashing tools used: _____
- [ ] Provide the output of this command: ``Backlog Template; Module; GPIO``:
```
Configuration output here:
```
- [ ] If using rules, provide the output of this command: ``Backlog Rule1; Rule2; Rule3``:
```
Rules output here:
```
- [ ] Provide the output of this command: ``Status 0``:
```
STATUS 0 output here:
```
- [ ] Provide the output of the Console log output when you experience your issue; if applicable:
_(Please use_ ``weblog 4`` _for more debug information)_
```
Console output here:
```
**(Please, remember to close the issue when the problem has been addressed)**

View File

@ -3,7 +3,12 @@ name: Feature request
about: Suggest an idea for this project
---
> Please take a few minutes to complete the requested information below. Our ability to provide assistance is greatly hampered without it. The details requested potentially affect which options to pursue. The small amount of time you spend completing the template will also help the volunteers providing the assistance to you to reduce the time required to help you.
<!-- Thanks for suggesting an idea for this project. READ THIS FIRST:
Please take a few minutes to complete the requested information below. Our ability to provide assistance is greatly hampered without it. The details requested potentially affect which options to pursue. The small amount of time you spend completing the template will also help the volunteers providing the assistance to you to reduce the time required to help you.
DO NOT DELETE ANY TEXT from this template! Otherwise the issue will be auto-closed.
-->
**Have you looked for this feature in other issues and in the wiki?**

8
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Tasmota Docs
url: https://tasmota.github.io/docs/#/
about: All the information related to Tasmota
- name: Tasmota Support Chat
url: https://discord.gg/Ks2Kzd4
about: Chat for feedback, questions and troubleshooting.

View File

@ -1,11 +1,11 @@
## Description:
**Related issue (if applicable):** fixes #<Sonoff-Tasmota issue number goes here>
**Related issue (if applicable):** fixes #<Tasmota issue number goes here>
## Checklist:
- [ ] The pull request is done against the latest dev branch
- [ ] Only relevant files were touched
- [ ] Only one feature/fix was added per PR.
- [ ] The code change is tested and works on core pre-2.6
- [ ] The code change is tested and works on core 2.6.1
- [ ] The code change pass travis tests. **Your PR cannot be merged unless tests pass**
- [ ] I accept the [CLA](https://github.com/arendst/Sonoff-Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla).
- [ ] I accept the [CLA](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla).

11
.github/config.yml vendored Normal file
View File

@ -0,0 +1,11 @@
# Configuration for sentiment-bot - https://github.com/behaviorbot/sentiment-bot
# *Required* toxicity threshold between 0 and .99 with the higher numbers being the most toxic
# Anything higher than this threshold will be marked as toxic and commented on
sentimentBotToxicityThreshold: .7
# *Required* Comment to reply with
sentimentBotReplyComment: >
Please be sure to review the code of conduct and be respectful of other users.
# Note: the bot will only work if your repository has a Code of Conduct

54
.github/issue-close-app.yml vendored Normal file
View File

@ -0,0 +1,54 @@
# CLOSE ISSUE BOT
# ---------------
# A bot which helps you to close issues that don't include some specific contents.
# See how to use it in https://github.com/offu/close-issue-app.
# Comment that will be sent if an issue is judged to be closed.
comment: >-
This issue has been automatically closed because the issue template is missing or incomplete.
Filling the template is required so standard questions don't need to be asked again each time.
Our ability to provide assistance is greatly hampered if few minutes are not taken to complete the issue template
with the requested information. The details requested potentially affect which options to pursue. The small amount
of time you spend completing the template will also help the volunteers providing the assistance to you, to reduce
the time required to help you.
Please, could you be so kind on completing the [issue template](https://github.com/arendst/Tasmota/issues/new/choose) in order to have more information so as to properly help you?
Thank you for taking the time to report, hopefully it can be resolved soon.
[Support Information](https://github.com/arendst/Sonoff-Tasmota/blob/development/SUPPORT.md)
[Wiki](https://tasmota.github.io/docs/#/) for more information.
[Chat](https://discord.gg/Ks2Kzd4) for more user experience.
[Community](https://groups.google.com/d/forum/sonoffusers) for forum.
[Code of Conduct](https://github.com/arendst/Sonoff-Tasmota/blob/development/CODE_OF_CONDUCT.md)
[Contributing Guideline and Policy](https://github.com/arendst/Sonoff-Tasmota/blob/development/CONTRIBUTING.md)
issueConfigs:
# There can be several configs for different kind of issues.
- content:
# template 1: bug report
- "PROBLEM DESCRIPTION"
- "REQUESTED INFORMATION"
- "TO REPRODUCE"
- "EXPECTED BEHAVIOUR"
- content:
# template 2: feature request
- "Have you looked for this feature in other issues and in the wiki"
- "Describe the solution you'd like"
# Optional configuration:
#
# whether the keywords are case-insensitive
# default value is false, which means keywords are case-sensitive
caseInsensitive: true
# the label that will be added when the bot close an issue
# The bot will only add a label if this property is set.
label: "template missing/incomplete"
# The issue is judged to be legal if it includes all keywords from any of these two configs.
# Or it will be closed by the app.

5
.gitignore vendored
View File

@ -8,10 +8,13 @@
.clang_complete
.gcc-flags.json
.cache
sonoff/user_config_override.h
tasmota/user_config_override.h
build
firmware.map
firmware.asm
tasmota*.bin
tasmota*.map
platformio_override.ini
## Visual Studio Code specific ######
.vscode

View File

@ -1,3 +1,3 @@
tasks:
- before: pip install -U platformio
command: platformio run -e sonoff
command: platformio run -e tasmota

View File

@ -7,40 +7,37 @@ install:
- platformio upgrade
- platformio update
cache:
directories:
- .cache
- $HOME/.platformio
cache: false
env:
- ENV=sonoff
- ENV=sonoff-minimal
- ENV=sonoff-basic
- ENV=sonoff-knx
- ENV=sonoff-sensors
- ENV=sonoff-display
- ENV=sonoff-ir
- ENV=sonoff-BG
- ENV=sonoff-BR
- ENV=sonoff-CN
- ENV=sonoff-CZ
- ENV=sonoff-DE
- ENV=sonoff-ES
- ENV=sonoff-FR
- ENV=sonoff-GR
- ENV=sonoff-HE
- ENV=sonoff-HU
- ENV=sonoff-IT
- ENV=sonoff-KO
- ENV=sonoff-NL
- ENV=sonoff-PL
- ENV=sonoff-PT
- ENV=sonoff-RU
- ENV=sonoff-SE
- ENV=sonoff-SK
- ENV=sonoff-TR
- ENV=sonoff-TW
- ENV=sonoff-UK
- ENV=tasmota
- ENV=tasmota-minimal
- ENV=tasmota-basic
- ENV=tasmota-knx
- ENV=tasmota-sensors
- ENV=tasmota-display
- ENV=tasmota-ir
- ENV=tasmota-BG
- ENV=tasmota-BR
- ENV=tasmota-CN
- ENV=tasmota-CZ
- ENV=tasmota-DE
- ENV=tasmota-ES
- ENV=tasmota-FR
- ENV=tasmota-GR
- ENV=tasmota-HE
- ENV=tasmota-HU
- ENV=tasmota-IT
- ENV=tasmota-KO
- ENV=tasmota-NL
- ENV=tasmota-PL
- ENV=tasmota-PT
- ENV=tasmota-RU
- ENV=tasmota-SE
- ENV=tasmota-SK
- ENV=tasmota-TR
- ENV=tasmota-TW
- ENV=tasmota-UK
script:
- platformio run -e $ENV

196
API.md
View File

@ -2,69 +2,149 @@
# Basic API information
Sonoff-Tasmota can easily be extended by developers using provided function pointers as callback Ids. This document lists the available callback function Ids. See the wiki (https://github.com/arendst/Sonoff-Tasmota/wiki/Sensor-API) for more information.
Tasmota can easily be extended by developers using provided function pointers as callback Ids. This document lists the available callback function Ids. Read [Sensor API](https://tasmota.github.io/docs/#/Sensor-API) for more information.
Callback availability can be checked by searching for either XdrvCall, XsnsCall, XdspCall and XnrgCall.
Callback availability can be checked by searching for either XdrvCall, XsnsCall, XdspCall, XnrgCall and XlgtCall.
## Driver, Sensor, Energy and Light Callback Ids
## Driver, Sensor and Energy Callback Ids
The following table lists Callback Ids and their availability for a Driver, Sensor or Energy service.
Callback Id | Bool | Version | xdrv | xsns | xnrg | Description
----------------------------|------|----------|------|------|------|----------------------------------
FUNC_SETTINGS_OVERRIDE | | 6.2.1.19 | x | | | Override start-up settings
FUNC_MODULE_INIT | x | 6.2.1.17 | x | | | Init module specific parameters
FUNC_PRE_INIT | | | x | | x | Once GPIO have been established
FUNC_INIT | | | x | x | x | At end of initialisation
FUNC_LOOP | | | x | | | In main loop
FUNC_EVERY_50_MSECOND | | | x | x | |
FUNC_EVERY_100_MSECOND | | | x | x | |
FUNC_EVERY_200_MSECOND | | | | x | x |
FUNC_EVERY_250_MSECOND | | | x | | |
FUNC_EVERY_SECOND | | | x | x | x |
FUNC_PREP_BEFORE_TELEPERIOD | | | | x | | Deprecated. Use a FUNC_EVERY_
FUNC_JSON_APPEND | | | | x | | Extend teleperiod JSON text
FUNC_WEB_APPEND | | | | x | | Extend webgui ajax info
FUNC_SAVE_BEFORE_RESTART | | | | x | | Just before a planned restart
FUNC_COMMAND | x | | x | x | | When a command is not recognized
FUNC_COMMAND_DRIVER | x | 6.4.1.21 | x | | | When command Driver\<id\> is executed
FUNC_COMMAND_SENSOR | x | 6.4.1.21 | | x | | When command Sensor\<id\> is executed
FUNC_MQTT_SUBSCRIBE | | 5.12.0k | x | | | At end of MQTT subscriptions
FUNC_MQTT_INIT | | 5.12.0k | x | | | Once at end of MQTT connection
FUNC_MQTT_DATA | x | 5.12.0k | x | | | Before decoding command
FUNC_SET_POWER | | | x | | | Before setting relays
FUNC_SET_DEVICE_POWER | x | 6.2.1.18 | x | | | Set relay
FUNC_SHOW_SENSOR | | | x | | | When FUNC_JSON_APPEND completes
FUNC_RULES_PROCESS | x | 6.0.0 | x | | | Process specific rule
FUNC_SERIAL | x | | x | | x | Process serial data
FUNC_FREE_MEM | | | x | | | Show free memory for debugging
FUNC_BUTTON_PRESSED | x | 6.2.1.18 | x | | | When a button is pressed
FUNC_WEB_ADD_BUTTON | | 6.2.1.14 | x | x | | Add a Configuration Button to GUI
FUNC_WEB_ADD_MAIN_BUTTON | | 6.2.1.14 | x | x | | Add a main button to GUI
FUNC_WEB_ADD_HANDLER | | 6.2.1.14 | x | x | | Add a webserver handler
Callback Id | Bool | xdrv | xsns | xnrg | xlgt | Description
----------------------------|------|------|------|------|------|----------------------------------
FUNC_SETTINGS_OVERRIDE | | x | | | | Override start-up settings
FUNC_PIN_STATE | x | 1 | 2 | | | At GPIO configuration
FUNC_MODULE_INIT | x | 1 | | | 2 | Init module specific parameters
FUNC_PRE_INIT | | 1 | | 2 | | Once GPIO have been established
FUNC_INIT | | 1 | 3 | 2 | | At end of initialisation
FUNC_LOOP | | 1 | 2 | | | In main loop
FUNC_EVERY_50_MSECOND | | 1 | 2 | | |
FUNC_EVERY_100_MSECOND | | 1 | 2 | | |
FUNC_EVERY_200_MSECOND | | | | x | |
FUNC_EVERY_250_MSECOND | | 1 | 3 | 2 | |
FUNC_EVERY_SECOND | | 1 | 2 | | |
FUNC_SAVE_AT_MIDNIGHT | | | x | | | At midnight
FUNC_SAVE_BEFORE_RESTART | | 2 | 1 | | | Just before a planned restart
FUNC_AFTER_TELEPERIOD | | x | | | | At end of teleperiod
FUNC_JSON_APPEND | | 2 | 1 | 3 | | Extend teleperiod JSON text
FUNC_WEB_SENSOR | | 2 | 1 | 3 | | Add sensor data to web GUI
FUNC_COMMAND | x | 1 | 2 | 3 | 4 | When a command is not recognized
FUNC_COMMAND_DRIVER | x | x | | | | When command Driver\<id\> is executed
FUNC_COMMAND_SENSOR | x | | x | | | When command Sensor\<id\> is executed
FUNC_MQTT_SUBSCRIBE | | x | | | | At end of MQTT subscriptions
FUNC_MQTT_INIT | | x | | | | Once at end of MQTT connection
FUNC_MQTT_DATA | x | x | | | | Before decoding command
FUNC_SET_POWER | | x | | | | Before setting relays
FUNC_SET_DEVICE_POWER | x | x | | | | Set relay
FUNC_SHOW_SENSOR | | x | | | | When FUNC_JSON_APPEND completes
FUNC_ANY_KEY | | x | | | |
FUNC_ENERGY_EVERY_SECOND | | | | x | |
FUNC_ENERGY_RESET | | | | x | |
FUNC_RULES_PROCESS | x | x | | | | Process specific rule
FUNC_SERIAL | x | 1 | | 2 | 3 | Process serial data
FUNC_FREE_MEM | | x | | | | Show free memory for debugging
FUNC_BUTTON_PRESSED | x | x | | | | When a button is pressed
FUNC_WEB_ADD_BUTTON | | 1 | 2 | | | Add a Configuration Button to GUI
FUNC_WEB_ADD_MAIN_BUTTON | | 1 | 2 | | | Add a main button to GUI
FUNC_WEB_ADD_HANDLER | | 1 | 2 | | | Add a webserver handler
FUNC_SET_CHANNELS | | 2 | | | 1 |
FUNC_SET_SCHEME | | | | | x |
The numbers represent the sequence of execution
## Display Call back Ids
The following table lists all Callback Ids for a Display service.
Callback Id | Bool | Version | Description
------------------------------|------|----------|---------------------
FUNC_DISPLAY_INIT_DRIVER | | 6.1.1.7 |
FUNC_DISPLAY_INIT | | 6.1.1.7 |
FUNC_DISPLAY_EVERY_50_MSECOND | | 6.1.1.7 |
FUNC_DISPLAY_EVERY_SECOND | | 6.1.1.7 |
FUNC_DISPLAY_MODEL | x | 6.1.1.7 |
FUNC_DISPLAY_MODE | | 6.1.1.7 |
FUNC_DISPLAY_POWER | | 6.1.1.7 |
FUNC_DISPLAY_CLEAR | | 6.1.1.7 |
FUNC_DISPLAY_DRAW_FRAME | | 6.1.1.7 |
FUNC_DISPLAY_DRAW_HLINE | | 6.1.1.7 |
FUNC_DISPLAY_DRAW_VLINE | | 6.1.1.7 |
FUNC_DISPLAY_DRAW_LINE | | 6.1.1.7 |
FUNC_DISPLAY_DRAW_CIRCLE | | 6.1.1.7 |
FUNC_DISPLAY_FILL_CIRCLE | | 6.1.1.7 |
FUNC_DISPLAY_DRAW_RECTANGLE | | 6.1.1.7 |
FUNC_DISPLAY_FILL_RECTANGLE | | 6.1.1.7 |
FUNC_DISPLAY_TEXT_SIZE | | 6.1.1.7 |
FUNC_DISPLAY_FONT_SIZE | | 6.1.1.7 |
FUNC_DISPLAY_ROTATION | | 6.1.1.7 |
FUNC_DISPLAY_DRAW_STRING | | 6.1.1.7 |
FUNC_DISPLAY_ONOFF | | 6.1.1.7 |
Callback Id | Bool | Description
------------------------------|------|---------------------
FUNC_DISPLAY_INIT_DRIVER | |
FUNC_DISPLAY_INIT | |
FUNC_DISPLAY_EVERY_50_MSECOND | |
FUNC_DISPLAY_EVERY_SECOND | |
FUNC_DISPLAY_MODEL | x |
FUNC_DISPLAY_MODE | |
FUNC_DISPLAY_POWER | |
FUNC_DISPLAY_CLEAR | |
FUNC_DISPLAY_DRAW_FRAME | |
FUNC_DISPLAY_DRAW_HLINE | |
FUNC_DISPLAY_DRAW_VLINE | |
FUNC_DISPLAY_DRAW_LINE | |
FUNC_DISPLAY_DRAW_CIRCLE | |
FUNC_DISPLAY_FILL_CIRCLE | |
FUNC_DISPLAY_DRAW_RECTANGLE | |
FUNC_DISPLAY_FILL_RECTANGLE | |
FUNC_DISPLAY_TEXT_SIZE | |
FUNC_DISPLAY_FONT_SIZE | |
FUNC_DISPLAY_ROTATION | |
FUNC_DISPLAY_DRAW_STRING | |
FUNC_DISPLAY_ONOFF | |
## Init sequence
The following list shows a typical callback init sequence
```
CFG: Loaded from flash at FB, Count 1581
xdrv - FUNC_SETTINGS_OVERRIDE
xdrv - FUNC_PIN_STATE
xsns - FUNC_PIN_STATE
xdrv - FUNC_MODULE_INIT
xlgt - FUNC_MODULE_INIT
xdrv - FUNC_PRE_INIT
xnrg - FUNC_PRE_INIT
SRC: Restart
xdrv - FUNC_SET_POWER
xlgt - FUNC_SET_CHANNELS
xdrv - FUNC_SET_DEVICE_POWER
Project tasmota Wemos 2 Version 7.0.0.3(tasmota)-STAGE
xdrv - FUNC_INIT
xsns - FUNC_INIT
I2C: ADS1115 found at 0x48
xdrv - FUNC_LOOP
xsns - FUNC_LOOP
xdrv - FUNC_EVERY_50_MSECOND
xlgt - FUNC_SET_CHANNELS
xsns - FUNC_EVERY_50_MSECOND
xdrv - FUNC_EVERY_100_MSECOND
xsns - FUNC_EVERY_100_MSECOND
xdrv - FUNC_EVERY_250_MSECOND
xsns - FUNC_EVERY_250_MSECOND
xdrv - FUNC_EVERY_SECOND
xsns - FUNC_EVERY_SECOND
WIF: Attempting connection...
WIF: Network (re)scan started...
WIF: Attempting connection...
WIF: Attempting connection...
WIF: Attempting connection...
WIF: Network 0, AP1, SSId indebuurt1, Channel 1, BSSId 24:D3:F2:97:C0:A1, RSSI -86, Encryption 1
WIF: Network 1, AP2, SSId indebuurt2, Channel 5, BSSId A0:AB:1B:7D:42:AC, RSSI -42, Encryption 1
WIF: Network 2, AP-, SSId indebuurt3, Channel 12, BSSId 60:E3:27:58:77:E6, RSSI -84, Encryption 1
WIF: Connecting to AP2 indebuurt2 in mode 11N as wemos2...
WIF: Attempting connection...
WIF: Attempting connection...
WIF: Attempting connection...
WIF: Connected
xdrv - FUNC_WEB_ADD_HANDLER
xsns - FUNC_WEB_ADD_HANDLER
HTP: Web server active on wemos2 with IP address 192.168.2.191
NTP: Drift 0, (UTC) Wed Nov 06 13:57:08 2019, (DST) Sun Mar 31 02:00:00 2019, (STD) Sun Oct 27 03:00:00 2019
APP: Boot Count 500
MQT: Attempting connection...
MQT: Connected
MQT: tele/wemos2/LWT = Online (retained)
MQT: cmnd/wemos2/POWER =
MQT: Subscribe to cmnd/wemos2/#
MQT: Subscribe to cmnd/sonoffs/#
MQT: Subscribe to cmnd/DVES_15568C_fb/#
xdrv - FUNC_MQTT_SUBSCRIBE
MQT: tele/wemos2/INFO1 = {"Module":"Generic","Version":"7.0.0.3(tasmota)","FallbackTopic":"cmnd/DVES_15568C_fb/","GroupTopic":"cmnd/sonoffs/"}
MQT: tele/wemos2/INFO2 = {"WebServerMode":"Admin","Hostname":"wemos2","IPAddress":"192.168.2.191"}
MQT: tele/wemos2/INFO3 = {"RestartReason":"Software/System restart"}
MQT: stat/wemos2/RESULT = {"POWER1":"OFF"}
MQT: stat/wemos2/POWER1 = OFF
MQT: stat/wemos2/RESULT = {"POWER2":"ON"}
MQT: stat/wemos2/POWER2 = ON
xdrv - FUNC_MQTT_INIT
CFG: Saved to flash at FA, Count 1582, Bytes 4096
```

147
BUILDS.md Normal file
View File

@ -0,0 +1,147 @@
## Available Features and Sensors
| Feature or Sensor | minimal | basic | tasmota | knx | sensors | ir | display | Remarks
|-----------------------|---------|-------|--------|-----|---------|----|---------|--------
| MY_LANGUAGE en-GB | x | x | x | x | x | x | x |
| USE_ARDUINO_OTA | - | - | - | - | - | - | - |
| USE_DOMOTICZ | - | - | x | x | x | x | - |
| USE_HOME_ASSISTANT | - | - | x | x | x | x | - |
| USE_MQTT_TLS | - | - | - | - | - | - | - |
| USE_MQTT_TLS_CA_CERT | - | - | - | - | - | - | - |
| USE_MQTT_AWS_IOT | - | - | - | - | - | - | - |
| USE_4K_RSA | - | - | - | - | - | - | - |
| USE_KNX | - | - | - | x | - | - | - |
| USE_WEBSERVER | x | x | x | x | x | x | x |
| USE_JAVASCRIPT_ES6 | - | - | - | - | - | - | - |
| USE_WEBSEND_RESPONSE | - | - | - | - | - | - | - |
| USE_EMULATION_HUE | - | x | x | - | x | - | - |
| USE_EMULATION_WEMO | - | x | x | - | x | - | - |
| USE_DISCOVERY | - | - | x | x | - | - | x |
| WEBSERVER_ADVERTISE | - | - | x | x | - | - | x |
| MQTT_HOST_DISCOVERY | - | - | x | x | - | - | x |
| USE_TIMERS | - | x | x | x | x | x | x |
| USE_TIMERS_WEB | - | x | x | x | x | x | x |
| USE_SUNRISE | - | x | x | x | x | x | x |
| USE_RULES | - | x | x | x | x | x | x |
| USE_SCRIPT | - | - | - | - | - | - | - |
| USE_EXPRESSION | - | - | - | - | - | - | - |
| SUPPORT_IF_STATEMENT | - | - | - | - | - | - | - |
| | | | | | | | |
| Feature or Sensor | minimal | basic | tasmota | knx | sensors | ir | display | Remarks
| ROTARY_V1 | - | - | - | - | - | - | - |
| USE_SONOFF_RF | - | - | x | x | x | - | - |
| USE_RF_FLASH | - | - | x | x | x | - | - |
| USE_SONOFF_SC | - | - | x | - | x | - | - |
| USE_TUYA_MCU | - | x | x | x | x | - | x |
| USE_ARMTRONIX_DIMMERS | - | - | x | x | - | - | - |
| USE_PS_16_DZ | - | - | x | x | x | - | - |
| USE_SONOFF_IFAN | - | - | x | x | x | - | - |
| USE_BUZZER | - | - | x | x | x | - | - |
| USE_ARILUX_RF | - | - | x | x | x | - | - |
| USE_SHUTTER | - | - | - | - | - | - | - |
| USE_DEEPSLEEP | - | - | x | - | x | - | - |
| USE_EXS_DIMMER | - | - | x | x | - | - | - |
| | | | | | | | |
| Feature or Sensor | minimal | basic | tasmota | knx | sensors | ir | display | Remarks
| USE_LIGHT | - | x | x | x | x | x | x |
| USE_WS2812 | - | - | x | x | x | - | x |
| USE_WS2812_DMA | - | - | - | - | - | - | - |
| USE_MY92X1 | - | - | x | x | x | - | x |
| USE_SM16716 | - | - | x | x | x | - | x |
| USE_SM2135 | - | - | x | x | x | - | x |
| USE_SONOFF_L1 | - | - | x | x | x | - | x |
| | | | | | | | |
| USE_ENERGY_SENSOR | - | x | x | x | x | - | - |
| USE_PZEM004T | - | - | x | x | x | - | - |
| USE_PZEM_AC | - | - | x | x | x | - | - |
| USE_PZEM_DC | - | - | x | x | x | - | - |
| USE_MCP39F501 | - | x | x | x | x | - | - |
| USE_SDM120 | - | - | - | - | x | - | - |
| USE_SDM630 | - | - | - | - | x | - | - |
| USE_DDS2382 | - | - | - | - | x | - | - |
| USE_DDSU666 | - | - | - | - | x | - | - |
| USE_SOLAX_X1 | - | - | - | - | - | - | - |
| | | | | | | | |
| USE_ADC_VCC | x | x | - | - | - | - | - |
| USE_COUNTER | - | - | x | x | x | x | x |
| USE_DS18x20 | - | - | x | x | x | - | x |
| USE_DHT | - | - | x | x | x | x | x |
| USE_MAX31855 | - | - | - | - | x | - | - |
| USE_MAX31865 | - | - | - | - | - | - | - |
| | | | | | | | |
| Feature or Sensor | minimal | basic | tasmota | knx | sensors | ir | display | Remarks
| USE_I2C | - | - | x | x | x | - | x |
| USE_SHT | - | - | x | x | x | - | x |
| USE_HTU | - | - | x | x | x | - | x |
| USE_BMP | - | - | x | x | x | - | x |
| USE_BME680 | - | - | - | - | x | - | - |
| USE_BH1750 | - | - | x | x | x | - | x |
| USE_VEML6070 | - | - | - | - | x | - | - |
| USE_ADS1115 | - | - | - | - | x | - | - |
| USE_ADS1115_I2CDEV | - | - | - | - | - | - | - |
| USE_INA219 | - | - | - | - | x | - | - |
| USE_INA226 | - | - | - | - | - | - | - |
| USE_SHT3X | - | - | x | x | x | - | x |
| USE_TSL2561 | - | - | - | - | x | - | - |
| USE_TSL2591 | - | - | - | - | - | - | - |
| USE_MGS | - | - | - | - | x | - | - |
| USE_SGP30 | - | - | x | x | x | - | x |
| USE_SI1145 | - | - | - | - | - | - | - |
| USE_LM75AD | - | - | x | x | x | - | x |
| USE_APDS9960 | - | - | - | - | - | - | - |
| USE_MCP230xx | - | - | - | - | - | - | - |
| USE_PCA9685 | - | - | - | - | - | - | - |
| USE_MPR121 | - | - | - | - | - | - | - |
| USE_CCS811 | - | - | - | - | - | - | - |
| USE_MPU6050 | - | - | - | - | - | - | - |
| USE_DS3231 | - | - | - | - | - | - | - |
| USE_MGC3130 | - | - | - | - | - | - | - |
| USE_MAX44009 | - | - | - | - | - | - | - |
| USE_SCD30 | - | - | - | - | x | - | - |
| USE_SPS30 | - | - | - | - | - | - | - |
| USE_ADE7953 | - | - | x | x | x | - | x |
| USE_VL53L0X | - | - | - | - | - | - | - |
| USE_MLX90614 | - | - | - | - | - | - | - |
| USE_CHIRP | - | - | - | - | - | - | - |
| USE_PAJ7620 | - | - | - | - | - | - | - |
| USE_PCF8574 | - | - | - | - | - | - | - |
| USE_HIH6 | - | - | - | - | x | - | - |
| | | | | | | | |
| Feature or Sensor | minimal | basic | tasmota | knx | sensors | ir | display | Remarks
| USE_SPI | - | - | - | - | - | - | x |
| USE_MHZ19 | - | - | x | x | x | - | x |
| USE_SENSEAIR | - | - | x | x | x | - | x |
| USE_PMS5003 | - | - | x | x | x | - | x |
| USE_NOVA_SDS | - | - | x | x | x | - | x |
| USE_HPMA | - | - | - | - | x | - | - |
| USE_SERIAL_BRIDGE | - | - | x | x | x | - | x |
| USE_MP3_PLAYER | - | - | - | - | x | - | - |
| USE_AZ7798 | - | - | - | - | - | - | - |
| USE_PN532_HSU | - | - | - | - | x | - | - |
| USE_ZIGBEE | - | - | - | - | - | - | - |
| | | | | | | | |
| USE_IR_REMOTE | - | - | x | x | x | x | x |
| USE_IR_RECEIVE | - | - | x | x | x | x | x |
| | | | | | | | |
| USE_SR04 | - | - | x | x | x | - | x |
| USE_TM1638 | - | - | - | - | x | - | - |
| USE_HX711 | - | - | x | x | x | - | x |
| USE_TX20_WIND_SENSOR | - | - | - | - | x | - | - |
| USE_RC_SWITCH | - | - | - | - | x | - | - |
| USE_RF_SENSOR | - | - | - | - | x | - | - | AlectoV2 only
| USE_HRE | - | - | - | - | x | - | - |
| USE_A4988_STEPPER | - | - | - | - | - | - | - |
| USE_TASMOTA_SLAVE | - | - | - | - | - | - | - | Experimental
| | | | | | | | |
| Feature or Sensor | minimal | basic | tasmota | knx | sensors | ir | display | Remarks
| USE_DISPLAY | - | - | - | - | - | - | x |
| USE_DISPLAY_LCD | - | - | - | - | - | - | x |
| USE_DISPLAY_SSD1306 | - | - | - | - | - | - | x |
| USE_DISPLAY_MATRIX | - | - | - | - | - | - | x |
| USE_DISPLAY_SH1106 | - | - | - | - | - | - | x |
| USE_DISPLAY_ILI9341 | - | - | - | - | - | - | x |
| USE_DISPLAY_EPAPER_29 | - | - | - | - | - | - | x |
| USE_DISPLAY_EPAPER_42 | - | - | - | - | - | - | x |
| USE_DISPLAY_ILI9488 | - | - | - | - | - | - | - |
| USE_DISPLAY_SSD1351 | - | - | - | - | - | - | - |
| USE_DISPLAY_RA8876 | - | - | - | - | - | - | - |

View File

@ -4,11 +4,11 @@
**Any contribution helps our team and makes Tasmota better for the entire community!**
Everybody is welcome and invited to contribute to Sonoff-Tasmota Project by:
Everybody is welcome and invited to contribute to Tasmota Project by:
* Testing newly released features and reporting issues.
* Providing Pull Requests (Features, Proof of Concepts, Language files or Fixes)
* Contributing missing documentation for features and devices on our [Wiki](https://github.com/arendst/Sonoff-Tasmota/wiki/Contributing)
* Contributing missing documentation for features and devices in our [documentation](https://tasmota.github.io/docs/#/Contributing)
This document describes rules that are in effect for this repository, meant for handling issues by contributors in the issue tracker and PRs.
@ -44,10 +44,10 @@ A Pull Request (PR) is the process where code modifications are managed in GitHu
The process is straight-forward.
- Read [How to get faster PR reviews](https://github.com/kubernetes/community/blob/master/contributors/guide/pull-requests.md#best-practices-for-faster-reviews) by Kubernetes (but skip step 0)
- Fork the Sonoff-Tasmota Repository [git repository](https://github.com/arendst/Sonoff-Tasmota).
- Fork the Tasmota Repository [git repository](https://github.com/arendst/Tasmota).
- Write/Change the code in your Fork for a new feature, bug fix, new sensor, optimization, etc.
- Ensure tests work.
- Create a Pull Request against the [**dev**](https://github.com/arendst/Sonoff-Tasmota/tree/dev) branch of Sonoff-Tasmota.
- Create a Pull Request against the [**dev**](https://github.com/arendst/Tasmota/tree/dev) branch of Tasmota.
1. All pull requests must be done against the dev branch.
2. Only relevant files should be touched (Also beware if your editor has auto-formatting feature enabled).

2489
Doxyfile Normal file

File diff suppressed because it is too large Load Diff

64
I2CDEVICES.md Normal file
View File

@ -0,0 +1,64 @@
# I2C devices
Tasmota supports several I2C devices but to use them they mostly need to be enabled at compile time to solve possible address conflicts.
Using command ``I2cDriver`` individual drivers can be enabled or disabled at runtime allowing duplicate I2C addresses at compile time. Use the Index from the table below to control I2C drivers like ``I2cDriver10 0`` for disabling BMP support.
## Supported I2C devices
The following table lists the supported I2C devices
Index | Define | Driver | Device | Address(es) | Description
------|---------------------|---------|----------|-------------|-----------------------------------------------
1 | USE_PCA9685 | xdrv_15 | PCA9685 | 0x40 - 0x47 | 16-channel 12-bit pwm driver
2 | USE_PCF8574 | xdrv_28 | PCF8574 | 0x20 - 0x26 | 8-bit I/O expander
2 | USE_PCF8574 | xdrv_28 | PCF8574A | 0x39 - 0x3F | 8-bit I/O expander
3 | USE_DISPLAY_LCD | xdsp_01 | | 0x27, 0x3F | LCD display
4 | USE_DISPLAY_SSD1306 | xdsp_02 | SSD1306 | 0x3C - 0x3D | Oled display
5 | USE_DISPLAY_MATRIX | xdsp_03 | HT16K33 | 0x70 - 0x77 | 8x8 led matrix
6 | USE_DISPLAY_SH1106 | xdsp_07 | SH1106 | 0x3C - 0x3D | Oled display
7 | USE_ADE7953 | xnrg_07 | ADE7953 | 0x38 | Energy monitor
8 | USE_SHT | xsns_07 | SHT1X | Any | Temperature and Humidity sensor
9 | USE_HTU | xsns_08 | HTU21 | 0x40 | Temperature and Humidity sensor
9 | USE_HTU | xsns_08 | SI7013 | 0x40 | Temperature and Humidity sensor
9 | USE_HTU | xsns_08 | SI7020 | 0x40 | Temperature and Humidity sensor
9 | USE_HTU | xsns_08 | SI7021 | 0x40 | Temperature and Humidity sensor
10 | USE_BMP | xsns_09 | BMP085 | 0x76 - 0x77 | Pressure and temperature sensor
10 | USE_BMP | xsns_09 | BMP180 | 0x76 - 0x77 | Pressure and temperature sensor
10 | USE_BMP | xsns_09 | BMP280 | 0x76 - 0x77 | Pressure and temperature sensor
10 | USE_BMP | xsns_09 | BME280 | 0x76 - 0x77 | Pressure, temperature and humidity sensor
10 | USE_BMP | xsns_09 | BME680 | 0x76 - 0x77 | Pressure, temperature, humidity and gas sensor
11 | USE_BH1750 | xsns_10 | BH1750 | 0x23, 0x5C | Ambient light intensity sensor
12 | USE_VEML6070 | xsns_11 | VEML6070 | 0x38 - 0x39 | Ultra violet light intensity sensor
13 | USE_ADS1115 | xsns_12 | ADS1115 | 0x48 - 0x4B | 4-channel 16-bit A/D converter
14 | USE_INA219 | xsns_13 | INA219 | 0x40 - 0x41, 0x44 - 0x45 | Low voltage current sensor
15 | USE_SHT3X | xsns_14 | SHT3X | 0x44 - 0x45 | Temperature and Humidity sensor
15 | USE_SHT3X | xsns_14 | SHTC3 | 0x70 | Temperature and Humidity sensor
16 | USE_TSL2561 | xsns_16 | TSL2561 | 0x29, 0x39, 0x49 | Light intensity sensor
17 | USE_MGS | xsns_19 | Grove | 0x04 | Multichannel gas sensor
18 | USE_SGP30 | xsns_21 | SGP30 | 0x58 | Gas (TVOC) and air quality sensor
19 | USE_SI1145 | xsns_24 | SI1145 | 0x60 | Ultra violet index and light sensor
19 | USE_SI1145 | xsns_24 | SI1146 | 0x60 | Ultra violet index and light sensor
19 | USE_SI1145 | xsns_24 | SI1147 | 0x60 | Ultra violet index and light sensor
20 | USE_LM75AD | xsns_26 | LM75AD | 0x48 - 0x4F | Temperature sensor
21 | USE_APDS9960 | xsns_27 | APDS9960 | 0x39 | Proximity ambient light RGB and gesture sensor
22 | USE_MCP230xx | xsns_29 | MCP23008 | 0x20 - 0x26 | 16-bit I/O expander
22 | USE_MCP230xx | xsns_29 | MCP23017 | 0x20 - 0x26 | 16-bit I/O expander
23 | USE_MPR121 | xsns_30 | MPR121 | 0x5A - 0x5D | Proximity capacitive touch sensor
24 | USE_CCS811 | xsns_31 | CCS811 | 0x5A | Gas (TVOC) and air quality sensor
25 | USE_MPU6050 | xsns_32 | MPU6050 | 0x68 - 0x69 | 3-axis gyroscope and temperature sensor
26 | USE_DS3231 | xsns_33 | DS3231 | 0x68 | Real time clock
27 | USE_MGC3130 | xsns_36 | MGC3130 | 0x42 | Electric field sensor
28 | USE_MAX44009 | xsns_41 | MAX44009 | 0x4A - 0x4B | Ambient light intensity sensor
29 | USE_SCD30 | xsns_42 | SCD30 | 0x61 | CO2 sensor
30 | USE_SPS30 | xsns_44 | SPS30 | 0x69 | Particle sensor
31 | USE_VL53L0X | xsns_45 | VL53L0X | 0x29 | Time-of-flight (ToF) distance sensor
32 | USE_MLX90614 | xsns_46 | MLX90614 | 0x5A | Infra red temperature sensor
33 | USE_CHIRP | xsns_48 | CHIRP | 0x20 | Soil moisture sensor
34 | USE_PAJ7620 | xsns_50 | PAJ7620 | 0x73 | Gesture sensor
35 | USE_INA226 | xsns_54 | INA226 | 0x40 - 0x41, 0x44 - 0x45 | Low voltage current sensor
36 | USE_HIH6 | xsns_55 | HIH6130 | 0x27 | Temperature and Humidity sensor
37 | USE_24C256 | xdrv_10 | 24C256 | 0x50 | Scripter EEPROM storage
38 | USE_DISPLAY_ILI9488 | xdsp_08 | FT6236 | 0x38 | Touch panel controller
39 | USE_DISPLAY_RA8876 | xdsp_10 | FT5316 | 0x38 | Touch panel controller
40 | USE_TSL2591 | xsns_57 | TLS2591 | 0x29 | Light intensity sensor

129
README.md
View File

@ -1,128 +1,112 @@
<img src="/tools/logo/TASMOTA_FullLogo_Vector.svg" alt="Logo" align="right" height="76"/>
![Tasmota logo](/tools/logo/TASMOTA_FullLogo_Vector.svg)
# Sonoff-Tasmota
Alternative firmware for _ESP8266 based devices_ like [iTead](https://www.itead.cc/) _**Sonoff**_ with **web UI, rules and timers, OTA updates, custom device templates and sensor support**. Allows control over **MQTT**, **HTTP**, **Serial** and **KNX** for integrations with smart home systems. Written for Arduino IDE and PlatformIO.
Alternative firmware for [ESP8266](https://en.wikipedia.org/wiki/ESP8266) based devices with **easy configuration using webUI, OTA updates, automation using timers or rules, expandability and entirely local control over MQTT, HTTP, Serial or KNX**.
_Written for Arduino IDE and PlatformIO._
[![GitHub version](https://img.shields.io/github/release/arendst/Sonoff-Tasmota.svg)](https://github.com/arendst/Sonoff-Tasmota/releases/latest)
[![GitHub download](https://img.shields.io/github/downloads/arendst/Sonoff-Tasmota/total.svg)](https://github.com/arendst/Sonoff-Tasmota/releases/latest)
[![License](https://img.shields.io/github/license/arendst/Sonoff-Tasmota.svg)](https://github.com/arendst/Sonoff-Tasmota/blob/master/LICENSE.txt)
[![GitHub version](https://img.shields.io/github/release/arendst/Tasmota.svg)](https://github.com/arendst/Tasmota/releases/latest)
[![GitHub download](https://img.shields.io/github/downloads/arendst/Tasmota/total.svg)](https://github.com/arendst/Tasmota/releases/latest)
[![License](https://img.shields.io/github/license/arendst/Tasmota.svg)](LICENSE.txt)
[![Chat](https://img.shields.io/discord/479389167382691863.svg)](https://discord.gg/Ks2Kzd4)
If you like **Sonoff-Tasmota**, give it a star, or fork it, and contribute!
If you like **Tasmota**, give it a star, or fork it and contribute!
[![GitHub stars](https://img.shields.io/github/stars/arendst/Sonoff-Tasmota.svg?style=social&label=Star)](https://github.com/arendst/Sonoff-Tasmota/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/arendst/Sonoff-Tasmota.svg?style=social&label=Fork)](https://github.com/arendst/Sonoff-Tasmota/network)
[![GitHub stars](https://img.shields.io/github/stars/arendst/Tasmota.svg?style=social&label=Star)](https://github.com/arendst/Tasmota/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/arendst/Tasmota.svg?style=social&label=Fork)](https://github.com/arendst/Tasmota/network)
[![donate](https://img.shields.io/badge/donate-PayPal-blue.svg)](https://paypal.me/tasmota)
See [RELEASENOTES.md](https://github.com/arendst/Sonoff-Tasmota/blob/master/RELEASENOTES.md) for release information.
See [RELEASENOTES.md](RELEASENOTES.md) for release information.
In addition to the [release webpage](https://github.com/arendst/Sonoff-Tasmota/releases/latest) the binaries can also be downloaded from http://thehackbox.org/tasmota/release/
In addition to the [release webpage](https://github.com/arendst/Tasmota/releases/latest) the binaries can also be downloaded from http://thehackbox.org/tasmota/release/
## Development
[![Dev Version](https://img.shields.io/badge/development%20version-v6.7.1.x-blue.svg)](https://github.com/arendst/Sonoff-Tasmota)
[![Download Dev](https://img.shields.io/badge/download-development-yellow.svg)](http://thehackbox.org/tasmota/)
[![Build Status](https://img.shields.io/travis/arendst/Sonoff-Tasmota.svg)](https://travis-ci.org/arendst/Sonoff-Tasmota)
See [sonoff/_changelog.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_changelog.ino) for detailed change information.
[![Dev Version](https://img.shields.io/badge/development%20version-v7.1.0.x-blue.svg)](https://github.com/arendst/Tasmota)
[![Download Dev](https://img.shields.io/badge/download-development-yellow.svg)](http://thehackbox.org/tasmota/)
[![Build Status](https://img.shields.io/travis/arendst/Tasmota.svg)](https://travis-ci.org/arendst/Tasmota)
See [tasmota/CHANGELOG.md](tasmota/CHANGELOG.md) for detailed change information.
Unless your Tasmota powered device exhibits a problem or you need to make use of a feature that is not available in the Tasmota version currently installed on your device, leave your device alone - it works so don't make unnecessary changes! If the release version (i.e., the master branch) exhibits unexpected behaviour for your device and configuration, you should upgrade to the latest development version instead to see if your problem is resolved as some bugs in previous releases or development builds may already have been resolved.
The Tasmota development codebase is checked every 1-2 hours for changes. If new commits have been merged and they compile successfuly, new binary files for every variant (excluding non-English languages) will be posted at http://thehackbox.org/tasmota/ (this web address can be used for OTA updates too). The last compiled commit number is also indicated on the same page. It is important to note that these binaries are based on the current development codebase. These commits are tested as much as is possible and are typically quite stable. However, it is infeasible to test on the hundreds of different types of devices with all the available configuration options permitted.
The Tasmota development codebase is checked every 1-2 hours for changes. If new commits have been merged and they compile successfuly, new binary files for every variant will be posted at http://thehackbox.org/tasmota/ (this web address can be used for OTA updates too). The last compiled commit number is also indicated on the same page. It is important to note that these binaries are based on the current development codebase. These commits are tested as much as is possible and are typically quite stable. However, it is infeasible to test on the hundreds of different types of devices with all the available configuration options permitted.
Note that there is a chance, as with any upgrade, that the device may not function as expected. You must always account for the possibility that you may need to flash the device via the serial programming interface if the OTA upgrade fails. Even with the master release, you should always attempt to test the device or a similar prototype before upgrading a device which is in production or is hard to reach. And, as always, make a backup of the device configuration before beginning any firmware update.
## Disclaimer
:warning: **DANGER OF ELECTROCUTION** :warning:
An ESP82xx Wi-Fi device is not a toy. It uses Mains AC so there is a danger of electrocution if not installed properly. If you don't know how to install it, please call an electrician. Remember: _**SAFETY FIRST**_. It is not worth risk to yourself, your family, and your home if you don't know exactly what you are doing. Never try to flash a device using the serial programming interface while it is connected to MAINS AC.
If your device connects to mains electricity (AC power) there is danger of electrocution if not installed properly. If you don't know how to install it, please call an electrician (***Beware:*** certain countries prohibit installation without a licensed electrician present). Remember: _**SAFETY FIRST**_. It is not worth the risk to yourself, your family and your home if you don't know exactly what you are doing. Never tinker or try to flash a device using the serial programming interface while it is connected to MAINS ELECTRICITY (AC power).
We don't take any responsibility nor liability for using this software nor for the installation or any tips, advice, videos, etc. given by any member of this site or any related site.
## Note
Please do not ask to add new devices unless it requires additional code for new features. If the device is not listed as a module, try using [Templates](https://github.com/arendst/Sonoff-Tasmota/wiki/Templates) first. If it is not listed in the [Tasmota Device Templates Repository](http://blakadder.github.io/templates) create your own [Template](https://github.com/arendst/Sonoff-Tasmota/wiki/Templates#creating-your-template-).
Please do not ask to add new devices unless it requires additional code for new features. If the device is not listed as a module, try using [Templates](https://tasmota.github.io/docs/#/Templates) first. If it is not listed in the [Tasmota Device Templates Repository](http://blakadder.github.io/templates) create your own [Template](https://tasmota.github.io/docs/#/Templates?id=creating-your-template).
## Quick Install
Download one of the released binaries from https://github.com/arendst/Sonoff-Tasmota/releases and flash it to your hardware as [documented in the wiki](https://github.com/arendst/Sonoff-Tasmota/wiki/Flashing).
Download one of the released binaries from https://github.com/arendst/Tasmota/releases and flash it to your hardware [using our installation guide](https://tasmota.github.io/docs/#/installation/).
## Important User Compilation Information
If you want to compile Sonoff-Tasmota yourself keep in mind the following:
If you want to compile Tasmota yourself keep in mind the following:
- Only Flash Mode **DOUT** is supported. Do not use Flash Mode DIO / QIO / QOUT as it might seem to brick your device. See [Wiki](https://github.com/arendst/Sonoff-Tasmota/wiki/Flashing) for background information.
- Sonoff-Tasmota uses a 1M linker script WITHOUT spiffs **1M (no SPIFFS)** for optimal code space. If you compile using ESP/Arduino library 2.3.0 then download the provided new linker script to your Arduino IDE or Platformio base folder. Later versions of ESP/Arduino library already contain the correct linker script. See [Wiki > Prerequisites](https://github.com/arendst/Sonoff-Tasmota/wiki/Prerequisites).
- To make compile time changes to Sonoff-Tasmota it can use the ``user_config_override.h`` file. It assures keeping your settings when you download and compile a new version. To use ``user_config.override.h`` you will have to make a copy of the provided ``user_config_override_sample.h`` file and add your setting overrides. To enable the override file you will need to use a compile define as documented in the ``user_config_override_sample.h`` file.
- Only Flash Mode **DOUT** is supported. Do not use Flash Mode DIO / QIO / QOUT as it might seem to brick your device.
- Tasmota uses a 1M linker script WITHOUT spiffs **1M (no SPIFFS)** for optimal code space.
- To make compile time changes to Tasmota use the `user_config_override.h` file. It assures keeping your custom settings when you download and compile a new version. You have to make a copy from the provided `user_config_override_sample.h` file and add your setting overrides. To enable the override you have to set a compile define as documented in the `user_config_override_sample.h` file.
## Configuration Information
Please refer to the Installation and configuration articles in the [wiki](https://github.com/arendst/Sonoff-Tasmota/wiki).
Please refer to the installation and configuration articles in our [documentation](https://tasmota.github.io/docs).
## Migration Information
See [wiki migration path](https://github.com/arendst/Sonoff-Tasmota/wiki/Upgrade#migration-path) for instructions how to migrate to a major version. Pay attention to the following version breaks due to dynamic settings updates:
See [wiki migration path](https://tasmota.github.io/docs/#/Upgrading?id=migration-path) for instructions how to migrate to a major version. Pay attention to the following version breaks due to dynamic settings updates:
1. Migrate to **Sonoff-Tasmota 3.9.x**
2. Migrate to **Sonoff-Tasmota 4.x**
3. Migrate to **Sonoff-Tasmota 5.14**
4. Migrate to **Sonoff-Tasmota 6.x**
5. Migrate to **Tasmota 7.x**
## Support Information
<img src="https://github.com/arendst/arendst.github.io/blob/master/media/sonoffbasic.jpg" width="250" align="right" />
<img src="https://user-images.githubusercontent.com/5904370/68332933-e6e5a600-00d7-11ea-885d-50395f7239a1.png" width=150 align="right" />
For a database of supported devices see [Tasmota Device Templates Repository](https://blakadder.github.io/templates)
See [Wiki](https://github.com/arendst/Sonoff-Tasmota/wiki) for use instructions and how-to's.<br />
See [Community](https://groups.google.com/d/forum/sonoffusers) for forum.<br />
Visit [Discord Chat](https://discord.gg/Ks2Kzd4) for discussions and troubleshooting.
If you're looking for support on **Tasmota** there are some options available:
### Documentation:
* [Documentation Site](https://tasmota.github.io/docs): For information on how to flash Tasmota, configure, use and expand it
* [FAQ and Troubleshooting](https://tasmota.github.io/docs/#/help/): For information on common problems and solutions.
* [Commands Information](https://tasmota.github.io/docs/#/Commands): For information on all the commands supported by Tasmota.
### Support's Community:
* [Tasmota Forum](https://groups.google.com/d/forum/sonoffusers): For usage and discussions.
* [Tasmota Support Chat](https://discord.gg/Ks2Kzd4): For support, troubleshooting and general questions. You have better chances to get fast answers from members of the Tasmota Community.
* [Search in Issues](https://github.com/arendst/Tasmota/issues): You might find an answer to your question by searching current or closed issues.
### Developers' Community:
* [Bug Report](https://github.com/arendst/Tasmota/issues/new?template=Bug_report.md): For reporting Bugs of Tasmota Software.
* [Feature Request](https://github.com/arendst/Tasmota/issues/new?template=Feature_request.md): For requesting features/functions to Tasmota Software.
* [Troubleshooting](https://github.com/arendst/Tasmota/issues/new?template=Custom.md): As a last resort, you can open new *Troubleshooting* issue on GitHub if the solution could not be found using the other channels. Just remember: the more info you provide the more chances you'll have to get an accurate answer.
* [Issue a question](https://github.com/arendst/Tasmota/issues/new/choose): As a last resort, you can open a new *Question* issue on GitHub if the answer could not be found using the other channels. Just remember: the more info you provide the more chances you'll have to get an accurate answer.
## Contribute
You can contribute to Sonoff-Tasmota by
You can contribute to Tasmota by
- providing Pull Requests (Features, Proof of Concepts, Language files or Fixes)
- testing new released features and report issues
- donating to acquire hardware for testing and implementing or out of gratitude
- contributing missing documentation for features and devices on our [Wiki](https://github.com/arendst/Sonoff-Tasmota/wiki)
- contributing missing [documentation](https://tasmota.github.io/docs) for features and devices
[![donate](https://img.shields.io/badge/donate-PayPal-blue.svg)](https://paypal.me/tasmota)
## Credits
### Libraries Used
Libraries used with Sonoff-Tasmota are:
- [ESP8266 core for Arduino](https://github.com/esp8266/Arduino)
- [Adafruit CCS811](https://github.com/adafruit/Adafruit_CCS811)
- [Adafruit ILI9341](https://github.com/adafruit/Adafruit_ILI9341)
- [Adafruit LED Backpack](https://github.com/adafruit/Adafruit-LED-Backpack-Library)
- [Adafruit MAX31865](https://github.com/adafruit/Adafruit_MAX31865)
- [Adafruit SGP30](https://github.com/adafruit/Adafruit_SGP30)
- Adafruit based SH1106
- [Adafruit SSD1306](https://github.com/adafruit/Adafruit_SSD1306)
- Adafruit based SSD1351
- [Adafruit GFX](https://github.com/adafruit/Adafruit-GFX-Library)
- Arduino Hex Parser
- [ArduinoJson](https://arduinojson.org/)
- AT24C256 I2C eeprom
- [Base64](https://github.com/Densaugeo/base64_arduino)
- [Bear SSL](https://github.com/earlephilhower/bearssl-esp8266.git)
- [Bosch BME680](https://github.com/BoschSensortec/BME680_driver)
- [C2 Programmer](http://app.cear.ufpb.br/~lucas.hartmann/tag/efm8bb1/)
- [esp-epaper-29-ws-20171230-gemu](https://github.com/gemu2015/Sonoff-Tasmota/tree/displays/lib)
- [esp-knx-ip](https://github.com/envy/esp-knx-ip)
- FrogmoreScd30
- FT6236
- [I2Cdevlib](https://github.com/jrowberg/i2cdevlib)
- [IRremoteEsp8266](https://github.com/markszabo/IRremoteESP8266)
- [JaretBurkett ILI9488](https://github.com/jaretburkett/ILI9488)
- [JobaTsl2561](https://github.com/joba-1/Joba_Tsl2561)
- [LinkedList](https://github.com/ivanseidel/LinkedList)
- [Liquid Cristal](https://github.com/marcoschwartz/LiquidCrystal_I2C)
- [MultiChannelGasSensor](http://wiki.seeedstudio.com/Grove-Multichannel_Gas_Sensor/)
- [NeoPixelBus](https://github.com/Makuna/NeoPixelBus)
- [NewPing](https://bitbucket.org/teckel12/arduino-new-ping/wiki/Home)
- [OneWire](https://github.com/PaulStoffregen/OneWire)
- [PubSubClient](https://github.com/knolleary/pubsubclient)
- [rc-switch](https://github.com/sui77/rc-switch)
- TasmotaModbus
- TasmotaSerial
- [Vl53l0x](https://github.com/pololu/vl53l0x-arduino)
- Xlatb Ra8876
### People inspiring me
People helping to keep the show on the road:
- David Lang providing initial issue resolution and code optimizations
- Heiko Krupp for his IRSend, HTU21, SI70xx and Wemo/Hue emulation drivers
@ -151,6 +135,7 @@ People helping to keep the show on the road:
- Stephan Hadinger for refactoring light driver, enhancing HueEmulation and Zigbee support
- tmo for designing the official Tasmota logo
- Stefan Bode for his Shutter and Deep sleep drivers
- Jacek Ziółkowski for his [TDM](https://github.com/jziolkowski/tdm) management tool
- Many more providing Tips, Wips, Pocs, PRs and Donations
## License

View File

@ -1,20 +0,0 @@
<img src="/tools/logo/TASMOTA_FullLogo_Vector.svg" alt="Logo" align="right" height="76"/>
# Reference
Tasmota backgound information.
## Supported Smart Switch with Energy Monitoring GPIO usage
Module | GPIO00 | GPIO01 | GPIO02 | GPIO03 | GPIO04 | GPIO05 | GPIO12 | GPIO13 | GPIO14 | GPIO15
-------|--------|--------|--------|--------|--------|--------|--------|--------|--------|--------
Sonoff Pow | KEY1 | - | - | - | - | NRG_SEL | REL1 | NRG_CF1 | HLW_CF | LED1
Sonoff Pow R2 | KEY1 | RXD | - | TXD | - | - | REL1 | LED1_INV | - | -
Shelly 2 | - | RXD | - | TXD | REL1 | REL2 | SWT1 | - | SWT2 | -
Huafan SS | LED1_INV | - | - | LED2_INV | KEY1 | REL1_INV | NRG_CF1 | NRG_SEL | HLW_CF | -
KMC 70011 | KEY1 | - | - | - | HLW_CF | NRG_CF1 | NRG_SEL | LED1_INV | REL1 | -
Teckin | - | KEY1 | - | LED2_INV | HJL_CF | NRG_CF1 | NRG_SEL_INV | LED1_INV | REL1 | -
AplicWDP303075 | - | - | - | KEY1 | HLW_CF | NRG_CF1 | NRG_SEL_INV | LED1_INV | REL1 | -
Gosund SP1 v23 | - | LED1_INV | - | KEY1 | HJL_CF | NRG_CF1 | NRG_SEL_INV | LED2_INV | REL1 | -
SK03 Outdoor | KEY1 | - | - | - | HLW_CF | NRG_CF1 | NRG_SEL_INV | LED2_INV | LED1_INV | REL1
BlitzWolf SHP | LED2_INV | - | LED1_INV | - | - | HJL_CF | NRG_SEL_INV | KEY1 | NRG_CF1 | REL1
Teckin US | LED2_INV | - | LED1_INV | - | REL1 | HJL_CF | NRG_SEL_INV | KEY1 | NRG_CF1 | -

View File

@ -1,27 +1,35 @@
<img src="https://github.com/arendst/Sonoff-Tasmota/blob/master/tools/logo/TASMOTA_FullLogo_Vector.svg" alt="Logo" align="right" height="76"/>
<img src="https://github.com/arendst/Tasmota/blob/master/tools/logo/TASMOTA_FullLogo_Vector.svg" alt="Logo" align="right" height="76"/>
# RELEASE NOTES
### Sonoff-Tasmota is now Tasmota
## Migration Information
See [wiki migration path](https://github.com/arendst/Sonoff-Tasmota/wiki/Upgrade#migration-path) for instructions how to migrate to a major version. Pay attention to the following version breaks due to dynamic settings updates:
See [migration path](https://tasmota.github.io/docs/#/Upgrading?id=migration-path) for instructions how to migrate to a major version. Pay attention to the following version breaks due to dynamic settings updates:
1. Migrate to **Sonoff-Tasmota 3.9.x**
2. Migrate to **Sonoff-Tasmota 4.x**
3. Migrate to **Sonoff-Tasmota 5.14**
4. Migrate to **Sonoff-Tasmota 6.x**
5. Migrate to **Tasmota 7.x**
## Supported Core versions
This release will be supported from ESP8266/Arduino library Core version **pre-2.6.0** due to reported security and stability issues on previous Core version.
Although it might still compile on previous Core versions all support will be removed starting in the next Release.
This release will be supported from ESP8266/Arduino library Core version **2.6.1** due to reported security and stability issues on previous Core version.
Although it might still compile on previous Core versions all support will be removed in the near future.
## Support of TLS
To save resources when TLS is enabled mDNS needs to be disabled. In addition to TLS using fingerprints now also user supplied CA certs and AWS IoT is supported. See full documentation on https://github.com/arendst/Sonoff-Tasmota/wiki/AWS-IoT
To save resources when TLS is enabled mDNS needs to be disabled. In addition to TLS using fingerprints now also user supplied CA certs and AWS IoT is supported. Read [full documentation](https://tasmota.github.io/docs/#/integrations/AWS-IoT)
## Initial configuration tools
For initial configuration this release supports Webserver based **WifiManager** or **Serial** based command interface only. Support for **WPS** and **SmartConfig** has been removed.
## Supported Modules
The following hardware modules are supported.
Module | Description
@ -102,277 +110,58 @@ Module | Description
Over 500 additional devices are supported using [templates](TEMPLATES.md).
## Provided Binary Downloads
The following binary downloads have been compiled with ESP8266/Arduino library core version **pre-2.6.0**.
- **sonoff.bin** = The Sonoff version with sensors. **RECOMMENDED RELEASE BINARY**
- **sonoff-BG.bin** to **sonoff-TW.bin** = The Sonoff version in different languages.
- **sonoff-basic.bin** = The Basic version without most sensors.
- **sonoff-knx.bin** = The Knx version without some features but adds KNX support.
- **sonoff-sensors.bin** = The Sensors version adds more useful sensors.
- **sonoff-ir** = The InfraRed Receiver and transmitter version allowing all available protocols provided by library IRremoteESP8266 but without most other features.
- **sonoff-display.bin** = The Display version without Energy Monitoring but adds display support.
- **sonoff-minimal.bin** = The Minimal version allows intermediate OTA uploads to support larger versions and does NOT change any persistent parameter. This version **should NOT be used for initial installation**.
The following binary downloads have been compiled with ESP8266/Arduino library core version **2.6.1**.
## Available Features and Sensors
- **tasmota.bin** = The Tasmota version with sensors. **RECOMMENDED RELEASE BINARY**
- **tasmota-BG.bin** to **tasmota-TW.bin** = The Tasmota version in different languages.
- **tasmota-basic.bin** = The Basic version without most sensors.
- **tasmota-knx.bin** = The Knx version without some features but adds KNX support.
- **tasmota-sensors.bin** = The Sensors version adds more useful sensors.
- **tasmota-ir** = The InfraRed Receiver and transmitter version allowing all available protocols provided by library IRremoteESP8266 but without most other features.
- **tasmota-display.bin** = The Display version without Energy Monitoring but adds display support.
- **tasmota-minimal.bin** = The Minimal version allows intermediate OTA uploads to support larger versions and does NOT change any persistent parameter. This version **should NOT be used for initial installation**.
| Feature or Sensor | minimal | basic | sonoff | knx | sensors | ir | display | Remarks
|-----------------------|---------|-------|--------|-----|---------|----|---------|--------
| MY_LANGUAGE en-GB | x | x | x | x | x | x | x |
| USE_ARDUINO_OTA | - | - | - | - | - | - | - |
| USE_DOMOTICZ | - | - | x | x | x | x | - |
| USE_HOME_ASSISTANT | - | - | x | x | x | x | - |
| USE_MQTT_TLS | - | - | - | - | - | - | - |
| USE_MQTT_TLS_CA_CERT | - | - | - | - | - | - | - |
| USE_MQTT_AWS_IOT | - | - | - | - | - | - | - |
| USE_KNX | - | - | - | x | - | - | - |
| USE_WEBSERVER | x | x | x | x | x | x | x |
| USE_JAVASCRIPT_ES6 | - | - | - | - | - | - | - |
| USE_WEBSEND_RESPONSE | - | - | - | - | - | - | - |
| USE_EMULATION_HUE | - | x | x | - | x | - | - |
| USE_EMULATION_WEMO | - | x | x | - | x | - | - |
| USE_DISCOVERY | - | - | x | x | - | - | x |
| WEBSERVER_ADVERTISE | - | - | x | x | - | - | x |
| MQTT_HOST_DISCOVERY | - | - | x | x | - | - | x |
| USE_TIMERS | - | x | x | x | x | x | x |
| USE_TIMERS_WEB | - | x | x | x | x | x | x |
| USE_SUNRISE | - | x | x | x | x | x | x |
| USE_RULES | - | x | x | x | x | x | x |
| USE_SCRIPT | - | - | - | - | - | - | - |
| USE_EXPRESSION | - | - | - | - | - | - | - |
| SUPPORT_IF_STATEMENT | - | - | - | - | - | - | - |
| | | | | | | | |
| Feature or Sensor | minimal | basic | sonoff | knx | sensors | ir | display | Remarks
| ROTARY_V1 | - | - | - | - | - | - | - |
| USE_SONOFF_RF | - | - | x | x | x | - | - |
| USE_RF_FLASH | - | - | x | x | x | - | - |
| USE_SONOFF_SC | - | - | x | - | x | - | - |
| USE_TUYA_MCU | - | x | x | x | x | - | x |
| USE_ARMTRONIX_DIMMERS | - | - | x | x | - | - | - |
| USE_PS_16_DZ | - | - | x | x | x | - | - |
| USE_SONOFF_IFAN | - | - | x | x | x | - | - |
| USE_BUZZER | - | - | x | x | x | - | - |
| USE_ARILUX_RF | - | - | x | x | x | - | - |
| USE_SHUTTER | - | - | - | - | - | - | - |
| USE_DEEPSLEEP | - | - | - | - | - | - | - |
| USE_EXS_DIMMER | - | - | x | x | - | - | - |
| | | | | | | | |
| Feature or Sensor | minimal | basic | sonoff | knx | sensors | ir | display | Remarks
| USE_LIGHT | - | x | x | x | x | x | x |
| USE_WS2812 | - | - | x | x | x | - | x |
| USE_WS2812_DMA | - | - | - | - | - | - | - |
| USE_MY92X1 | - | - | x | x | x | - | x |
| USE_SM16716 | - | - | x | x | x | - | x |
| USE_SM2135 | - | - | x | x | x | - | x |
| USE_SONOFF_L1 | - | - | x | x | x | - | x |
| | | | | | | | |
| USE_ENERGY_SENSOR | - | x | x | x | x | - | - |
| USE_PZEM004T | - | - | x | x | x | - | - |
| USE_PZEM_AC | - | - | x | x | x | - | - |
| USE_PZEM_DC | - | - | x | x | x | - | - |
| USE_MCP39F501 | - | x | x | x | x | - | - |
| USE_SDM120 | - | - | - | - | x | - | - |
| USE_SDM630 | - | - | - | - | x | - | - |
| USE_DDS2382 | - | - | - | - | x | - | - |
| USE_DDSU666 | - | - | - | - | x | - | - |
| USE_SOLAX_X1 | - | - | - | - | - | - | - |
| | | | | | | | |
| USE_ADC_VCC | x | x | - | - | - | - | - |
| USE_COUNTER | - | - | x | x | x | x | x |
| USE_DS18x20 | - | - | x | x | x | - | x |
| USE_DHT | - | - | x | x | x | x | x |
| USE_MAX31855 | - | - | - | - | x | - | - |
| USE_MAX31865 | - | - | - | - | - | - | - |
| | | | | | | | |
| Feature or Sensor | minimal | basic | sonoff | knx | sensors | ir | display | Remarks
| USE_I2C | - | - | x | x | x | - | x |
| USE_SHT | - | - | x | x | x | - | x |
| USE_HTU | - | - | x | x | x | - | x |
| USE_BMP | - | - | x | x | x | - | x |
| USE_BME680 | - | - | - | - | x | - | - |
| USE_BH1750 | - | - | x | x | x | - | x |
| USE_VEML6070 | - | - | - | - | x | - | - |
| USE_ADS1115 | - | - | - | - | x | - | - |
| USE_ADS1115_I2CDEV | - | - | - | - | - | - | - |
| USE_INA219 | - | - | - | - | x | - | - |
| USE_INA226 | - | - | - | - | - | - | - |
| USE_SHT3X | - | - | x | x | x | - | x |
| USE_TSL2561 | - | - | - | - | x | - | - |
| USE_MGS | - | - | - | - | x | - | - |
| USE_SGP30 | - | - | x | x | x | - | x |
| USE_SI1145 | - | - | - | - | - | - | - |
| USE_LM75AD | - | - | x | x | x | - | x |
| USE_APDS9960 | - | - | - | - | - | - | - |
| USE_MCP230xx | - | - | - | - | - | - | - |
| USE_PCA9685 | - | - | - | - | - | - | - |
| USE_MPR121 | - | - | - | - | - | - | - |
| USE_CCS811 | - | - | - | - | - | - | - |
| USE_MPU6050 | - | - | - | - | - | - | - |
| USE_DS3231 | - | - | - | - | - | - | - |
| USE_MGC3130 | - | - | - | - | - | - | - |
| USE_MAX44009 | - | - | - | - | - | - | - |
| USE_SCD30 | - | - | - | - | x | - | - |
| USE_SPS30 | - | - | - | - | - | - | - |
| USE_ADE7953 | - | - | x | x | x | - | x |
| USE_VL53L0X | - | - | - | - | - | - | - |
| USE_MLX90614 | - | - | - | - | - | - | - |
| USE_CHIRP | - | - | - | - | - | - | - |
| USE_PAJ7620 | - | - | - | - | - | - | - |
| USE_PCF8574 | - | - | - | - | - | - | - |
| | | | | | | | |
| Feature or Sensor | minimal | basic | sonoff | knx | sensors | ir | display | Remarks
| USE_SPI | - | - | - | - | - | - | x |
| USE_MHZ19 | - | - | x | x | x | - | x |
| USE_SENSEAIR | - | - | x | x | x | - | x |
| USE_PMS5003 | - | - | x | x | x | - | x |
| USE_NOVA_SDS | - | - | x | x | x | - | x |
| USE_SERIAL_BRIDGE | - | - | x | x | x | - | x |
| USE_MP3_PLAYER | - | - | - | - | x | - | - |
| USE_AZ7798 | - | - | - | - | - | - | - |
| USE_PN532_HSU | - | - | - | - | x | - | - |
| USE_ZIGBEE | - | - | - | - | - | - | - | Experimental
| | | | | | | | |
| USE_IR_REMOTE | - | - | x | x | x | x | x |
| USE_IR_HVAC | - | - | - | - | x | x | - |
| USE_IR_RECEIVE | - | - | x | x | x | x | x |
| | | | | | | | |
| USE_SR04 | - | - | x | x | x | - | x |
| USE_TM1638 | - | - | - | - | x | - | - |
| USE_HX711 | - | - | x | x | x | - | x |
| USE_TX20_WIND_SENSOR | - | - | - | - | x | - | - |
| USE_RC_SWITCH | - | - | - | - | x | - | - |
| USE_RF_SENSOR | - | - | - | - | x | - | - | AlectoV2 only
| USE_HRE | - | - | - | - | x | - | - |
| USE_A4988_STEPPER | - | - | - | - | - | - | - |
| USE_ARDUINO_SLAVE | - | - | - | - | - | - | - | Experimental
| | | | | | | | |
| Feature or Sensor | minimal | basic | sonoff | knx | sensors | ir | display | Remarks
| USE_DISPLAY | - | - | - | - | - | - | x |
| USE_DISPLAY_LCD | - | - | - | - | - | - | x |
| USE_DISPLAY_SSD1306 | - | - | - | - | - | - | x |
| USE_DISPLAY_MATRIX | - | - | - | - | - | - | x |
| USE_DISPLAY_SH1106 | - | - | - | - | - | - | x |
| USE_DISPLAY_ILI9341 | - | - | - | - | - | - | x |
| USE_DISPLAY_EPAPER_29 | - | - | - | - | - | - | x |
| USE_DISPLAY_EPAPER_42 | - | - | - | - | - | - | x |
| USE_DISPLAY_ILI9488 | - | - | - | - | - | - | - |
| USE_DISPLAY_SSD1351 | - | - | - | - | - | - | - |
| USE_DISPLAY_RA8876 | - | - | - | - | - | - | - |
[Complete list](BUILDS.md) of available feature and sensors.
## Changelog
Version 6.7.1 20191026
* Remove support for WPS and SmartConfig in favour of Web server (!) based WifiManager (#6680)
* Remove binary sonoff-classic (#6680)
* Remove command ``SetOption2``
* Remove default DS18B20 driver and only support define **USE_DS18x20** (#6647)
* Remove support for define **USE_DS18x20_LEGACY** and legacy DS18x20 driver (#6486)
* Replace xsns_23_sdm120 with xnrg_08_sdm120
* Replace xsns_25_sdm630 with xnrg_10_sdm630
* Replace xsns_49_solaxX1 with xnrg_12_solaxX1 (#6677)
* Change Sonoff L1 support by adding define **USE_SONOFF_L1**
* Change light drivers internals to ease management
* Change command ``PulseTime`` JSON message format and allow display of all pulsetimer information (#6519)
* Change command ``SetOption43`` to make it more general. Now supports PS_16_DZ driver too (#6544)
* Change command handling by moving buffers up in chain solving ``MQTTlog`` support (#6529)
* Change commands ``Var`` and ``Mem`` to show all parameters when no index is given (#6107)
* Change detection of non-MQTT commands by allowing non-space characters as delimiter (#6540)
* Change rename "Data" to "Hash" and limit to 32 bits when receiving UNKNOWN IR protocol (see DECODE_HASH from IRremoteESP8266)
* Change JSON output format for commands ``Adc``, ``Adcs``, ``Modules``, ``Gpio`` and ``Gpios`` from list to dictionary (#6407)
* Change energy sensors for three phase/channel support
* Change Settings crc calculation allowing short term backward compatibility
* Change Improve reliability of TasmotaSerial at 115200 bauds and reduce IRAM usage
* Change Tuya support by Shantur Rathore removing tuya related commands ``SetOption34, 41, 44, 45, 46, 65, 66 and 69`` (#6353)
* Change theoretical baudrate range to 300..19660500 bps in 300 increments (#6294)
* Change Settings area to 4k for future use
* Change some table locations from RAM to Flash
* Change filename of configuration backup from using FriendlyName1 to Hostname solving diacritic issues (#2422)
* Change Store AWS IoT Private Key and Certificate in SPI Flash avoiding device-specific compilations
* Change defines **USE_TX20_WIND_SENSOR** and **USE_RC_SWITCH** in my_user_config.h to disable to lower iram usage enabling latest core compilation (#6060, #6062)
* Fix PowerDelta related exception0: epc1:0x4000dce5 (#6750)
* Fix handling of ligth channels when pwm_multichannel (``SetOption68``) is enabled
* Fix better handling of PWM White Temperature mode for Module 48 (#6534)
* Fix TasmotaSerial: move serial send to IRAM for high speed baud rates
* Fix Domoticz battery level set to 100 if define **USE_ADC_VCC** is not used (#6033)
* Fix Force Elliptic Curve for Letsencrypt TLS #6042
* Fix WeMo emulation for 1G echo and 2G echo dot (#6086)
* Fix Xiaomi Philips brightness (#6091)
* Add support for EX-Store WiFi Dimmer V4 (#5856)
* Add support for Arduino serial connection (EXPERIMENTAL)
* Add support for Zigbee devices Xiaomi lumi.weather air quality sensor, Osram mini-switch
* Add support for Zigbee device cc2530 initialization and basic ZCL decoding
* Add support for PMS3003 dust particle sensor
* Add support for Chint DDSU666 Modbus energy meter by Pablo Zerón
* Add support for SM2135 as used in Action LSC Smart Led E14 (#6495)
* Add support for Shelly 2.5 dual energy (#6160)
* Add support for shutters by Stefan Bode (#288)
* Add support for PCF8574 I2C I/O Expander (currently output only) by Stefan Bode
* Add support for up to three PZEM-014/-016 on one serial modbus connection with addresses 1 (default), 2 and 3 (#2315)
* Add support for up to three PZEM-004T on one serial connection with addresses 192.168.1.1 (default), 2 and 3 (#2315)
* Add support for up to three PZEM-003/-017 on one serial modbus connection with addresses 1 (default), 2 and 3 (#2315)
* Add support for up to 4 INA226 Voltage and Current sensors by Steve Rogers (#6342)
* Add support for A4988 stepper-motor-driver-circuit by Tim Leuschner (#6370)
* Add support for Hiking DDS238-2 Modbus energy meter by Matteo Campanella (#6384)
* Add support for HM17 bluetooth LE passive scan of ibeacon devices by Gerhard Mutz
* Add support for Solax X1 inverter by Pablo Zerón
* Add support for PAJ7620 gesture sensor by Christian Baars
* Add support for MAX31865 Thermocouple sensor by Alberto Lopez Siemens
* Add support for RDM6300 125kHz RFID Reader by Gerhard Mutz
* Add support for CHIRP soil moisture sensor by Christian Baars
* Add support for Sonoff iFan03 as module 71 (#5988)
* Add support for a buzzer
* Add support for IRSend long press ('repeat' feature from IRRemoteESP8266) (#6074)
* Add support for IRHVAC Midea/Komeco protocol (#3227)
* Add support for more IRSend protocols enabled in my_user_config.h
* Add support for IRSend Pioneer protocol (#6100)
* Add support for up to 4 INA219 sensors (#6046)
* Add support for I2C display driver SH1106 oled by Gerhard Mutz
* Add support for SPI display drivers epaper 4.2 inch, ILI9488 TFT, SSD1351 Color oled and RA8876 TFT by Gerhard Mutz
* Add command ``Buzzer`` with optional parameters <number of beeps>,<duration of beep in 100mS steps>,<duration of silence in 100mS steps> enabled when a buzzer is configured (#5988)
* Add command ``DimmerRange`` in Light module to support 2 byte dimming ranges from Tuya
* Add command ``DisplayHeight`` to set pixel height on supported devices
* Add command ``DisplayWidth`` to set pixel width on supported devices
* Add command ``EnergyReset4 x,x`` to initialize total usage for two tarrifs
* Add command ``EnergyReset5 x,x`` to initialize total export (or production) for two tarrifs
* Add command ``Gpio 255/All`` to show physical GPIO configuration of all non-flash pins (#6407)
* Add command ``Gpios 255/All`` to show all available GPIO components (#6407)
* Add command ``ModuleAddress 1/2/3`` to set Pzem module address when a single module is connected (#2315)
* Add command ``MqttLog <loglevel>`` for support of MQTT logging (#6498)
* Add command ``Power0 0/1/2/Off/On/Toggle`` to control all power outputs at once (#6340)
* Add command ``PowerDelta 101..32000`` for absolute power delta where 101 = 101-100 = 1W, 202 = 202-100 = 102W (#5901)
* Add command ``Reset 99`` to reset bootcount to zero (#684, #6351)
* Add command ``Sensor29 pin,0/1/2`` for OFF/ON/TOGGLE
* Add command ``Sensor34 8,0`` and ``Sensor34 8,1`` to disable/enable JSON message on weight change over 4 gram
* Add command ``SetOption34 0..255`` to set backlog delay. Default value is 200 (mSeconds) (#6562)
* Add command ``SetOption42 0..255`` to set overtemperature (Celsius only) threshold resulting in power off all on energy monitoring devices. Default setting is 90 (#6036)
* Add command ``SetOption65 0/1`` to disable (1) fast power cycle detection fixing unwanted brownout trigger
* Add command ``SetOption67 0/1`` to disable or enable a buzzer as used in iFan03
* Add command ``SetOption68 0/1`` to enable multi-channel PWM instead of a single light (#6134)
* Add command ``SetOption71 0/1`` to switch between different Modbus Active Energy registers on DDS238-2 energy meters (#6531)
* Add command ``SetOption72 0/1`` to switch between software (0) or hardware (1) energy total counter (#6561)
* Add command ``Time`` to disable NTP and set UTC time as Epoch value if above 1451602800 (=20160101). ``Time 0`` re-enables NTP (#5279)
* Add command ``Time 1/2/3`` to select JSON time format ISO + Epoch, ISO or Epoch
* Add command ``Tariff`` to default to 0 (=disabled) and allowing to set both Standard Time (ST) and Daylight Savings Time (DST) start hour
ex. ``Tariff1 22,23`` = Tariff1 (Off-Peak) ST,DST ``Tariff2 6,7`` = Tariff2 (Standard) ST,DST ``Tariff9 0/1`` = Weekend toggle (1 = Off-Peak during weekend)
* Add command ``WebSensor<sensor number> 0/1`` to control display of sensor data in web GUI (#6085)
* Add command ``ZigbeeRead`` (#6095)
* Add define **USE_DEEPSLEEP** and command ``DeepSleepTime 0 or 10..86400`` (seconds) to enter deepsleep mode (#6638)
* Add define **USE_ENERGY_MARGIN_DETECTION** to disable Energy Margin and Power Limit detection
* Add define **USE_ENERGY_POWER_LIMIT** to disable Energy Power Limit detection while Energy Margin detection is active
* Add define **USE_SONOFF_RF** to enable/disable Sonoff Rf support (#6648)
* Add define **USE_WS2812_HARDWARE** to select hardware type WS2812, WS2812X, WS2813, SK6812, LC8812 or APA106 (DMA mode only)
* Add incremental beeps to Ifan03 remote control fan speed buttons (#6636)
* Add rule support after every command execution like Fanspeed#Data=2 (#6636)
* Add WebUI for multiple, independent PWM channels
* Add JSON array index support to rules evaluation allowing trigger on ENERGY#POWER[2]>0.60 from JSON ..,"Power":[0.00,0.68],.. (#6160)
* Add Full support of all protocols in IRremoteESP8266, to be used on dedicated-IR Tasmota version. Warning: +81k Flash when compiling with **USE_IR_REMOTE_FULL**
* Add 'sonoff-ir' pre-packaged IR-dedicated firmware and 'sonoff-ircustom' to customize firmware with IR Full protocol support
* Add Tuya Energy monitoring by Shantur Rathore
* Add Domoticz P1 Smart Meter support using energy sensors handled by xdrv_03_energy.ino based on an idea by pablozg
* Add debug compile features using defines **DEBUG_TASMOTA_CORE**, **DEBUG_TASMOTA_DRIVER** and **DEBUG_TASMOTA_SENSOR**.
See **DEBUG_CORE_LOG** example in sonoff.ino and **DEBUG_DRIVER_LOG** example in xdrv_09_timers.ino
* Add option 0 to ``Width1`` (Marker), ``Width2`` (Second), ``Width3`` (Minute) and ``Width4`` (Hour) disabling display (#6152)
* Add MqttCount metric to STATE (#6155)
* Add allow repeat/longpress for IRSend raw, introduced ``IRSend<r>`` option (#6074)
* Add Oled reset GPIO option "OLED reset"
* Add blend RGB leds with White leds for better whites (#5895, #5704)
* Add AZ7798 automatic setting of clock display (#6034)
* Add Epoch and UptimeSec to JSON messages (#6068)
### Version 7.1.0 Betty
- Remove update support for versions before 6.0
- Remove driver xsns_12_ads1115_i2cdev replaced by xsns_12_ads1115
- Remove most IR protocols from non dedicated IR firmware except NEC, RC5 and RC6
- Change repository name from Sonoff-Tasmota to Tasmota and all code references from Sonoff to Tasmota
- Change documentation from wiki to [documentation repository](https://tasmota.github.io/docs/) by @Blakadder
- Change default GUI to dark theme
- Change ArduinoSlave to TasmotaSlave
- Change IRremoteESP8266 library to v2.7.1
- Change supported PCF8574 I2C address range to 0x20 - 0x26 allowing other I2C devices with address 0x27 to be used at the same time
- Change supported PCF8574A I2C address range to 0x39 - 0x3F allowing other I2C devices with address 0x38 to be used at the same time
- Change supported MCP230xx I2C address range to 0x20 - 0x26 allowing other I2C devices with address 0x27 to be used at the same time
- Change Reset erase end address from as seen by SDK (getFlashChipSize) to full flash size (getFlashChipRealSize)
- Change new Fade system much smoother, Speed now up to 40 (#6942, #3714)
- Fix better control of RGB/White when ``SetOption37`` >128, added ``Dimmer1`` and ``Dimmer2`` commands (#6714)
- Fix random crash caused by UPNP flood
- Fix check deepsleep for valid values in Settings (#6961)
- Fix Wifi instability when light is on, due to ``Sleep 0`` (#6961, #6608)
- Fix auto-power on/off when setting channel to non-zero or zero value, when ``SetOption68 1``
- Fix postpone saving settings to flash until Fade is complete, avoids pause in Fade
- Add support for Tuya battery powered devices (#6735)
- Add support for Honeywell I2C HIH series Humidity and Temperetaure sensor (#6808)
- Add support for Honeywell HPMA115S0 particle concentration sensor by David Hunt (#6843)
- Add support for I2C sensor TLS2591 Light Intensity sensor (#6873)
- Add command ``SetOption73 0/1`` to re-enable HTTP Cross-Origin Resource Sharing (CORS) now default disabled (#6767)
- Add command ``SetOption74 0/1`` to enable DS18x20 internal pull-up and remove define DS18B20_INTERNAL_PULLUP (#6795)
- Add command ``SetOption75 0/1`` to switch between grouptopic (0) using fulltopic replacing %topic% or (1) is cmnd/\<grouptopic\> (#6779)
- Add command ``SetOption76 0/1`` to enable incrementing bootcount when deepsleep is enabled (#6930)
- Add command ``SetOption77 0/1`` to keep power on when slider is far left
- Add command ``I2cDriver`` for I2C driver runtime control using document I2CDEVICES.md
- Add command ``TempOffset -12.6 .. 12.6`` to set global temperature sensor offset (#6958)
- Add command ``WebColor19`` to control color of Module and Name (#6811)
- Add command ``WifiPower 0 .. 20.5`` to set Wifi Output Power which will be default set to 17dBm
- Add frequency to ADE7953 energy monitor as used in Shelly 2.5 by ljakob (#6778)
- Add hide Alexa objects with friendlyname starting with '$' (#6722, #6762)
- Add Zigbee command support, considered as v1.0 for full Zigbee support
- Add hardware detection to be overruled with ``SetOption51`` (#6969)
- Add Colorpicker to WebUI by Christian Staars (#6984)

View File

@ -1,25 +0,0 @@
<img src="/tools/logo/TASMOTA_FullLogo_Vector.svg" alt="Logo" align="right" height="76"/>
# Support
If you're looking for support on **Sonoff-Tasmota** there are some options available:
## Documentation:
* [Wiki Pages](https://github.com/arendst/Sonoff-Tasmota/wiki): For information on how to Flash Tasmota, configure and use it.
* [FAQ](https://github.com/arendst/Sonoff-Tasmota/wiki/FAQ): For information on common problems and solutions.
* [Troubleshooting Information](https://github.com/arendst/Sonoff-Tasmota/wiki/Troubleshooting): For ways to debug and troubleshoot.
* [Commands Information](https://github.com/arendst/Sonoff-Tasmota/wiki/Commands): For information on all the commands supported by Tasmota.
## Support's Community:
* [Tasmota Forum](https://groups.google.com/d/forum/sonoffusers): For usage and discussions.
* [Tasmota Support Chat](https://discord.gg/Ks2Kzd4): For support, troubleshooting and general questions. You have better chances to get fast answers from members of the Tasmota Community.
* [Search in Issues](https://github.com/arendst/Sonoff-Tasmota/issues): You might find an answer to your question by searching current or closed issues.
## Developers' Community:
* [Bug Report](https://github.com/arendst/Sonoff-Tasmota/issues/new?template=Bug_report.md): For reporting Bugs of Tasmota Software.
* [Feature Request](https://github.com/arendst/Sonoff-Tasmota/issues/new?template=Feature_request.md): For requesting features/functions to Tasmota Software.
* [Troubleshooting](https://github.com/arendst/Sonoff-Tasmota/issues/new?template=Custom.md): As a last resort, you can open new *Troubleshooting* issue on GitHub if the solution could not be found using the other channels. Just remember: the more info you provide the more chances you'll have to get an accurate answer.
* [Issue a question](https://github.com/arendst/Sonoff-Tasmota/issues/new/choose): As a last resort, you can open a new *Question* issue on GitHub if the answer could not be found using the other channels. Just remember: the more info you provide the more chances you'll have to get an accurate answer.

File diff suppressed because it is too large Load Diff

View File

@ -1,157 +0,0 @@
# ESP8266 platform
# ------------------------------
# For more info:
# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification
name=ESP8266 Boards (2.5.2)
version=2.5.2
# These will be removed by the packager script when doing a JSON release
runtime.tools.signing={runtime.platform.path}/tools/signing.py
runtime.tools.elf2bin={runtime.platform.path}/tools/elf2bin.py
runtime.tools.makecorever={runtime.platform.path}/tools/makecorever.py
runtime.tools.eboot={runtime.platform.path}/bootloaders/eboot/eboot.elf
compiler.warning_flags=-w
compiler.warning_flags.none=-w
compiler.warning_flags.default=
compiler.warning_flags.more=-Wall
compiler.warning_flags.all=-Wall -Wextra
build.lwip_lib=-llwip_gcc
build.lwip_include=lwip/include
build.lwip_flags=-DLWIP_OPEN_SRC
build.vtable_flags=-DVTABLES_IN_FLASH
build.sslflags=
build.exception_flags=-fno-exceptions
build.stdcpp_lib=-lstdc++
#build.float=-u _printf_float -u _scanf_float
build.float=
build.led=
build.sdk=NONOSDK221
compiler.path={runtime.tools.xtensa-lx106-elf-gcc.path}/bin/
compiler.sdk.path={runtime.platform.path}/tools/sdk
compiler.libc.path={runtime.platform.path}/tools/sdk/libc/xtensa-lx106-elf
compiler.cpreprocessor.flags=-D__ets__ -DICACHE_FLASH -U__STRICT_ANSI__ "-I{compiler.sdk.path}/include" "-I{compiler.sdk.path}/{build.lwip_include}" "-I{compiler.libc.path}/include" "-I{build.path}/core"
compiler.c.cmd=xtensa-lx106-elf-gcc
compiler.c.flags=-c {compiler.warning_flags} -Os -g -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -falign-functions=4 -MMD -std=gnu99 -ffunction-sections -fdata-sections {build.exception_flags} {build.sslflags}
compiler.S.cmd=xtensa-lx106-elf-gcc
compiler.S.flags=-c -g -x assembler-with-cpp -MMD -mlongcalls
compiler.c.elf.flags=-g {compiler.warning_flags} -Os -nostdlib -Wl,--no-check-sections -u app_entry {build.float} -Wl,-static "-L{compiler.sdk.path}/lib" "-L{compiler.sdk.path}/lib/{build.sdk}" "-L{compiler.sdk.path}/ld" "-L{compiler.libc.path}/lib" "-T{build.flash_ld}" -Wl,--gc-sections -Wl,-wrap,system_restart_local -Wl,-wrap,spi_flash_read
compiler.c.elf.cmd=xtensa-lx106-elf-gcc
compiler.c.elf.libs=-lhal -lphy -lpp -lnet80211 {build.lwip_lib} -lwpa -lcrypto -lmain -lwps -lbearssl -laxtls -lespnow -lsmartconfig -lairkiss -lwpa2 {build.stdcpp_lib} -lm -lc -lgcc
compiler.cpp.cmd=xtensa-lx106-elf-g++
compiler.cpp.flags=-c {compiler.warning_flags} -Os -g -mlongcalls -mtext-section-literals -fno-rtti -falign-functions=4 -std=c++11 -MMD -ffunction-sections -fdata-sections {build.exception_flags} {build.sslflags}
compiler.as.cmd=xtensa-lx106-elf-as
compiler.ar.cmd=xtensa-lx106-elf-ar
compiler.ar.flags=cru
compiler.elf2hex.cmd=esptool
compiler.elf2hex.flags=
compiler.size.cmd=xtensa-lx106-elf-size
# This can be overriden in boards.txt
build.extra_flags=-DESP8266
# These can be overridden in platform.local.txt
compiler.c.extra_flags=
compiler.c.elf.extra_flags=
compiler.S.extra_flags=
compiler.cpp.extra_flags=
compiler.ar.extra_flags=
compiler.objcopy.eep.extra_flags=
compiler.elf2hex.extra_flags=
## generate file with git version number
## needs bash, git, and echo
recipe.hooks.core.prebuild.1.pattern="{runtime.tools.python.path}/python" "{runtime.tools.signing}" --mode header --publickey "{build.source.path}/public.key" --out "{build.path}/core/Updater_Signing.h"
## Build the app.ld linker file
recipe.hooks.linking.prelink.1.pattern="{compiler.path}{compiler.c.cmd}" -CC -E -P {build.vtable_flags} "{runtime.platform.path}/tools/sdk/ld/eagle.app.v6.common.ld.h" -o "{build.path}/local.eagle.app.v6.common.ld"
## Compile c files
recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.cpreprocessor.flags} {compiler.c.flags} -D{build.sdk}=1 -DF_CPU={build.f_cpu} {build.lwip_flags} {build.debug_port} {build.debug_level} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -DARDUINO_BOARD="{build.board}" {build.led} {build.flash_flags} {compiler.c.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"
## Compile c++ files
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpreprocessor.flags} {compiler.cpp.flags} -D{build.sdk}=1 -DF_CPU={build.f_cpu} {build.lwip_flags} {build.debug_port} {build.debug_level} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -DARDUINO_BOARD="{build.board}" {build.led} {build.flash_flags} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"
## Compile S files
recipe.S.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.cpreprocessor.flags} {compiler.S.flags} -D{build.sdk}=1 -DF_CPU={build.f_cpu} {build.lwip_flags} {build.debug_port} {build.debug_level} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -DARDUINO_BOARD="{build.board}" {build.led} {build.flash_flags} {compiler.c.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"
## Create archives
recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}"
## Combine gc-sections, archives, and objects
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {build.exception_flags} -Wl,-Map "-Wl,{build.path}/{build.project_name}.map" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" -Wl,--start-group {object_files} "{archive_file_path}" {compiler.c.elf.libs} -Wl,--end-group "-L{build.path}"
## Create eeprom
recipe.objcopy.eep.pattern=
## Create hex
recipe.objcopy.hex.1.pattern="{runtime.tools.python.path}/python" "{runtime.tools.elf2bin}" --eboot "{runtime.tools.eboot}" --app "{build.path}/{build.project_name}.elf" --flash_mode {build.flash_mode} --flash_freq {build.flash_freq} --flash_size {build.flash_size} --path "{runtime.tools.xtensa-lx106-elf-gcc.path}/bin" --out "{build.path}/{build.project_name}.bin"
recipe.objcopy.hex.2.pattern="{runtime.tools.python.path}/python" "{runtime.tools.signing}" --mode sign --privatekey "{build.source.path}/private.key" --bin "{build.path}/{build.project_name}.bin" --out "{build.path}/{build.project_name}.bin.signed"
## Save hex
recipe.output.tmp_file={build.project_name}.bin
recipe.output.save_file={build.project_name}.{build.variant}.bin
## Compute size
recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf"
recipe.size.regex=^(?:\.irom0\.text|\.text|\.text1|\.data|\.rodata|)\s+([0-9]+).*
recipe.size.regex.data=^(?:\.data|\.rodata|\.bss)\s+([0-9]+).*
#recipe.size.regex.eeprom=^(?:\.eeprom)\s+([0-9]+).*
# ------------------------------
tools.esptool.path=
# Because the variable expansion doesn't allow one tool to find another, the following lines
# will point to "{runtime.platform.path}/tools/python/python" in GIT and
# "{runtime.tools.python.path}/python" for JSON board manager releases.
tools.esptool.cmd={runtime.tools.python.path}/python
tools.esptool.network_cmd={runtime.tools.python.path}/python
tools.esptool.upload.protocol=esp
tools.esptool.upload.params.verbose=--trace
tools.esptool.upload.params.quiet=
# First, potentially perform an erase or nothing
# Next, do the binary upload
# Combined in one rule because Arduino doesn't suport upload.1.pattern/upload.3.pattern
tools.esptool.upload.pattern="{cmd}" "{runtime.platform.path}/tools/upload.py" --chip esp8266 --port "{serial.port}" --baud "{upload.speed}" "{upload.verbose}" {upload.erase_cmd} --end --chip esp8266 --port "{serial.port}" --baud "{upload.speed}" "{upload.verbose}" write_flash 0x0 "{build.path}/{build.project_name}.bin" --end
tools.esptool.upload.network_pattern="{network_cmd}" "{runtime.platform.path}/tools/espota.py" -i "{serial.port}" -p "{network.port}" "--auth={network.password}" -f "{build.path}/{build.project_name}.bin"
tools.mkspiffs.cmd=mkspiffs
tools.mkspiffs.cmd.windows=mkspiffs.exe
tools.mkspiffs.path={runtime.tools.mkspiffs.path}
tools.espupload.cmd=python
tools.espupload.cmd.windows=python.exe
tools.espupload.path={runtime.platform.path}/tools
tools.espupload.upload.protocol=espupload
tools.espupload.upload.params.verbose=
tools.espupload.upload.params.quiet=
tools.espupload.upload.pattern="{cmd}" "{path}/espupload.py" -f "{build.path}/{build.project_name}.bin"

View File

@ -5,8 +5,8 @@
# For more info:
# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification
name=ESP8266 Boards (2.5.2-196-g45d71ae4)
version=2.5.2-196-g45d71ae4
name=ESP8266 Boards (2.6.1)
version=2.6.1
# These will be removed by the packager script when doing a JSON release
@ -37,10 +37,15 @@ build.exception_flags=-fno-exceptions
build.stdcpp_lib=-lstdc++
build.stdcpp_level=-std=gnu++11
# build.float=-u _printf_float -u _scanf_float
#build.float=-u _printf_float -u _scanf_float
build.float=
build.led=
build.sdk=NONOSDK22y
# default SDK for all boards
# (generic board overrides this variable)
build.sdk=NONOSDK22x_190703
#build.sdk=NONOSDK22x_191024
#build.sdk=NONOSDK22x_191105
compiler.path={runtime.tools.xtensa-lx106-elf-gcc.path}/bin/
compiler.sdk.path={runtime.platform.path}/tools/sdk
@ -88,7 +93,7 @@ compiler.elf2hex.extra_flags=
## needs git
recipe.hooks.sketch.prebuild.pattern="{runtime.tools.python3.path}/python3" "{runtime.tools.signing}" --mode header --publickey "{build.source.path}/public.key" --out "{build.path}/core/Updater_Signing.h"
# This is quite a working hack. This form of prebuild hook, while intuitive, is not explicitly documented.
recipe.hooks.prebuild.10.pattern="{runtime.tools.python3.path}/python3" "{runtime.tools.makecorever}" --build_path "{build.path}" --platform_path "{runtime.platform.path}" --version "unix-{version}"
## Build the app.ld linker file
recipe.hooks.linking.prelink.1.pattern="{compiler.path}{compiler.c.cmd}" -CC -E -P {build.vtable_flags} "{runtime.platform.path}/tools/sdk/ld/eagle.app.v6.common.ld.h" -o "{build.path}/local.eagle.app.v6.common.ld"
@ -145,7 +150,7 @@ tools.esptool.upload.params.quiet=
# First, potentially perform an erase or nothing
# Next, do the binary upload
# Combined in one rule because Arduino doesn't suport upload.1.pattern/upload.3.pattern
tools.esptool.upload.pattern="{cmd}" "{runtime.platform.path}/tools/upload.py" --chip esp8266 --port "{serial.port}" --baud "{upload.speed}" "{upload.verbose}" {upload.erase_cmd} --end --chip esp8266 --port "{serial.port}" --baud "{upload.speed}" "{upload.verbose}" write_flash 0x0 "{build.path}/{build.project_name}.bin" --end
tools.esptool.upload.pattern="{cmd}" "{runtime.platform.path}/tools/upload.py" --chip esp8266 --port "{serial.port}" --baud "{upload.speed}" "{upload.verbose}" {upload.erase_cmd} {upload.resetmethod} "{build.path}/{build.project_name}.bin"
tools.esptool.upload.network_pattern="{network_cmd}" "{runtime.platform.path}/tools/espota.py" -i "{serial.port}" -p "{network.port}" "--auth={network.password}" -f "{build.path}/{build.project_name}.bin"

View File

@ -1,24 +0,0 @@
FROM python:2
LABEL author="Eduard Angold"
# Install platformio. To be able to build tasmota <=v6.6.0 (and later)
# we have to use version 3.6.7 of platformio.
RUN pip install --upgrade pip &&\
pip install -U platformio==3.6.7
# Init project
COPY init_pio_tasmota /init_pio_tasmota
# Install project dependencies using a init project.
RUN cd /init_pio_tasmota &&\
pio run &&\
cd ../ &&\
rm -fr init_pio_tasmota &&\
cp -r /root/.platformio / &&\
chmod -R 777 /.platformio
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]

View File

@ -1,26 +0,0 @@
# Docker container for tasmota builds
This Container will setup a proper build environment for [Sonoff-Tasmota](https://github.com/arendst/Sonoff-Tasmota)
## Create container
`docker build -t mytasmota:latest .`
## Use a ready container from docker hub
Use instead of the container `mytasmota:latest` the published container `eddyhub/docker-tasmota:latest` from docker hub.
## Build all development binaries
`git clone https://github.com/arendst/Sonoff-Tasmota.git`
`docker run -ti --rm -v $(pwd)/Sonoff-Tasmota:/tasmota -u $UID:$GID mytasmota:latest`
## Build a specific binary with custom options
Checkout Sonoff-Tasmota: `git clone https://github.com/arendst/Sonoff-Tasmota.git`
Mount the source as volume in `/tasmota`. **Prefix** any parameter available in `Sonoff-Tasmota/sonoff/my_user_config.h` with `TASMOTA_` as a environment variable for the container. **Also don't forget to escape what needs to be escaped in your shell.** **Strings** should be in **double quotes**. My config example:
`docker run -ti --rm -v $(pwd)/Sonoff-Tasmota:/tasmota -e TASMOTA_STA_SSID1='"my-wifi"' -e TASMOTA_STA_PASS1='"my-wifi-password"' -e TASMOTA_MQTT_HOST='my-mqtt-host' -e TASMOTA_MQTT_USER='"my-mqtt-user"' -e TASMOTA_MQTT_PASS='"my-mqtt-password"' -e TASMOTA_WEB_PASSWORD='"my-web-password"' -u $UID:$GID mytasmota:latest --environment sonoff-DE
Now you should have the file Sonoff-Tasmota/.pioenvs/sonoff-DE/firmware.bin which can be flashed on your device.
## Build a specific version of tasmota
Checkout out the needed version before using the build instructions above:
- `git clone https://github.com/arendst/Sonoff-Tasmota.git`
- `git -C Sonoff-Tasmota checkout v6.6.0`
Build it:
- `docker run -ti --rm -v $(pwd)/Sonoff-Tasmota:/tasmota -u $UID:$GID mytasmota:latest`

View File

@ -1,35 +0,0 @@
# configure build via environment
#!/bin/bash
TASMOTA_VOLUME='/tasmota'
USER_CONFIG_OVERRIDE="${TASMOTA_VOLUME}/sonoff/user_config_override.h"
if [ -d $TASMOTA_VOLUME ]; then
cd $TASMOTA_VOLUME
if [ -n "$(env | grep ^TASMOTA_)" ]; then
echo "Removing $USER_CONFIG_OVERRIDE and creating a new one."
rm "$USER_CONFIG_OVERRIDE"
#export PLATFORMIO_BUILD_FLAGS='-DUSE_CONFIG_OVERRIDE'
sed -i 's/^; *-DUSE_CONFIG_OVERRIDE/ -DUSE_CONFIG_OVERRIDE/' platformio.ini
echo '#ifndef _USER_CONFIG_OVERRIDE_H_' >> $USER_CONFIG_OVERRIDE
echo '#define _USER_CONFIG_OVERRIDE_H_' >> $USER_CONFIG_OVERRIDE
echo '#warning **** user_config_override.h: Using Settings from this File ****' >> $USER_CONFIG_OVERRIDE
echo '#undef CFG_HOLDER' >> $USER_CONFIG_OVERRIDE
echo '#define CFG_HOLDER 1' >> $USER_CONFIG_OVERRIDE
for i in $(env | grep ^TASMOTA_); do
config=${i#TASMOTA_}
key=$(echo $config | cut -d '=' -f 1)
value=$(echo $config | cut -d '=' -f 2)
echo "#undef ${key}" >> $USER_CONFIG_OVERRIDE
echo "#define ${key} ${value}" >> $USER_CONFIG_OVERRIDE
done
echo '#endif' >> $USER_CONFIG_OVERRIDE
fi
echo "Compiling..."
#pio run -t clean
pio run $@
echo "Everything done you find your builds in .pioenvs/<build-flavour>/firmware.bin"
else
echo ">>> NO TASMOTA VOLUME MOUNTED --> EXITING"
exit 0;
fi

View File

@ -1,30 +0,0 @@
[env:core_2_3_0]
; *** Esp8266 core for Arduino version 2.3.0
platform = espressif8266@1.5.0
framework = arduino
board = esp01_1m
[env:core_2_4_2]
; *** Esp8266 core for Arduino version 2.4.2
platform = espressif8266@1.8.0
framework = arduino
board = esp01_1m
[env:core_2_5_2]
; *** Esp8266 core for Arduino version 2.5.2
platform = espressif8266@~2.2.2
framework = arduino
board = esp01_1m
[env:core_stage]
; *** Esp8266 core for Arduino version latest beta
platform = https://github.com/platformio/platform-espressif8266.git#feature/stage
framework = arduino
board = esp01_1m
[env:core_pre]
; *** Arduino Esp8266 core pre 2.6.x for Tasmota (mqtt reconnects fixed)
platform = https://github.com/Jason2866/platform-espressif8266.git#Tasmota
framework = arduino
board = esp01_1m

View File

@ -1,3 +0,0 @@
#include <Arduino.h>
void setup() {}
void loop() {}

View File

@ -563,6 +563,13 @@ boolean Adafruit_SSD1306::begin(uint8_t vcs, uint8_t addr, boolean reset,
SSD1306_SETCONTRAST }; // 0x81
ssd1306_commandList(init4c, sizeof(init4c));
ssd1306_command1((vccstate == SSD1306_EXTERNALVCC) ? 0x10 : 0xAF);
} else if((WIDTH == 64) && (HEIGHT == 48)) {
static const uint8_t PROGMEM init4d[] = {
SSD1306_SETCOMPINS, // 0xDA
0x12,
SSD1306_SETCONTRAST }; // 0x81
ssd1306_commandList(init4d, sizeof(init4d));
ssd1306_command1((vccstate == SSD1306_EXTERNALVCC) ? 0x9F : 0xCF);
} else {
// Other screen varieties -- TBD
}

View File

@ -0,0 +1,464 @@
/**************************************************************************/
/*!
@file Adafruit_TSL2591.cpp
@author KT0WN (adafruit.com)
This is a library for the Adafruit TSL2591 breakout board
This library works with the Adafruit TSL2591 breakout
----> https://www.adafruit.com/products/1980
Check out the links above for our tutorials and wiring diagrams
These chips use I2C to communicate
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
@section LICENSE
Software License Agreement (BSD License)
Copyright (c) 2014 Adafruit Industries
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**************************************************************************/
#if defined(ESP8266) || defined(ESP32)
#include <pgmspace.h>
#else
#include <avr/pgmspace.h>
#endif
#if defined(__AVR__)
#include <util/delay.h>
#endif
#include <stdlib.h>
#include "Adafruit_TSL2591.h"
#define TSL2591_VISIBLE (2) ///< (channel 0) - (channel 1)
#define TSL2591_INFRARED (1) ///< channel 1
#define TSL2591_FULLSPECTRUM (0) ///< channel 0
#define TSL2591_ADDR (0x29) ///< Default I2C address
#define TSL2591_COMMAND_BIT (0xA0) ///< 1010 0000: bits 7 and 5 for 'command normal'
///! Special Function Command for "Clear ALS and no persist ALS interrupt"
#define TSL2591_CLEAR_INT (0xE7)
///! Special Function Command for "Interrupt set - forces an interrupt"
#define TSL2591_TEST_INT (0xE4)
#define TSL2591_WORD_BIT (0x20) ///< 1 = read/write word (rather than byte)
#define TSL2591_BLOCK_BIT (0x10) ///< 1 = using block read/write
#define TSL2591_ENABLE_POWEROFF (0x00) ///< Flag for ENABLE register to disable
#define TSL2591_ENABLE_POWERON (0x01) ///< Flag for ENABLE register to enable
#define TSL2591_ENABLE_AEN (0x02) ///< ALS Enable. This field activates ALS function. Writing a one activates the ALS. Writing a zero disables the ALS.
#define TSL2591_ENABLE_AIEN (0x10) ///< ALS Interrupt Enable. When asserted permits ALS interrupts to be generated, subject to the persist filter.
#define TSL2591_ENABLE_NPIEN (0x80) ///< No Persist Interrupt Enable. When asserted NP Threshold conditions will generate an interrupt, bypassing the persist filter
#define TSL2591_LUX_DF (408.0F) ///< Lux cooefficient
#define TSL2591_LUX_COEFB (1.64F) ///< CH0 coefficient
#define TSL2591_LUX_COEFC (0.59F) ///< CH1 coefficient A
#define TSL2591_LUX_COEFD (0.86F) ///< CH2 coefficient B
/// TSL2591 Register map
enum
{
TSL2591_REGISTER_ENABLE = 0x00, // Enable register
TSL2591_REGISTER_CONTROL = 0x01, // Control register
TSL2591_REGISTER_THRESHOLD_AILTL = 0x04, // ALS low threshold lower byte
TSL2591_REGISTER_THRESHOLD_AILTH = 0x05, // ALS low threshold upper byte
TSL2591_REGISTER_THRESHOLD_AIHTL = 0x06, // ALS high threshold lower byte
TSL2591_REGISTER_THRESHOLD_AIHTH = 0x07, // ALS high threshold upper byte
TSL2591_REGISTER_THRESHOLD_NPAILTL = 0x08, // No Persist ALS low threshold lower byte
TSL2591_REGISTER_THRESHOLD_NPAILTH = 0x09, // No Persist ALS low threshold higher byte
TSL2591_REGISTER_THRESHOLD_NPAIHTL = 0x0A, // No Persist ALS high threshold lower byte
TSL2591_REGISTER_THRESHOLD_NPAIHTH = 0x0B, // No Persist ALS high threshold higher byte
TSL2591_REGISTER_PERSIST_FILTER = 0x0C, // Interrupt persistence filter
TSL2591_REGISTER_PACKAGE_PID = 0x11, // Package Identification
TSL2591_REGISTER_DEVICE_ID = 0x12, // Device Identification
TSL2591_REGISTER_DEVICE_STATUS = 0x13, // Internal Status
TSL2591_REGISTER_CHAN0_LOW = 0x14, // Channel 0 data, low byte
TSL2591_REGISTER_CHAN0_HIGH = 0x15, // Channel 0 data, high byte
TSL2591_REGISTER_CHAN1_LOW = 0x16, // Channel 1 data, low byte
TSL2591_REGISTER_CHAN1_HIGH = 0x17, // Channel 1 data, high byte
};
/**************************************************************************/
/*!
@brief Instantiates a new Adafruit TSL2591 class
*/
/**************************************************************************/
Adafruit_TSL2591::Adafruit_TSL2591()
{
_initialized = false;
_integration = TSL2591_INTEGRATIONTIME_100MS;
_gain = TSL2591_GAIN_MED;
// we cant do wire initialization till later, because we havent loaded Wire yet
}
/**************************************************************************/
/*!
@brief Setups the I2C interface and hardware, identifies if chip is found
@returns True if a TSL2591 is found, false on any failure
*/
/**************************************************************************/
boolean Adafruit_TSL2591::begin(void)
{
Wire.begin();
/*
for (uint8_t i=0; i<0x20; i++)
{
uint8_t id = read8(0x12);
Serial.print("$"); Serial.print(i, HEX);
Serial.print(" = 0x"); Serial.println(read8(i), HEX);
}
*/
uint8_t id = read8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_DEVICE_ID);
if (id != 0x50 ) {
return false;
}
// Serial.println("Found Adafruit_TSL2591");
_initialized = true;
// Set default integration time and gain
setTiming(_integration);
setGain(_gain);
// Note: by default, the device is in power down mode on bootup
disable();
return true;
}
/**************************************************************************/
/*!
@brief Enables the chip, so it's ready to take readings
*/
/**************************************************************************/
void Adafruit_TSL2591::enable(void)
{
if (!_initialized)
{
if (!begin())
{
return;
}
}
// Enable the device by setting the control bit to 0x01
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_ENABLE,
TSL2591_ENABLE_POWERON | TSL2591_ENABLE_AEN | TSL2591_ENABLE_AIEN | TSL2591_ENABLE_NPIEN);
}
/**************************************************************************/
/*!
@brief Disables the chip, so it's in power down mode
*/
/**************************************************************************/
void Adafruit_TSL2591::disable(void)
{
if (!_initialized) {
if (!begin()) {
return;
}
}
// Disable the device by setting the control bit to 0x00
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_ENABLE, TSL2591_ENABLE_POWEROFF);
}
/************************************************************************/
/*!
@brief Setter for sensor light gain
@param gain {@link tsl2591Gain_t} gain value
*/
/**************************************************************************/
void Adafruit_TSL2591::setGain(tsl2591Gain_t gain)
{
if (!_initialized) {
if (!begin()) {
return;
}
}
enable();
_gain = gain;
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CONTROL, _integration | _gain);
disable();
}
/************************************************************************/
/*!
@brief Getter for sensor light gain
@returns {@link tsl2591Gain_t} gain value
*/
/**************************************************************************/
tsl2591Gain_t Adafruit_TSL2591::getGain()
{
return _gain;
}
/************************************************************************/
/*!
@brief Setter for sensor integration time setting
@param integration {@link tsl2591IntegrationTime_t} integration time setting
*/
/**************************************************************************/
void Adafruit_TSL2591::setTiming(tsl2591IntegrationTime_t integration)
{
if (!_initialized) {
if (!begin()) {
return;
}
}
enable();
_integration = integration;
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CONTROL, _integration | _gain);
disable();
}
/************************************************************************/
/*!
@brief Getter for sensor integration time setting
@returns {@link tsl2591IntegrationTime_t} integration time
*/
/**************************************************************************/
tsl2591IntegrationTime_t Adafruit_TSL2591::getTiming()
{
return _integration;
}
/************************************************************************/
/*!
@brief Calculates the visible Lux based on the two light sensors
@param ch0 Data from channel 0 (IR+Visible)
@param ch1 Data from channel 1 (IR)
@returns Lux, based on AMS coefficients (or < 0 if overflow)
*/
/**************************************************************************/
float Adafruit_TSL2591::calculateLux(uint16_t ch0, uint16_t ch1)
{
float atime, again;
float cpl, lux1, lux2, lux;
uint32_t chan0, chan1;
// Check for overflow conditions first
if ((ch0 == 0xFFFF) | (ch1 == 0xFFFF))
{
// Signal an overflow
return -1;
}
// Note: This algorithm is based on preliminary coefficients
// provided by AMS and may need to be updated in the future
switch (_integration)
{
case TSL2591_INTEGRATIONTIME_100MS :
atime = 100.0F;
break;
case TSL2591_INTEGRATIONTIME_200MS :
atime = 200.0F;
break;
case TSL2591_INTEGRATIONTIME_300MS :
atime = 300.0F;
break;
case TSL2591_INTEGRATIONTIME_400MS :
atime = 400.0F;
break;
case TSL2591_INTEGRATIONTIME_500MS :
atime = 500.0F;
break;
case TSL2591_INTEGRATIONTIME_600MS :
atime = 600.0F;
break;
default: // 100ms
atime = 100.0F;
break;
}
switch (_gain)
{
case TSL2591_GAIN_LOW :
again = 1.0F;
break;
case TSL2591_GAIN_MED :
again = 25.0F;
break;
case TSL2591_GAIN_HIGH :
again = 428.0F;
break;
case TSL2591_GAIN_MAX :
again = 9876.0F;
break;
default:
again = 1.0F;
break;
}
// cpl = (ATIME * AGAIN) / DF
cpl = (atime * again) / TSL2591_LUX_DF;
// Original lux calculation (for reference sake)
//lux1 = ( (float)ch0 - (TSL2591_LUX_COEFB * (float)ch1) ) / cpl;
//lux2 = ( ( TSL2591_LUX_COEFC * (float)ch0 ) - ( TSL2591_LUX_COEFD * (float)ch1 ) ) / cpl;
//lux = lux1 > lux2 ? lux1 : lux2;
// Alternate lux calculation 1
// See: https://github.com/adafruit/Adafruit_TSL2591_Library/issues/14
lux = ( ((float)ch0 - (float)ch1 )) * (1.0F - ((float)ch1/(float)ch0) ) / cpl;
// Alternate lux calculation 2
//lux = ( (float)ch0 - ( 1.7F * (float)ch1 ) ) / cpl;
// Signal I2C had no errors
return lux;
}
/************************************************************************/
/*!
@brief Reads the raw data from both light channels
@returns 32-bit raw count where high word is IR, low word is IR+Visible
*/
/**************************************************************************/
uint32_t Adafruit_TSL2591::getFullLuminosity (void)
{
if (!_initialized) {
if (!begin()) {
return 0;
}
}
// Enable the device
enable();
// Wait x ms for ADC to complete
for (uint8_t d=0; d<=_integration; d++)
{
delay(120);
}
// CHAN0 must be read before CHAN1
// See: https://forums.adafruit.com/viewtopic.php?f=19&t=124176
uint32_t x;
uint16_t y;
y = read16(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN0_LOW);
x = read16(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN1_LOW);
x <<= 16;
x |= y;
disable();
return x;
}
/************************************************************************/
/*!
@brief Reads the raw data from the channel
@param channel Can be 0 (IR+Visible, 1 (IR) or 2 (Visible only)
@returns 16-bit raw count, or 0 if channel is invalid
*/
/**************************************************************************/
uint16_t Adafruit_TSL2591::getLuminosity (uint8_t channel)
{
uint32_t x = getFullLuminosity();
if (channel == TSL2591_FULLSPECTRUM)
{
// Reads two byte value from channel 0 (visible + infrared)
return (x & 0xFFFF);
}
else if (channel == TSL2591_INFRARED)
{
// Reads two byte value from channel 1 (infrared)
return (x >> 16);
}
else if (channel == TSL2591_VISIBLE)
{
// Reads all and subtracts out just the visible!
return ( (x & 0xFFFF) - (x >> 16));
}
// unknown channel!
return 0;
}
uint8_t Adafruit_TSL2591::read8(uint8_t reg)
{
uint8_t x;
Wire.beginTransmission(TSL2591_ADDR);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(TSL2591_ADDR, 1);
x = Wire.read();
return x;
}
uint16_t Adafruit_TSL2591::read16(uint8_t reg)
{
uint16_t x;
uint16_t t;
Wire.beginTransmission(TSL2591_ADDR);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(TSL2591_ADDR, 2);
t = Wire.read();
x = Wire.read();
x <<= 8;
x |= t;
return x;
}
void Adafruit_TSL2591::write8 (uint8_t reg, uint8_t value)
{
Wire.beginTransmission(TSL2591_ADDR);
Wire.write(reg);
Wire.write(value);
Wire.endTransmission();
}
void Adafruit_TSL2591::write8 (uint8_t reg)
{
Wire.beginTransmission(TSL2591_ADDR);
Wire.write(reg);
Wire.endTransmission();
}

View File

@ -0,0 +1,86 @@
/**************************************************************************/
/*!
@file Adafruit_TSL2591.h
@author KT0WN (adafruit.com)
This is a library for the Adafruit TSL2591 breakout board
This library works with the Adafruit TSL2591 breakout
----> https://www.adafruit.com/products/1980
Check out the links above for our tutorials and wiring diagrams
These chips use I2C to communicate
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
*/
/**************************************************************************/
#ifndef _TSL2591_H_
#define _TSL2591_H_
#if ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
#include <Wire.h>
/// Enumeration for the sensor integration timing
typedef enum
{
TSL2591_INTEGRATIONTIME_100MS = 0x00, // 100 millis
TSL2591_INTEGRATIONTIME_200MS = 0x01, // 200 millis
TSL2591_INTEGRATIONTIME_300MS = 0x02, // 300 millis
TSL2591_INTEGRATIONTIME_400MS = 0x03, // 400 millis
TSL2591_INTEGRATIONTIME_500MS = 0x04, // 500 millis
TSL2591_INTEGRATIONTIME_600MS = 0x05, // 600 millis
}
tsl2591IntegrationTime_t;
/// Enumeration for the sensor gain
typedef enum
{
TSL2591_GAIN_LOW = 0x00, /// low gain (1x)
TSL2591_GAIN_MED = 0x10, /// medium gain (25x)
TSL2591_GAIN_HIGH = 0x20, /// medium gain (428x)
TSL2591_GAIN_MAX = 0x30, /// max gain (9876x)
}
tsl2591Gain_t;
/**************************************************************************/
/*!
@brief Class that stores state and functions for interacting with TSL2591 Light Sensor
*/
/**************************************************************************/
class Adafruit_TSL2591
{
public:
Adafruit_TSL2591();
boolean begin ( void );
void enable ( void );
void disable ( void );
float calculateLux ( uint16_t ch0, uint16_t ch1 );
void setGain ( tsl2591Gain_t gain );
void setTiming ( tsl2591IntegrationTime_t integration );
uint16_t getLuminosity (uint8_t channel );
uint32_t getFullLuminosity ( );
tsl2591IntegrationTime_t getTiming();
tsl2591Gain_t getGain();
private:
void write8 ( uint8_t r);
void write8 ( uint8_t r, uint8_t v );
uint16_t read16 ( uint8_t reg );
uint8_t read8 ( uint8_t reg );
tsl2591IntegrationTime_t _integration;
tsl2591Gain_t _gain;
boolean _initialized;
};
#endif

View File

@ -1,3 +0,0 @@
# ArduinoHexParse
Parse hex files created by Arduino for Uno/Mini/Nano

View File

@ -1,25 +0,0 @@
#######################################
# Syntax Coloring Map for ArduinoHexParse
# (esp8266)
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
ArduinoHexParse KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
ArduinoHexParse KEYWORD2
ParseLine KEYWORD2
GetFlashPage KEYWORD2
GetLoadAddress KEYWORD2
IsFlashPageReady KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################

View File

@ -1,12 +0,0 @@
{
"name": "ArduinoHexParse",
"version": "0.0.1",
"description": "Parse hex files created by Arduino for Uno/Mini/Nano",
"repository":
{
"type": "git",
"url": "https://github.com/arendst/Sonoff-Tasmota/lib/ArduinoHexParse"
},
"frameworks": "arduino",
"platforms": "espressif8266"
}

View File

@ -1,9 +0,0 @@
name=ArduinoHexParse
version=0.0.1
author=Andre Thomas
maintainer=Andre Thomas <andre1024@gmail.com>
sentence=Parse hex files created by Arduino for Uno/Mini/Nano
paragraph=
category=Signal Input/Output
url=
architectures=esp8266

View File

@ -1,134 +0,0 @@
/*
Copyright (C) 2019 Andre Thomas and Theo Arends
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Arduino.h>
#include "ArduinoHexParse.h"
ArduinoHexParse::ArduinoHexParse(void)
{
loadAddress[0] = 0;
loadAddress[1] = 0;
}
void ArduinoHexParse::ParseLine(byte* hexline)
{
recordType = GetRecordType(hexline);
if (0 == recordType) {
address = GetAddress(hexline);
len = GetLength(hexline);
GetData(hexline, len);
if (128 == PageMemIdx) {
if (!firstRun) {
loadAddress[1] += 0x40;
if (0 == loadAddress[1]) {
loadAddress[0] += 1;
}
}
firstRun = false;
FlashPageReady = true;
PageMemIdx = 0;
}
nextAddress = address + len;
}
if (1 == recordType) {
EndOfFile();
FlashPageReady = true;
}
}
bool ArduinoHexParse::IsFlashPageReady(void)
{
return FlashPageReady;
}
byte* ArduinoHexParse::GetFlashPage(void)
{
FlashPageReady = false;
return FlashPage;
}
byte* ArduinoHexParse::GetLoadAddress(void)
{
return loadAddress;
}
void ArduinoHexParse::GetLoadAddress(byte* hexline)
{
char buff[3];
buff[2] = '\0';
buff[0] = hexline[3];
buff[1] = hexline[4];
loadAddress[0] = strtol(buff, 0, 16);
buff[0] = hexline[5];
buff[1] = hexline[6];
loadAddress[1] = strtol(buff, 0, 16);
}
byte* ArduinoHexParse::GetData(byte* hexline, uint32_t len)
{
uint32_t start = 9;
uint32_t end = (len * 2) + start;
char buff[3];
buff[2] = '\0';
for (uint32_t x = start; x < end; x = x+2) {
buff[0] = hexline[x];
buff[1] = hexline[x+1];
FlashPage[PageMemIdx] = strtol(buff, 0, 16);
PageMemIdx++;
}
}
void ArduinoHexParse::EndOfFile(void)
{
loadAddress[1] += 0x40;
if (0 == loadAddress[1]) {
loadAddress[0] += 1;
}
while (128 > PageMemIdx) { // Fill the remaing space in the memory page with 0xFF
FlashPage[PageMemIdx] = 0xFF;
PageMemIdx++;
}
}
uint32_t ArduinoHexParse::GetAddress(byte* hexline)
{
char buff[5];
buff[0] = hexline[3];
buff[1] = hexline[4];
buff[2] = hexline[5];
buff[3] = hexline[6];
buff[4] = '\0';
return strtol(buff, 0, 16);
}
uint16_t ArduinoHexParse::GetLength(byte* hexline)
{
char buff[3];
buff[0] = hexline[1];
buff[1] = hexline[2];
buff[2] = '\0';
return strtol(buff, 0, 16);
}
uint16_t ArduinoHexParse::GetRecordType(byte* hexline)
{
char buff[3];
buff[0] = hexline[7];
buff[1] = hexline[8];
buff[2] = '\0';
return strtol(buff, 0, 16);
}

View File

@ -1,47 +0,0 @@
/*
Copyright (C) 2019 Andre Thomas and Theo Arends
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __ARDUINOHEXPARSE_H__
#include <Arduino.h>
class ArduinoHexParse {
public:
ArduinoHexParse(void);
void ParseLine(byte* data);
byte* GetFlashPage(void);
byte* GetLoadAddress(void);
bool IsFlashPageReady(void);
private:
uint32_t address = 0;
uint32_t len = 0;
uint32_t nextAddress = 0;
uint32_t PageMemIdx = 0;
uint32_t recordType = 0;
byte FlashPage[128];
byte loadAddress[2];
bool FlashPageReady = false;
bool firstRun = true;
uint32_t GetAddress(byte* hexline);
uint16_t GetLength(byte* hexline);
uint16_t GetRecordType(byte* hexline);
byte* GetData(byte* hexline, uint32_t len);
void GetLoadAddress(byte* hexline);
void EndOfFile(void);
};
#endif // __ARDUINOHEXPARSE_H__

View File

@ -3,7 +3,7 @@ version=5.13.4
author=Benoit Blanchon <blog.benoitblanchon.fr>
maintainer=Benoit Blanchon <blog.benoitblanchon.fr>
sentence=An efficient and elegant JSON library for Arduino.
paragraph=ArduinoJson supports serialization, deserialization, fixed allocation, zero-copy, streams, and more. It is the most popular Arduino library on GitHub ❤❤❤❤❤. Check out arduinojson.org for a comprehensive documentation.
paragraph=ArduinoJson supports serialization, deserialization, fixed allocation, zero-copy, streams, and more. It is the most popular Arduino library on GitHub. Check out arduinojson.org for a comprehensive documentation.
category=Data Processing
url=https://arduinojson.org/?utm_source=meta&utm_medium=library.properties
architectures=*

7
lib/HPMA115S0/LICENSE.md Normal file
View File

@ -0,0 +1,7 @@
Copyright 2017 Felix Galindo
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

2
lib/HPMA115S0/README.md Normal file
View File

@ -0,0 +1,2 @@
# HPMA115S0
Library for Honeywell's Particle Sensor (HPMA115S0-XXX)

View File

@ -0,0 +1,34 @@
/**
* @file example.ino
* @author Felix Galindo
* @date June 2017
* @brief Example using HPMA115S0 sensor library on a Feather 32u4
* @license MIT
*/
#include <hpma115S0.h>
#include <SoftwareSerial.h>
//Create an instance of software serial
SoftwareSerial hpmaSerial(10, 11); // Feather TX, Feather RX
//Create an instance of the hpma115S0 library
HPMA115S0 hpma115S0(hpmaSerial);
void setup() {
Serial.begin(57600);
hpmaSerial.begin(9600);
delay(5000);
Serial.println("Starting...");
hpma115S0.Init();
hpma115S0.StartParticleMeasurement();
}
void loop() {
unsigned int pm2_5, pm10;
if (hpma115S0.ReadParticleMeasurement(&pm2_5, &pm10)) {
Serial.println("PM 2.5: " + String(pm2_5) + " ug/m3" );
Serial.println("PM 10: " + String(pm10) + " ug/m3" );
}
delay(1000);
}

View File

@ -0,0 +1,9 @@
name=HPMA115S0 Arduino Library
version=1.0.0
author=Felix Galindo
maintainer=Felix Galindo
sentence=A library for Honeywell HPMA115S0 Particle Sensor
paragraph=Supports the HPMA115S0
category=Sensors
url=https://github.com/felixgalindo/HPMA115S0.git
architectures=*

View File

@ -0,0 +1,200 @@
/**
* @file HPMA115S0.cpp
* @author Felix Galindo
* @date June 2017
* @brief Arduino Library for Honeywell's Particle Sensor (HPMA115S0-XXX)
* @license MIT
*/
#include "Arduino.h"
#include "hpma115S0.h"
extern "C" {
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
}
/**
* @brief Constructor for HPMA115S0 class
* @param a Stream ({Software/Hardware}Serial) object.
* @note The serial stream should be already initialized
* @return void
*/
HPMA115S0::HPMA115S0(Stream& serial):
_serial(serial)
{
_serial.setTimeout(100);
}
/**
* @brief Function that initializes sensor
* @return a String containing sensor response
*/
void HPMA115S0::Init() {
//Serial.println("PS- Initializing...");
delay(100);
StartParticleMeasurement();
delay(100);
DisableAutoSend();
}
/**
* @brief Function that sends serial command to sensor
* @param a unsigned char * containing the command
* @param size of buffer
* @return void
*/
void HPMA115S0::SendCmd(const char * cmdBuf, unsigned int cmdSize) {
//Clear RX
while (_serial.available())
_serial.read();
//Send command
//Serial.print("PS- Sending cmd: ");
unsigned int index = 0;
for (index = 0; index < cmdSize; index++) {
//Serial.print(cmdBuf[index], HEX);
//Serial.print(" ");
_serial.write(cmdBuf[index]);
}
//Serial.println("");
return;
}
/**
* @brief Function that reads command response from sensor
* @param Buffer to store data in
* @param Buffer size
* @param Expected command type
* @return returns number of bytes read from sensor
*/
int HPMA115S0::ReadCmdResp(unsigned char * dataBuf, unsigned int dataBufSize, unsigned int cmdType) {
static unsigned char respBuf[HPM_MAX_RESP_SIZE];
static unsigned int respIdx = 0;
static unsigned int calChecksum = 0;
//Read response
respIdx = 0;
calChecksum = 0;
memset(respBuf, 0, sizeof(respBuf));
_serial.setTimeout(100);
//Serial.println("PS- Waiting for cmd resp...");
if (_serial.readStringUntil(HPM_CMD_RESP_HEAD)) {
delay(1); //wait for the rest of the bytes to arrive
respBuf[HPM_HEAD_IDX] = HPM_CMD_RESP_HEAD;
respBuf[HPM_LEN_IDX] = _serial.read(); //Read the command length
//Ensure buffers are big enough
if (respBuf[HPM_LEN_IDX] && ((respBuf[HPM_LEN_IDX] + 1) <= sizeof(respBuf) - 2) && (respBuf[HPM_LEN_IDX] - 1) <= dataBufSize ) {
if (_serial.readBytes(&respBuf[HPM_CMD_IDX], respBuf[HPM_LEN_IDX] + 1) == (respBuf[HPM_LEN_IDX] + 1)) { //read respBuf[HPM_LEN_IDX] num of bytes + calChecksum byte
if (respBuf[HPM_CMD_IDX] == cmdType) { //check if CMD type matches
//Calculate and validate checksum
for (respIdx = 0; respIdx < (2 + respBuf[HPM_LEN_IDX]); respIdx++) {
calChecksum += respBuf[respIdx];
}
calChecksum = (65536 - calChecksum) % 256;
if (calChecksum == respBuf[2 + respBuf[HPM_LEN_IDX]]) {
//Serial.println("PS- Received valid data!!!");
memset(dataBuf, 0, dataBufSize);
memcpy(dataBuf, &respBuf[HPM_DATA_START_IDX], respBuf[HPM_LEN_IDX] - 1);
return (respBuf[HPM_LEN_IDX] - 1);
}
}
}
}
}
return false;
}
/**
* @brief Function that sends a read command to sensor
* @return returns true if valid measurements were read from sensor
*/
boolean HPMA115S0::ReadParticleMeasurement(unsigned int * pm2_5, unsigned int * pm10) {
const char cmdBuf[] = {0x68, 0x01, 0x04, 0x93};
static unsigned char dataBuf[HPM_READ_PARTICLE_MEASURMENT_LEN_C - 1];
int len;
// Serial.println("PS- Reading Particle Measurements..." );
//Send command
SendCmd(cmdBuf, 4);
//Read response
len = ReadCmdResp(dataBuf, sizeof(dataBuf), READ_PARTICLE_MEASURMENT);
if ((len == (HPM_READ_PARTICLE_MEASURMENT_LEN - 1)) || (len == (HPM_READ_PARTICLE_MEASURMENT_LEN_C - 1))) {
if (len == (HPM_READ_PARTICLE_MEASURMENT_LEN - 1)) {
// HPMA115S0 Standard devices
_pm2_5 = dataBuf[0] * 256 + dataBuf[1];
_pm10 = dataBuf[2] * 256 + dataBuf[3];
} else {
// HPMA115C0 Compact devices
_pm2_5 = dataBuf[2] * 256 + dataBuf[3];
_pm10 = dataBuf[6] * 256 + dataBuf[7];
}
*pm2_5 = _pm2_5;
*pm10 = _pm10;
// Serial.println("PS- PM 2.5: " + String(_pm2_5) + " ug/m3" );
// Serial.println("PS- PM 10: " + String(_pm10) + " ug/m3" );
return true;
}
return false;
}
/**
* @brief Function that starts sensor measurement
* @return void
*/
void HPMA115S0::StartParticleMeasurement() {
const char cmd[] = {0x68, 0x01, 0x01, 0x96};
SendCmd(cmd, 4);
}
/**
* @brief Function that stops sensor measurement
* @return void
*/
void HPMA115S0::StopParticleMeasurement() {
const char cmd[] = {0x68, 0x01, 0x02, 0x95};
SendCmd(cmd, 4);
}
/**
* @brief Function that enables auto send
* @return void
*/
void HPMA115S0::EnableAutoSend() {
const char cmd[] = {0x68, 0x01, 0x40, 0x57};
SendCmd(cmd, 4);
}
/**
* @brief Function that stops auto send
* @return void
*/
void HPMA115S0::DisableAutoSend() {
const char cmd[] = {0x68, 0x01, 0x20, 0x77};
SendCmd(cmd, 4);
}
/**
* @brief Function that returns the latest PM 2.5 reading
* @note Sensor reports new reading ~ every 1 sec.
* @return PM 2.5 reading (unsigned int)
*/
unsigned int HPMA115S0::GetPM2_5() {
return _pm2_5;
}
/**
* @brief Function that returns the latest PM 10 reading
* @note Sensor reports new reading ~ every 1 sec.
* @return PM 10 reading (unsigned int)
*/
unsigned int HPMA115S0::GetPM10() {
return _pm10;
}

View File

@ -0,0 +1,124 @@
/**
*
* @file HPMA115S0.h
* @author Felix A. Galindo
* @date June 2017
* @brief Arduino Library for Honeywell's Particle Sensor (HPMA115S0-XXX)
*
*/
#ifndef HPMA115S0_H
#define HPMA115S0_H
#include "Arduino.h"
#define HPM_CMD_RESP_HEAD 0x40
#define HPM_MAX_RESP_SIZE 16 // max command response size is 16 bytes
#define HPM_READ_PARTICLE_MEASURMENT_LEN 5
#define HPM_READ_PARTICLE_MEASURMENT_LEN_C 13
enum CMD_TYPE_T {
READ_PARTICLE_MEASURMENT = 0x04,
START_PARTICLE_MEASURMENT = 0x01,
STOP_PARTICLE_MEASURMENT = 0x02,
SET_ADJUSTMENT_COEFFICIENT = 0x08,
READ_ADJUSTMENT_COEFFICIENT = 0x08,
STOP_AUTO_SEND = 0x20,
ENABLE_AUTO_SEND = 0x40,
};
enum HPM_PACKET_T {
HPM_HEAD_IDX,
HPM_LEN_IDX,
HPM_CMD_IDX,
HPM_DATA_START_IDX
};
class HPMA115S0
{
public:
/**
* @brief Constructor for HPMA115S0 class
* @param a Stream ({Software/Hardware}Serial) object.
* @note The serial stream should be already initialized
* @return void
*/
HPMA115S0(Stream& serial);
/**
* @brief Function that initializes sensor
* @return a String containing sensor response
*/
void Init();
/**
* @brief Function that sends a read command to sensor
* @return returns true if valid measurements were read from sensor
*/
boolean ReadParticleMeasurement(unsigned int * pm2_5, unsigned int * pm10);
/**
* @brief Function that starts sensor measurement
* @return void
*/
void StartParticleMeasurement();
/**
* @brief Function that stops sensor measurement
* @return void
*/
void StopParticleMeasurement();
/**
* @brief Function that enables auto send
* @return void
*/
void EnableAutoSend();
/**
* @brief Function that stops auto send
* @return void
*/
void DisableAutoSend();
/**
* @brief Function that returns the latest PM 2.5 reading
* @note Sensor reports new reading ~ every 1 sec.
* @return PM 2.5 reading (unsigned int)
*/
unsigned int GetPM2_5();
/**
* @brief Function that returns the latest PM 10 reading
* @note Sensor reports new reading ~ every 1 sec.
* @return PM 10 reading (unsigned int)
*/
unsigned int GetPM10();
private:
Stream& _serial;
//Latest PM 2.5 reading
unsigned int _pm2_5 = 0;
//Latest PM 10 reading
unsigned int _pm10 = 0;
/**
* @brief Function that sends serial command to sensor
* @param a char * containing the command
* @param size of buffer
* @return void
*/
void SendCmd(const char * command, unsigned int size);
/**
* @brief Function that reads command response from sensor
* @param Buffer to store data in
* @param Buffer size
* @param Expected command type
* @return returns number of bytes read from sensor
*/
int ReadCmdResp(unsigned char * dataBuf, unsigned int dataBufSize, unsigned int cmdType);
};
#endif

View File

@ -1,40 +0,0 @@
{
"name": "I2Cdevlib-ADS1115",
"repository": {
"url": "https://github.com/jrowberg/i2cdevlib.git",
"type": "git"
},
"platforms": [
"atmelavr"
],
"frameworks": [
"arduino"
],
"dependencies": {
"frameworks": "arduino",
"name": "I2Cdevlib-Core"
},
"export": {
"include": "Arduino/ADS1115"
},
"version": "3b4c8bda90",
"authors": [
{
"maintainer": false,
"name": "Jeff Rowberg",
"url": "https://github.com/jrowberg",
"email": "jeff@rowberg.net"
}
],
"keywords": [
"i2c",
"comparator",
"reference",
"pga",
"oscillator",
"mux",
"i2cdevlib"
],
"id": 95,
"description": "ADS1115 is 16-Bit ADC with Integrated MUX, PGA, Comparator, Oscillator, and Reference"
}

View File

@ -1,649 +0,0 @@
// I2Cdev library collection - ADS1115 I2C device class
// Based on Texas Instruments ADS1113/4/5 datasheet, May 2009 (SBAS444B, revised October 2009)
// Note that the ADS1115 uses 16-bit registers, not 8-bit registers.
// 8/2/2011 by Jeff Rowberg <jeff@rowberg.net>
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
//
// Changelog:
// 2013-05-05 - Add debug information. Rename methods to match datasheet.
// 2011-11-06 - added getVoltage, F. Farzanegan
// 2011-10-29 - added getDifferentialx() methods, F. Farzanegan
// 2011-08-02 - initial release
/* ============================================
I2Cdev device library code is placed under the MIT license
Copyright (c) 2011 Jeff Rowberg
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
===============================================
*/
#include "ADS1115.h"
/** Default constructor, uses default I2C address.
* @see ADS1115_DEFAULT_ADDRESS
*/
ADS1115::ADS1115() {
devAddr = ADS1115_DEFAULT_ADDRESS;
}
/** Specific address constructor.
* @param address I2C address
* @see ADS1115_DEFAULT_ADDRESS
* @see ADS1115_ADDRESS_ADDR_GND
* @see ADS1115_ADDRESS_ADDR_VDD
* @see ADS1115_ADDRESS_ADDR_SDA
* @see ADS1115_ADDRESS_ADDR_SDL
*/
ADS1115::ADS1115(uint8_t address) {
devAddr = address;
}
/** Power on and prepare for general usage.
* This device is ready to use automatically upon power-up. It defaults to
* single-shot read mode, P0/N1 mux, 2.048v gain, 128 samples/sec, default
* comparator with hysterysis, active-low polarity, non-latching comparator,
* and comparater-disabled operation.
*/
void ADS1115::initialize() {
setMultiplexer(ADS1115_MUX_P0_N1);
setGain(ADS1115_PGA_2P048);
setMode(ADS1115_MODE_SINGLESHOT);
setRate(ADS1115_RATE_128);
setComparatorMode(ADS1115_COMP_MODE_HYSTERESIS);
setComparatorPolarity(ADS1115_COMP_POL_ACTIVE_LOW);
setComparatorLatchEnabled(ADS1115_COMP_LAT_NON_LATCHING);
setComparatorQueueMode(ADS1115_COMP_QUE_DISABLE);
}
/** Verify the I2C connection.
* Make sure the device is connected and responds as expected.
* @return True if connection is valid, false otherwise
*/
bool ADS1115::testConnection() {
return I2Cdev::readWord(devAddr, ADS1115_RA_CONVERSION, buffer) == 1;
}
/** Poll the operational status bit until the conversion is finished
* Retry at most 'max_retries' times
* conversion is finished, then return true;
* @see ADS1115_CFG_OS_BIT
* @return True if data is available, false otherwise
*/
bool ADS1115::pollConversion(uint16_t max_retries) {
for(uint16_t i = 0; i < max_retries; i++) {
if (isConversionReady()) return true;
}
return false;
}
/** Read differential value based on current MUX configuration.
* The default MUX setting sets the device to get the differential between the
* AIN0 and AIN1 pins. There are 8 possible MUX settings, but if you are using
* all four input pins as single-end voltage sensors, then the default option is
* not what you want; instead you will need to set the MUX to compare the
* desired AIN* pin with GND. There are shortcut methods (getConversion*) to do
* this conveniently, but you can also do it manually with setMultiplexer()
* followed by this method.
*
* In single-shot mode, this register may not have fresh data. You need to write
* a 1 bit to the MSB of the CONFIG register to trigger a single read/conversion
* before this will be populated with fresh data. This technique is not as
* effortless, but it has enormous potential to save power by only running the
* comparison circuitry when needed.
*
* @param triggerAndPoll If true (and only in singleshot mode) the conversion trigger
* will be executed and the conversion results will be polled.
* @return 16-bit signed differential value
* @see getConversionP0N1();
* @see getConversionPON3();
* @see getConversionP1N3();
* @see getConversionP2N3();
* @see getConversionP0GND();
* @see getConversionP1GND();
* @see getConversionP2GND();
* @see getConversionP3GND);
* @see setMultiplexer();
* @see ADS1115_RA_CONVERSION
* @see ADS1115_MUX_P0_N1
* @see ADS1115_MUX_P0_N3
* @see ADS1115_MUX_P1_N3
* @see ADS1115_MUX_P2_N3
* @see ADS1115_MUX_P0_NG
* @see ADS1115_MUX_P1_NG
* @see ADS1115_MUX_P2_NG
* @see ADS1115_MUX_P3_NG
*/
int16_t ADS1115::getConversion(bool triggerAndPoll) {
if (triggerAndPoll && devMode == ADS1115_MODE_SINGLESHOT) {
triggerConversion();
pollConversion(I2CDEV_DEFAULT_READ_TIMEOUT);
}
I2Cdev::readWord(devAddr, ADS1115_RA_CONVERSION, buffer);
return buffer[0];
}
/** Get AIN0/N1 differential.
* This changes the MUX setting to AIN0/N1 if necessary, triggers a new
* measurement (also only if necessary), then gets the differential value
* currently in the CONVERSION register.
* @return 16-bit signed differential value
* @see getConversion()
*/
int16_t ADS1115::getConversionP0N1() {
if (muxMode != ADS1115_MUX_P0_N1) setMultiplexer(ADS1115_MUX_P0_N1);
return getConversion();
}
/** Get AIN0/N3 differential.
* This changes the MUX setting to AIN0/N3 if necessary, triggers a new
* measurement (also only if necessary), then gets the differential value
* currently in the CONVERSION register.
* @return 16-bit signed differential value
* @see getConversion()
*/
int16_t ADS1115::getConversionP0N3() {
if (muxMode != ADS1115_MUX_P0_N3) setMultiplexer(ADS1115_MUX_P0_N3);
return getConversion();
}
/** Get AIN1/N3 differential.
* This changes the MUX setting to AIN1/N3 if necessary, triggers a new
* measurement (also only if necessary), then gets the differential value
* currently in the CONVERSION register.
* @return 16-bit signed differential value
* @see getConversion()
*/
int16_t ADS1115::getConversionP1N3() {
if (muxMode != ADS1115_MUX_P1_N3) setMultiplexer(ADS1115_MUX_P1_N3);
return getConversion();
}
/** Get AIN2/N3 differential.
* This changes the MUX setting to AIN2/N3 if necessary, triggers a new
* measurement (also only if necessary), then gets the differential value
* currently in the CONVERSION register.
* @return 16-bit signed differential value
* @see getConversion()
*/
int16_t ADS1115::getConversionP2N3() {
if (muxMode != ADS1115_MUX_P2_N3) setMultiplexer(ADS1115_MUX_P2_N3);
return getConversion();
}
/** Get AIN0/GND differential.
* This changes the MUX setting to AIN0/GND if necessary, triggers a new
* measurement (also only if necessary), then gets the differential value
* currently in the CONVERSION register.
* @return 16-bit signed differential value
* @see getConversion()
*/
int16_t ADS1115::getConversionP0GND() {
if (muxMode != ADS1115_MUX_P0_NG) setMultiplexer(ADS1115_MUX_P0_NG);
return getConversion();
}
/** Get AIN1/GND differential.
* This changes the MUX setting to AIN1/GND if necessary, triggers a new
* measurement (also only if necessary), then gets the differential value
* currently in the CONVERSION register.
* @return 16-bit signed differential value
* @see getConversion()
*/
int16_t ADS1115::getConversionP1GND() {
if (muxMode != ADS1115_MUX_P1_NG) setMultiplexer(ADS1115_MUX_P1_NG);
return getConversion();
}
/** Get AIN2/GND differential.
* This changes the MUX setting to AIN2/GND if necessary, triggers a new
* measurement (also only if necessary), then gets the differential value
* currently in the CONVERSION register.
* @return 16-bit signed differential value
* @see getConversion()
*/
int16_t ADS1115::getConversionP2GND() {
if (muxMode != ADS1115_MUX_P2_NG) setMultiplexer(ADS1115_MUX_P2_NG);
return getConversion();
}
/** Get AIN3/GND differential.
* This changes the MUX setting to AIN3/GND if necessary, triggers a new
* measurement (also only if necessary), then gets the differential value
* currently in the CONVERSION register.
* @return 16-bit signed differential value
* @see getConversion()
*/
int16_t ADS1115::getConversionP3GND() {
if (muxMode != ADS1115_MUX_P3_NG) setMultiplexer(ADS1115_MUX_P3_NG);
return getConversion();
}
/** Get the current voltage reading
* Read the current differential and return it multiplied
* by the constant for the current gain. mV is returned to
* increase the precision of the voltage
* @param triggerAndPoll If true (and only in singleshot mode) the conversion trigger
* will be executed and the conversion results will be polled.
*/
float ADS1115::getMilliVolts(bool triggerAndPoll) {
switch (pgaMode) {
case ADS1115_PGA_6P144:
return (getConversion(triggerAndPoll) * ADS1115_MV_6P144);
break;
case ADS1115_PGA_4P096:
return (getConversion(triggerAndPoll) * ADS1115_MV_4P096);
break;
case ADS1115_PGA_2P048:
return (getConversion(triggerAndPoll) * ADS1115_MV_2P048);
break;
case ADS1115_PGA_1P024:
return (getConversion(triggerAndPoll) * ADS1115_MV_1P024);
break;
case ADS1115_PGA_0P512:
return (getConversion(triggerAndPoll) * ADS1115_MV_0P512);
break;
case ADS1115_PGA_0P256:
case ADS1115_PGA_0P256B:
case ADS1115_PGA_0P256C:
return (getConversion(triggerAndPoll) * ADS1115_MV_0P256);
break;
}
}
/**
* Return the current multiplier for the PGA setting.
*
* This may be directly retreived by using getMilliVolts(),
* but this causes an independent read. This function could
* be used to average a number of reads from the getConversion()
* getConversionx() functions and cut downon the number of
* floating-point calculations needed.
*
*/
float ADS1115::getMvPerCount() {
switch (pgaMode) {
case ADS1115_PGA_6P144:
return ADS1115_MV_6P144;
break;
case ADS1115_PGA_4P096:
return ADS1115_MV_4P096;
break;
case ADS1115_PGA_2P048:
return ADS1115_MV_2P048;
break;
case ADS1115_PGA_1P024:
return ADS1115_MV_1P024;
break;
case ADS1115_PGA_0P512:
return ADS1115_MV_0P512;
break;
case ADS1115_PGA_0P256:
case ADS1115_PGA_0P256B:
case ADS1115_PGA_0P256C:
return ADS1115_MV_0P256;
break;
}
}
// CONFIG register
/** Get operational status.
* @return Current operational status (false for active conversion, true for inactive)
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_OS_BIT
*/
bool ADS1115::isConversionReady() {
I2Cdev::readBitW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_OS_BIT, buffer);
return buffer[0];
}
/** Trigger a new conversion.
* Writing to this bit will only have effect while in power-down mode (no conversions active).
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_OS_BIT
*/
void ADS1115::triggerConversion() {
I2Cdev::writeBitW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_OS_BIT, 1);
}
/** Get multiplexer connection.
* @return Current multiplexer connection setting
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_MUX_BIT
* @see ADS1115_CFG_MUX_LENGTH
*/
uint8_t ADS1115::getMultiplexer() {
I2Cdev::readBitsW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_MUX_BIT, ADS1115_CFG_MUX_LENGTH, buffer);
muxMode = (uint8_t)buffer[0];
return muxMode;
}
/** Set multiplexer connection. Continous mode may fill the conversion register
* with data before the MUX setting has taken effect. A stop/start of the conversion
* is done to reset the values.
* @param mux New multiplexer connection setting
* @see ADS1115_MUX_P0_N1
* @see ADS1115_MUX_P0_N3
* @see ADS1115_MUX_P1_N3
* @see ADS1115_MUX_P2_N3
* @see ADS1115_MUX_P0_NG
* @see ADS1115_MUX_P1_NG
* @see ADS1115_MUX_P2_NG
* @see ADS1115_MUX_P3_NG
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_MUX_BIT
* @see ADS1115_CFG_MUX_LENGTH
*/
void ADS1115::setMultiplexer(uint8_t mux) {
if (I2Cdev::writeBitsW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_MUX_BIT, ADS1115_CFG_MUX_LENGTH, mux)) {
muxMode = mux;
if (devMode == ADS1115_MODE_CONTINUOUS) {
// Force a stop/start
setMode(ADS1115_MODE_SINGLESHOT);
getConversion();
setMode(ADS1115_MODE_CONTINUOUS);
}
}
}
/** Get programmable gain amplifier level.
* @return Current programmable gain amplifier level
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_PGA_BIT
* @see ADS1115_CFG_PGA_LENGTH
*/
uint8_t ADS1115::getGain() {
I2Cdev::readBitsW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_PGA_BIT, ADS1115_CFG_PGA_LENGTH, buffer);
pgaMode=(uint8_t)buffer[0];
return pgaMode;
}
/** Set programmable gain amplifier level.
* Continous mode may fill the conversion register
* with data before the gain setting has taken effect. A stop/start of the conversion
* is done to reset the values.
* @param gain New programmable gain amplifier level
* @see ADS1115_PGA_6P144
* @see ADS1115_PGA_4P096
* @see ADS1115_PGA_2P048
* @see ADS1115_PGA_1P024
* @see ADS1115_PGA_0P512
* @see ADS1115_PGA_0P256
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_PGA_BIT
* @see ADS1115_CFG_PGA_LENGTH
*/
void ADS1115::setGain(uint8_t gain) {
if (I2Cdev::writeBitsW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_PGA_BIT, ADS1115_CFG_PGA_LENGTH, gain)) {
pgaMode = gain;
if (devMode == ADS1115_MODE_CONTINUOUS) {
// Force a stop/start
setMode(ADS1115_MODE_SINGLESHOT);
getConversion();
setMode(ADS1115_MODE_CONTINUOUS);
}
}
}
/** Get device mode.
* @return Current device mode
* @see ADS1115_MODE_CONTINUOUS
* @see ADS1115_MODE_SINGLESHOT
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_MODE_BIT
*/
bool ADS1115::getMode() {
I2Cdev::readBitW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_MODE_BIT, buffer);
devMode = buffer[0];
return devMode;
}
/** Set device mode.
* @param mode New device mode
* @see ADS1115_MODE_CONTINUOUS
* @see ADS1115_MODE_SINGLESHOT
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_MODE_BIT
*/
void ADS1115::setMode(bool mode) {
if (I2Cdev::writeBitW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_MODE_BIT, mode)) {
devMode = mode;
}
}
/** Get data rate.
* @return Current data rate
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_DR_BIT
* @see ADS1115_CFG_DR_LENGTH
*/
uint8_t ADS1115::getRate() {
I2Cdev::readBitsW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_DR_BIT, ADS1115_CFG_DR_LENGTH, buffer);
return (uint8_t)buffer[0];
}
/** Set data rate.
* @param rate New data rate
* @see ADS1115_RATE_8
* @see ADS1115_RATE_16
* @see ADS1115_RATE_32
* @see ADS1115_RATE_64
* @see ADS1115_RATE_128
* @see ADS1115_RATE_250
* @see ADS1115_RATE_475
* @see ADS1115_RATE_860
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_DR_BIT
* @see ADS1115_CFG_DR_LENGTH
*/
void ADS1115::setRate(uint8_t rate) {
I2Cdev::writeBitsW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_DR_BIT, ADS1115_CFG_DR_LENGTH, rate);
}
/** Get comparator mode.
* @return Current comparator mode
* @see ADS1115_COMP_MODE_HYSTERESIS
* @see ADS1115_COMP_MODE_WINDOW
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_COMP_MODE_BIT
*/
bool ADS1115::getComparatorMode() {
I2Cdev::readBitW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_COMP_MODE_BIT, buffer);
return buffer[0];
}
/** Set comparator mode.
* @param mode New comparator mode
* @see ADS1115_COMP_MODE_HYSTERESIS
* @see ADS1115_COMP_MODE_WINDOW
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_COMP_MODE_BIT
*/
void ADS1115::setComparatorMode(bool mode) {
I2Cdev::writeBitW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_COMP_MODE_BIT, mode);
}
/** Get comparator polarity setting.
* @return Current comparator polarity setting
* @see ADS1115_COMP_POL_ACTIVE_LOW
* @see ADS1115_COMP_POL_ACTIVE_HIGH
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_COMP_POL_BIT
*/
bool ADS1115::getComparatorPolarity() {
I2Cdev::readBitW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_COMP_POL_BIT, buffer);
return buffer[0];
}
/** Set comparator polarity setting.
* @param polarity New comparator polarity setting
* @see ADS1115_COMP_POL_ACTIVE_LOW
* @see ADS1115_COMP_POL_ACTIVE_HIGH
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_COMP_POL_BIT
*/
void ADS1115::setComparatorPolarity(bool polarity) {
I2Cdev::writeBitW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_COMP_POL_BIT, polarity);
}
/** Get comparator latch enabled value.
* @return Current comparator latch enabled value
* @see ADS1115_COMP_LAT_NON_LATCHING
* @see ADS1115_COMP_LAT_LATCHING
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_COMP_LAT_BIT
*/
bool ADS1115::getComparatorLatchEnabled() {
I2Cdev::readBitW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_COMP_LAT_BIT, buffer);
return buffer[0];
}
/** Set comparator latch enabled value.
* @param enabled New comparator latch enabled value
* @see ADS1115_COMP_LAT_NON_LATCHING
* @see ADS1115_COMP_LAT_LATCHING
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_COMP_LAT_BIT
*/
void ADS1115::setComparatorLatchEnabled(bool enabled) {
I2Cdev::writeBitW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_COMP_LAT_BIT, enabled);
}
/** Get comparator queue mode.
* @return Current comparator queue mode
* @see ADS1115_COMP_QUE_ASSERT1
* @see ADS1115_COMP_QUE_ASSERT2
* @see ADS1115_COMP_QUE_ASSERT4
* @see ADS1115_COMP_QUE_DISABLE
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_COMP_QUE_BIT
* @see ADS1115_CFG_COMP_QUE_LENGTH
*/
uint8_t ADS1115::getComparatorQueueMode() {
I2Cdev::readBitsW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_COMP_QUE_BIT, ADS1115_CFG_COMP_QUE_LENGTH, buffer);
return (uint8_t)buffer[0];
}
/** Set comparator queue mode.
* @param mode New comparator queue mode
* @see ADS1115_COMP_QUE_ASSERT1
* @see ADS1115_COMP_QUE_ASSERT2
* @see ADS1115_COMP_QUE_ASSERT4
* @see ADS1115_COMP_QUE_DISABLE
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_COMP_QUE_BIT
* @see ADS1115_CFG_COMP_QUE_LENGTH
*/
void ADS1115::setComparatorQueueMode(uint8_t mode) {
I2Cdev::writeBitsW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_COMP_QUE_BIT, ADS1115_CFG_COMP_QUE_LENGTH, mode);
}
// *_THRESH registers
/** Get low threshold value.
* @return Current low threshold value
* @see ADS1115_RA_LO_THRESH
*/
int16_t ADS1115::getLowThreshold() {
I2Cdev::readWord(devAddr, ADS1115_RA_LO_THRESH, buffer);
return buffer[0];
}
/** Set low threshold value.
* @param threshold New low threshold value
* @see ADS1115_RA_LO_THRESH
*/
void ADS1115::setLowThreshold(int16_t threshold) {
I2Cdev::writeWord(devAddr, ADS1115_RA_LO_THRESH, threshold);
}
/** Get high threshold value.
* @return Current high threshold value
* @see ADS1115_RA_HI_THRESH
*/
int16_t ADS1115::getHighThreshold() {
I2Cdev::readWord(devAddr, ADS1115_RA_HI_THRESH, buffer);
return buffer[0];
}
/** Set high threshold value.
* @param threshold New high threshold value
* @see ADS1115_RA_HI_THRESH
*/
void ADS1115::setHighThreshold(int16_t threshold) {
I2Cdev::writeWord(devAddr, ADS1115_RA_HI_THRESH, threshold);
}
/** Configures ALERT/RDY pin as a conversion ready pin.
* It does this by setting the MSB of the high threshold register to '1' and the MSB
* of the low threshold register to '0'. COMP_POL and COMP_QUE bits will be set to '0'.
* Note: ALERT/RDY pin requires a pull up resistor.
*/
void ADS1115::setConversionReadyPinMode() {
I2Cdev::writeBitW(devAddr, ADS1115_RA_HI_THRESH, 15, 1);
I2Cdev::writeBitW(devAddr, ADS1115_RA_LO_THRESH, 15, 0);
setComparatorPolarity(0);
setComparatorQueueMode(0);
}
// Create a mask between two bits
unsigned createMask(unsigned a, unsigned b) {
unsigned mask = 0;
for (unsigned i=a; i<=b; i++)
mask |= 1 << i;
return mask;
}
uint16_t shiftDown(uint16_t extractFrom, int places) {
return (extractFrom >> places);
}
uint16_t getValueFromBits(uint16_t extractFrom, int high, int length) {
int low= high-length +1;
uint16_t mask = createMask(low ,high);
return shiftDown(extractFrom & mask, low);
}
/** Show all the config register settings
*/
void ADS1115::showConfigRegister() {
I2Cdev::readWord(devAddr, ADS1115_RA_CONFIG, buffer);
uint16_t configRegister =buffer[0];
#ifdef ADS1115_SERIAL_DEBUG
Serial.print("Register is:");
Serial.println(configRegister,BIN);
Serial.print("OS:\t");
Serial.println(getValueFromBits(configRegister,
ADS1115_CFG_OS_BIT,1), BIN);
Serial.print("MUX:\t");
Serial.println(getValueFromBits(configRegister,
ADS1115_CFG_MUX_BIT,ADS1115_CFG_MUX_LENGTH), BIN);
Serial.print("PGA:\t");
Serial.println(getValueFromBits(configRegister,
ADS1115_CFG_PGA_BIT,ADS1115_CFG_PGA_LENGTH), BIN);
Serial.print("MODE:\t");
Serial.println(getValueFromBits(configRegister,
ADS1115_CFG_MODE_BIT,1), BIN);
Serial.print("DR:\t");
Serial.println(getValueFromBits(configRegister,
ADS1115_CFG_DR_BIT,ADS1115_CFG_DR_LENGTH), BIN);
Serial.print("CMP_MODE:\t");
Serial.println(getValueFromBits(configRegister,
ADS1115_CFG_COMP_MODE_BIT,1), BIN);
Serial.print("CMP_POL:\t");
Serial.println(getValueFromBits(configRegister,
ADS1115_CFG_COMP_POL_BIT,1), BIN);
Serial.print("CMP_LAT:\t");
Serial.println(getValueFromBits(configRegister,
ADS1115_CFG_COMP_LAT_BIT,1), BIN);
Serial.print("CMP_QUE:\t");
Serial.println(getValueFromBits(configRegister,
ADS1115_CFG_COMP_QUE_BIT,ADS1115_CFG_COMP_QUE_LENGTH), BIN);
#endif
};

View File

@ -1,200 +0,0 @@
// I2Cdev library collection - ADS1115 I2C device class header file
// Based on Texas Instruments ADS1113/4/5 datasheet, May 2009 (SBAS444B, revised October 2009)
// Note that the ADS1115 uses 16-bit registers, not 8-bit registers.
// 8/2/2011 by Jeff Rowberg <jeff@rowberg.net>
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
//
// Changelog:
// 2013-05-05 - Add debug information. Clean up Single Shot implementation
// 2011-10-29 - added getDifferentialx() methods, F. Farzanegan
// 2011-08-02 - initial release
/* ============================================
I2Cdev device library code is placed under the MIT license
Copyright (c) 2011 Jeff Rowberg
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
===============================================
*/
#ifndef _ADS1115_H_
#define _ADS1115_H_
#include "I2Cdev.h"
// -----------------------------------------------------------------------------
// Arduino-style "Serial.print" debug constant (uncomment to enable)
// -----------------------------------------------------------------------------
//#define ADS1115_SERIAL_DEBUG
#define ADS1115_ADDRESS_ADDR_GND 0x48 // address pin low (GND)
#define ADS1115_ADDRESS_ADDR_VDD 0x49 // address pin high (VCC)
#define ADS1115_ADDRESS_ADDR_SDA 0x4A // address pin tied to SDA pin
#define ADS1115_ADDRESS_ADDR_SCL 0x4B // address pin tied to SCL pin
#define ADS1115_DEFAULT_ADDRESS ADS1115_ADDRESS_ADDR_GND
#define ADS1115_RA_CONVERSION 0x00
#define ADS1115_RA_CONFIG 0x01
#define ADS1115_RA_LO_THRESH 0x02
#define ADS1115_RA_HI_THRESH 0x03
#define ADS1115_CFG_OS_BIT 15
#define ADS1115_CFG_MUX_BIT 14
#define ADS1115_CFG_MUX_LENGTH 3
#define ADS1115_CFG_PGA_BIT 11
#define ADS1115_CFG_PGA_LENGTH 3
#define ADS1115_CFG_MODE_BIT 8
#define ADS1115_CFG_DR_BIT 7
#define ADS1115_CFG_DR_LENGTH 3
#define ADS1115_CFG_COMP_MODE_BIT 4
#define ADS1115_CFG_COMP_POL_BIT 3
#define ADS1115_CFG_COMP_LAT_BIT 2
#define ADS1115_CFG_COMP_QUE_BIT 1
#define ADS1115_CFG_COMP_QUE_LENGTH 2
#define ADS1115_MUX_P0_N1 0x00 // default
#define ADS1115_MUX_P0_N3 0x01
#define ADS1115_MUX_P1_N3 0x02
#define ADS1115_MUX_P2_N3 0x03
#define ADS1115_MUX_P0_NG 0x04
#define ADS1115_MUX_P1_NG 0x05
#define ADS1115_MUX_P2_NG 0x06
#define ADS1115_MUX_P3_NG 0x07
#define ADS1115_PGA_6P144 0x00
#define ADS1115_PGA_4P096 0x01
#define ADS1115_PGA_2P048 0x02 // default
#define ADS1115_PGA_1P024 0x03
#define ADS1115_PGA_0P512 0x04
#define ADS1115_PGA_0P256 0x05
#define ADS1115_PGA_0P256B 0x06
#define ADS1115_PGA_0P256C 0x07
#define ADS1115_MV_6P144 0.187500
#define ADS1115_MV_4P096 0.125000
#define ADS1115_MV_2P048 0.062500 // default
#define ADS1115_MV_1P024 0.031250
#define ADS1115_MV_0P512 0.015625
#define ADS1115_MV_0P256 0.007813
#define ADS1115_MV_0P256B 0.007813
#define ADS1115_MV_0P256C 0.007813
#define ADS1115_MODE_CONTINUOUS 0x00
#define ADS1115_MODE_SINGLESHOT 0x01 // default
#define ADS1115_RATE_8 0x00
#define ADS1115_RATE_16 0x01
#define ADS1115_RATE_32 0x02
#define ADS1115_RATE_64 0x03
#define ADS1115_RATE_128 0x04 // default
#define ADS1115_RATE_250 0x05
#define ADS1115_RATE_475 0x06
#define ADS1115_RATE_860 0x07
#define ADS1115_COMP_MODE_HYSTERESIS 0x00 // default
#define ADS1115_COMP_MODE_WINDOW 0x01
#define ADS1115_COMP_POL_ACTIVE_LOW 0x00 // default
#define ADS1115_COMP_POL_ACTIVE_HIGH 0x01
#define ADS1115_COMP_LAT_NON_LATCHING 0x00 // default
#define ADS1115_COMP_LAT_LATCHING 0x01
#define ADS1115_COMP_QUE_ASSERT1 0x00
#define ADS1115_COMP_QUE_ASSERT2 0x01
#define ADS1115_COMP_QUE_ASSERT4 0x02
#define ADS1115_COMP_QUE_DISABLE 0x03 // default
// -----------------------------------------------------------------------------
// Arduino-style "Serial.print" debug constant (uncomment to enable)
// -----------------------------------------------------------------------------
//#define ADS1115_SERIAL_DEBUG
class ADS1115 {
public:
ADS1115();
ADS1115(uint8_t address);
void initialize();
bool testConnection();
// SINGLE SHOT utilities
bool pollConversion(uint16_t max_retries);
void triggerConversion();
// Read the current CONVERSION register
int16_t getConversion(bool triggerAndPoll=true);
// Differential
int16_t getConversionP0N1();
int16_t getConversionP0N3();
int16_t getConversionP1N3();
int16_t getConversionP2N3();
// Single-ended
int16_t getConversionP0GND();
int16_t getConversionP1GND();
int16_t getConversionP2GND();
int16_t getConversionP3GND();
// Utility
float getMilliVolts(bool triggerAndPoll=true);
float getMvPerCount();
// CONFIG register
bool isConversionReady();
uint8_t getMultiplexer();
void setMultiplexer(uint8_t mux);
uint8_t getGain();
void setGain(uint8_t gain);
bool getMode();
void setMode(bool mode);
uint8_t getRate();
void setRate(uint8_t rate);
bool getComparatorMode();
void setComparatorMode(bool mode);
bool getComparatorPolarity();
void setComparatorPolarity(bool polarity);
bool getComparatorLatchEnabled();
void setComparatorLatchEnabled(bool enabled);
uint8_t getComparatorQueueMode();
void setComparatorQueueMode(uint8_t mode);
void setConversionReadyPinMode();
// *_THRESH registers
int16_t getLowThreshold();
void setLowThreshold(int16_t threshold);
int16_t getHighThreshold();
void setHighThreshold(int16_t threshold);
// DEBUG
void showConfigRegister();
private:
uint8_t devAddr;
uint16_t buffer[2];
bool devMode;
uint8_t muxMode;
uint8_t pgaMode;
};
#endif /* _ADS1115_H_ */

View File

@ -1,91 +0,0 @@
// I2C device class (I2Cdev) demonstration Arduino sketch for ADS1115 class
// Example of reading two differential inputs of the ADS1115 and showing the value in mV
// 06 May 2013 by Frederick Farzanegan (frederick1@farzanegan.org)
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
//
// Changelog:
// 2013-05-13 - initial release
/* ============================================
I2Cdev device library code is placed under the MIT license
Copyright (c) 2011 Jeff Rowberg
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
===============================================
*/
#include "ADS1115.h"
ADS1115 adc0(ADS1115_DEFAULT_ADDRESS);
void setup() {
Wire.begin(); // join I2C bus
Serial.begin(19200); // initialize serial communication
Serial.println("Initializing I2C devices...");
adc0.initialize(); // initialize ADS1115 16 bit A/D chip
Serial.println("Testing device connections...");
Serial.println(adc0.testConnection() ? "ADS1115 connection successful" : "ADS1115 connection failed");
// To get output from this method, you'll need to turn on the
//#define ADS1115_SERIAL_DEBUG // in the ADS1115.h file
adc0.showConfigRegister();
// We're going to do continuous sampling
adc0.setMode(ADS1115_MODE_CONTINUOUS);
}
void loop() {
// Sensor is on P0/N1 (pins 4/5)
Serial.println("Sensor 1 ************************");
// Set the gain (PGA) +/- 1.024v
adc0.setGain(ADS1115_PGA_1P024);
// Get the number of counts of the accumulator
Serial.print("Counts for sensor 1 is:");
// The below method sets the mux and gets a reading.
int sensorOneCounts=adc0.getConversionP0N1(); // counts up to 16-bits
Serial.println(sensorOneCounts);
// To turn the counts into a voltage, we can use
Serial.print("Voltage for sensor 1 is:");
Serial.println(sensorOneCounts*adc0.getMvPerCount());
Serial.println();
// 2nd sensor is on P2/N3 (pins 6/7)
Serial.println("Sensor 2 ************************");
// Set the gain (PGA) +/- 0.256v
adc0.setGain(ADS1115_PGA_0P256);
// Manually set the MUX // could have used the getConversionP* above
adc0.setMultiplexer(ADS1115_MUX_P2_N3);
Serial.print("Counts for sensor 2 is:");
Serial.println(adc0.getConversion());
Serial.print("mVoltage sensor 2 is:");
Serial.println(adc0.getMilliVolts()); // Convenience method to calculate voltage
Serial.println();
delay(500);
}

View File

@ -1,110 +0,0 @@
// I2C device class (I2Cdev) demonstration Arduino sketch for ADS1115 class
// Example of reading two differential inputs of the ADS1115 and showing the value in mV
// 2016-03-22 by Eadf (https://github.com/eadf)
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
//
// Changelog:
// 2016-03-22 - initial release
/* ============================================
I2Cdev device library code is placed under the MIT license
Copyright (c) 2011 Jeff Rowberg
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
===============================================
*/
#include "ADS1115.h"
ADS1115 adc0(ADS1115_DEFAULT_ADDRESS);
// Wire ADS1115 ALERT/RDY pin to Arduino pin 2
const int alertReadyPin = 2;
void setup() {
//I2Cdev::begin(); // join I2C bus
Wire.begin();
Serial.begin(115200); // initialize serial communication
Serial.println("Testing device connections...");
Serial.println(adc0.testConnection() ? "ADS1115 connection successful" : "ADS1115 connection failed");
adc0.initialize(); // initialize ADS1115 16 bit A/D chip
// We're going to do single shot sampling
adc0.setMode(ADS1115_MODE_SINGLESHOT);
// Slow things down so that we can see that the "poll for conversion" code works
adc0.setRate(ADS1115_RATE_8);
// Set the gain (PGA) +/- 6.144V
// Note that any analog input must be higher than 0.3V and less than VDD +0.3
adc0.setGain(ADS1115_PGA_6P144);
// ALERT/RDY pin will indicate when conversion is ready
pinMode(alertReadyPin,INPUT_PULLUP);
adc0.setConversionReadyPinMode();
// To get output from this method, you'll need to turn on the
//#define ADS1115_SERIAL_DEBUG // in the ADS1115.h file
#ifdef ADS1115_SERIAL_DEBUG
adc0.showConfigRegister();
Serial.print("HighThreshold="); Serial.println(adc0.getHighThreshold(),BIN);
Serial.print("LowThreshold="); Serial.println(adc0.getLowThreshold(),BIN);
#endif
}
/** Poll the assigned pin for conversion status
*/
void pollAlertReadyPin() {
for (uint32_t i = 0; i<100000; i++)
if (!digitalRead(alertReadyPin)) return;
Serial.println("Failed to wait for AlertReadyPin, it's stuck high!");
}
void loop() {
// The below method sets the mux and gets a reading.
adc0.setMultiplexer(ADS1115_MUX_P0_NG);
adc0.triggerConversion();
pollAlertReadyPin();
Serial.print("A0: "); Serial.print(adc0.getMilliVolts(false)); Serial.print("mV\t");
adc0.setMultiplexer(ADS1115_MUX_P1_NG);
adc0.triggerConversion();
pollAlertReadyPin();
Serial.print("A1: "); Serial.print(adc0.getMilliVolts(false)); Serial.print("mV\t");
adc0.setMultiplexer(ADS1115_MUX_P2_NG);
adc0.triggerConversion();
pollAlertReadyPin();
Serial.print("A2: "); Serial.print(adc0.getMilliVolts(false)); Serial.print("mV\t");
adc0.setMultiplexer(ADS1115_MUX_P3_NG);
// Do conversion polling via I2C on this last reading:
Serial.print("A3: "); Serial.print(adc0.getMilliVolts(true)); Serial.print("mV");
Serial.println(digitalRead(alertReadyPin));
delay(500);
}

View File

@ -1,18 +0,0 @@
{
"name": "I2Cdevlib-ADS1115",
"keywords": "MUX, PGA, comparator, oscillator, reference, i2cdevlib, i2c",
"description": "ADS1115 is 16-Bit ADC with Integrated MUX, PGA, Comparator, Oscillator, and Reference",
"include": "Arduino/ADS1115",
"repository":
{
"type": "git",
"url": "https://github.com/jrowberg/i2cdevlib.git"
},
"dependencies":
{
"name": "I2Cdevlib-Core",
"frameworks": "arduino"
},
"frameworks": "arduino",
"platforms": "atmelavr"
}

View File

@ -3,7 +3,7 @@
// 8/24/2011 by Jeff Rowberg <jeff@rowberg.net>
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
//
// Adapted for Sonoff-Tasmota by Oliver Welter <contact@verbotene.zone> 02-04-2018
// Adapted for Tasmota by Oliver Welter <contact@verbotene.zone> 02-04-2018
//
// Changelog:
// ... - ongoing debug release
@ -871,7 +871,7 @@ void MPU6050::setMasterClockSpeed(uint8_t speed) {
* operation, and if it is cleared, then it's a write operation. The remaining
* bits (6-0) are the 7-bit device address of the slave device.
*
* In read mode, the result of the read is placed in the lowest available
* In read mode, the result of the read is placed in the lowest available
* EXT_SENS_DATA register. For further information regarding the allocation of
* read results, please refer to the EXT_SENS_DATA register description
* (Registers 73 - 96).
@ -2957,7 +2957,7 @@ void MPU6050::readMemoryBlock(uint8_t *data, uint16_t dataSize, uint8_t bank, ui
// read the chunk of data as specified
I2Cdev::readBytes(devAddr, MPU6050_RA_MEM_R_W, chunkSize, data + i);
// increase byte index by [chunkSize]
i += chunkSize;
@ -2991,7 +2991,7 @@ bool MPU6050::writeMemoryBlock(const uint8_t *data, uint16_t dataSize, uint8_t b
// make sure this chunk doesn't go past the bank boundary (256 bytes)
if (chunkSize > 256 - address) chunkSize = 256 - address;
if (useProgMem) {
// write the chunk of data as specified
for (j = 0; j < chunkSize; j++) progBuffer[j] = pgm_read_byte(data + i + j);
@ -3105,7 +3105,7 @@ bool MPU6050::writeDMPConfigurationSet(const uint8_t *data, uint16_t dataSize, b
Serial.println(" found...");*/
if (special == 0x01) {
// enable DMP-related interrupts
//setIntZeroMotionEnabled(true);
//setIntFIFOBufferOverflowEnabled(true);
//setIntDMPEnabled(true);
@ -3117,7 +3117,7 @@ bool MPU6050::writeDMPConfigurationSet(const uint8_t *data, uint16_t dataSize, b
success = false;
}
}
if (!success) {
if (useProgMem) free(progBuffer);
return false; // uh oh

View File

@ -4,7 +4,7 @@
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
//
// Adapted for Sonoff-Tasmota by Oliver Welter <contact@verbotene.zone> 02-04-2018
// Adapted for Tasmota by Oliver Welter <contact@verbotene.zone> 02-04-2018
//
// Changelog:
// ... - ongoing debug release
@ -408,7 +408,7 @@ class MPU6050 {
void initialize();
bool testConnection();
// Patch for Tasmota
void setAddr(uint8_t address);
@ -682,9 +682,9 @@ class MPU6050 {
// WHO_AM_I register
uint8_t getDeviceID();
void setDeviceID(uint8_t id);
// ======== UNDOCUMENTED/DMP REGISTERS/METHODS ========
// XG_OFFS_TC register
uint8_t getOTPBankValid();
void setOTPBankValid(bool enabled);
@ -734,13 +734,13 @@ class MPU6050 {
// ZG_OFFS_USR* register
int16_t getZGyroOffset();
void setZGyroOffset(int16_t offset);
// INT_ENABLE register (DMP functions)
bool getIntPLLReadyEnabled();
void setIntPLLReadyEnabled(bool enabled);
bool getIntDMPEnabled();
void setIntDMPEnabled(bool enabled);
// DMP_INT_STATUS
bool getDMPInt5Status();
bool getDMPInt4Status();
@ -752,18 +752,18 @@ class MPU6050 {
// INT_STATUS register (DMP functions)
bool getIntPLLReadyStatus();
bool getIntDMPStatus();
// USER_CTRL register (DMP functions)
bool getDMPEnabled();
void setDMPEnabled(bool enabled);
void resetDMP();
// BANK_SEL register
void setMemoryBank(uint8_t bank, bool prefetchEnabled=false, bool userBank=false);
// MEM_START_ADDR register
void setMemoryStartAddress(uint8_t address);
// MEM_R_W register
uint8_t readMemoryByte();
void writeMemoryByte(uint8_t data);
@ -795,12 +795,12 @@ class MPU6050 {
uint8_t dmpGetSampleStepSizeMS();
uint8_t dmpGetSampleFrequency();
int32_t dmpDecodeTemperature(int8_t tempReg);
// Register callbacks after a packet of FIFO data is processed
//uint8_t dmpRegisterFIFORateProcess(inv_obj_func func, int16_t priority);
//uint8_t dmpUnregisterFIFORateProcess(inv_obj_func func);
uint8_t dmpRunFIFORateProcesses();
// Setup FIFO for various output
uint8_t dmpSendQuaternion(uint_fast16_t accuracy);
uint8_t dmpSendGyro(uint_fast16_t elements, uint_fast16_t accuracy);
@ -860,7 +860,7 @@ class MPU6050 {
uint8_t dmpGetQuantizedAccel(VectorInt16 *v, const uint8_t* packet=0);
uint8_t dmpGetExternalSensorData(int32_t *data, uint16_t size, const uint8_t* packet=0);
uint8_t dmpGetEIS(int32_t *data, const uint8_t* packet=0);
uint8_t dmpGetEuler(float *data, Quaternion *q);
uint8_t dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity);
@ -896,12 +896,12 @@ class MPU6050 {
uint8_t dmpGetSampleStepSizeMS();
uint8_t dmpGetSampleFrequency();
int32_t dmpDecodeTemperature(int8_t tempReg);
// Register callbacks after a packet of FIFO data is processed
//uint8_t dmpRegisterFIFORateProcess(inv_obj_func func, int16_t priority);
//uint8_t dmpUnregisterFIFORateProcess(inv_obj_func func);
uint8_t dmpRunFIFORateProcesses();
// Setup FIFO for various output
uint8_t dmpSendQuaternion(uint_fast16_t accuracy);
uint8_t dmpSendGyro(uint_fast16_t elements, uint_fast16_t accuracy);
@ -962,7 +962,7 @@ class MPU6050 {
uint8_t dmpGetQuantizedAccel(VectorInt16 *v, const uint8_t* packet=0);
uint8_t dmpGetExternalSensorData(int32_t *data, uint16_t size, const uint8_t* packet=0);
uint8_t dmpGetEIS(int32_t *data, const uint8_t* packet=0);
uint8_t dmpGetEuler(float *data, Quaternion *q);
uint8_t dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity);

View File

@ -3,7 +3,7 @@
// 5/20/2013 by Jeff Rowberg <jeff@rowberg.net>
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
//
// Adapted for Sonoff-Tasmota by Oliver Welter <contact@verbotene.zone> 02-04-2018
// Adapted for Tasmota by Oliver Welter <contact@verbotene.zone> 02-04-2018
//
// Changelog:
// ... - ongoing debug release
@ -71,16 +71,16 @@ THE SOFTWARE.
typedef uint16_t prog_uint16_t;
typedef int32_t prog_int32_t;
typedef uint32_t prog_uint32_t;
#define strcpy_P(dest, src) strcpy((dest), (src))
#define strcat_P(dest, src) strcat((dest), (src))
#define strcmp_P(a, b) strcmp((a), (b))
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define pgm_read_word(addr) (*(const unsigned short *)(addr))
#define pgm_read_dword(addr) (*(const unsigned long *)(addr))
#define pgm_read_float(addr) (*(const float *)(addr))
#define pgm_read_byte_near(addr) pgm_read_byte(addr)
#define pgm_read_word_near(addr) pgm_read_word(addr)
#define pgm_read_dword_near(addr) pgm_read_dword(addr)
@ -732,7 +732,7 @@ uint8_t MPU6050::dmpReadAndProcessFIFOPacket(uint8_t numPackets, uint8_t *proces
// process packet
if ((status = dmpProcessFIFOPacket(buf)) > 0) return status;
// increment external process count variable, if supplied
if (processed != 0) *processed++;
}

View File

@ -3,7 +3,7 @@
// 6/18/2012 by Jeff Rowberg <jeff@rowberg.net>
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
//
// Adapted for Sonoff-Tasmota by Oliver Welter <contact@verbotene.zone> 02-04-2018
// Adapted for Tasmota by Oliver Welter <contact@verbotene.zone> 02-04-2018
//
// Changelog:
// ... - ongoing debug release
@ -67,16 +67,16 @@ THE SOFTWARE.
typedef uint16_t prog_uint16_t;
typedef int32_t prog_int32_t;
typedef uint32_t prog_uint32_t;
#define strcpy_P(dest, src) strcpy((dest), (src))
#define strcat_P(dest, src) strcat((dest), (src))
#define strcmp_P(a, b) strcmp((a), (b))
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define pgm_read_word(addr) (*(const unsigned short *)(addr))
#define pgm_read_dword(addr) (*(const unsigned long *)(addr))
#define pgm_read_float(addr) (*(const float *)(addr))
#define pgm_read_byte_near(addr) pgm_read_byte(addr)
#define pgm_read_word_near(addr) pgm_read_word(addr)
#define pgm_read_dword_near(addr) pgm_read_dword(addr)
@ -159,7 +159,7 @@ const prog_uchar dmpMemory[MPU6050_DMP_CODE_SIZE] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x25, 0x4D, 0x00, 0x2F, 0x70, 0x6D, 0x00, 0x00, 0x05, 0xAE, 0x00, 0x0C, 0x02, 0xD0,
// bank 2, 256 bytes
0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x54, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00,
@ -177,7 +177,7 @@ const prog_uchar dmpMemory[MPU6050_DMP_CODE_SIZE] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x78, 0xA2,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// bank 3, 256 bytes
0xD8, 0xDC, 0xF4, 0xD8, 0xB9, 0xAB, 0xF3, 0xF8, 0xFA, 0xF1, 0xBA, 0xA2, 0xDE, 0xB2, 0xB8, 0xB4,
0xA8, 0x81, 0x98, 0xF7, 0x4A, 0x90, 0x7F, 0x91, 0x6A, 0xF3, 0xF9, 0xDB, 0xA8, 0xF9, 0xB0, 0xBA,
@ -195,7 +195,7 @@ const prog_uchar dmpMemory[MPU6050_DMP_CODE_SIZE] PROGMEM = {
0x7D, 0xAF, 0x83, 0xB5, 0x93, 0xF0, 0x00, 0x28, 0x50, 0xF5, 0xBA, 0xAD, 0x8F, 0x9F, 0x28, 0x54,
0x7C, 0xB9, 0xF1, 0xA3, 0x86, 0x9F, 0x61, 0xA6, 0xDA, 0xDE, 0xDF, 0xDB, 0xB2, 0xB6, 0x8E, 0x9D,
0xAE, 0xF5, 0x60, 0x68, 0x70, 0xB1, 0xB5, 0xF1, 0xDA, 0xA6, 0xDF, 0xD9, 0xA6, 0xFA, 0xA3, 0x86,
// bank 4, 256 bytes
0x96, 0xDB, 0x31, 0xA6, 0xD9, 0xF8, 0xDF, 0xBA, 0xA6, 0x8F, 0xC2, 0xC5, 0xC7, 0xB2, 0x8C, 0xC1,
0xB8, 0xA2, 0xDF, 0xDF, 0xDF, 0xA3, 0xDF, 0xDF, 0xDF, 0xD8, 0xD8, 0xF1, 0xB8, 0xA8, 0xB2, 0x86,
@ -213,7 +213,7 @@ const prog_uchar dmpMemory[MPU6050_DMP_CODE_SIZE] PROGMEM = {
0x32, 0xD8, 0x70, 0x5D, 0xDA, 0x3A, 0xD8, 0x58, 0x79, 0xD9, 0x3A, 0xD8, 0x78, 0x93, 0xA3, 0x4D,
0xDA, 0x2A, 0xD8, 0x48, 0x69, 0xD9, 0x2A, 0xD8, 0x68, 0x55, 0xDA, 0x32, 0xD8, 0x50, 0x71, 0xD9,
0x32, 0xD8, 0x70, 0x5D, 0xDA, 0x3A, 0xD8, 0x58, 0x79, 0xD9, 0x3A, 0xD8, 0x78, 0xA8, 0x8A, 0x9A,
// bank 5, 256 bytes
0xF0, 0x28, 0x50, 0x78, 0x9E, 0xF3, 0x88, 0x18, 0xF1, 0x9F, 0x1D, 0x98, 0xA8, 0xD9, 0x08, 0xD8,
0xC8, 0x9F, 0x12, 0x9E, 0xF3, 0x15, 0xA8, 0xDA, 0x12, 0x10, 0xD8, 0xF1, 0xAF, 0xC8, 0x97, 0x87,
@ -249,7 +249,7 @@ const prog_uchar dmpMemory[MPU6050_DMP_CODE_SIZE] PROGMEM = {
0x81, 0xAD, 0xD9, 0x01, 0xD8, 0xF2, 0xAE, 0xDA, 0x26, 0xD8, 0x8E, 0x91, 0x29, 0x83, 0xA7, 0xD9,
0xAD, 0xAD, 0xAD, 0xAD, 0xF3, 0x2A, 0xD8, 0xD8, 0xF1, 0xB0, 0xAC, 0x89, 0x91, 0x3E, 0x5E, 0x76,
0xF3, 0xAC, 0x2E, 0x2E, 0xF1, 0xB1, 0x8C, 0x5A, 0x9C, 0xAC, 0x2C, 0x28, 0x28, 0x28, 0x9C, 0xAC,
// bank 7, 170 bytes (remainder)
0x30, 0x18, 0xA8, 0x98, 0x81, 0x28, 0x34, 0x3C, 0x97, 0x24, 0xA7, 0x28, 0x34, 0x3C, 0x9C, 0x24,
0xF2, 0xB0, 0x89, 0xAC, 0x91, 0x2C, 0x4C, 0x6C, 0x8A, 0x9B, 0x2D, 0xD9, 0xD8, 0xD8, 0x51, 0xD9,
@ -381,9 +381,9 @@ uint8_t MPU6050::dmpInitialize() {
DEBUG_PRINTLN(ygOffset);
DEBUG_PRINT(F("Z gyro offset = "));
DEBUG_PRINTLN(zgOffset);
I2Cdev::readByte(devAddr, MPU6050_RA_USER_CTRL, buffer); // ?
DEBUG_PRINTLN(F("Enabling interrupt latch, clear on any read, AUX bypass enabled"));
I2Cdev::writeByte(devAddr, MPU6050_RA_INT_PIN_CFG, 0x32);
@ -572,7 +572,7 @@ uint8_t MPU6050::dmpInitialize() {
DEBUG_PRINTLN(F("Writing final memory update 11/19 (function unknown)..."));
for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]);
writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]);
DEBUG_PRINTLN(F("Reading final memory update 12/19 (function unknown)..."));
for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]);
readMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]);
@ -831,7 +831,7 @@ uint8_t MPU6050::dmpReadAndProcessFIFOPacket(uint8_t numPackets, uint8_t *proces
// process packet
if ((status = dmpProcessFIFOPacket(buf)) > 0) return status;
// increment external process count variable, if supplied
if (processed != 0) *processed++;
}

View File

@ -2,7 +2,7 @@
// 6/5/2012 by Jeff Rowberg <jeff@rowberg.net>
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
//
// Adapted for Sonoff-Tasmota by Oliver Welter <contact@verbotene.zone> 02-04-2018
// Adapted for Tasmota by Oliver Welter <contact@verbotene.zone> 02-04-2018
//
// Changelog:
// 2012-06-05 - add 3D math helper file to DMP6 example sketch
@ -40,14 +40,14 @@ class Quaternion {
float x;
float y;
float z;
Quaternion() {
w = 1.0f;
x = 0.0f;
y = 0.0f;
z = 0.0f;
}
Quaternion(float nw, float nx, float ny, float nz) {
w = nw;
x = nx;
@ -71,11 +71,11 @@ class Quaternion {
Quaternion getConjugate() {
return Quaternion(w, -x, -y, -z);
}
float getMagnitude() {
return sqrt(w*w + x*x + y*y + z*z);
}
void normalize() {
float m = getMagnitude();
w /= m;
@ -83,7 +83,7 @@ class Quaternion {
y /= m;
z /= m;
}
Quaternion getNormalized() {
Quaternion r(w, x, y, z);
r.normalize();
@ -102,7 +102,7 @@ class VectorInt16 {
y = 0;
z = 0;
}
VectorInt16(int16_t nx, int16_t ny, int16_t nz) {
x = nx;
y = ny;
@ -119,19 +119,19 @@ class VectorInt16 {
y /= m;
z /= m;
}
VectorInt16 getNormalized() {
VectorInt16 r(x, y, z);
r.normalize();
return r;
}
void rotate(Quaternion *q) {
// http://www.cprogramming.com/tutorial/3d/quaternions.html
// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/transforms/index.htm
// http://content.gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation
// ^ or: http://webcache.googleusercontent.com/search?q=cache:xgJAp3bDNhQJ:content.gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation&hl=en&gl=us&strip=1
// P_out = q * P_in * conj(q)
// - P_out is the output vector
// - q is the orientation quaternion
@ -169,7 +169,7 @@ class VectorFloat {
y = 0;
z = 0;
}
VectorFloat(float nx, float ny, float nz) {
x = nx;
y = ny;
@ -186,13 +186,13 @@ class VectorFloat {
y /= m;
z /= m;
}
VectorFloat getNormalized() {
VectorFloat r(x, y, z);
r.normalize();
return r;
}
void rotate(Quaternion *q) {
Quaternion p(0, x, y, z);

View File

@ -1,82 +0,0 @@
# Contributing to the IRremoteESP8266 library
:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
The following is a set of guidelines for contributing to the IRremoteESP8266 library, hosted on GitHub. These are guidelines, [not rules](http://imgur.com/mSHi8). Use your best judgment, and feel free to propose changes to this document in a pull request.
#### Table Of Contents
[Code of Conduct](#code-of-conduct)
[How Can I Contribute?](#how-can-i-contribute)
* [Reporting Bugs](#reporting-bugs)
* [Pull Requests](#pull-requests)
[Styleguides](#styleguides)
* [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html)
* [Git Commit Messages](#git-commit-messages)
## Code of Conduct
This project and everyone participating in it is governed by the principle of ["Be excellent to each other"](http://www.imdb.com/title/tt0096928/quotes). That's it. TL;DR: _Don't be a jerk._
## How Can I Contribute?
### Reporting Bugs
This section guides you through submitting a bug report for the library. Following these guidelines helps maintainers and the community understand your report :pencil:, reproduce the behavior :computer: :computer:, and find related reports :mag_right:.
Before creating bug reports, please check [this list](#before-submitting-a-bug-report) as you might find out that you don't need to create one. When you are creating a bug report, please [include as much detail as possible](#how-do-i-submit-a-good-bug-report). Fill out [the required template](issue_template.md), the information it asks for helps us resolve issues faster.
> **Note:** If you find a **Closed** issue that seems like it's the same thing that you're experiencing, open a new issue and include a link to the original issue in the body of your new one.
#### Before Submitting A Bug Report
* **Check the [Troubleshooting Guide](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Troubleshooting-Guide).** You might be able to find the cause of the problem and fix it yourself. Most importantly, check if you can reproduce the problem in the latest version (a.k.a. 'master') of the library.
* **Perform a [cursory search](https://github.com/issues?q=+is%3Aissue+repo%3Acrankyoldgit/IRremoteESP8266)** to see if the problem is already reported. If it has **and the issue is still open**, add a comment to the existing issue instead of opening a new one.
#### How Do I Submit A (Good) Bug Report?
Bugs are tracked as [GitHub issues](https://guides.github.com/features/issues/). Create an issue and provide the following information by filling in [the template](issue_template.md).
Explain the problem and include any additional details to help maintainers reproduce the problem:
* **Use a clear and descriptive title** for the issue to identify the problem.
* **Describe the exact steps which reproduce the problem** in as much detail as possible.
* **Provide specific examples to demonstrate the steps**. Include links to files or GitHub projects, or copy/pasteable snippets, which you use in those examples. If you're providing snippets in the issue, use [Markdown code blocks](https://help.github.com/articles/markdown-basics/#multiple-lines).
* **Describe the behavior you observed after following the steps** and point out what exactly is the problem with that behavior.
* **Explain which behavior you expected to see instead and why.**
* **If the problem wasn't triggered by a specific action**, describe what you were doing before the problem happened and share more information using the guidelines below.
Provide more context by answering these questions:
* **Can you reproduce the problem in one of the code examples?**
* **Did the problem start happening recently** (e.g. after updating to a new version of Arduino or the library) or was this always a problem?
* If the problem started happening recently, **can you reproduce the problem in an older version of the library?** What's the most recent version in which the problem doesn't happen? You can download older versions of the library from [the releases page](https://github.com/crankyoldgit/IRremoteESP8266/releases).
* **Can you reliably reproduce the issue?** If not, provide details about how often the problem happens and under which conditions it normally happens.
Include details about your configuration, circuit and environment:
* **Which version of the library are you using?** You can get the exact version by inspecting the `library.json` file in the root directory of the library.
* **What board are you running this on?**
### Pull Requests
* Do not include issue numbers in the PR title
* Include as much data and comments as practicle.
* Follow the [C++ style guide](https://google.github.io/styleguide/cppguide.html).
* Please write or ensure Unit Tests cover the change you are making, if you can.
* End all files with a newline
* Avoid platform-dependent code.
* Use c98 types where possible for better portablity.
* In almost all cases, code & documentation should be peer-reviewed by at least one other contributor.
* The code should pass all the existing testing infrastructure in Travis. e.g. Unit tests, cpplint, and basic compilation.
* State if you have tested this under real conditions if you have, and what other tests you may have carried out.
### Git Commit Messages
* Limit the first line to 72 characters or less
* Reference issues and pull requests liberally after the first line
* Humour is always acceptable. Be liberal with it. ;-)
* While not required, a comprehensive description of all the changes in the PR is best.

View File

@ -1,20 +0,0 @@
## Contributors of this project
### Main contributors & maintainers
- [Mark Szabo](https://github.com/markszabo/) : Initial IR sending on ESP8266
- [Sébastien Warin](https://github.com/sebastienwarin/) (http://sebastien.warin.fr) : Initial IR receiving on ESP8266
- [David Conran](https://github.com/crankyoldgit/) : ESP32 support and pretty much everything else.
- [Roi Dayan](https://github.com/roidayan/)
- [Marcos de Alcântara Marinho](https://github.com/marcosamarinho/)
- [Massimiliano Pinto](https://github.com/pintomax/)
- [Darsh Patel](https://github.com/darshkpatel/)
- [Jonny Graham](https://github.com/jonnygraham/)
- [Stu Fisher](https://github.com/stufisher/)
- [Jorge Cisneros](https://github.com/jorgecis/)
- [Denes Varga](https://github.com/denxhun/)
- [Brett T. Warden](https://github.com/bwarden/)
- [Fabien Valthier](https://github.com/hcoohb)
- [Ajay Pala](https://github.com/ajaypala/)
All contributors can be found on the [contributors site](https://github.com/crankyoldgit/IRremoteESP8266/graphs/contributors).
### Contributors of the [original project](https://github.com/z3t0/Arduino-IRremote) can be found on the [original project's contributors page](https://github.com/z3t0/Arduino-IRremote/blob/master/Contributors.md)

View File

@ -1,42 +0,0 @@
_(Please use this template for reporting issues. You can delete what ever is not relevant. Giving us this information will help us help you faster. Please also read the [FAQ](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Frequently-Asked-Questions) & [Troubleshooting Guide](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Troubleshooting-Guide). Your problem may already have an answer there.)_
### Version/revision of the library used
_Typically located in the `library.json` & `src/IRremoteESP8266.h` files in the root directory of the library.
e.g. v2.0.0, or 'master' as at 1st of June, 2017. etc._
### Expected behavior
_What steps did you do and what should it have done?_
e.g.
1. Initialise the IRsend class.
2. IRsend.sendFoobar(0xdeadbeef);
3. Foobar branded BBQ turns on and cooks me some ribs.
### Actual behavior
_What steps did you do, and what did or didn't actually happen?_
e.g.
1. Initialise the IRsend class.
2. IRsend.sendFoobar(0xdeadbeef);
3. Foobar BBQ went into Cow(er)-saving mode and fried me a couple of eggs instead.
#### Output of raw data from IRrecvDumpV2.ino (if applicable)
_Include some raw dumps of what the device saw._
### Steps to reproduce the behavior
_What can we do to (pref. reliably) repeat what is happening?_
#### Example code used
_Include all relevant code snippets or links to the actual code files. Tip: [How to quote your code so it is still readable](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#code)._
#### Circuit diagram and hardware used (if applicable)
_Link to an image of the circuit diagram used. Part number of the IR receiver module etc. ESP8266 or ESP32 board type._
### I have followed the steps in the [Troubleshooting Guide](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Troubleshooting-Guide) & read the [FAQ](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Frequently-Asked-Questions)
_Yes/No._
### Has this library/code previously worked as expected for you?
_Yes/No. If "Yes", which version last worked for you?_
### Other useful information
_More information is always welcome. Be verbose._

View File

@ -1,53 +0,0 @@
#----------------------------------------#
# .gitingore for IRremoteESP8266 library #
#----------------------------------------#
### Files to ignore.
## Editors
# vi/vim
**/*.swp
# vscode
.vscode
## Build environments
# Platformio
**/.pio/
**/.pioenvs/
**/.piolibdeps/
**/.clang_complete
**/.gcc-flags.json
examples/**/lib
examples/**/.travis.yml
examples/**/.gitignore
lib/readme.txt
lib/googletest/**/*
# GCC pre-compiled headers.
**/*.gch
# Python compiled files
**/*.pyc
# Unit Test builds
test/*.o
test/*.a
test/*_test
# Tools builds
tools/*.o
tools/*.a
tools/gc_decode
tools/mode2_decode
.pioenvs
.piolibdeps
.clang_complete
.gcc-flags.json
#Cygwin builds
*.exe
# Mac extended attributes
.DS_Store

View File

@ -1,4 +0,0 @@
[submodule "lib/googletest"]
path = lib/googletest
url = https://github.com/google/googletest.git
branch = v1.8.x

View File

@ -1,3 +0,0 @@
[style]
based_on_style: google
indent_width: 2

View File

@ -1,74 +0,0 @@
language: c
env:
- BD=esp8266:esp8266:nodemcuv2:xtal=80,eesz=4M3M,ip=lm2f,exception=disabled
# - BD=esp8266:esp8266:d1_mini:xtal=80,eesz=4M3M,ip=lm2f,exception=disabled
before_install:
- "/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16"
- sleep 3
- export DISPLAY=:1.0
- wget http://downloads.arduino.cc/arduino-1.8.8-linux64.tar.xz
- tar xf arduino-1.8.8-linux64.tar.xz
- sudo mv arduino-1.8.8 /usr/local/share/arduino
- sudo ln -s /usr/local/share/arduino/arduino /usr/local/bin/arduino
- wget https://raw.githubusercontent.com/google/styleguide/gh-pages/cpplint/cpplint.py
install:
- ln -s $PWD /usr/local/share/arduino/libraries/
- git clone https://github.com/tzapu/WiFiManager.git /usr/local/share/arduino/libraries/WiFiManager
- git clone https://github.com/knolleary/pubsubclient.git /usr/local/share/arduino/libraries/PubSubClient
- git clone https://github.com/bblanchon/ArduinoJson.git --branch 5.x /usr/local/share/arduino/libraries/ArduinoJson
- arduino --pref "boardsmanager.additional.urls=http://arduino.esp8266.com/stable/package_esp8266com_index.json" --save-prefs
- arduino --install-boards esp8266:esp8266
- arduino --board $BD --save-prefs
- arduino --pref "compiler.warning_level=all" --save-prefs
- sudo apt-get install jq
- sudo apt-get purge python-enum34
- sudo apt-get install pylint3
script: echo Running checks
notifications:
email:
on_success: change
on_failure: change
jobs:
include:
- script:
# Check that everything compiles. (Part 1)
- arduino --verify --board $BD $PWD/examples/IRrecvDemo/IRrecvDemo.ino 2> /dev/null
- arduino --verify --board $BD $PWD/examples/IRGCSendDemo/IRGCSendDemo.ino 2> /dev/null
- arduino --verify --board $BD $PWD/examples/IRGCTCPServer/IRGCTCPServer.ino 2> /dev/null
- arduino --verify --board $BD $PWD/examples/IRServer/IRServer.ino 2> /dev/null
- arduino --verify --board $BD $PWD/examples/IRrecvDumpV2/IRrecvDumpV2.ino 2> /dev/null
- arduino --verify --board $BD $PWD/examples/IRsendDemo/IRsendDemo.ino 2> /dev/null
- arduino --verify --board $BD $PWD/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino 2> /dev/null
- arduino --verify --board $BD $PWD/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino 2> /dev/null
- arduino --verify --board $BD $PWD/examples/TurnOnFujitsuAC/TurnOnFujitsuAC.ino 2> /dev/null
- arduino --verify --board $BD $PWD/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino 2> /dev/null
- arduino --verify --board $BD $PWD/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino 2> /dev/null
- script:
# Check that everything compiles. (Part 2)
- arduino --verify --board $BD $PWD/examples/IRsendProntoDemo/IRsendProntoDemo.ino 2> /dev/null
- arduino --verify --board $BD $PWD/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino 2> /dev/null
- arduino --verify --board $BD $PWD/examples/LGACSend/LGACSend.ino 2> /dev/null
- arduino --verify --board $BD $PWD/examples/TurnOnArgoAC/TurnOnArgoAC.ino 2> /dev/null
- arduino --verify --board $BD $PWD/examples/IRMQTTServer/IRMQTTServer.ino 2> /dev/null
- arduino --verify --board $BD $PWD/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino 2> /dev/null
- arduino --verify --board $BD $PWD/examples/ControlSamsungAC/ControlSamsungAC.ino 2> /dev/null
- arduino --verify --board $BD $PWD/examples/TurnOnPanasonicAC/TurnOnPanasonicAC.ino 2> /dev/null
- arduino --verify --board $BD $PWD/examples/TurnOnMitsubishiHeavyAc/TurnOnMitsubishiHeavyAc.ino 2> /dev/null
- arduino --verify --board $BD $PWD/examples/DumbIRRepeater/DumbIRRepeater.ino 2> /dev/null
- arduino --verify --board $BD $PWD/examples/SmartIRRepeater/SmartIRRepeater.ino 2> /dev/null
- arduino --verify --board $BD $PWD/examples/CommonAcControl/CommonAcControl.ino 2> /dev/null
- script:
# Check the version numbers match.
- LIB_VERSION=$(egrep "^#define\s+_IRREMOTEESP8266_VERSION_\s+" src/IRremoteESP8266.h | cut -d\" -f2)
- test ${LIB_VERSION} == "$(jq -r .version library.json)"
- grep -q "^version=${LIB_VERSION}$" library.properties
# Check the tools programs compile.
- (cd tools; make all)
# Check for lint issues.
- shopt -s nullglob
- python cpplint.py --extensions=c,cc,cpp,ino --headers=h,hpp {src,test,tools}/*.{h,c,cc,cpp,hpp,ino} examples/*/*.{h,c,cc,cpp,hpp,ino}
- pylint3 -d F0001 {src,test,tools}/*.py
- shopt -u nullglob
# Build and run the unit tests.
- (cd test; make run)
- (cd tools; make run_tests)

View File

@ -1,81 +0,0 @@
/* Copyright 2019 David Conran
*
* This example code demonstrates how to use the "Common" IRac class to control
* various air conditions. The IRac class does not support all the features
* for every protocol. Some have more detailed support that what the "Common"
* interface offers, and some only have a limited subset of the "Common" options.
*
* This example code will:
* o Try to turn on, then off every fully supported A/C protocol we know of.
* o It will try to put the A/C unit into Cooling mode at 25C, with a medium
* fan speed, and no fan swinging.
* Note: Some protocols support multiple models, only the first model is tried.
*
*/
#include <Arduino.h>
#include <IRremoteESP8266.h>
#include <IRac.h>
#include <IRutils.h>
const uint16_t kIrLed = 4; // The ESP GPIO pin to use that controls the IR LED.
IRac ac(kIrLed); // Create a A/C object using GPIO to sending messages with.
stdAc::state_t state; // Where we will store the desired state of the A/C.
stdAc::state_t prev; // Where we will store the previous state of the A/C.
void setup() {
Serial.begin(115200);
delay(200);
// Set up what we want to send.
// See state_t, opmode_t, fanspeed_t, swingv_t, & swingh_t in IRsend.h for
// all the various options.
state.protocol = decode_type_t::DAIKIN; // Set a protocol to use.
state.model = 1; // Some A/C's have different models. Let's try using just 1.
state.mode = stdAc::opmode_t::kCool; // Run in cool mode initially.
state.celsius = true; // Use Celsius for units of temp. False = Fahrenheit
state.degrees = 25; // 25 degrees.
state.fanspeed = stdAc::fanspeed_t::kMedium; // Start with the fan at medium.
state.swingv = stdAc::swingv_t::kOff; // Don't swing the fan up or down.
state.swingh = stdAc::swingh_t::kOff; // Don't swing the fan left or right.
state.light = false; // Turn off any LED/Lights/Display that we can.
state.beep = false; // Turn off any beep from the A/C if we can.
state.econo = false; // Turn off any economy modes if we can.
state.filter = false; // Turn off any Ion/Mold/Health filters if we can.
state.turbo = false; // Don't use any turbo/powerful/etc modes.
state.quiet = false; // Don't use any quiet/silent/etc modes.
state.sleep = -1; // Don't set any sleep time or modes.
state.clean = false; // Turn off any Cleaning options if we can.
state.clock = -1; // Don't set any current time if we can avoid it.
state.power = false; // Initially start with the unit off.
prev = state; // Make sure we have a valid previous state.
}
void loop() {
// For every protocol the library has ...
for (int i = 1; i < kLastDecodeType; i++) {
decode_type_t protocol = (decode_type_t)i;
// If the protocol is supported by the IRac class ...
if (ac.isProtocolSupported(protocol)) {
state.protocol = protocol; // Change the protocol used.
Serial.println("Protocol " + String(protocol) + " / " +
typeToString(protocol));
state.power = true; // We want to turn on the A/C unit.
// Have the IRac class create and send a message.
// We need a `prev` state as some A/Cs use toggle messages.
// e.g. On & Off are the same message. When given the previous state,
// it will try to do the correct thing for you.
ac.sendAc(state, &prev); // Construct and send the message.
Serial.println("Sent a message to turn ON the A/C unit.");
prev = state; // Copy new state over the previous one.
delay(5000); // Wait 5 seconds.
state.power = false; // Now we want to turn the A/C off.
ac.sendAc(state, &prev); // Construct and send the message.
Serial.println("Sent a message to turn OFF the A/C unit.");
prev = state; // Copy new state over the previous one.
delay(1000); // Wait 1 second.
}
}
Serial.println("Starting from the begining again ...");
}

View File

@ -1,18 +0,0 @@
[platformio]
src_dir = .
[env]
lib_extra_dirs = ../../
lib_ldf_mode = deep+
lib_ignore = examples
build_flags =
[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
[env:esp32dev]
platform = espressif32
framework = arduino
board = esp32dev

View File

@ -1,18 +0,0 @@
[platformio]
src_dir = .
[env]
lib_extra_dirs = ../../
lib_ldf_mode = deep+
lib_ignore = examples
build_flags =
[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
[env:esp32dev]
platform = espressif32
framework = arduino
board = esp32dev

View File

@ -1,18 +0,0 @@
[platformio]
src_dir = .
[env]
lib_extra_dirs = ../../
lib_ldf_mode = deep+
lib_ignore = examples
build_flags =
[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
[env:esp32dev]
platform = espressif32
framework = arduino
board = esp32dev

View File

@ -1,18 +0,0 @@
[platformio]
src_dir = .
[env]
lib_extra_dirs = ../../
lib_ldf_mode = deep+
lib_ignore = examples
build_flags =
[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
[env:esp32dev]
platform = espressif32
framework = arduino
board = esp32dev

View File

@ -1,18 +0,0 @@
[platformio]
src_dir = .
[env]
lib_extra_dirs = ../../
lib_ldf_mode = deep+
lib_ignore = examples
build_flags =
[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
[env:esp32dev]
platform = espressif32
framework = arduino
board = esp32dev

View File

@ -1,18 +0,0 @@
[platformio]
src_dir = .
[env]
lib_extra_dirs = ../../
lib_ldf_mode = deep+
lib_ignore = examples
build_flags =
[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
[env:esp32dev]
platform = espressif32
framework = arduino
board = esp32dev

View File

@ -1,18 +0,0 @@
[platformio]
src_dir = .
[env]
lib_extra_dirs = ../../
lib_ldf_mode = deep+
lib_ignore = examples
build_flags =
[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
[env:esp32dev]
platform = espressif32
framework = arduino
board = esp32dev

View File

@ -1,18 +0,0 @@
[platformio]
src_dir = .
[env]
lib_extra_dirs = ../../
lib_ldf_mode = deep+
lib_ignore = examples
build_flags =
[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
[env:esp32dev]
platform = espressif32
framework = arduino
board = esp32dev

View File

@ -1,18 +0,0 @@
[platformio]
src_dir = .
[env]
lib_extra_dirs = ../../
lib_ldf_mode = deep+
lib_ignore = examples
build_flags =
[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
[env:esp32dev]
platform = espressif32
framework = arduino
board = esp32dev

View File

@ -1,18 +0,0 @@
[platformio]
src_dir = .
[env]
lib_extra_dirs = ../../
lib_ldf_mode = deep+
lib_ignore = examples
build_flags =
[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
[env:esp32dev]
platform = espressif32
framework = arduino
board = esp32dev

View File

@ -1,18 +0,0 @@
[platformio]
src_dir = .
[env]
lib_extra_dirs = ../../
lib_ldf_mode = deep+
lib_ignore = examples
build_flags =
[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
[env:esp32dev]
platform = espressif32
framework = arduino
board = esp32dev

View File

@ -1,18 +0,0 @@
[platformio]
src_dir = .
[env]
lib_extra_dirs = ../../
lib_ldf_mode = deep+
lib_ignore = examples
build_flags =
[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
[env:esp32dev]
platform = espressif32
framework = arduino
board = esp32dev

View File

@ -1,18 +0,0 @@
[platformio]
src_dir = .
[env]
lib_extra_dirs = ../../
lib_ldf_mode = deep+
lib_ignore = examples
build_flags =
[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
[env:esp32dev]
platform = espressif32
framework = arduino
board = esp32dev

View File

@ -1,18 +0,0 @@
[platformio]
src_dir = .
[env]
lib_extra_dirs = ../../
lib_ldf_mode = deep+
lib_ignore = examples
build_flags =
[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
[env:esp32dev]
platform = espressif32
framework = arduino
board = esp32dev

View File

@ -1,18 +0,0 @@
[platformio]
src_dir = .
[env]
lib_extra_dirs = ../../
lib_ldf_mode = deep+
lib_ignore = examples
build_flags =
[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
[env:esp32dev]
platform = espressif32
framework = arduino
board = esp32dev

View File

@ -1,18 +0,0 @@
[platformio]
src_dir = .
[env]
lib_extra_dirs = ../../
lib_ldf_mode = deep+
lib_ignore = examples
build_flags =
[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
[env:esp32dev]
platform = espressif32
framework = arduino
board = esp32dev

View File

@ -1,18 +0,0 @@
[platformio]
src_dir = .
[env]
lib_extra_dirs = ../../
lib_ldf_mode = deep+
lib_ignore = examples
build_flags =
[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
[env:esp32dev]
platform = espressif32
framework = arduino
board = esp32dev

View File

@ -1,18 +0,0 @@
[platformio]
src_dir = .
[env]
lib_extra_dirs = ../../
lib_ldf_mode = deep+
lib_ignore = examples
build_flags =
[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
[env:esp32dev]
platform = espressif32
framework = arduino
board = esp32dev

View File

@ -1,18 +0,0 @@
[platformio]
src_dir = .
[env]
lib_extra_dirs = ../../
lib_ldf_mode = deep+
lib_ignore = examples
build_flags =
[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
[env:esp32dev]
platform = espressif32
framework = arduino
board = esp32dev

View File

@ -1,442 +0,0 @@
// Copyright 2018 David Conran
//
// Code to emulate Hitachi protocol compatible devices.
// Should be compatible with:
// * Hitachi RAS-35THA6 remote
//
#include "ir_Hitachi.h"
#include <algorithm>
#ifndef ARDUINO
#include <string>
#endif
#include "IRrecv.h"
#include "IRremoteESP8266.h"
#include "IRsend.h"
#include "IRutils.h"
// Constants
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/417
const uint16_t kHitachiAcHdrMark = 3300;
const uint16_t kHitachiAcHdrSpace = 1700;
const uint16_t kHitachiAc1HdrMark = 3400;
const uint16_t kHitachiAc1HdrSpace = 3400;
const uint16_t kHitachiAcBitMark = 400;
const uint16_t kHitachiAcOneSpace = 1250;
const uint16_t kHitachiAcZeroSpace = 500;
const uint32_t kHitachiAcMinGap = kDefaultMessageGap; // Just a guess.
using irutils::addBoolToString;
using irutils::addIntToString;
using irutils::addLabeledString;
using irutils::addModeToString;
using irutils::addFanToString;
using irutils::addTempToString;
#if (SEND_HITACHI_AC || SEND_HITACHI_AC2)
// Send a Hitachi A/C message.
//
// Args:
// data: An array of bytes containing the IR command.
// nbytes: Nr. of bytes of data in the array. (>=kHitachiAcStateLength)
// repeat: Nr. of times the message is to be repeated. (Default = 0).
//
// Status: ALPHA / Untested.
//
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/417
void IRsend::sendHitachiAC(const unsigned char data[], const uint16_t nbytes,
const uint16_t repeat) {
if (nbytes < kHitachiAcStateLength)
return; // Not enough bytes to send a proper message.
sendGeneric(kHitachiAcHdrMark, kHitachiAcHdrSpace, kHitachiAcBitMark,
kHitachiAcOneSpace, kHitachiAcBitMark, kHitachiAcZeroSpace,
kHitachiAcBitMark, kHitachiAcMinGap, data, nbytes, 38, true,
repeat, 50);
}
#endif // (SEND_HITACHI_AC || SEND_HITACHI_AC2)
#if SEND_HITACHI_AC1
// Send a Hitachi A/C 13-byte message.
//
// For devices:
// Hitachi A/C Series VI (Circa 2007) / Remote: LT0541-HTA
//
// Args:
// data: An array of bytes containing the IR command.
// nbytes: Nr. of bytes of data in the array. (>=kHitachiAc1StateLength)
// repeat: Nr. of times the message is to be repeated. (Default = 0).
//
// Status: BETA / Appears to work.
//
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/453
// Basically the same as sendHitatchiAC() except different size and header.
void IRsend::sendHitachiAC1(const unsigned char data[], const uint16_t nbytes,
const uint16_t repeat) {
if (nbytes < kHitachiAc1StateLength)
return; // Not enough bytes to send a proper message.
sendGeneric(kHitachiAc1HdrMark, kHitachiAc1HdrSpace, kHitachiAcBitMark,
kHitachiAcOneSpace, kHitachiAcBitMark, kHitachiAcZeroSpace,
kHitachiAcBitMark, kHitachiAcMinGap, data, nbytes, 38, true,
repeat, 50);
}
#endif // SEND_HITACHI_AC1
#if SEND_HITACHI_AC2
// Send a Hitachi A/C 53-byte message.
//
// For devices:
// Hitachi A/C Series VI (Circa 2007) / Remote: LT0541-HTA
//
// Args:
// data: An array of bytes containing the IR command.
// nbytes: Nr. of bytes of data in the array. (>=kHitachiAc2StateLength)
// repeat: Nr. of times the message is to be repeated. (Default = 0).
//
// Status: BETA / Appears to work.
//
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/417
// Basically the same as sendHitatchiAC() except different size.
void IRsend::sendHitachiAC2(const unsigned char data[], const uint16_t nbytes,
const uint16_t repeat) {
if (nbytes < kHitachiAc2StateLength)
return; // Not enough bytes to send a proper message.
sendHitachiAC(data, nbytes, repeat);
}
#endif // SEND_HITACHI_AC2
// Class for handling the remote control on a Hitachi 28 byte A/C message.
// Inspired by:
// https://github.com/ToniA/arduino-heatpumpir/blob/master/HitachiHeatpumpIR.cpp
IRHitachiAc::IRHitachiAc(const uint16_t pin, const bool inverted,
const bool use_modulation)
: _irsend(pin, inverted, use_modulation) { stateReset(); }
void IRHitachiAc::stateReset(void) {
remote_state[0] = 0x80;
remote_state[1] = 0x08;
remote_state[2] = 0x0C;
remote_state[3] = 0x02;
remote_state[4] = 0xFD;
remote_state[5] = 0x80;
remote_state[6] = 0x7F;
remote_state[7] = 0x88;
remote_state[8] = 0x48;
remote_state[9] = 0x10;
for (uint8_t i = 10; i < kHitachiAcStateLength; i++) remote_state[i] = 0x00;
remote_state[14] = 0x60;
remote_state[15] = 0x60;
remote_state[24] = 0x80;
setTemp(23);
}
void IRHitachiAc::begin(void) { _irsend.begin(); }
uint8_t IRHitachiAc::calcChecksum(const uint8_t state[],
const uint16_t length) {
int8_t sum = 62;
for (uint16_t i = 0; i < length - 1; i++) sum -= reverseBits(state[i], 8);
return reverseBits((uint8_t)sum, 8);
}
void IRHitachiAc::checksum(const uint16_t length) {
remote_state[length - 1] = calcChecksum(remote_state, length);
}
bool IRHitachiAc::validChecksum(const uint8_t state[], const uint16_t length) {
if (length < 2) return true; // Assume true for lengths that are too short.
return (state[length - 1] == calcChecksum(state, length));
}
uint8_t *IRHitachiAc::getRaw(void) {
checksum();
return remote_state;
}
void IRHitachiAc::setRaw(const uint8_t new_code[], const uint16_t length) {
for (uint8_t i = 0; i < length && i < kHitachiAcStateLength; i++)
remote_state[i] = new_code[i];
}
#if SEND_HITACHI_AC
void IRHitachiAc::send(const uint16_t repeat) {
checksum();
_irsend.sendHitachiAC(remote_state, kHitachiAcStateLength, repeat);
}
#endif // SEND_HITACHI_AC
bool IRHitachiAc::getPower(void) { return (remote_state[17] & 0x01); }
void IRHitachiAc::setPower(const bool on) {
if (on)
remote_state[17] |= 0x01;
else
remote_state[17] &= 0xFE;
}
void IRHitachiAc::on(void) { setPower(true); }
void IRHitachiAc::off(void) { setPower(false); }
uint8_t IRHitachiAc::getMode(void) { return reverseBits(remote_state[10], 8); }
void IRHitachiAc::setMode(const uint8_t mode) {
uint8_t newmode = mode;
switch (mode) {
case kHitachiAcFan:
// Fan mode sets a special temp.
setTemp(64);
break;
case kHitachiAcAuto:
case kHitachiAcHeat:
case kHitachiAcCool:
case kHitachiAcDry:
break;
default:
newmode = kHitachiAcAuto;
}
remote_state[10] = reverseBits(newmode, 8);
if (mode != kHitachiAcFan) setTemp(_previoustemp);
setFan(getFan()); // Reset the fan speed after the mode change.
}
uint8_t IRHitachiAc::getTemp(void) {
return reverseBits(remote_state[11], 8) >> 1;
}
void IRHitachiAc::setTemp(const uint8_t celsius) {
uint8_t temp;
if (celsius != 64) _previoustemp = celsius;
switch (celsius) {
case 64:
temp = celsius;
break;
default:
temp = std::min(celsius, kHitachiAcMaxTemp);
temp = std::max(temp, kHitachiAcMinTemp);
}
remote_state[11] = reverseBits(temp << 1, 8);
if (temp == kHitachiAcMinTemp)
remote_state[9] = 0x90;
else
remote_state[9] = 0x10;
}
uint8_t IRHitachiAc::getFan(void) { return reverseBits(remote_state[13], 8); }
void IRHitachiAc::setFan(const uint8_t speed) {
uint8_t fanmin = kHitachiAcFanAuto;
uint8_t fanmax = kHitachiAcFanHigh;
switch (getMode()) {
case kHitachiAcDry: // Only 2 x low speeds in Dry mode.
fanmin = kHitachiAcFanLow;
fanmax = kHitachiAcFanLow + 1;
break;
case kHitachiAcFan:
fanmin = kHitachiAcFanLow; // No Auto in Fan mode.
break;
}
uint8_t newspeed = std::max(speed, fanmin);
newspeed = std::min(newspeed, fanmax);
remote_state[13] = reverseBits(newspeed, 8);
}
bool IRHitachiAc::getSwingVertical(void) { return remote_state[14] & 0x80; }
void IRHitachiAc::setSwingVertical(const bool on) {
if (on)
remote_state[14] |= 0x80;
else
remote_state[14] &= 0x7F;
}
bool IRHitachiAc::getSwingHorizontal(void) { return remote_state[15] & 0x80; }
void IRHitachiAc::setSwingHorizontal(const bool on) {
if (on)
remote_state[15] |= 0x80;
else
remote_state[15] &= 0x7F;
}
// Convert a standard A/C mode into its native mode.
uint8_t IRHitachiAc::convertMode(const stdAc::opmode_t mode) {
switch (mode) {
case stdAc::opmode_t::kCool:
return kHitachiAcCool;
case stdAc::opmode_t::kHeat:
return kHitachiAcHeat;
case stdAc::opmode_t::kDry:
return kHitachiAcDry;
case stdAc::opmode_t::kFan:
return kHitachiAcFan;
default:
return kHitachiAcAuto;
}
}
// Convert a standard A/C Fan speed into its native fan speed.
uint8_t IRHitachiAc::convertFan(const stdAc::fanspeed_t speed) {
switch (speed) {
case stdAc::fanspeed_t::kMin:
case stdAc::fanspeed_t::kLow:
return kHitachiAcFanLow;
case stdAc::fanspeed_t::kMedium:
return kHitachiAcFanLow + 1;
case stdAc::fanspeed_t::kHigh:
return kHitachiAcFanHigh - 1;
case stdAc::fanspeed_t::kMax:
return kHitachiAcFanHigh;
default:
return kHitachiAcFanAuto;
}
}
// Convert a native mode to it's common equivalent.
stdAc::opmode_t IRHitachiAc::toCommonMode(const uint8_t mode) {
switch (mode) {
case kHitachiAcCool: return stdAc::opmode_t::kCool;
case kHitachiAcHeat: return stdAc::opmode_t::kHeat;
case kHitachiAcDry: return stdAc::opmode_t::kDry;
case kHitachiAcFan: return stdAc::opmode_t::kFan;
default: return stdAc::opmode_t::kAuto;
}
}
// Convert a native fan speed to it's common equivalent.
stdAc::fanspeed_t IRHitachiAc::toCommonFanSpeed(const uint8_t speed) {
switch (speed) {
case kHitachiAcFanHigh: return stdAc::fanspeed_t::kMax;
case kHitachiAcFanHigh - 1: return stdAc::fanspeed_t::kHigh;
case kHitachiAcFanLow + 1: return stdAc::fanspeed_t::kMedium;
case kHitachiAcFanLow: return stdAc::fanspeed_t::kLow;
default: return stdAc::fanspeed_t::kAuto;
}
}
// Convert the A/C state to it's common equivalent.
stdAc::state_t IRHitachiAc::toCommon(void) {
stdAc::state_t result;
result.protocol = decode_type_t::HITACHI_AC;
result.model = -1; // No models used.
result.power = this->getPower();
result.mode = this->toCommonMode(this->getMode());
result.celsius = true;
result.degrees = this->getTemp();
result.fanspeed = this->toCommonFanSpeed(this->getFan());
result.swingv = this->getSwingVertical() ? stdAc::swingv_t::kAuto :
stdAc::swingv_t::kOff;
result.swingh = this->getSwingHorizontal() ? stdAc::swingh_t::kAuto :
stdAc::swingh_t::kOff;
// Not supported.
result.quiet = false;
result.turbo = false;
result.clean = false;
result.econo = false;
result.filter = false;
result.light = false;
result.beep = false;
result.sleep = -1;
result.clock = -1;
return result;
}
// Convert the internal state into a human readable string.
String IRHitachiAc::toString(void) {
String result = "";
result.reserve(110); // Reserve some heap for the string to reduce fragging.
result += addBoolToString(getPower(), F("Power"), false);
result += addModeToString(getMode(), kHitachiAcAuto, kHitachiAcCool,
kHitachiAcHeat, kHitachiAcDry, kHitachiAcFan);
result += addTempToString(getTemp());
result += addFanToString(getFan(), kHitachiAcFanHigh, kHitachiAcFanLow,
kHitachiAcFanAuto, kHitachiAcFanAuto,
kHitachiAcFanMed);
result += addBoolToString(getSwingVertical(), F("Swing (Vertical)"));
result += addBoolToString(getSwingHorizontal(), F("Swing (Horizontal)"));
return result;
}
#if (DECODE_HITACHI_AC || DECODE_HITACHI_AC1 || DECODE_HITACHI_AC2)
// Decode the supplied Hitachi A/C message.
//
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// nbits: The number of data bits to expect.
// Typically kHitachiAcBits, kHitachiAc1Bits, kHitachiAc2Bits
// strict: Flag indicating if we should perform strict matching.
// Returns:
// boolean: True if it can decode it, false if it can't.
//
// Status: ALPHA / Untested.
//
// Supported devices:
// Hitachi A/C Series VI (Circa 2007) / Remote: LT0541-HTA
//
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/417
// https://github.com/crankyoldgit/IRremoteESP8266/issues/453
bool IRrecv::decodeHitachiAC(decode_results *results, const uint16_t nbits,
const bool strict) {
const uint8_t k_tolerance = _tolerance + 5;
if (results->rawlen < 2 * nbits + kHeader + kFooter - 1)
return false; // Can't possibly be a valid HitachiAC message.
if (strict) {
switch (nbits) {
case kHitachiAcBits:
case kHitachiAc1Bits:
case kHitachiAc2Bits:
break; // Okay to continue.
default:
return false; // Not strictly a Hitachi message.
}
}
uint16_t offset = kStartOffset;
uint16_t hmark;
uint32_t hspace;
if (nbits == kHitachiAc1Bits) {
hmark = kHitachiAc1HdrMark;
hspace = kHitachiAc1HdrSpace;
} else {
hmark = kHitachiAcHdrMark;
hspace = kHitachiAcHdrSpace;
}
// Match Header + Data + Footer
if (!matchGeneric(results->rawbuf + offset, results->state,
results->rawlen - offset, nbits,
hmark, hspace,
kHitachiAcBitMark, kHitachiAcOneSpace,
kHitachiAcBitMark, kHitachiAcZeroSpace,
kHitachiAcBitMark, kHitachiAcMinGap, true,
k_tolerance)) return false;
// Compliance
if (strict) {
if (nbits / 8 == kHitachiAcStateLength &&
!IRHitachiAc::validChecksum(results->state, kHitachiAcStateLength))
return false;
}
// Success
switch (nbits) {
case kHitachiAc1Bits:
results->decode_type = HITACHI_AC1;
break;
case kHitachiAc2Bits:
results->decode_type = HITACHI_AC2;
break;
case kHitachiAcBits:
default:
results->decode_type = HITACHI_AC;
}
results->bits = nbits;
// No need to record the state as we stored it as we decoded it.
// As we use result->state, we don't record value, address, or command as it
// is a union data type.
return true;
}
#endif // (DECODE_HITACHI_AC || DECODE_HITACHI_AC1 || DECODE_HITACHI_AC2)

View File

@ -1,90 +0,0 @@
// Hitachi A/C
//
// Copyright 2018 David Conran
// Supports:
// Brand: Hitachi, Model: RAS-35THA6 remote
// Brand: Hitachi, Model: LT0541-HTA remote
// Brand: Hitachi, Model: Series VI A/C (Circa 2007)
#ifndef IR_HITACHI_H_
#define IR_HITACHI_H_
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#ifndef UNIT_TEST
#include <Arduino.h>
#endif
#include "IRremoteESP8266.h"
#include "IRsend.h"
#ifdef UNIT_TEST
#include "IRsend_test.h"
#endif
// Constants
const uint8_t kHitachiAcAuto = 2;
const uint8_t kHitachiAcHeat = 3;
const uint8_t kHitachiAcCool = 4;
const uint8_t kHitachiAcDry = 5;
const uint8_t kHitachiAcFan = 0xC;
const uint8_t kHitachiAcFanAuto = 1;
const uint8_t kHitachiAcFanLow = 2;
const uint8_t kHitachiAcFanMed = 3;
const uint8_t kHitachiAcFanHigh = 5;
const uint8_t kHitachiAcMinTemp = 16; // 16C
const uint8_t kHitachiAcMaxTemp = 32; // 32C
const uint8_t kHitachiAcAutoTemp = 23; // 23C
// Classes
class IRHitachiAc {
public:
explicit IRHitachiAc(const uint16_t pin, const bool inverted = false,
const bool use_modulation = true);
void stateReset(void);
#if SEND_HITACHI_AC
void send(const uint16_t repeat = kHitachiAcDefaultRepeat);
uint8_t calibrate(void) { return _irsend.calibrate(); }
#endif // SEND_HITACHI_AC
void begin(void);
void on(void);
void off(void);
void setPower(const bool on);
bool getPower(void);
void setTemp(const uint8_t temp);
uint8_t getTemp(void);
void setFan(const uint8_t speed);
uint8_t getFan(void);
void setMode(const uint8_t mode);
uint8_t getMode(void);
void setSwingVertical(const bool on);
bool getSwingVertical(void);
void setSwingHorizontal(const bool on);
bool getSwingHorizontal(void);
uint8_t* getRaw(void);
void setRaw(const uint8_t new_code[],
const uint16_t length = kHitachiAcStateLength);
static bool validChecksum(const uint8_t state[],
const uint16_t length = kHitachiAcStateLength);
static uint8_t calcChecksum(const uint8_t state[],
const uint16_t length = kHitachiAcStateLength);
uint8_t convertMode(const stdAc::opmode_t mode);
uint8_t convertFan(const stdAc::fanspeed_t speed);
static stdAc::opmode_t toCommonMode(const uint8_t mode);
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
stdAc::state_t toCommon(void);
String toString(void);
#ifndef UNIT_TEST
private:
IRsend _irsend;
#else
IRsendTest _irsend;
#endif
// The state of the IR remote in IR code form.
uint8_t remote_state[kHitachiAcStateLength];
void checksum(const uint16_t length = kHitachiAcStateLength);
uint8_t _previoustemp;
};
#endif // IR_HITACHI_H_

View File

@ -1,811 +0,0 @@
// Copyright 2009 Ken Shirriff
// Copyright 2017-2018 David Conran
// Copyright 2018 Denes Varga
// Mitsubishi
#include "ir_Mitsubishi.h"
#include <algorithm>
#ifndef ARDUINO
#include <string>
#endif
#include "IRrecv.h"
#include "IRsend.h"
#include "IRutils.h"
// Mitsubishi (TV) decoding added from https://github.com/z3t0/Arduino-IRremote
// Mitsubishi (TV) sending & Mitsubishi A/C support added by David Conran
// Constants
// Mitsubishi TV
// period time is 1/33000Hz = 30.303 uSeconds (T)
// Ref:
// GlobalCache's Control Tower's Mitsubishi TV data.
// https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Mitsubishi.cpp
const uint16_t kMitsubishiTick = 30;
const uint16_t kMitsubishiBitMarkTicks = 10;
const uint16_t kMitsubishiBitMark = kMitsubishiBitMarkTicks * kMitsubishiTick;
const uint16_t kMitsubishiOneSpaceTicks = 70;
const uint16_t kMitsubishiOneSpace = kMitsubishiOneSpaceTicks * kMitsubishiTick;
const uint16_t kMitsubishiZeroSpaceTicks = 30;
const uint16_t kMitsubishiZeroSpace =
kMitsubishiZeroSpaceTicks * kMitsubishiTick;
const uint16_t kMitsubishiMinCommandLengthTicks = 1786;
const uint16_t kMitsubishiMinCommandLength =
kMitsubishiMinCommandLengthTicks * kMitsubishiTick;
const uint16_t kMitsubishiMinGapTicks = 936;
const uint16_t kMitsubishiMinGap = kMitsubishiMinGapTicks * kMitsubishiTick;
// Mitsubishi Projector (HC3000)
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/441
const uint16_t kMitsubishi2HdrMark = 8400;
const uint16_t kMitsubishi2HdrSpace = kMitsubishi2HdrMark / 2;
const uint16_t kMitsubishi2BitMark = 560;
const uint16_t kMitsubishi2ZeroSpace = 520;
const uint16_t kMitsubishi2OneSpace = kMitsubishi2ZeroSpace * 3;
const uint16_t kMitsubishi2MinGap = 28500;
// Mitsubishi A/C
// Ref:
// https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266.ino#L84
const uint16_t kMitsubishiAcHdrMark = 3400;
const uint16_t kMitsubishiAcHdrSpace = 1750;
const uint16_t kMitsubishiAcBitMark = 450;
const uint16_t kMitsubishiAcOneSpace = 1300;
const uint16_t kMitsubishiAcZeroSpace = 420;
const uint16_t kMitsubishiAcRptMark = 440;
const uint16_t kMitsubishiAcRptSpace = 17100;
using irutils::addBoolToString;
using irutils::addFanToString;
using irutils::addIntToString;
using irutils::addLabeledString;
using irutils::addModeToString;
using irutils::addTempToString;
using irutils::minsToString;
#if SEND_MITSUBISHI
// Send a Mitsubishi message
//
// Args:
// data: Contents of the message to be sent.
// nbits: Nr. of bits of data to be sent. Typically kMitsubishiBits.
// repeat: Nr. of additional times the message is to be sent.
//
// Status: ALPHA / untested.
//
// Notes:
// This protocol appears to have no header.
// Ref:
// https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Mitsubishi.cpp
// GlobalCache's Control Tower's Mitsubishi TV data.
void IRsend::sendMitsubishi(uint64_t data, uint16_t nbits, uint16_t repeat) {
sendGeneric(0, 0, // No Header
kMitsubishiBitMark, kMitsubishiOneSpace, kMitsubishiBitMark,
kMitsubishiZeroSpace, kMitsubishiBitMark, kMitsubishiMinGap,
kMitsubishiMinCommandLength, data, nbits, 33, true, repeat, 50);
}
#endif // SEND_MITSUBISHI
#if DECODE_MITSUBISHI
// Decode the supplied Mitsubishi message.
//
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// nbits: Nr. of data bits to expect.
// strict: Flag indicating if we should perform strict matching.
// Returns:
// boolean: True if it can decode it, false if it can't.
//
// Status: BETA / previously working.
//
// Notes:
// This protocol appears to have no header.
//
// Ref:
// GlobalCache's Control Tower's Mitsubishi TV data.
bool IRrecv::decodeMitsubishi(decode_results *results, uint16_t nbits,
bool strict) {
if (strict && nbits != kMitsubishiBits)
return false; // Request is out of spec.
uint16_t offset = kStartOffset;
uint64_t data = 0;
// Match Data + Footer
if (!matchGeneric(results->rawbuf + offset, &data,
results->rawlen - offset, nbits,
0, 0, // No header
kMitsubishiBitMark, kMitsubishiOneSpace,
kMitsubishiBitMark, kMitsubishiZeroSpace,
kMitsubishiBitMark, kMitsubishiMinGap,
true, 30)) return false;
// Success
results->decode_type = MITSUBISHI;
results->bits = nbits;
results->value = data;
results->address = 0;
results->command = 0;
return true;
}
#endif // DECODE_MITSUBISHI
#if SEND_MITSUBISHI2
// Send a Mitsubishi2 message
//
// Args:
// data: Contents of the message to be sent.
// nbits: Nr. of bits of data to be sent. Typically kMitsubishiBits.
// repeat: Nr. of additional times the message is to be sent.
//
// Status: ALPHA / untested.
//
// Notes:
// Based on a Mitsubishi HC3000 projector's remote.
// This protocol appears to have a manditory in-protocol repeat.
// That is in *addition* to the entire message needing to be sent twice
// for the device to accept the command. That is separate from the repeat.
// i.e. Allegedly, the real remote requires the "Off" button pressed twice.
// You will need to add a suitable gap yourself.
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/441
void IRsend::sendMitsubishi2(uint64_t data, uint16_t nbits, uint16_t repeat) {
for (uint16_t i = 0; i <= repeat; i++) {
// First half of the data.
sendGeneric(kMitsubishi2HdrMark, kMitsubishi2HdrSpace, kMitsubishi2BitMark,
kMitsubishi2OneSpace, kMitsubishi2BitMark,
kMitsubishi2ZeroSpace, kMitsubishi2BitMark,
kMitsubishi2HdrSpace, data >> (nbits / 2), nbits / 2, 33, true,
0, 50);
// Second half of the data.
sendGeneric(0, 0, // No header for the second data block
kMitsubishi2BitMark, kMitsubishi2OneSpace, kMitsubishi2BitMark,
kMitsubishi2ZeroSpace, kMitsubishi2BitMark, kMitsubishi2MinGap,
data & ((1 << (nbits / 2)) - 1), nbits / 2, 33, true, 0, 50);
}
}
#endif // SEND_MITSUBISHI2
#if DECODE_MITSUBISHI2
// Decode the supplied Mitsubishi2 message.
//
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// nbits: Nr. of data bits to expect.
// strict: Flag indicating if we should perform strict matching.
// Returns:
// boolean: True if it can decode it, false if it can't.
//
// Status: BETA / Works with simulated data.
//
// Notes:
// Hardware supported:
// * Mitsubishi HC3000 projector's remote.
//
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/441
bool IRrecv::decodeMitsubishi2(decode_results *results, uint16_t nbits,
bool strict) {
if (results->rawlen < 2 * nbits + kHeader + (kFooter * 2) - 1)
return false; // Shorter than shortest possibly expected.
if (strict && nbits != kMitsubishiBits)
return false; // Request is out of spec.
uint16_t offset = kStartOffset;
results->value = 0;
// Header
if (!matchMark(results->rawbuf[offset++], kMitsubishi2HdrMark)) return false;
if (!matchSpace(results->rawbuf[offset++], kMitsubishi2HdrSpace))
return false;
for (uint8_t i = 0; i < 2; i++) {
// Match Data + Footer
uint16_t used;
uint64_t data = 0;
used = matchGeneric(results->rawbuf + offset, &data,
results->rawlen - offset, nbits / 2,
0, 0, // No header
kMitsubishi2BitMark, kMitsubishi2OneSpace,
kMitsubishi2BitMark, kMitsubishi2ZeroSpace,
kMitsubishi2BitMark, kMitsubishi2HdrSpace,
i % 2);
if (!used) return false;
offset += used;
results->value <<= (nbits / 2);
results->value += data;
}
// Success
results->decode_type = MITSUBISHI2;
results->bits = nbits;
results->address = results->value >> (nbits / 2);
results->command = results->value & ((1 << (nbits / 2)) - 1);
return true;
}
#endif // DECODE_MITSUBISHI2
#if SEND_MITSUBISHI_AC
// Send a Mitsubishi A/C message.
//
// Args:
// data: An array of bytes containing the IR command.
// nbytes: Nr. of bytes of data in the array. (>=kMitsubishiACStateLength)
// repeat: Nr. of times the message is to be repeated.
// (Default = kMitsubishiACMinRepeat).
//
// Status: BETA / Appears to be working.
//
void IRsend::sendMitsubishiAC(const unsigned char data[], const uint16_t nbytes,
const uint16_t repeat) {
if (nbytes < kMitsubishiACStateLength)
return; // Not enough bytes to send a proper message.
sendGeneric(kMitsubishiAcHdrMark, kMitsubishiAcHdrSpace, kMitsubishiAcBitMark,
kMitsubishiAcOneSpace, kMitsubishiAcBitMark,
kMitsubishiAcZeroSpace, kMitsubishiAcRptMark,
kMitsubishiAcRptSpace, data, nbytes, 38, false, repeat, 50);
}
#endif // SEND_MITSUBISHI_AC
#if DECODE_MITSUBISHI_AC
// Decode the supplied Mitsubishi message.
//
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// nbits: Nr. of data bits to expect.
// strict: Flag indicating if we should perform strict matching.
// Returns:
// boolean: True if it can decode it, false if it can't.
//
// Status: ALPHA / Under development
//
// Ref:
// https://www.analysir.com/blog/2015/01/06/reverse-engineering-mitsubishi-ac-infrared-protocol/
bool IRrecv::decodeMitsubishiAC(decode_results *results, uint16_t nbits,
bool strict) {
if (results->rawlen < ((kMitsubishiACBits * 2) + 2)) {
DPRINTLN("Shorter than shortest possibly expected.");
return false; // Shorter than shortest possibly expected.
}
if (strict && nbits != kMitsubishiACBits) {
DPRINTLN("Request is out of spec.");
return false; // Request is out of spec.
}
uint16_t offset = kStartOffset;
for (uint8_t i = 0; i < kMitsubishiACStateLength; i++) {
results->state[i] = 0;
}
bool failure = false;
uint8_t rep = 0;
do {
failure = false;
// Header:
// Sometime happens that junk signals arrives before the real message
bool headerFound = false;
while (!headerFound &&
offset < (results->rawlen - (kMitsubishiACBits * 2 + 2))) {
headerFound =
matchMark(results->rawbuf[offset++], kMitsubishiAcHdrMark) &&
matchSpace(results->rawbuf[offset++], kMitsubishiAcHdrSpace);
}
if (!headerFound) {
DPRINTLN("Header mark not found.");
failure = true;
}
// Decode byte-by-byte:
match_result_t data_result;
for (uint8_t i = 0; i < kMitsubishiACStateLength && !failure; i++) {
results->state[i] = 0;
data_result =
matchData(&(results->rawbuf[offset]), 8, kMitsubishiAcBitMark,
kMitsubishiAcOneSpace, kMitsubishiAcBitMark,
kMitsubishiAcZeroSpace, _tolerance, kMarkExcess, false);
if (data_result.success == false) {
failure = true;
DPRINT("Byte decode failed at #");
DPRINTLN((uint16_t)i);
} else {
results->state[i] = data_result.data;
offset += data_result.used;
DPRINT((uint16_t)results->state[i]);
DPRINT(",");
}
DPRINTLN("");
}
// HEADER validation:
if (failure || results->state[0] != 0x23 || results->state[1] != 0xCB ||
results->state[2] != 0x26 || results->state[3] != 0x01 ||
results->state[4] != 0x00) {
DPRINTLN("Header mismatch.");
failure = true;
} else {
// DATA part:
// FOOTER checksum:
if (IRMitsubishiAC::calculateChecksum(results->state) !=
results->state[kMitsubishiACStateLength - 1]) {
DPRINTLN("Checksum error.");
failure = true;
}
}
if (rep != kMitsubishiACMinRepeat && failure) {
bool repeatMarkFound = false;
while (!repeatMarkFound &&
offset < (results->rawlen - (kMitsubishiACBits * 2 + 4))) {
repeatMarkFound =
matchMark(results->rawbuf[offset++], kMitsubishiAcRptMark) &&
matchSpace(results->rawbuf[offset++], kMitsubishiAcRptSpace);
}
if (!repeatMarkFound) {
DPRINTLN("First attempt failure and repeat mark not found.");
return false;
}
}
rep++;
// Check if the repeat is correct if we need strict decode:
if (strict && !failure) {
DPRINTLN("Strict repeat check enabled.");
// Repeat mark and space:
if (!matchMark(results->rawbuf[offset++], kMitsubishiAcRptMark) ||
!matchSpace(results->rawbuf[offset++], kMitsubishiAcRptSpace)) {
DPRINTLN("Repeat mark error.");
return false;
}
// Header mark and space:
if (!matchMark(results->rawbuf[offset++], kMitsubishiAcHdrMark) ||
!matchSpace(results->rawbuf[offset++], kMitsubishiAcHdrSpace)) {
DPRINTLN("Repeat header error.");
return false;
}
// Payload:
for (uint8_t i = 0; i < kMitsubishiACStateLength; i++) {
data_result =
matchData(&(results->rawbuf[offset]), 8, kMitsubishiAcBitMark,
kMitsubishiAcOneSpace, kMitsubishiAcBitMark,
kMitsubishiAcZeroSpace, _tolerance, kMarkExcess, false);
if (data_result.success == false ||
data_result.data != results->state[i]) {
DPRINTLN("Repeat payload error.");
return false;
}
offset += data_result.used;
}
} // strict repeat check
} while (failure && rep <= kMitsubishiACMinRepeat);
results->decode_type = MITSUBISHI_AC;
results->bits = kMitsubishiACStateLength * 8;
return true;
}
#endif // DECODE_MITSUBISHI_AC
// Code to emulate Mitsubishi A/C IR remote control unit.
// Inspired and derived from the work done at:
// https://github.com/r45635/HVAC-IR-Control
//
// Warning: Consider this very alpha code. Seems to work, but not validated.
//
// Equipment it seems compatible with:
// * <Add models (A/C & remotes) you've gotten it working with here>
// Initialise the object.
IRMitsubishiAC::IRMitsubishiAC(const uint16_t pin, const bool inverted,
const bool use_modulation)
: _irsend(pin, inverted, use_modulation) { this->stateReset(); }
// Reset the state of the remote to a known good state/sequence.
void IRMitsubishiAC::stateReset(void) {
// The state of the IR remote in IR code form.
// Known good state obtained from:
// https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266.ino#L108
// Note: Can't use the following because it requires -std=c++11
// uint8_t known_good_state[kMitsubishiACStateLength] = {
// 0x23, 0xCB, 0x26, 0x01, 0x00, 0x20, 0x08, 0x06, 0x30, 0x45, 0x67, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F};
remote_state[0] = 0x23;
remote_state[1] = 0xCB;
remote_state[2] = 0x26;
remote_state[3] = 0x01;
remote_state[4] = 0x00;
remote_state[5] = 0x20;
remote_state[6] = 0x08;
remote_state[7] = 0x06;
remote_state[8] = 0x30;
remote_state[9] = 0x45;
remote_state[10] = 0x67;
for (uint8_t i = 11; i < kMitsubishiACStateLength - 1; i++)
remote_state[i] = 0;
remote_state[kMitsubishiACStateLength - 1] = 0x1F;
this->checksum(); // Calculate the checksum
}
// Configure the pin for output.
void IRMitsubishiAC::begin(void) { _irsend.begin(); }
#if SEND_MITSUBISHI_AC
// Send the current desired state to the IR LED.
void IRMitsubishiAC::send(const uint16_t repeat) {
this->checksum(); // Ensure correct checksum before sending.
_irsend.sendMitsubishiAC(remote_state, kMitsubishiACStateLength, repeat);
}
#endif // SEND_MITSUBISHI_AC
// Return a pointer to the internal state date of the remote.
uint8_t *IRMitsubishiAC::getRaw(void) {
this->checksum();
return remote_state;
}
void IRMitsubishiAC::setRaw(const uint8_t *data) {
for (uint8_t i = 0; i < (kMitsubishiACStateLength - 1); i++) {
remote_state[i] = data[i];
}
this->checksum();
}
// Calculate the checksum for the current internal state of the remote.
void IRMitsubishiAC::checksum(void) {
remote_state[17] = this->calculateChecksum(remote_state);
}
uint8_t IRMitsubishiAC::calculateChecksum(const uint8_t *data) {
uint8_t sum = 0;
// Checksum is simple addition of all previous bytes stored
// as an 8 bit value.
for (uint8_t i = 0; i < 17; i++) sum += data[i];
return sum & 0xFFU;
}
// Set the requested power state of the A/C to off.
void IRMitsubishiAC::on(void) {
// state = ON;
remote_state[5] |= kMitsubishiAcPower;
}
// Set the requested power state of the A/C to off.
void IRMitsubishiAC::off(void) {
// state = OFF;
remote_state[5] &= ~kMitsubishiAcPower;
}
// Set the requested power state of the A/C.
void IRMitsubishiAC::setPower(bool on) {
if (on)
this->on();
else
this->off();
}
// Return the requested power state of the A/C.
bool IRMitsubishiAC::getPower(void) {
return ((remote_state[5] & kMitsubishiAcPower) != 0);
}
// Set the temp. in deg C
void IRMitsubishiAC::setTemp(const uint8_t degrees) {
uint8_t temp = std::max((uint8_t)kMitsubishiAcMinTemp, degrees);
temp = std::min((uint8_t)kMitsubishiAcMaxTemp, temp);
remote_state[7] = temp - kMitsubishiAcMinTemp;
}
// Return the set temp. in deg C
uint8_t IRMitsubishiAC::getTemp(void) {
return (remote_state[7] + kMitsubishiAcMinTemp);
}
// Set the speed of the fan, 0-6.
// 0 is auto, 1-5 is the speed, 6 is silent.
void IRMitsubishiAC::setFan(const uint8_t speed) {
uint8_t fan = speed;
// Bounds check
if (fan > kMitsubishiAcFanSilent)
fan = kMitsubishiAcFanMax; // Set the fan to maximum if out of range.
if (fan == kMitsubishiAcFanAuto) { // Automatic is a special case.
remote_state[9] = 0b10000000 | (remote_state[9] & 0b01111000);
return;
} else if (fan >= kMitsubishiAcFanMax) {
fan--; // There is no spoon^H^H^Heed 5 (max), pretend it doesn't exist.
}
remote_state[9] &= 0b01111000; // Clear the previous state
remote_state[9] |= fan;
}
// Return the requested state of the unit's fan.
uint8_t IRMitsubishiAC::getFan(void) {
uint8_t fan = remote_state[9] & 0b111;
if (fan == kMitsubishiAcFanMax) return kMitsubishiAcFanSilent;
return fan;
}
// Return the requested climate operation mode of the a/c unit.
uint8_t IRMitsubishiAC::getMode(void) { return (remote_state[6]); }
// Set the requested climate operation mode of the a/c unit.
void IRMitsubishiAC::setMode(const uint8_t mode) {
// If we get an unexpected mode, default to AUTO.
switch (mode) {
case kMitsubishiAcAuto:
remote_state[8] = 0b00110000;
break;
case kMitsubishiAcCool:
remote_state[8] = 0b00110110;
break;
case kMitsubishiAcDry:
remote_state[8] = 0b00110010;
break;
case kMitsubishiAcHeat:
remote_state[8] = 0b00110000;
break;
default:
this->setMode(kMitsubishiAcAuto);
return;
}
remote_state[6] = mode;
}
// Set the requested vane operation mode of the a/c unit.
void IRMitsubishiAC::setVane(const uint8_t position) {
uint8_t pos = std::min(position, (uint8_t)0b111); // bounds check
pos |= 0b1000;
pos <<= 3;
remote_state[9] &= 0b11000111; // Clear the previous setting.
remote_state[9] |= pos;
}
// Set the requested wide-vane operation mode of the a/c unit.
void IRMitsubishiAC::setWideVane(const uint8_t position) {
uint8_t pos = std::min(position, kMitsubishiAcWideVaneAuto); // bounds check
pos <<= 4;
remote_state[8] &= 0b00001111; // Clear the previous setting.
remote_state[8] |= pos;
}
// Return the requested vane operation mode of the a/c unit.
uint8_t IRMitsubishiAC::getVane(void) {
return ((remote_state[9] & 0b00111000) >> 3);
}
// Return the requested wide vane operation mode of the a/c unit.
uint8_t IRMitsubishiAC::getWideVane(void) {
return (remote_state[8] >> 4);
}
// Return the clock setting of the message. 1=1/6 hour. e.g. 4pm = 48
uint8_t IRMitsubishiAC::getClock(void) { return remote_state[10]; }
// Set the current time. 1 = 1/6 hour. e.g. 6am = 36.
void IRMitsubishiAC::setClock(const uint8_t clock) {
remote_state[10] = clock;
}
// Return the desired start time. 1 = 1/6 hour. e.g. 1am = 6
uint8_t IRMitsubishiAC::getStartClock(void) { return remote_state[12]; }
// Set the desired start time of the AC. 1 = 1/6 hour. e.g. 8pm = 120
void IRMitsubishiAC::setStartClock(const uint8_t clock) {
remote_state[12] = clock;
}
// Return the desired stop time of the AC. 1 = 1/6 hour. e.g 10pm = 132
uint8_t IRMitsubishiAC::getStopClock(void) { return remote_state[11]; }
// Set the desired stop time of the AC. 1 = 1/6 hour. e.g 10pm = 132
void IRMitsubishiAC::setStopClock(const uint8_t clock) {
remote_state[11] = clock;
}
// Return the timer setting. Possible values: kMitsubishiAcNoTimer,
// kMitsubishiAcStartTimer, kMitsubishiAcStopTimer,
// kMitsubishiAcStartStopTimer
uint8_t IRMitsubishiAC::getTimer(void) { return remote_state[13] & 0b111; }
// Set the timer setting. Possible values: kMitsubishiAcNoTimer,
// kMitsubishiAcStartTimer, kMitsubishiAcStopTimer,
// kMitsubishiAcStartStopTimer
void IRMitsubishiAC::setTimer(uint8_t timer) {
remote_state[13] = timer & 0b111;
}
// Convert a standard A/C mode into its native mode.
uint8_t IRMitsubishiAC::convertMode(const stdAc::opmode_t mode) {
switch (mode) {
case stdAc::opmode_t::kCool:
return kMitsubishiAcCool;
case stdAc::opmode_t::kHeat:
return kMitsubishiAcHeat;
case stdAc::opmode_t::kDry:
return kMitsubishiAcDry;
default:
return kMitsubishiAcAuto;
}
}
// Convert a standard A/C Fan speed into its native fan speed.
uint8_t IRMitsubishiAC::convertFan(const stdAc::fanspeed_t speed) {
switch (speed) {
case stdAc::fanspeed_t::kMin:
return kMitsubishiAcFanSilent;
case stdAc::fanspeed_t::kLow:
return kMitsubishiAcFanRealMax - 3;
case stdAc::fanspeed_t::kMedium:
return kMitsubishiAcFanRealMax - 2;
case stdAc::fanspeed_t::kHigh:
return kMitsubishiAcFanRealMax - 1;
case stdAc::fanspeed_t::kMax:
return kMitsubishiAcFanRealMax;
default:
return kMitsubishiAcFanAuto;
}
}
// Convert a standard A/C vertical swing into its native setting.
uint8_t IRMitsubishiAC::convertSwingV(const stdAc::swingv_t position) {
switch (position) {
case stdAc::swingv_t::kHighest:
return kMitsubishiAcVaneAutoMove - 6;
case stdAc::swingv_t::kHigh:
return kMitsubishiAcVaneAutoMove - 5;
case stdAc::swingv_t::kMiddle:
return kMitsubishiAcVaneAutoMove - 4;
case stdAc::swingv_t::kLow:
return kMitsubishiAcVaneAutoMove - 3;
case stdAc::swingv_t::kLowest:
return kMitsubishiAcVaneAutoMove - 2;
case stdAc::swingv_t::kAuto:
return kMitsubishiAcVaneAutoMove;
default:
return kMitsubishiAcVaneAuto;
}
}
// Convert a standard A/C wide wane swing into its native setting.
uint8_t IRMitsubishiAC::convertSwingH(const stdAc::swingh_t position) {
switch (position) {
case stdAc::swingh_t::kLeftMax:
return kMitsubishiAcWideVaneAuto - 7;
case stdAc::swingh_t::kLeft:
return kMitsubishiAcWideVaneAuto - 6;
case stdAc::swingh_t::kMiddle:
return kMitsubishiAcWideVaneAuto - 5;
case stdAc::swingh_t::kRight:
return kMitsubishiAcWideVaneAuto - 4;
case stdAc::swingh_t::kRightMax:
return kMitsubishiAcWideVaneAuto - 3;
case stdAc::swingh_t::kWide:
return kMitsubishiAcWideVaneAuto - 2;
case stdAc::swingh_t::kAuto:
return kMitsubishiAcWideVaneAuto;
default:
return kMitsubishiAcWideVaneAuto - 5;
}
}
// Convert a native mode to it's common equivalent.
stdAc::opmode_t IRMitsubishiAC::toCommonMode(const uint8_t mode) {
switch (mode) {
case kMitsubishiAcCool: return stdAc::opmode_t::kCool;
case kMitsubishiAcHeat: return stdAc::opmode_t::kHeat;
case kMitsubishiAcDry: return stdAc::opmode_t::kDry;
default: return stdAc::opmode_t::kAuto;
}
}
// Convert a native fan speed to it's common equivalent.
stdAc::fanspeed_t IRMitsubishiAC::toCommonFanSpeed(const uint8_t speed) {
switch (speed) {
case kMitsubishiAcFanRealMax: return stdAc::fanspeed_t::kMax;
case kMitsubishiAcFanRealMax - 1: return stdAc::fanspeed_t::kHigh;
case kMitsubishiAcFanRealMax - 2: return stdAc::fanspeed_t::kMedium;
case kMitsubishiAcFanRealMax - 3: return stdAc::fanspeed_t::kLow;
case kMitsubishiAcFanSilent: return stdAc::fanspeed_t::kMin;
default: return stdAc::fanspeed_t::kAuto;
}
}
// Convert a native vertical swing to it's common equivalent.
stdAc::swingv_t IRMitsubishiAC::toCommonSwingV(const uint8_t pos) {
switch (pos) {
case 1: return stdAc::swingv_t::kHighest;
case 2: return stdAc::swingv_t::kHigh;
case 3: return stdAc::swingv_t::kMiddle;
case 4: return stdAc::swingv_t::kLow;
case 5: return stdAc::swingv_t::kLowest;
default: return stdAc::swingv_t::kAuto;
}
}
// Convert a native horizontal swing to it's common equivalent.
stdAc::swingh_t IRMitsubishiAC::toCommonSwingH(const uint8_t pos) {
switch (pos) {
case 1: return stdAc::swingh_t::kLeftMax;
case 2: return stdAc::swingh_t::kLeft;
case 3: return stdAc::swingh_t::kMiddle;
case 4: return stdAc::swingh_t::kRight;
case 5: return stdAc::swingh_t::kRightMax;
case 6: return stdAc::swingh_t::kWide;
default: return stdAc::swingh_t::kAuto;
}
}
// Convert the A/C state to it's common equivalent.
stdAc::state_t IRMitsubishiAC::toCommon(void) {
stdAc::state_t result;
result.protocol = decode_type_t::MITSUBISHI_AC;
result.model = -1; // No models used.
result.power = this->getPower();
result.mode = this->toCommonMode(this->getMode());
result.celsius = true;
result.degrees = this->getTemp();
result.fanspeed = this->toCommonFanSpeed(this->getFan());
result.swingv = this->toCommonSwingV(this->getVane());
result.swingh = this->toCommonSwingH(this->getWideVane());
result.quiet = this->getFan() == kMitsubishiAcFanSilent;
// Not supported.
result.turbo = false;
result.clean = false;
result.econo = false;
result.filter = false;
result.light = false;
result.beep = false;
result.sleep = -1;
result.clock = -1;
return result;
}
// Convert the internal state into a human readable string.
String IRMitsubishiAC::toString(void) {
String result = "";
result.reserve(110); // Reserve some heap for the string to reduce fragging.
result += addBoolToString(getPower(), F("Power"), false);
result += addModeToString(getMode(), kMitsubishiAcAuto, kMitsubishiAcCool,
kMitsubishiAcHeat, kMitsubishiAcDry,
kMitsubishiAcAuto);
result += addTempToString(getTemp());
result += addFanToString(getFan(), kMitsubishiAcFanRealMax,
kMitsubishiAcFanRealMax - 3,
kMitsubishiAcFanAuto, kMitsubishiAcFanQuiet,
kMitsubishiAcFanRealMax - 2);
result += F(", Vane: ");
switch (this->getVane()) {
case MITSUBISHI_AC_VANE_AUTO:
result += F("AUTO");
break;
case MITSUBISHI_AC_VANE_AUTO_MOVE:
result += F("AUTO MOVE");
break;
default:
result += uint64ToString(this->getVane());
}
result += F(", Wide Vane: ");
switch (this->getWideVane()) {
case kMitsubishiAcWideVaneAuto:
result += F("AUTO");
break;
default:
result += uint64ToString(this->getWideVane());
}
result += addLabeledString(minsToString(getClock() * 10), F("Time"));
result += addLabeledString(minsToString(getStartClock() * 10), F("On timer"));
result += addLabeledString(minsToString(getStopClock() * 10), F("Off timer"));
result += F(", Timer: ");
switch (this->getTimer()) {
case kMitsubishiAcNoTimer:
result += '-';
break;
case kMitsubishiAcStartTimer:
result += F("Start");
break;
case kMitsubishiAcStopTimer:
result += F("Stop");
break;
case kMitsubishiAcStartStopTimer:
result += F("Start+Stop");
break;
default:
result += F("? (");
result += this->getTimer();
result += F(")\n");
}
return result;
}

View File

@ -1,121 +0,0 @@
// Copyright 2009 Ken Shirriff
// Copyright 2017 David Conran
// Mitsubishi
// Supports:
// Brand: Mitsubishi, Model: TV
// Brand: Mitsubishi, Model: HC3000 Projector
#ifndef IR_MITSUBISHI_H_
#define IR_MITSUBISHI_H_
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#ifndef UNIT_TEST
#include <Arduino.h>
#endif
#include "IRremoteESP8266.h"
#include "IRsend.h"
#ifdef UNIT_TEST
#include "IRsend_test.h"
#endif
// Mitsubishi (TV) decoding added from https://github.com/z3t0/Arduino-IRremote
// Mitsubishi (TV) sending & Mitsubishi A/C support added by David Conran
// Constants
const uint8_t kMitsubishiAcAuto = 0x20;
const uint8_t kMitsubishiAcCool = 0x18;
const uint8_t kMitsubishiAcDry = 0x10;
const uint8_t kMitsubishiAcHeat = 0x08;
const uint8_t kMitsubishiAcPower = 0x20;
const uint8_t kMitsubishiAcFanAuto = 0;
const uint8_t kMitsubishiAcFanMax = 5;
const uint8_t kMitsubishiAcFanRealMax = 4;
const uint8_t kMitsubishiAcFanSilent = 6;
const uint8_t kMitsubishiAcFanQuiet = kMitsubishiAcFanSilent;
const uint8_t kMitsubishiAcMinTemp = 16; // 16C
const uint8_t kMitsubishiAcMaxTemp = 31; // 31C
const uint8_t kMitsubishiAcVaneAuto = 0;
const uint8_t kMitsubishiAcVaneAutoMove = 7;
const uint8_t kMitsubishiAcNoTimer = 0;
const uint8_t kMitsubishiAcStartTimer = 5;
const uint8_t kMitsubishiAcStopTimer = 3;
const uint8_t kMitsubishiAcStartStopTimer = 7;
const uint8_t kMitsubishiAcWideVaneAuto = 8;
// Legacy defines (Deprecated)
#define MITSUBISHI_AC_VANE_AUTO_MOVE kMitsubishiAcVaneAutoMove
#define MITSUBISHI_AC_VANE_AUTO kMitsubishiAcVaneAuto
#define MITSUBISHI_AC_POWER kMitsubishiAcPower
#define MITSUBISHI_AC_MIN_TEMP kMitsubishiAcMinTemp
#define MITSUBISHI_AC_MAX_TEMP kMitsubishiAcMaxTemp
#define MITSUBISHI_AC_HEAT kMitsubishiAcHeat
#define MITSUBISHI_AC_FAN_SILENT kMitsubishiAcFanSilent
#define MITSUBISHI_AC_FAN_REAL_MAX kMitsubishiAcFanRealMax
#define MITSUBISHI_AC_FAN_MAX kMitsubishiAcFanMax
#define MITSUBISHI_AC_FAN_AUTO kMitsubishiAcFanAuto
#define MITSUBISHI_AC_DRY kMitsubishiAcDry
#define MITSUBISHI_AC_COOL kMitsubishiAcCool
#define MITSUBISHI_AC_AUTO kMitsubishiAcAuto
class IRMitsubishiAC {
public:
explicit IRMitsubishiAC(const uint16_t pin, const bool inverted = false,
const bool use_modulation = true);
static uint8_t calculateChecksum(const uint8_t* data);
void stateReset(void);
#if SEND_MITSUBISHI_AC
void send(const uint16_t repeat = kMitsubishiACMinRepeat);
uint8_t calibrate(void) { return _irsend.calibrate(); }
#endif // SEND_MITSUBISHI_AC
void begin(void);
void on(void);
void off(void);
void setPower(const bool on);
bool getPower(void);
void setTemp(const uint8_t degrees);
uint8_t getTemp(void);
void setFan(const uint8_t speed);
uint8_t getFan(void);
void setMode(const uint8_t mode);
uint8_t getMode(void);
void setVane(const uint8_t position);
void setWideVane(const uint8_t position);
uint8_t getVane(void);
uint8_t getWideVane(void);
uint8_t* getRaw(void);
void setRaw(const uint8_t* data);
uint8_t getClock(void);
void setClock(const uint8_t clock);
uint8_t getStartClock(void);
void setStartClock(const uint8_t clock);
uint8_t getStopClock(void);
void setStopClock(const uint8_t clock);
uint8_t getTimer(void);
void setTimer(const uint8_t timer);
uint8_t convertMode(const stdAc::opmode_t mode);
uint8_t convertFan(const stdAc::fanspeed_t speed);
uint8_t convertSwingV(const stdAc::swingv_t position);
uint8_t convertSwingH(const stdAc::swingh_t position);
static stdAc::opmode_t toCommonMode(const uint8_t mode);
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
static stdAc::swingv_t toCommonSwingV(const uint8_t pos);
static stdAc::swingh_t toCommonSwingH(const uint8_t pos);
stdAc::state_t toCommon(void);
String toString(void);
#ifndef UNIT_TEST
private:
IRsend _irsend;
#else
IRsendTest _irsend;
#endif
uint8_t remote_state[kMitsubishiACStateLength];
void checksum(void);
};
#endif // IR_MITSUBISHI_H_

View File

@ -1,432 +0,0 @@
#!/usr/bin/python
"""Attempt an automatic analysis of IRremoteESP8266's Raw data output.
Makes suggestions on key values and tried to break down the message
into likely chunks."""
#
# Copyright 2018 David Conran
import argparse
import sys
class RawIRMessage():
"""Basic analyse functions & structure for raw IR messages."""
# pylint: disable=too-many-instance-attributes
def __init__(self, margin, timings, output=sys.stdout, verbose=True):
self.hdr_mark = None
self.hdr_space = None
self.bit_mark = None
self.zero_space = None
self.one_space = None
self.gaps = []
self.margin = margin
self.marks = []
self.mark_buckets = {}
self.spaces = []
self.space_buckets = {}
self.output = output
self.verbose = verbose
if len(timings) <= 3:
raise ValueError("Too few message timings supplied.")
self.timings = timings
self._generate_timing_candidates()
self._calc_values()
def _generate_timing_candidates(self):
"""Determine the likely values from the given data."""
count = 0
for usecs in self.timings:
count = count + 1
if count % 2:
self.marks.append(usecs)
else:
self.spaces.append(usecs)
self.marks, self.mark_buckets = self.reduce_list(self.marks)
self.spaces, self.space_buckets = self.reduce_list(self.spaces)
def reduce_list(self, items):
"""Reduce a list of numbers into buckets that are at least margin apart."""
result = []
last = -1
buckets = {}
for item in sorted(items, reverse=True):
if last == -1 or item < last - self.margin:
result.append(item)
last = item
buckets[last] = [item]
else:
buckets[last].append(item)
return result, buckets
def _usec_compare(self, seen, expected):
"""Compare two usec values and see if they match within a
subtractive margin."""
return expected - self.margin < seen <= expected
def _usec_compares(self, usecs, expecteds):
"""Compare a usec value to a list of values and return True
if they are within a subtractive margin."""
for expected in expecteds:
if self._usec_compare(usecs, expected):
return True
return False
def display_binary(self, binary_str):
"""Display common representations of the suppied binary string."""
num = int(binary_str, 2)
bits = len(binary_str)
rev_binary_str = binary_str[::-1]
rev_num = int(rev_binary_str, 2)
self.output.write("\n Bits: %d\n"
" Hex: %s (MSB first)\n"
" %s (LSB first)\n"
" Dec: %s (MSB first)\n"
" %s (LSB first)\n"
" Bin: 0b%s (MSB first)\n"
" 0b%s (LSB first)\n" %
(bits, ("0x{0:0%dX}" % (bits / 4)).format(num),
("0x{0:0%dX}" % (bits / 4)).format(rev_num), num,
rev_num, binary_str, rev_binary_str))
def add_data_code(self, bin_str, footer=True):
"""Add the common "data" sequence of code to send the bulk of a message."""
# pylint: disable=no-self-use
code = []
code.append(" // Data")
code.append(" // e.g. data = 0x%X, nbits = %d" % (int(bin_str, 2),
len(bin_str)))
code.append(" sendData(kBitMark, kOneSpace, kBitMark, kZeroSpace, data, "
"nbits, true);")
if footer:
code.append(" // Footer")
code.append(" mark(kBitMark);")
return code
def _calc_values(self):
"""Calculate the values which describe the standard timings
for the protocol."""
if self.verbose:
self.output.write("Potential Mark Candidates:\n"
"%s\n"
"Potential Space Candidates:\n"
"%s\n" % (str(self.marks), str(self.spaces)))
# Largest mark is likely the kHdrMark
self.hdr_mark = self.marks[0]
# The bit mark is likely to be the smallest mark.
self.bit_mark = self.marks[-1]
if self.is_space_encoded() and len(self.spaces) >= 3:
if self.verbose and len(self.marks) > 2:
self.output.write("DANGER: Unexpected and unused mark timings!")
# We should have 3 space candidates at least.
# They should be: zero_space (smallest), one_space, & hdr_space (largest)
spaces = list(self.spaces)
self.zero_space = spaces.pop()
self.one_space = spaces.pop()
self.hdr_space = spaces.pop()
# Rest are probably message gaps
self.gaps = spaces
def is_space_encoded(self):
"""Make an educated guess if the message is space encoded."""
return len(self.spaces) > len(self.marks)
def is_hdr_mark(self, usec):
"""Is usec the header mark?"""
return self._usec_compare(usec, self.hdr_mark)
def is_hdr_space(self, usec):
"""Is usec the header space?"""
return self._usec_compare(usec, self.hdr_space)
def is_bit_mark(self, usec):
"""Is usec the bit mark?"""
return self._usec_compare(usec, self.bit_mark)
def is_one_space(self, usec):
"""Is usec the one space?"""
return self._usec_compare(usec, self.one_space)
def is_zero_space(self, usec):
"""Is usec the zero_space?"""
return self._usec_compare(usec, self.zero_space)
def is_gap(self, usec):
"""Is usec the a space gap?"""
return self._usec_compares(usec, self.gaps)
def avg_list(items):
"""Return the average of a list of numbers."""
if items:
return int(sum(items) / len(items))
return 0
def add_bit(so_far, bit, output=sys.stdout):
"""Add a bit to the end of the bits collected so far."""
if bit == "reset":
return ""
output.write(str(bit)) # This effectively displays in LSB first order.
return so_far + str(bit) # Storing it in MSB first order.
def convert_rawdata(data_str):
"""Parse a C++ rawdata declaration into a list of values."""
start = data_str.find('{')
end = data_str.find('}')
if end == -1:
end = len(data_str)
if start > end:
raise ValueError("Raw Data not parsible due to parentheses placement.")
data_str = data_str[start + 1:end]
results = []
for timing in [x.strip() for x in data_str.split(',')]:
try:
results.append(int(timing))
except ValueError:
raise ValueError(
"Raw Data contains a non-numeric value of '%s'." % timing)
return results
def dump_constants(message, defines, output=sys.stdout):
"""Dump the key constants and generate the C++ #defines."""
hdr_mark = avg_list(message.mark_buckets[message.hdr_mark])
bit_mark = avg_list(message.mark_buckets[message.bit_mark])
hdr_space = avg_list(message.space_buckets[message.hdr_space])
one_space = avg_list(message.space_buckets[message.one_space])
zero_space = avg_list(message.space_buckets[message.zero_space])
output.write("Guessing key value:\n"
"kHdrMark = %d\n"
"kHdrSpace = %d\n"
"kBitMark = %d\n"
"kOneSpace = %d\n"
"kZeroSpace = %d\n" % (hdr_mark, hdr_space, bit_mark, one_space,
zero_space))
defines.append("const uint16_t kHdrMark = %d;" % hdr_mark)
defines.append("const uint16_t kBitMark = %d;" % bit_mark)
defines.append("const uint16_t kHdrSpace = %d;" % hdr_space)
defines.append("const uint16_t kOneSpace = %d;" % one_space)
defines.append("const uint16_t kZeroSpace = %d;" % zero_space)
avg_gaps = [avg_list(message.space_buckets[x]) for x in message.gaps]
if len(message.gaps) == 1:
output.write("kSpaceGap = %d\n" % avg_gaps[0])
defines.append("const uint16_t kSpaceGap = %d;" % avg_gaps[0])
else:
count = 0
for gap in avg_gaps:
# We probably (still) have a gap in the protocol.
count = count + 1
output.write("kSpaceGap%d = %d\n" % (count, gap))
defines.append("const uint16_t kSpaceGap%d = %d;" % (count, gap))
def parse_and_report(rawdata_str, margin, gen_code=False, output=sys.stdout):
"""Analyse the rawdata c++ definition of a IR message."""
defines = []
function_code = []
# Parse the input.
rawdata = convert_rawdata(rawdata_str)
output.write("Found %d timing entries.\n" % len(rawdata))
message = RawIRMessage(margin, rawdata, output)
output.write("\nGuessing encoding type:\n")
if message.is_space_encoded():
output.write("Looks like it uses space encoding. Yay!\n\n")
dump_constants(message, defines, output)
else:
output.write("Sorry, it looks like it is Mark encoded. "
"I can't do that yet. Exiting.\n")
sys.exit(1)
total_bits = decode_data(message, defines, function_code, output)
if gen_code:
generate_irsend_code(defines, function_code, total_bits, output)
def decode_data(message, defines, function_code, output=sys.stdout):
"""Decode the data sequence with the given values in mind."""
# pylint: disable=too-many-branches,too-many-statements
# Now we have likely candidates for the key values, go through the original
# sequence and break it up and indicate accordingly.
output.write("\nDecoding protocol based on analysis so far:\n\n")
state = ""
count = 1
total_bits = ""
binary_value = add_bit("", "reset")
function_code.extend([
"// Function should be safe up to 64 bits.",
"void IRsend::sendXyz(const uint64_t data, const uint16_t"
" nbits, const uint16_t repeat) {",
" enableIROut(38); // A guess. Most common frequency.",
" for (uint16_t r = 0; r <= repeat; r++) {"
])
for usec in message.timings:
if (message.is_hdr_mark(usec) and count % 2 and
not message.is_bit_mark(usec)):
state = "HM"
if binary_value:
message.display_binary(binary_value)
function_code.extend(message.add_data_code(binary_value, False))
total_bits = total_bits + binary_value
binary_value = add_bit(binary_value, "reset")
output.write("kHdrMark+")
function_code.extend([" // Header", " mark(kHdrMark);"])
elif message.is_hdr_space(usec) and not message.is_one_space(usec):
if state != "HM":
if binary_value:
message.display_binary(binary_value)
total_bits = total_bits + binary_value
function_code.extend(message.add_data_code(binary_value))
binary_value = add_bit(binary_value, "reset")
output.write("UNEXPECTED->")
state = "HS"
output.write("kHdrSpace+")
function_code.append(" space(kHdrSpace);")
elif message.is_bit_mark(usec) and count % 2:
if state not in ("HS", "BS"):
output.write("kBitMark(UNEXPECTED)")
state = "BM"
elif message.is_zero_space(usec):
if state != "BM":
output.write("kZeroSpace(UNEXPECTED)")
state = "BS"
binary_value = add_bit(binary_value, 0, output)
elif message.is_one_space(usec):
if state != "BM":
output.write("kOneSpace(UNEXPECTED)")
state = "BS"
binary_value = add_bit(binary_value, 1, output)
elif message.is_gap(usec):
if state != "BM":
output.write("UNEXPECTED->")
state = "GS"
output.write("GAP(%d)" % usec)
if binary_value:
message.display_binary(binary_value)
function_code.extend(message.add_data_code(binary_value))
else:
function_code.extend([" // Gap", " mark(kBitMark);"])
function_code.append(" space(kSpaceGap);")
total_bits = total_bits + binary_value
binary_value = add_bit(binary_value, "reset")
else:
output.write("UNKNOWN(%d)" % usec)
state = "UNK"
count = count + 1
if binary_value:
message.display_binary(binary_value)
function_code.extend(message.add_data_code(binary_value))
function_code.extend([
" space(100000); // A 100% made up guess of the gap"
" between messages.", " }", "}"
])
total_bits = total_bits + binary_value
output.write("\nTotal Nr. of suspected bits: %d\n" % len(total_bits))
defines.append("const uint16_t kXyzBits = %d;" % len(total_bits))
if len(total_bits) > 64:
defines.append("const uint16_t kXyzStateLength = %d;" %
(len(total_bits) / 8))
return total_bits
def generate_irsend_code(defines, normal, bits_str, output=sys.stdout):
"""Output the estimated C++ code to reproduce the IR message."""
output.write("\nGenerating a VERY rough code outline:\n\n"
"// WARNING: This probably isn't directly usable."
" It's a guide only.\n")
for line in defines:
output.write("%s\n" % line)
if len(bits_str) > 64: # Will it fit in a uint64_t?
output.write("// DANGER: More than 64 bits detected. A uint64_t for "
"'data' won't work!\n")
# Display the "normal" version's code incase there are some
# oddities in it.
for line in normal:
output.write("%s\n" % line)
if len(bits_str) > 64: # Will it fit in a uint64_t?
output.write("\n\n// Alternative >64 bit Function\n"
"void IRsend::sendXyz(uint8_t data[], uint16_t nbytes,"
" uint16_t repeat) {\n"
" // nbytes should typically be kXyzStateLength\n"
" // data should typically be:\n"
" // uint8_t data[kXyzStateLength] = {0x%s};\n"
" // data[] is assumed to be in MSB order for this code.\n"
" for (uint16_t r = 0; r <= repeat; r++) {\n"
" sendGeneric(kHdrMark, kHdrSpace,\n"
" kBitMark, kOneSpace,\n"
" kBitMark, kZeroSpace,\n"
" kBitMark,\n"
" 100000, // 100%% made-up guess at the"
" message gap.\n"
" data, nbytes,\n"
" 38000, // Complete guess of the modulation"
" frequency.\n"
" true, 0, 50);\n"
" }\n"
"}\n" % ", 0x".join("%02X" % int(bits_str[i:i + 8], 2)
for i in range(0, len(bits_str), 8)))
def main():
"""Parse the commandline arguments and call the method."""
arg_parser = argparse.ArgumentParser(
description="Read an IRremoteESP8266 rawData declaration and tries to "
"analyse it.",
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
arg_parser.add_argument(
"-g",
"--code",
action="store_true",
default=False,
dest="gen_code",
help="Generate a C++ code outline to aid making an IRsend function.")
arg_group = arg_parser.add_mutually_exclusive_group(required=True)
arg_group.add_argument(
"rawdata",
help="A rawData line from IRrecvDumpV2. e.g. 'uint16_t rawbuf[37] = {"
"7930, 3952, 494, 1482, 520, 1482, 494, 1508, 494, 520, 494, 1482, 494, "
"520, 494, 1482, 494, 1482, 494, 3978, 494, 520, 494, 520, 494, 520, "
"494, 520, 520, 520, 494, 520, 494, 520, 494, 520, 494};'",
nargs="?")
arg_group.add_argument(
"-f", "--file", help="Read in a rawData line from the file.")
arg_parser.add_argument(
"-r",
"--range",
type=int,
help="Max number of micro-seconds difference between values to consider"
" it the same value.",
dest="margin",
default=200)
arg_group.add_argument(
"--stdin",
help="Read in a rawData line from STDIN.",
action="store_true",
default=False)
arg_options = arg_parser.parse_args()
if arg_options.stdin:
data = sys.stdin.read()
elif arg_options.file:
with open(arg_options.file) as input_file:
data = input_file.read()
else:
data = arg_options.rawdata
parse_and_report(data, arg_options.margin, arg_options.gen_code)
if __name__ == '__main__':
main()

View File

@ -1,492 +0,0 @@
#!/usr/bin/python3
"""Unit tests for auto_analyse_raw_data.py"""
from io import StringIO
import unittest
import auto_analyse_raw_data as analyse
class TestRawIRMessage(unittest.TestCase):
"""Unit tests for the RawIRMessage class."""
# pylint: disable=too-many-public-methods
def test_display_binary(self):
"""Test the display_binary() method."""
output = StringIO()
message = analyse.RawIRMessage(100, [8000, 4000, 500, 500, 500], output,
False)
self.assertEqual(output.getvalue(), '')
message.display_binary("10101010")
message.display_binary("0000000000000000")
message.display_binary("00010010001101000101011001111000")
self.assertEqual(output.getvalue(), '\n'
' Bits: 8\n'
' Hex: 0xAA (MSB first)\n'
' 0x55 (LSB first)\n'
' Dec: 170 (MSB first)\n'
' 85 (LSB first)\n'
' Bin: 0b10101010 (MSB first)\n'
' 0b01010101 (LSB first)\n'
'\n'
' Bits: 16\n'
' Hex: 0x0000 (MSB first)\n'
' 0x0000 (LSB first)\n'
' Dec: 0 (MSB first)\n'
' 0 (LSB first)\n'
' Bin: 0b0000000000000000 (MSB first)\n'
' 0b0000000000000000 (LSB first)\n'
'\n'
' Bits: 32\n'
' Hex: 0x12345678 (MSB first)\n'
' 0x1E6A2C48 (LSB first)\n'
' Dec: 305419896 (MSB first)\n'
' 510274632 (LSB first)\n'
' Bin: 0b00010010001101000101011001111000 (MSB first)\n'
' 0b00011110011010100010110001001000 (LSB first)\n')
class TestAutoAnalyseRawData(unittest.TestCase):
"""Unit tests for the functions in AutoAnalyseRawData."""
# pylint: disable=too-many-public-methods
def test_dump_constants_simple(self):
"""Simple tests for the dump_constants() function."""
ignore = StringIO()
output = StringIO()
defs = []
message = analyse.RawIRMessage(200, [
7930, 3952, 494, 1482, 520, 1482, 494, 1508, 494, 520, 494, 1482, 494,
520, 494, 1482, 494, 1482, 494, 3978, 494, 520, 494, 520, 494, 520, 494,
520, 520, 520, 494, 520, 494, 520, 494, 1482, 494
], ignore)
analyse.dump_constants(message, defs, output)
self.assertEqual(defs, [
'const uint16_t kHdrMark = 7930;', 'const uint16_t kBitMark = 496;',
'const uint16_t kHdrSpace = 3965;', 'const uint16_t kOneSpace = 1485;',
'const uint16_t kZeroSpace = 520;'
])
self.assertEqual(output.getvalue(), 'Guessing key value:\n'
'kHdrMark = 7930\n'
'kHdrSpace = 3965\n'
'kBitMark = 496\n'
'kOneSpace = 1485\n'
'kZeroSpace = 520\n')
def test_dump_constants_aircon(self):
"""More complex tests for the dump_constants() function."""
ignore = StringIO()
output = StringIO()
defs = []
message = analyse.RawIRMessage(200, [
9008, 4496, 644, 1660, 676, 530, 648, 558, 672, 1636, 646, 1660, 644,
556, 650, 584, 626, 560, 644, 580, 628, 1680, 624, 560, 648, 1662, 644,
582, 648, 536, 674, 530, 646, 580, 628, 560, 670, 532, 646, 562, 644,
556, 672, 536, 648, 1662, 646, 1660, 652, 554, 644, 558, 672, 538, 644,
560, 668, 560, 648, 1638, 668, 536, 644, 1660, 668, 532, 648, 560, 648,
1660, 674, 554, 622, 19990, 646, 580, 624, 1660, 648, 556, 648, 558,
674, 556, 622, 560, 644, 564, 668, 536, 646, 1662, 646, 1658, 672, 534,
648, 558, 644, 562, 648, 1662, 644, 584, 622, 558, 648, 562, 668, 534,
670, 536, 670, 532, 672, 536, 646, 560, 646, 558, 648, 558, 670, 534,
650, 558, 646, 560, 646, 560, 668, 1638, 646, 1662, 646, 1660, 646,
1660, 648
], ignore)
analyse.dump_constants(message, defs, output)
self.assertEqual(defs, [
'const uint16_t kHdrMark = 9008;', 'const uint16_t kBitMark = 650;',
'const uint16_t kHdrSpace = 4496;', 'const uint16_t kOneSpace = 1657;',
'const uint16_t kZeroSpace = 554;', 'const uint16_t kSpaceGap = 19990;'
])
self.assertEqual(output.getvalue(), 'Guessing key value:\n'
'kHdrMark = 9008\n'
'kHdrSpace = 4496\n'
'kBitMark = 650\n'
'kOneSpace = 1657\n'
'kZeroSpace = 554\n'
'kSpaceGap = 19990\n')
def test_convert_rawdata(self):
"""Tests for the convert_rawdata() function."""
# trivial cases
self.assertEqual(analyse.convert_rawdata("0"), [0])
with self.assertRaises(ValueError) as context:
analyse.convert_rawdata("")
self.assertEqual(str(context.exception),
"Raw Data contains a non-numeric value of ''.")
# Single parenthesis
self.assertEqual(analyse.convert_rawdata("foo {10"), [10])
self.assertEqual(analyse.convert_rawdata("20} bar"), [20])
# No parentheses
self.assertEqual(analyse.convert_rawdata("10,20 , 30"), [10, 20, 30])
# Dual parentheses
self.assertEqual(analyse.convert_rawdata("{10,20 , 30}"), [10, 20, 30])
self.assertEqual(analyse.convert_rawdata("foo{10,20}bar"), [10, 20])
# Many parentheses
self.assertEqual(analyse.convert_rawdata("foo{10,20}{bar}"), [10, 20])
self.assertEqual(analyse.convert_rawdata("foo{10,20}{bar}}{"), [10, 20])
# Bad parentheses
with self.assertRaises(ValueError) as context:
analyse.convert_rawdata("}10{")
self.assertEqual(str(context.exception),
"Raw Data not parsible due to parentheses placement.")
# Non base-10 values
with self.assertRaises(ValueError) as context:
analyse.convert_rawdata("10, 20, foo, bar, 30")
self.assertEqual(str(context.exception),
"Raw Data contains a non-numeric value of 'foo'.")
# A messy usual "good" case.
input_str = """uint16_t rawbuf[6] = {
9008, 4496, 644,
1660, 676,
530}
;"""
self.assertEqual(
analyse.convert_rawdata(input_str), [9008, 4496, 644, 1660, 676, 530])
def test_parse_and_report(self):
"""Tests for the parse_and_report() function."""
# Without code generation.
output = StringIO()
input_str = """
uint16_t rawbuf[139] = {9008, 4496, 644, 1660, 676, 530, 648, 558, 672,
1636, 646, 1660, 644, 556, 650, 584, 626, 560, 644, 580, 628, 1680,
624, 560, 648, 1662, 644, 582, 648, 536, 674, 530, 646, 580, 628,
560, 670, 532, 646, 562, 644, 556, 672, 536, 648, 1662, 646, 1660,
652, 554, 644, 558, 672, 538, 644, 560, 668, 560, 648, 1638, 668,
536, 644, 1660, 668, 532, 648, 560, 648, 1660, 674, 554, 622, 19990,
646, 580, 624, 1660, 648, 556, 648, 558, 674, 556, 622, 560, 644,
564, 668, 536, 646, 1662, 646, 1658, 672, 534, 648, 558, 644, 562,
648, 1662, 644, 584, 622, 558, 648, 562, 668, 534, 670, 536, 670,
532, 672, 536, 646, 560, 646, 558, 648, 558, 670, 534, 650, 558,
646, 560, 646, 560, 668, 1638, 646, 1662, 646, 1660, 646, 1660,
648};"""
analyse.parse_and_report(input_str, 200, False, output)
self.assertEqual(
output.getvalue(), 'Found 139 timing entries.\n'
'Potential Mark Candidates:\n'
'[9008, 676]\n'
'Potential Space Candidates:\n'
'[19990, 4496, 1680, 584]\n'
'\n'
'Guessing encoding type:\n'
'Looks like it uses space encoding. Yay!\n'
'\n'
'Guessing key value:\n'
'kHdrMark = 9008\n'
'kHdrSpace = 4496\n'
'kBitMark = 650\n'
'kOneSpace = 1657\n'
'kZeroSpace = 554\n'
'kSpaceGap = 19990\n'
'\n'
'Decoding protocol based on analysis so far:\n'
'\n'
'kHdrMark+kHdrSpace+10011000010100000000011000001010010GAP(19990)\n'
' Bits: 35\n'
' Hex: 0x4C2803052 (MSB first)\n'
' 0x250600A19 (LSB first)\n'
' Dec: 20443050066 (MSB first)\n'
' 9938405913 (LSB first)\n'
' Bin: 0b10011000010100000000011000001010010 (MSB first)\n'
' 0b01001010000011000000000101000011001 (LSB first)\n'
'kBitMark(UNEXPECTED)01000000110001000000000000001111\n'
' Bits: 32\n'
' Hex: 0x40C4000F (MSB first)\n'
' 0xF0002302 (LSB first)\n'
' Dec: 1086586895 (MSB first)\n'
' 4026540802 (LSB first)\n'
' Bin: 0b01000000110001000000000000001111 (MSB first)\n'
' 0b11110000000000000010001100000010 (LSB first)\n'
'\n'
'Total Nr. of suspected bits: 67\n')
# With code generation.
output = StringIO()
input_str = """
uint16_t rawbuf[37] = {7930, 3952, 494, 1482, 520, 1482, 494,
1508, 494, 520, 494, 1482, 494, 520, 494, 1482, 494, 1482, 494,
3978, 494, 520, 494, 520, 494, 520, 494, 520, 520, 520, 494, 520,
494, 520, 494, 1482, 494};"""
analyse.parse_and_report(input_str, 200, True, output)
self.assertEqual(
output.getvalue(), 'Found 37 timing entries.\n'
'Potential Mark Candidates:\n'
'[7930, 520]\n'
'Potential Space Candidates:\n'
'[3978, 1508, 520]\n'
'\n'
'Guessing encoding type:\n'
'Looks like it uses space encoding. Yay!\n'
'\n'
'Guessing key value:\n'
'kHdrMark = 7930\n'
'kHdrSpace = 3965\n'
'kBitMark = 496\n'
'kOneSpace = 1485\n'
'kZeroSpace = 520\n'
'\n'
'Decoding protocol based on analysis so far:\n'
'\n'
'kHdrMark+kHdrSpace+11101011\n'
' Bits: 8\n'
' Hex: 0xEB (MSB first)\n'
' 0xD7 (LSB first)\n'
' Dec: 235 (MSB first)\n'
' 215 (LSB first)\n'
' Bin: 0b11101011 (MSB first)\n'
' 0b11010111 (LSB first)\n'
'UNEXPECTED->kHdrSpace+00000001\n'
' Bits: 8\n'
' Hex: 0x01 (MSB first)\n'
' 0x80 (LSB first)\n'
' Dec: 1 (MSB first)\n'
' 128 (LSB first)\n'
' Bin: 0b00000001 (MSB first)\n'
' 0b10000000 (LSB first)\n'
'\n'
'Total Nr. of suspected bits: 16\n'
'\n'
'Generating a VERY rough code outline:\n'
'\n'
"// WARNING: This probably isn't directly usable. It's a guide only.\n"
'const uint16_t kHdrMark = 7930;\n'
'const uint16_t kBitMark = 496;\n'
'const uint16_t kHdrSpace = 3965;\n'
'const uint16_t kOneSpace = 1485;\n'
'const uint16_t kZeroSpace = 520;\n'
'const uint16_t kXyzBits = 16;\n'
'// Function should be safe up to 64 bits.\n'
'void IRsend::sendXyz(const uint64_t data, const uint16_t nbits,'
' const uint16_t repeat) {\n'
' enableIROut(38); // A guess. Most common frequency.\n'
' for (uint16_t r = 0; r <= repeat; r++) {\n'
' // Header\n'
' mark(kHdrMark);\n'
' space(kHdrSpace);\n'
' // Data\n'
' // e.g. data = 0xEB, nbits = 8\n'
' sendData(kBitMark, kOneSpace, kBitMark, kZeroSpace, data, nbits,'
' true);\n'
' // Footer\n'
' mark(kBitMark);\n'
' space(kHdrSpace);\n'
' // Data\n'
' // e.g. data = 0x1, nbits = 8\n'
' sendData(kBitMark, kOneSpace, kBitMark, kZeroSpace, data, nbits,'
' true);\n'
' // Footer\n'
' mark(kBitMark);\n'
' space(100000); // A 100% made up guess of the gap between'
' messages.\n'
' }\n'
'}\n')
def test_unusual_gaps(self):
"""Tests for unusual Space Gaps in parse_and_report() function."""
# Tests for unusual Gaps. (Issue #482)
output = StringIO()
input_str = """
uint16_t rawbuf[272] = {3485, 3512, 864, 864, 864, 2620, 864, 864,
864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864,
864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620,
864, 2620, 864, 864, 864, 2620, 864, 864, 864, 864, 864, 864,
864, 864, 864, 864, 864, 864, 864, 864, 864, 2620, 864, 864,
864, 864, 864, 864, 864, 864, 864, 864, 864, 864,
3485, 3512, 864, 864, 864, 2620, 864, 864, 864, 2620, 864, 2620,
864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 864,
864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864,
864, 2620, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864,
864, 864, 864, 864, 2620, 864, 864, 864, 864, 864, 864, 864, 864,
864, 864, 864, 864,
3485, 3512, 864, 13996,
3485, 3512, 864, 864, 864, 864, 864, 2620, 864, 864, 864, 2620,
864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 864, 864, 2620,
864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864,
864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 864,
864, 864, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 2620,
864, 2620, 864, 864, 864, 864,
3485, 3512, 864, 864, 864, 864, 864, 2620, 864, 864, 864, 2620,
864, 2620, 864, 2620, 864, 2620, 864, 864, 864, 864, 864, 2620,
864, 864, 864, 2620, 864, 2620, 864, 2620, 864, 2620, 864, 864,
864, 2620, 864, 2620, 864, 864, 864, 2620, 864, 2620, 864, 864,
864, 864, 864, 864, 864, 2620, 864, 2620, 864, 864, 864, 2620,
864, 2620, 864, 864, 864, 864, 3485, 3512, 864, 13996};"""
analyse.parse_and_report(input_str, 200, True, output)
self.assertEqual(
output.getvalue(), 'Found 272 timing entries.\n'
'Potential Mark Candidates:\n'
'[3485, 864]\n'
'Potential Space Candidates:\n'
'[13996, 3512, 2620, 864]\n'
'\n'
'Guessing encoding type:\n'
'Looks like it uses space encoding. Yay!\n'
'\n'
'Guessing key value:\n'
'kHdrMark = 3485\n'
'kHdrSpace = 3512\n'
'kBitMark = 864\n'
'kOneSpace = 2620\n'
'kZeroSpace = 864\n'
'kSpaceGap = 13996\n'
'\n'
'Decoding protocol based on analysis so far:\n'
'\n'
'kHdrMark+kHdrSpace+01011111010111110100000001000000\n'
' Bits: 32\n'
' Hex: 0x5F5F4040 (MSB first)\n'
' 0x0202FAFA (LSB first)\n'
' Dec: 1600077888 (MSB first)\n'
' 33749754 (LSB first)\n'
' Bin: 0b01011111010111110100000001000000 (MSB first)\n'
' 0b00000010000000101111101011111010 (LSB first)\n'
'kHdrMark+kHdrSpace+01011111010111110100000001000000\n'
' Bits: 32\n'
' Hex: 0x5F5F4040 (MSB first)\n'
' 0x0202FAFA (LSB first)\n'
' Dec: 1600077888 (MSB first)\n'
' 33749754 (LSB first)\n'
' Bin: 0b01011111010111110100000001000000 (MSB first)\n'
' 0b00000010000000101111101011111010 (LSB first)\n'
'kHdrMark+kHdrSpace+GAP(13996)'
'kHdrMark+kHdrSpace+00101111001011110110110001101100\n'
' Bits: 32\n'
' Hex: 0x2F2F6C6C (MSB first)\n'
' 0x3636F4F4 (LSB first)\n'
' Dec: 791637100 (MSB first)\n'
' 909571316 (LSB first)\n'
' Bin: 0b00101111001011110110110001101100 (MSB first)\n'
' 0b00110110001101101111010011110100 (LSB first)\n'
'kHdrMark+kHdrSpace+00101111001011110110110001101100\n'
' Bits: 32\n'
' Hex: 0x2F2F6C6C (MSB first)\n'
' 0x3636F4F4 (LSB first)\n'
' Dec: 791637100 (MSB first)\n'
' 909571316 (LSB first)\n'
' Bin: 0b00101111001011110110110001101100 (MSB first)\n'
' 0b00110110001101101111010011110100 (LSB first)\n'
'kHdrMark+kHdrSpace+GAP(13996)\n'
'Total Nr. of suspected bits: 128\n'
'\n'
'Generating a VERY rough code outline:\n'
'\n'
"// WARNING: This probably isn't directly usable. It's a guide only.\n"
'const uint16_t kHdrMark = 3485;\n'
'const uint16_t kBitMark = 864;\n'
'const uint16_t kHdrSpace = 3512;\n'
'const uint16_t kOneSpace = 2620;\n'
'const uint16_t kZeroSpace = 864;\n'
'const uint16_t kSpaceGap = 13996;\n'
'const uint16_t kXyzBits = 128;\n'
'const uint16_t kXyzStateLength = 16;\n'
"// DANGER: More than 64 bits detected. A uint64_t for 'data' won't"
' work!\n'
'// Function should be safe up to 64 bits.\n'
'void IRsend::sendXyz(const uint64_t data, const uint16_t nbits,'
' const uint16_t repeat) {\n'
' enableIROut(38); // A guess. Most common frequency.\n'
' for (uint16_t r = 0; r <= repeat; r++) {\n'
' // Header\n'
' mark(kHdrMark);\n'
' space(kHdrSpace);\n'
' // Data\n'
' // e.g. data = 0x5F5F4040, nbits = 32\n'
' sendData(kBitMark, kOneSpace, kBitMark, kZeroSpace, data, nbits,'
' true);\n'
' // Header\n'
' mark(kHdrMark);\n'
' space(kHdrSpace);\n'
' // Data\n'
' // e.g. data = 0x5F5F4040, nbits = 32\n'
' sendData(kBitMark, kOneSpace, kBitMark, kZeroSpace, data, nbits,'
' true);\n'
' // Header\n'
' mark(kHdrMark);\n'
' space(kHdrSpace);\n'
' // Gap\n'
' mark(kBitMark);\n'
' space(kSpaceGap);\n'
' // Header\n'
' mark(kHdrMark);\n'
' space(kHdrSpace);\n'
' // Data\n'
' // e.g. data = 0x2F2F6C6C, nbits = 32\n'
' sendData(kBitMark, kOneSpace, kBitMark, kZeroSpace, data, nbits,'
' true);\n'
' // Header\n'
' mark(kHdrMark);\n'
' space(kHdrSpace);\n'
' // Data\n'
' // e.g. data = 0x2F2F6C6C, nbits = 32\n'
' sendData(kBitMark, kOneSpace, kBitMark, kZeroSpace, data, nbits,'
' true);\n'
' // Header\n'
' mark(kHdrMark);\n'
' space(kHdrSpace);\n'
' // Gap\n'
' mark(kBitMark);\n'
' space(kSpaceGap);\n'
' space(100000); // A 100% made up guess of the gap between'
' messages.\n'
' }\n'
'}\n'
'\n'
'\n'
'// Alternative >64 bit Function\n'
'void IRsend::sendXyz(uint8_t data[], uint16_t nbytes, uint16_t repeat)'
' {\n'
' // nbytes should typically be kXyzStateLength\n'
' // data should typically be:\n'
' // uint8_t data[kXyzStateLength] = {0x5F, 0x5F, 0x40, 0x40, 0x5F,'
' 0x5F, 0x40, 0x40, 0x2F, 0x2F, 0x6C, 0x6C, 0x2F, 0x2F, 0x6C, 0x6C};\n'
' // data[] is assumed to be in MSB order for this code.\n'
' for (uint16_t r = 0; r <= repeat; r++) {\n'
' sendGeneric(kHdrMark, kHdrSpace,\n'
' kBitMark, kOneSpace,\n'
' kBitMark, kZeroSpace,\n'
' kBitMark,\n'
' 100000, // 100% made-up guess at the message gap.\n'
' data, nbytes,\n'
' 38000, // Complete guess of the modulation'
' frequency.\n'
' true, 0, 50);\n'
' }\n'
'}\n')
def test_reduce_list(self):
"""Tests for the reduce_list method."""
ignore = StringIO()
message = analyse.RawIRMessage(200, [
7930, 3952, 494, 1482, 520, 1482, 494, 1508, 494, 520, 494, 1482, 494,
520, 494, 1482, 494, 1482, 494, 3978, 494, 520, 494, 520, 494, 520, 494,
520, 520, 520, 494, 520, 494, 520, 494, 1482, 494
], ignore)
test_space_data = [4496, 1660, 530, 558, 1636, 1660, 556]
result_list, result_dict = message.reduce_list(test_space_data)
self.assertEqual([4496, 1660, 558], result_list)
self.assertEqual({
558: [558, 556, 530],
1660: [1660, 1660, 1636],
4496: [4496]
}, result_dict)
def test_avg_list(self):
"""Tests for the avg_list method."""
self.assertEqual(0, analyse.avg_list([]))
self.assertEqual(23, analyse.avg_list([10, 20, 40]))
if __name__ == '__main__':
unittest.main(verbosity=2)

View File

@ -9,8 +9,8 @@
This library enables you to **send _and_ receive** infra-red signals on an [ESP8266](https://github.com/esp8266/Arduino) or an
[ESP32](https://github.com/espressif/arduino-esp32) using the [Arduino framework](https://www.arduino.cc/) using common 940nm IR LEDs and common IR receiver modules. e.g. TSOP{17,22,24,36,38,44,48}* demodulators etc.
## v2.6.5 Now Available
Version 2.6.4 of the library is now [available](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). You can view the [Release Notes](ReleaseNotes.md) for all the significant changes.
## v2.7.1 Now Available
Version 2.7.1 of the library is now [available](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). You can view the [Release Notes](ReleaseNotes.md) for all the significant changes.
#### Upgrading from pre-v2.0
Usage of the library has been slightly changed in v2.0. You will need to change your usage to work with v2.0 and beyond. You can read more about the changes required on our [Upgrade to v2.0](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Upgrading-to-v2.0) page.
@ -25,12 +25,12 @@ The most likely externally used `#define`s have been _aliased_ for limited
backward compatibility for projects using the old style. Going forward, only the
new `kConstantName` style will be supported for new protocol additions.
In the unlikely case it does break your code, then you may have been referencing
In the unlikely case, it does break your code, then you may have been referencing
something you likely should not have. You should be able to quickly determine
the new name from the old. e.g. `CONSTANT_NAME` to `kConstantName`.
Use common sense or examining the library's code if this does affect code.
## Supported protocols
## Supported Protocols
You can find the details of which protocols & devices are supported
[here](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/SupportedProtocols.md).
@ -55,22 +55,22 @@ Some common answers to common questions and problems are on our [F.A.Q. wiki pag
1. Restart your Arduino IDE.
1. Check out the examples.
##### Using Git to install library ( Linux )
##### Using Git to install the library ( Linux )
```
cd ~/Arduino/libraries
git clone https://github.com/crankyoldgit/IRremoteESP8266.git
```
###### To Update to the latest version of the library
###### To update to the latest version of the library
```
cd ~/Arduino/libraries/IRremoteESP8266 && git pull
```
## Contributing
If you want to [contribute](.github/CONTRIBUTING.md#how-can-i-contribute) to this project, consider:
- [Report](.github/CONTRIBUTING.md#reporting-bugs) bugs and errors
- [Reporting](.github/CONTRIBUTING.md#reporting-bugs) bugs and errors
- Ask for enhancements
- Improve our documentation
- [Create issues](.github/CONTRIBUTING.md#reporting-bugs) and [pull requests](.github/CONTRIBUTING.md#pull-requests)
- [Creating issues](.github/CONTRIBUTING.md#reporting-bugs) and [pull requests](.github/CONTRIBUTING.md#pull-requests)
- Tell other people about this library
## Contributors

View File

@ -0,0 +1,83 @@
# IRremote ESP8266 Library
[![Build Status](https://travis-ci.org/crankyoldgit/IRremoteESP8266.svg?branch=master)](https://travis-ci.org/crankyoldgit/IRremoteESP8266)
[![arduino-library-badge](https://www.ardu-badge.com/badge/IRremoteESP8266.svg?)](https://www.ardu-badge.com/IRremoteESP8266)
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/crankyoldgit/IRremoteESP8266.svg)](http://isitmaintained.com/project/crankyoldgit/IRremoteESP8266 "Average time to resolve an issue")
[![Percentage of issues still open](http://isitmaintained.com/badge/open/crankyoldgit/IRremoteESP8266.svg)](http://isitmaintained.com/project/crankyoldgit/IRremoteESP8266 "Percentage of issues still open")
[![GitLicense](https://gitlicense.com/badge/crankyoldgit/IRremoteESP8266)](https://gitlicense.com/license/crankyoldgit/IRremoteESP8266)
Cette librairie vous permetra de **recevoir et d'envoyer des signaux** infrarouge sur le protocole [ESP8266](https://github.com/esp8266/Arduino) ou sur le protocole
[ESP32](https://github.com/espressif/arduino-esp32) en utilisant le [Arduino framework](https://www.arduino.cc/) qui utilise la norme 940nm IR LEDs et le module basique de reception d'onde IR. Exemple : TSOP{17,22,24,36,38,44,48}* modules etc.
## v2.7.1 disponible
Version 2.7.1 de la libraire est maintenant [disponible](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). Vous pouvez voir le [Release Notes](ReleaseNotes.md) pour tous les changements importants.
#### mise à jour depuis pre-v2.0
L'utilisation de la librairie à un peu changer depuis la version in v2.0. Si vous voulez l'utiliser vous devrez changer votre utilisation aussi. Vous pouvez vous renseigner sur les précondition d'utilisation ici : [Upgrade to v2.0](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Upgrading-to-v2.0) page.
#### Mise à jour depuis pre-v2.5
La librairie à changer, elle n'utilise plus les constantes déclarées comme `#define` mais comme :
[const](https://google.github.io/styleguide/cppguide.html#Constant_Names) avec le nom approprié par le langage
[C++ style guide](https://google.github.io/styleguide/cppguide.html).
Il se peut que d'ancien programme ne compile pas.
Le cas le plus utilisé de `#define`s à été remplacé par _aliased_ pour limiter
la compatibilité de revenir en arrière pour les vieux projet. En revenant en arrière seulement la
nouvelle `kConstantName` style est supporté.
Dans le cas peu probable, votre code serait cassé, alors vous avez peut-être fait référence à
quelque chose que vous ne devriez probablement pas avoir.Vous devez être capable de determiner le nouveau nom
qui remplacera l'ancien. exemple : `CONSTANT_NAME` par `kConstantName`.
Si vous avez un problème examinez le code pour trouver le problème.
## Protocoles supportés
Vous pouvez trouver le détails des protocoles et machines supportés
[here](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/SupportedProtocols.md).
## Dépannage
Avant de reporter un probème ou de demander de l'aide, essayez de suivre notre [guide de dépannage](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Troubleshooting-Guide) first.
## Questions fréquentes
Les questions les plus fréquentes sont ici, avec des réponses [F.A.Q. wiki page](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Frequently-Asked-Questions).
## Installation
##### Officiel releases avec l'Arduino IDE v1.8+ (Windows & Linux)
1. Cliquez sur _"Sketch"_ -> _"Include Library"_ -> _"Manage Libraries..."_ Menu items.
1. Entrez `IRremoteESP8266` dans le _"Filter your search..."_ barre de recherche en haut à droite.
1. Cliquez sur le IRremoteESP8266 pour avoir les résultats de la recherche.
1. Selectionnez la version que vous voulez installer et cliquez sur _"Install"_.
##### Installation manuelle pour Windows
1. cliquez le boutton sur _"Clone or Download"_ , et _"[Download ZIP](https://github.com/crankyoldgit/IRremoteESP8266/archive->master.zip)"_ on the page.
1. Extraire l'archive.
1. renommez le fichier par _"IRremoteESP8266"_.
1. déplacer le fichier dans votre fichier de bibliothèques. (Pour windows : `C:\Users\VOTRE_NOM\Documents\Arduino\libraries\`)
1. Redemarrez arduino IDE.
1. Regardez les exemples.
##### En utilisant GIT ( Linux )
```
cd ~/Arduino/libraries
git clone https://github.com/crankyoldgit/IRremoteESP8266.git
```
###### Pour se mettre à jour
```
cd ~/Arduino/libraries/IRremoteESP8266 && git pull
```
## Contribution
Si vous voulez [contribuer](.github/CONTRIBUTING.md#how-can-i-contribute) au projet, pour les erreurs:
- [Reporting](.github/CONTRIBUTING.md#reporting-bugs) bug et erreurs
- Demander des améliorations
- Améliorer notre documentation
- [Création d'issues](.github/CONTRIBUTING.md#reporting-bugs) et [pull requests](.github/CONTRIBUTING.md#pull-requests)
- Parlez de cettre librairie à d'autres personnes
## Contributeurs
disponible [ici](.github/Contributors.md)
## Historique de la bibliothèque
Elle est basée sur le travail de Shirriff (https://github.com/shirriff/Arduino-IRremote/)
[Mark Szabo](https://github.com/crankyoldgit/IRremoteESP8266) à mis a jour la IRsend class pour qu'elle soit fonctionnelle sur ESP8266 et [Sebastien Warin](https://github.com/sebastienwarin/IRremoteESP8266) s'est occupé de la partie réception et décodage (IRrecv class).
Comme pour la version 2.0, la bibliothèque à été completement réécrite avec les ressources sur ESP8266.

View File

@ -1,5 +1,91 @@
# Release Notes
## _v2.7.1 (20191125)_
**[Bug Fixes]**
- Hitachi424Ac: Fix Incorrect Power Byte Values (#987)
- Coolix: Fix setPower(false) issue. (#990)
**[Features]**
- Use `char*` instead of `String` for common text. Saves ~1-3k. (#992, #989)
- Hitachi424Ac: Add Vertical Swing ability (#986)
**[Misc]**
- IRMQTTServer: Update HA example/discovery message. (#995)
- Move newly added common text to a better location. (#993)
## _v2.7.0 (20191030)_
**[Bug Fixes]**
- auto_analyse: Fix > 64 bit send code generation. (#976)
- auto_analyse: Fix missing arguments in generated code for send64+ (#972)
- IRsendProntoDemo: Fix compile issue on ESP32 platform. (#938)
- IRMQTTServer: Fix compile error when `MQTT_ENABLE` is false. (#933)
**[Features]**
- Add Hitachi 424 bit A/C support. (#975, #980, #981)
- Experimental detailed support for `DAIKIN152` (#971)
- Mitsubishi 112bit A/C support (#947, #968)
- gc_decode: Adding Support for Decoding codes in raw code format (#963)
- Refactor to use common routines/macros to handle bit manipulation. (#934)
- Use centralised common strings. Saves ~1.5k of program space. (#946)
- Add Internationalisation (i18n) / Locale support. (#946, #955, #966)
- `de-CH`: Swiss German. (#949, #954)
- `de-DE`: German. (#946, #950, #952)
- `en-AU`: English/Australia (Default locale) (#946)
- `en-IE`: English/Ireland (#946)
- `en-UK`: English/United Kingdom (#946)
- `en-US`: English/United States (#946)
- `es-ES`: Spanish. (#953)
- `fr-FR`: French. (#962)
- Port CI pipeline to PlatformIO (#936)
**[Misc]**
- Add DAIKIN128 & DAIKIN152 to `decodeToState()` (#982)
- auto_analyse: Produce better code when leader is detected. (#977)
- Coolix A/C improvements (#944)
- A/C setRaw/getRaw/stateReset() cleanup. (#967)
- Add documentation on how to use & support the i18n aspects of the library.
- Make travis checks faster. (#957)
- Translate README.md to french (#959)
- Fixed Coolix kCoolixDefaultState (#941)
- Improve generation of list of pio projects. (#940)
## _v2.6.6 (20190923)_
**[Bug Fixes]**
- Ensure `begin()` is called for every supported common a/c. (#905, #899)
- IRMQTTServer: Fix JSON state parsing. (#896)
- IRMQTTServer: Fix compilation error when `MQTT_CLIMATE_JSON` is `true`. (#893)
**[Features]**
- Mitsubishi136: Full A/C support. (#898, #890)
- Fujitsu: Add support for ARRY4 remote. (#895)
- Web-AC-control: Add new WebUI example sketch. (#880, #886)
- Improve Common A/C API (#913)
- IRMQTTServer: Support for multiple climates. (#903)
- IRMQTTServer: Add TX channel support for HTTP interface. (#929)
- IRMQTTServer: Add option to clear retained settings. (#917)
- auto_analyse_raw_data.py: Add decode code generation. (#909)
- auto_analyse_raw_data.py: General improvements (#906)
**[Misc]**
- IRMQTTServer: Use latest API for common A/C. (#928)
- IRMQTTServer: Add flag & documentation for Home Assistant mode. (#919)
- IRMQTTServer: Move from ArduinoJson v5 to v6. (#878)
- IRMQTTServer: Use retain for discovery message. (#881)
- Goodweather: Adjust timings & minor fixes. (#924)
- PanasonicAc: Add better SwingV support for common a/c framework. (#923)
- Daikin2: Corrections for common A/C interface. (#910)
- MitsubishiAC: Improve decoding. (#914)
- Fujitsu: Disable horiz swing for ARRY4. (#907)
- SamsungAc: Only send power on/off code if it's needed. (#884)
- Teco: Add timer support. (#883)
- More consistent A/C `::toString()` output. (#920)
## _v2.6.5 (20190828)_
**[Bug Fixes]**

View File

@ -1,6 +1,6 @@
<!--- WARNING: Do NOT edit this file directly.
It is generated by './tools/scrape_supported_devices.py'.
Last generated: Wed Aug 28 12:37:20 2019 --->
Last generated: Mon Nov 25 11:12:06 2019 --->
# IR Protocols supported by this library
| Protocol | Brand | Model | A/C Model | Detailed A/C Support |
@ -11,21 +11,22 @@
| [Carrier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Carrier.cpp) | **Carrier/Surrey** | 42QG5A55970 remote<BR>53NGK009/012 Inverter<BR>619EGX0090E0 A/C<BR>619EGX0120E0 A/C<BR>619EGX0180E0 A/C<BR>619EGX0220E0 A/C | | - |
| [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Beko](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | BINR 070/071 split-type A/C<BR>BINR 070/071 split-type A/C<BR>RG57K7(B)/BGEF Remote<BR>RG57K7(B)/BGEF Remote | | Yes |
| [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | MS12FU-10HRDN1-QRD0GW(B) A/C<BR>MS12FU-10HRDN1-QRD0GW(B) A/C<BR>MSABAU-07HRFN1-QRD0GW A/C (circa 2016)<BR>MSABAU-07HRFN1-QRD0GW A/C (circa 2016)<BR>RG52D/BGE Remote<BR>RG52D/BGE Remote | | Yes |
| [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Tokio](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | AATOEMF17-12CHR1SW split-type RG51|50/BGE Remote<BR>AATOEMF17-12CHR1SW split-type RG51|50/BGE Remote | | Yes |
| [Daikin](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Daikin.cpp) | **[Daikin](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Daikin.h)** | 17 Series A/C (DAIKIN128)<BR>ARC423A5 remote<BR>ARC433** remote<BR>ARC433B69 remote<BR>ARC477A1 remote<BR>ARC480A5 remote (DAIKIN152)<BR>BRC4C153 remote<BR>BRC52B63 remote (DAIKIN128)<BR>FTE12HV2S A/C<BR>FTXB09AXVJU A/C (DAIKIN128)<BR>FTXB12AXVJU A/C (DAIKIN128)<BR>FTXZ25NV1B A/C<BR>FTXZ35NV1B A/C<BR>FTXZ50NV1B A/C | | Yes |
| [Denon](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Denon.cpp) | **Unknown** | | | - |
| [Dish](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Dish.cpp) | **DISH NETWORK** | echostar 301 | | - |
| [Electra](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.cpp) | **[AUX](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.h)** | KFR-35GW/BpNFW=3 A/C<BR>YKR-T/011 remote | | Yes |
| [Fujitsu](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Fujitsu.cpp) | **[Fujitsu](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Fujitsu.h)** | AR-DB1 remote<BR>AR-RAE1E remote<BR>AR-RAH2E remote<BR>AR-REB1E remote<BR>AST9RSGCW A/C<BR>ASYG30LFCA A/C<BR>ASYG7LMCA A/C | ARDB1<BR>ARJW2<BR>ARRAH2E<BR>ARREB1E | Yes |
| [Fujitsu](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Fujitsu.cpp) | **[Fujitsu General](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Fujitsu.h)** | AR-JW2 remote | ARDB1<BR>ARJW2<BR>ARRAH2E<BR>ARREB1E | Yes |
| [Fujitsu](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Fujitsu.cpp) | **[Fujitsu](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Fujitsu.h)** | AGTV14LAC A/C<BR>AR-DB1 remote<BR>AR-DL10 remote<BR>AR-RAC1E remote<BR>AR-RAE1E remote<BR>AR-RAH2E remote<BR>AR-REB1E remote<BR>AR-RY4 remote<BR>AST9RSGCW A/C<BR>ASTB09LBC A/C<BR>ASU30C1 A/C<BR>ASYG30LFCA A/C<BR>ASYG7LMCA A/C | | Yes |
| [Fujitsu](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Fujitsu.cpp) | **[Fujitsu General](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Fujitsu.h)** | AR-JW2 remote | | Yes |
| [GICable](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_GICable.cpp) | **Unknown** | | | - |
| [GlobalCache](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_GlobalCache.cpp) | **Unknown** | | | - |
| [Goodweather](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Goodweather.cpp) | **[Goodweather](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Goodweather.h)** | ZH/JT-03 remote | | Yes |
| [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[EKOKAI](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | A/C | YAW1F<BR>YBOFB | Yes |
| [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[Green](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | YBOFB remote<BR>YBOFB2 remote | YAW1F<BR>YBOFB | Yes |
| [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[RusClimate](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | EACS/I-09HAR_X/N3 A/C<BR>YAW1F remote | YAW1F<BR>YBOFB | Yes |
| [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[Ultimate](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | Heat Pump | YAW1F<BR>YBOFB | Yes |
| [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[EKOKAI](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | A/C | | Yes |
| [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[Green](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | YBOFB remote<BR>YBOFB2 remote | | Yes |
| [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[RusClimate](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | EACS/I-09HAR_X/N3 A/C<BR>YAW1F remote | | Yes |
| [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[Ultimate](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | Heat Pump | | Yes |
| [Haier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Haier.cpp) | **[Haier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Haier.h)** | HSU-09HMC203 A/C<BR>HSU07-HEA03 remote<BR>YR-W02 remote | | Yes |
| [Hitachi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Hitachi.cpp) | **[Hitachi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Hitachi.h)** | LT0541-HTA remote<BR>RAS-35THA6 remote<BR>Series VI A/C (Circa 2007) | | Yes |
| [Hitachi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Hitachi.cpp) | **[Hitachi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Hitachi.h)** | LT0541-HTA remote<BR>RAR-8P2 remote<BR>RAS-35THA6 remote<BR>RAS-AJ25H A/C<BR>Series VI A/C (Circa 2007) | | Yes |
| [Inax](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Inax.cpp) | **Lixil** | Inax DT-BA283 Toilet | | - |
| [JVC](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_JVC.cpp) | **Unknown** | | | - |
| [Kelvinator](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.cpp) | **[Green](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.h)** | YAPOF3 remote | | Yes |
@ -39,12 +40,13 @@
| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Comfee](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | MPD1-12CRN7 A/C | | Yes |
| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Keystone](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | RG57H4(B)BGEF remote | | Yes |
| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Pioneer System](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | RUBO18GMFILCAD A/C (18K BTU)<BR>RYBO12GMFILCAD A/C (12K BTU) | | Yes |
| [Mitsubishi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.cpp) | **[Mitsubishi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.h)** | HC3000 Projector<BR>TV | | Yes |
| [Mitsubishi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.cpp) | **[Mitsubishi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.h)** | HC3000 Projector<BR>KM14A 0179213 remote<BR>MS-GK24VA A/C<BR>TV | | Yes |
| [Mitsubishi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.cpp) | **[Mitsubishi Electric](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.h)** | 001CP T7WE10714 remote<BR>KPOA remote<BR>MSH-A24WV / MUH-A24WV A/C<BR>PEAD-RP71JAA Ducted A/C | | Yes |
| [MitsubishiHeavy](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_MitsubishiHeavy.cpp) | **[Mitsubishi Heavy Industries](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_MitsubishiHeavy.h)** | RKX502A001C remote<BR>RLA502A700B remote<BR>SRKxxZJ-S A/C<BR>SRKxxZM-S A/C<BR>SRKxxZMXA-S A/C | | Yes |
| [NEC](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.cpp) | **[Yamaha](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.h)** | RAV561 remote<BR>RXV585B A/V Receiver | | Yes |
| [Neoclima](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Neoclima.cpp) | **[Neoclima](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Neoclima.h)** | NS-09AHTI A/C<BR>NS-09AHTI A/C<BR>ZH/TY-01 remote<BR>ZH/TY-01 remote | | Yes |
| [Nikai](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Nikai.cpp) | **Unknown** | | | - |
| [Panasonic](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Panasonic.cpp) | **[Panasonic](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Panasonic.h)** | A75C2311 remote (CKP)<BR>A75C3704 remote<BR>A75C3747 remote<BR>A75C3747 remote<BR>A75C3747 remote<BR>A75C3747 remote<BR>CKP series A/C<BR>CS-ME10CKPG A/C<BR>CS-ME12CKPG A/C<BR>CS-ME14CKPG A/C<BR>CS-YW9MKD A/C<BR>CS-Z9RKR A/C<BR>DKE series A/C<BR>JKE series A/C<BR>NKE series A/C<BR>RKR series A/C<BR>TV | CKP<BR>DKE<BR>JKE<BR>LKE<BR>NKE<BR>RKR | Yes |
| [Panasonic](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Panasonic.cpp) | **[Panasonic](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Panasonic.h)** | A75C2311 remote (CKP)<BR>A75C3704 remote<BR>A75C3747 remote<BR>A75C3747 remote<BR>A75C3747 remote<BR>A75C3747 remote<BR>CKP series A/C<BR>CS-ME10CKPG A/C<BR>CS-ME12CKPG A/C<BR>CS-ME14CKPG A/C<BR>CS-YW9MKD A/C<BR>CS-Z9RKR A/C<BR>DKE series A/C<BR>JKE series A/C<BR>NKE series A/C<BR>RKR series A/C<BR>TV | | Yes |
| [Pioneer](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Pioneer.cpp) | **Unknown** | | | - |
| [Pronto](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Pronto.cpp) | **Unknown** | | | - |
| [RC5_RC6](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_RC5_RC6.cpp) | **Unknown** | | | - |
@ -59,16 +61,18 @@
| [Toshiba](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Toshiba.cpp) | **[Toshiba](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Toshiba.h)** | Akita EVO II<BR>RAS 18SKP-ES<BR>RAS-B13N3KV2<BR>RAS-B13N3KVP-E<BR>WC-L03SE<BR>WH-TA04NE | | Yes |
| [Trotec](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Trotec.cpp) | **[Unknown](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Trotec.h)** | | | Yes |
| [Vestel](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Vestel.cpp) | **[Vestel](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Vestel.h)** | BIOX CXP-9 A/C (9K BTU) | | Yes |
| [Whirlpool](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Whirlpool.cpp) | **[Whirlpool](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Whirlpool.h)** | DG11J1-04 remote<BR>DG11J1-3A remote<BR>DG11J1-91 remote<BR>SPIS409L A/C<BR>SPIS412L A/C<BR>SPIW409L A/C<BR>SPIW412L A/C<BR>SPIW418L A/C | DG11J13A<BR>DG11J191 | Yes |
| [Whirlpool](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Whirlpool.cpp) | **[Whirlpool](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Whirlpool.h)** | DG11J1-04 remote<BR>DG11J1-3A remote<BR>DG11J1-91 remote<BR>SPIS409L A/C<BR>SPIS412L A/C<BR>SPIW409L A/C<BR>SPIW412L A/C<BR>SPIW418L A/C | | Yes |
| [Whynter](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Whynter.cpp) | **Whynter** | ARC-110WD A/C | | - |
## Send only protocols:
- GLOBALCACHE
- MITSUBISHI112
- PRONTO
- RAW
- SHERWOOD
- TCL112AC
## Send & decodable protocols:
@ -97,6 +101,7 @@
- HITACHI_AC
- HITACHI_AC1
- HITACHI_AC2
- HITACHI_AC424
- INAX
- JVC
- KELVINATOR
@ -108,6 +113,7 @@
- MAGIQUEST
- MIDEA
- MITSUBISHI
- MITSUBISHI136
- MITSUBISHI2
- MITSUBISHI_AC
- MITSUBISHI_HEAVY_152
@ -132,10 +138,10 @@
- SHARP
- SHARP_AC
- SONY
- TCL112AC
- TECO
- TOSHIBA_AC
- TROTEC
- VESTEL_AC
- WHIRLPOOL_AC
- WHYNTER
- typeguess

View File

@ -0,0 +1,72 @@
/* Copyright 2019 David Conran
*
* This example code demonstrates how to use the "Common" IRac class to control
* various air conditions. The IRac class does not support all the features
* for every protocol. Some have more detailed support that what the "Common"
* interface offers, and some only have a limited subset of the "Common" options.
*
* This example code will:
* o Try to turn on, then off every fully supported A/C protocol we know of.
* o It will try to put the A/C unit into Cooling mode at 25C, with a medium
* fan speed, and no fan swinging.
* Note: Some protocols support multiple models, only the first model is tried.
*
*/
#include <Arduino.h>
#include <IRremoteESP8266.h>
#include <IRac.h>
#include <IRutils.h>
const uint16_t kIrLed = 4; // The ESP GPIO pin to use that controls the IR LED.
IRac ac(kIrLed); // Create a A/C object using GPIO to sending messages with.
void setup() {
Serial.begin(115200);
delay(200);
// Set up what we want to send.
// See state_t, opmode_t, fanspeed_t, swingv_t, & swingh_t in IRsend.h for
// all the various options.
ac.next.protocol = decode_type_t::DAIKIN; // Set a protocol to use.
ac.next.model = 1; // Some A/Cs have different models. Try just the first.
ac.next.mode = stdAc::opmode_t::kCool; // Run in cool mode initially.
ac.next.celsius = true; // Use Celsius for temp units. False = Fahrenheit
ac.next.degrees = 25; // 25 degrees.
ac.next.fanspeed = stdAc::fanspeed_t::kMedium; // Start the fan at medium.
ac.next.swingv = stdAc::swingv_t::kOff; // Don't swing the fan up or down.
ac.next.swingh = stdAc::swingh_t::kOff; // Don't swing the fan left or right.
ac.next.light = false; // Turn off any LED/Lights/Display that we can.
ac.next.beep = false; // Turn off any beep from the A/C if we can.
ac.next.econo = false; // Turn off any economy modes if we can.
ac.next.filter = false; // Turn off any Ion/Mold/Health filters if we can.
ac.next.turbo = false; // Don't use any turbo/powerful/etc modes.
ac.next.quiet = false; // Don't use any quiet/silent/etc modes.
ac.next.sleep = -1; // Don't set any sleep time or modes.
ac.next.clean = false; // Turn off any Cleaning options if we can.
ac.next.clock = -1; // Don't set any current time if we can avoid it.
ac.next.power = false; // Initially start with the unit off.
Serial.println("Try to turn on & off every supported A/C type ...");
}
void loop() {
// For every protocol the library has ...
for (int i = 1; i < kLastDecodeType; i++) {
decode_type_t protocol = (decode_type_t)i;
// If the protocol is supported by the IRac class ...
if (ac.isProtocolSupported(protocol)) {
Serial.println("Protocol " + String(protocol) + " / " +
typeToString(protocol) + " is supported.");
ac.next.protocol = protocol; // Change the protocol used.
ac.next.power = true; // We want to turn on the A/C unit.
Serial.println("Sending a message to turn ON the A/C unit.");
ac.sendAc(); // Have the IRac class create and send a message.
delay(5000); // Wait 5 seconds.
ac.next.power = false; // Now we want to turn the A/C off.
Serial.println("Send a message to turn OFF the A/C unit.");
ac.sendAc(); // Send the message.
delay(1000); // Wait 1 second.
}
}
Serial.println("Starting from the begining again ...");
}

View File

@ -5,14 +5,13 @@ src_dir = .
lib_extra_dirs = ../../
lib_ldf_mode = deep+
lib_ignore = examples
build_flags =
framework = arduino
build_flags = ; -D_IR_LOCALE_=en-AU
[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
[env:esp32dev]
platform = espressif32
framework = arduino
board = esp32dev

View File

@ -5,14 +5,13 @@ src_dir = .
lib_extra_dirs = ../../
lib_ldf_mode = deep+
lib_ignore = examples
build_flags =
framework = arduino
build_flags = ; -D_IR_LOCALE_=en-AU
[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
[env:esp32dev]
platform = espressif32
framework = arduino
board = esp32dev

View File

@ -5,14 +5,13 @@ src_dir = .
lib_extra_dirs = ../../
lib_ldf_mode = deep+
lib_ignore = examples
build_flags =
framework = arduino
build_flags = ; -D_IR_LOCALE_=en-AU
[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
[env:esp32dev]
platform = espressif32
framework = arduino
board = esp32dev

Some files were not shown because too many files have changed in this diff Show More