* Allow 100% high or low periods. Let output remain at current level on stopping instead of always turning to low. * Fix serious jitter issues in previous versions. * Use ESP.getCycleCount() just like everyone else. * Highest timer rate at which this runs stable appears to be 2µs (500kHz). * Guard for zero period length undefined waveforms. Fix for zero duty or off cycles and expiring from them. * Cycle precision for expiry instead of special treatment for 0 value. * Give expiry proper precedence over updating a waveform * Important comment * Refactored, identical behavior. * Use plural for bit arrays. * Fix for completely duty or all off cycle period case. * Expiration is explicitly relative to service time. * Comment updated, here it's about cycles not usecs. * Revert misconception of how waveformToEnable/Disable communicates with the NMI handler. * Rewrite to keep phase in sync if period remains same during duty cycle change. Refactor identifies to distinguish CPU clock cycle from waveform cycle. * Rather iterate even if full-duty or no-duty cycle in period, than too many calculations in NMI handler. * Must fire timer early to reach waveform deadlines, otherwise under some load aggressive jitter occurs. * Schedule expiry explicitly, too. Needed to keep track of next timer ccy in each iteration, not just when changing level. * Quick change lets analogWrite keep phase for any duty cycle (including 0% and 100%). * Set duration to multiple of period, so tone stops on LOW pin output. * Improve phase timing * Eror causing next Timer IRQ to fail busy-to-off cycle transitions. * Regression fix, don't reset timer if pending shortly. * Rather reschedule ISR instead of busy looping during permitted maximum time. * Lead time improved for ISR * Reduce number of cycle calculations. * Reactive the gcc optimize pragmas. * Simplify calculation. * handles overshoot where an updated period is shorter than the previous duty cycle * Misleading code, there must ever be only one bit set at a time, start and stop block until the ISR has handled and reset the token. * Prevent missing a duty cycle unless it is overshot already. * Continuously remove distant pending waveform edges from the loop, continuously update now. * Replace volatile for one-way exchange into ISR with memory fence. * Remove redundant stack object. * Revert pending waveform removal from loop - corrupts continuous next event computation. * Reduce if/do ... while to while * Convert relative timings to absolute. * Relax waveform start to possibly cluster phases into same IRQ interval. * max 12us in ISR seems to work best for servo/fan/led/tone combo test. * Restructured code in ISR for expiration, this saves 36 byte IRAM, and improves PWM resolution. * Simplified overshot detection and 0% / 100% duty cycle. * Leave ISR early if rescheduling is more promising than busy-waiting until next edge. * Stabilized timings. * Prevent WDT under load. * Use clock cycle resolution instead of us for analogWrite. * Reduce idle calculations in ISR. * Optimize in-ISR time. * Support starting new waveform in phase with another running waveform. * Align phase for analogWrite PWMs. * Tune preshoot, add lost period fast forward. * Adapt phase sync code from analogWrite to Servo * Fix for going off 100% duty cycle period. * Eschew obfuscation. * Fixed logic for zero duty cycle. * Determine generator quantum during same IRQ - this is better than timer resolution, but non-zero. * Tune timings, fix write barriers and overshoot logic. * Migrate Tone to waveform with CPU cycle precision * Can do 60kHz PWM. * Recalibrated timings after performance optimizations. Initialize GPIO if needed. * Fix regression for waveform runtime. * Test cycle duration values for signed arithmetic safety. * Performance tuning. * Performance tweak, in-ISR quantum is now 1.12µs. * Round up duration instead of down - possibly to zero, which means forever. * Extend phase alignment with optional phase offset. * Slightly better in-ISR quantum approximation for steadier increments. * Waveform stopped by runtime limit in iSR doesn't deinit the timer, but stopWaveform refuses to do anything if the waveform was stopped by runtime, either. * Improved quantum correction code. * Fix broken multi-wave generation. * Aggregate GPIO output across inner loop. True phase sync, and now better performance. * IRQ latency can be reduced from 2 to 1 us now, no WDT etc. * Improved handling of complete idle cycle miss, progress directly into duty cycle. * Recalibrated after latest changes and reverts. * Overshoot compensation for duty cycle results in PWM milestone. * Adjustments to duty/idle cycle to mitigate effects of floating duty cycle logic. * Remove implicit condition from loop guard and fix timer restart duration * Host all static globals in an anonymous static struct. * Busy wait directly for next pending event and go to that pin. * Record nextEventCcy in waveform struct to save a few cycles. * Adapt duty cycle modification to only fix full duty and all idle cases. * Remember next pin to operate between IRQs. * Don't set pinMode each time on already running PWM or Tone. * Remove quantum, correct irq latency from testing,reuse isr timeout from master et al * Move updating "now" out of inner loop, prevents float between pins that are in phase lock. * Merge init loop with action loop again. * Adaptive PWM frequency and floating duty cycle. * Predictive static frequency scaling. * Dynamic frequency down-scaling * Frequency scaling is only for PWM-like applications, anything needing real time duty cycles or frequency must be able to fail on overload. * Conserve IRAM cache, resort to best effort. * Directly scale frequency for all duty/all idle waves to reasonable maximum, reduces thrashing. * Getting the math right beats permanently reducing PWM frequency. * Rename identifier to help think about the problem. * AutoPwm correction moved to correct location - after overshoot recalc - and allow limited duty floating * Finish overshoot math fixes. * First set pin mode, then digital write. * Simplify calculations, fix non-autoPwm for servo use, where exact duty is needed, idle is elastic. * Move wave initialization and modification outside the inner loop. * Some optimizing. * Updating "now" in the inner loop should lessen interference * Finally get rid of volatile and use atomic thread fence memory barriers, great for ISR performance. * Improved idle cycle overshoot mitigation. * Improved duty cycle overshoot mitigation. Case for investigation: 3% (shl 5) vs. 1.5% (shl 6), either less fuzz, but a few marked stray spots, or more fuzz, but no bumps in counter-PWM travel test. * Move startPin etc. into common static struct * Persist next event cycle across ISR invocations, like initPin was before. * Recalibrated DELTAIRQ and IRQLATENCY. Tested @ 3x 40kHz PWM + 440Hz Tone * CPU clock to Timer1 ccy correction must be dynamic even when BSP is compiled for fixed CPU clock. * Corrected use of Timer1 registers and add rationale to Timer1 use in comment. Recalibrate for improved frequence downscaling @ 80MHz and 160MHz. * Let duty cycle overshoot correction depend on relative impact compareed to both period and duty. * 80MHz/160MHz specific code can be compile-time selected in general, only NMI is affected by apparent CPU frequency scaling in SDK code. * Seems that removing the redudant resetting of edge interrupt mode shaves 0.5us off rearm latency. * Recalibrated delta irq ccys. * Off-by-one in 100% duty overshoot correction. * Simple register writes. * Memory fences checked and joining events into same loop iteration that are close to one another. * Shorten progression when going off 100% duty. * Code simplifications. * Dynamically map pins out from in-ISR handling based on next event timing. Major performance boost. * Reverting maximum IRQ period to 10ms. This sets the wave reprogramming rate to 100Hz max. * Revert recent change that is the most likely cause of reported PWM frequency drop regression. * Much simplified overshoot mitigation code. * Fixing overshoot mitigation, 3x 880Hz, 256 states now. * Increase resolution by keeping reference time moving forward earlier. * Mitigation logic for ESP8266 SDK boosting to 160MHz during some WiFi ops. * Event timestamps are all recorded for compile-time CPU frequency, the timer ticks conversion must be set at compile-time also. The SDK WiFi 160MHz boost mitigation temporarily handles the CPU clock running twice as fast. * Expired pins must not be checked for next event. * Recalibrate after latest changes. * Save a few bytes code. * Guards are in place, so xor rather than and bitwise not. * Reduce memory use. * SDK boost to 160MHz may last across multiple ISR invocations, therefore adjust target ccy instead of ccount. * Overshoot mitigation w/o PWM frequency change. * New PWM overshoot mitigation code keeps frequency. Averages duty between consecutive periods. * Small refactoring, remove code path that is never taken even at 3x25kHz/1023 PWM. * Don't ever skip off duty, no matter if late or infinitely short. * Shed speed-up code that didn't speed up things. * Must always recompute new waveform.nextEventCcy if there is any busy pin. * Break out of ISR if timespan to next event allows, instead of busy waiting and stealing CPU cycles from userland. * Minor code simplification. * Improve code efficiency. * Improved performance of loop. * Recalibrated. * No positive effect of lead time inclusion was found during testing, remove this code. Maximum period duration limit is implicit to timer, consider it documented constraint, don't runtime check in ISR. * Fix WDT when at 160MHz CPU clock the Timer1 is set below 1µs. * Consolidate 160MHz constexpr check, finish 1µs minimum for Timer1 fix. * Test for non-zero before subtract should improve performance. * Reviewers/tested noted they were seeing WDT, and this change appeared to fix that. * More expressive use of parentheses and alias CPU2X for reduced code size. * Bug fix: at 160MHz compiled, don't force minimum Timer1 latency to 2µs. * Alternate CPU frequency scaling mitigation. * Handle time-of-flight in the right spot. * Remove _toneMap from Tone.cpp Co-authored-by: david gauchard <gauchard@laas.fr>
Arduino core for ESP8266 WiFi chip
Quick links
Arduino on ESP8266
This project brings support for the ESP8266 chip to the Arduino environment. It lets you write sketches, using familiar Arduino functions and libraries, and run them directly on ESP8266, with no external microcontroller required.
ESP8266 Arduino core comes with libraries to communicate over WiFi using TCP and UDP, set up HTTP, mDNS, SSDP, and DNS servers, do OTA updates, use a file system in flash memory, and work with SD cards, servos, SPI and I2C peripherals.
Contents
- Installing options:
- Documentation
- Issues and support
- Contributing
- License and credits
Installing with Boards Manager
Starting with 1.6.4, Arduino allows installation of third-party platform packages using Boards Manager. We have packages available for Windows, Mac OS, and Linux (32 and 64 bit).
- Install the current upstream Arduino IDE at the 1.8.9 level or later. The current version is on the Arduino website.
- Start Arduino and open the Preferences window.
- Enter
https://arduino.esp8266.com/stable/package_esp8266com_index.json
into the Additional Board Manager URLs field. You can add multiple URLs, separating them with commas. - Open Boards Manager from Tools > Board menu and install esp8266 platform (and don't forget to select your ESP8266 board from Tools > Board menu after installation).
Latest release 
Boards manager link: https://arduino.esp8266.com/stable/package_esp8266com_index.json
Documentation: https://arduino-esp8266.readthedocs.io/en/2.7.4_a/
Using git version
Also known as latest git or master branch.
- Install the current upstream Arduino IDE at the 1.8 level or later. The current version is on the Arduino website.
- Follow the instructions in the documentation.
Using PlatformIO
PlatformIO is an open source ecosystem for IoT development with a cross-platform build system, a library manager, and full support for Espressif (ESP8266) development. It works on the following popular host operating systems: macOS, Windows, Linux 32/64, and Linux ARM (like Raspberry Pi, BeagleBone, CubieBoard).
- What is PlatformIO?
- PlatformIO IDE
- PlatformIO Core (command line tool)
- Advanced usage - custom settings, uploading to SPIFFS, Over-the-Air (OTA), staging version
- Integration with Cloud and Standalone IDEs - Cloud9, Codeanywhere, Eclipse Che (Codenvy), Atom, CLion, Eclipse, Emacs, NetBeans, Qt Creator, Sublime Text, VIM, Visual Studio, and VSCode
- Project Examples
Building with make
makeEspArduino is a generic makefile for any ESP8266 Arduino project. Using make instead of the Arduino IDE makes it easier to do automated and production builds.
Documentation
Documentation for latest development version: https://arduino-esp8266.readthedocs.io/en/latest/
Issues and support
ESP8266 Community Forum is a well-established community for questions and answers about Arduino for ESP8266. Stackoverflow is also an alternative. If you need help, have a "How do I..." type question, have a problem with a 3rd party library not hosted in this repo, or just want to discuss how to approach a problem, please ask there.
If you find the forum useful, please consider supporting it with a donation.
If you encounter an issue which you think is a bug in the ESP8266 Arduino Core or the associated libraries, or if you want to propose an enhancement, you are welcome to submit it here on Github: https://github.com/esp8266/Arduino/issues.
Please provide as much context as possible, as well as the information requested in the issue template:
- ESP8266 Arduino core version which you are using (you can check it in Boards Manager)
- your sketch code; please wrap it into a code block, see Github markdown manual
- when encountering an issue that happens at run time, attach the serial output. Wrap it into a code block, just like the code.
- for issues that happen at compile time, enable verbose compiler output in the IDE preferences, and attach that output (also inside a code block)
- ESP8266 development board model
- IDE settings (board choice, flash size)
- etc
Contributing
For minor fixes of code and documentation, please go ahead and submit a pull request. A gentle introduction to the process can be found here.
Check out the list of issues that are easy to fix — easy issues pending. Working on them is a great way to move the project forward.
Larger changes (rewriting parts of existing code from scratch, adding new functions to the core, adding new libraries) should generally be discussed by opening an issue first. PRs with such changes require testing and approval.
Feature branches with lots of small commits (especially titled "oops", "fix typo", "forgot to add file", etc.) should be squashed before opening a pull request. At the same time, please refrain from putting multiple unrelated changes into a single pull request.
License and credits
Arduino IDE is developed and maintained by the Arduino team. The IDE is licensed under GPL.
ESP8266 core includes an xtensa gcc toolchain, which is also under GPL.
Esptool.py was initially created by Fredrik Ahlberg (@themadinventor, @kongo), and is currently maintained by Angus Gratton (@projectgus) under GPL 2.0 license.
Espressif's NONOS SDK included in this build is under Espressif MIT License.
ESP8266 core files are licensed under LGPL.
SPI Flash File System (SPIFFS) written by Peter Andersson is used in this project. It is distributed under the MIT license.
umm_malloc memory management library written by Ralph Hempel is used in this project. It is distributed under the MIT license.
SoftwareSerial library and examples written by Peter Lerup. Distributed under LGPL 2.1.
BearSSL library written by Thomas Pornin, built from https://github.com/earlephilhower/bearssl-esp8266, is used in this project. It is distributed under the MIT License.
LittleFS library written by ARM Limited and released under the BSD 3-clause license.
uzlib library written and (c) 2014-2018 Paul Sokolovsky, licensed under the ZLib license (https://www.zlib.net/zlib_license.html). uzlib is based on: tinf library by Joergen Ibsen (Deflate decompression); Deflate Static Huffman tree routines by Simon Tatham; LZ77 compressor by Paul Sokolovsky; with library integrated and maintained by Paul Sokolovsky.
Other useful links
Serial Monitor Arduino IDE plugin Original discussion here, quick download there.