mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-22 21:23:07 +03:00
Matching standard Arduino cores, make the default analogWrite() take values from 0...255. Users can always use the analogWriteRange() call to change to a different setup. Add a `analogWriteResolution` which takes a number of bits and sets the range from 0...(1<<bits)-1, part of the standard Arduino API. Remove the PWMRANGE define. It's non-standard and not generally valid (i.e. it's fixed at 1024 of 256, but the real range varies depending on what you last set). Also add note about the change and how to fix pre 3.0 applications. Fixes #2895
336 lines
14 KiB
ReStructuredText
336 lines
14 KiB
ReStructuredText
Reference
|
|
=========
|
|
|
|
Interrupts
|
|
----------
|
|
|
|
Interrupts can be used on the ESP8266, but they must be used with care
|
|
and have several limitations:
|
|
|
|
* Interrupt callback functions must be in IRAM, because the flash may be
|
|
in the middle of other operations when they occur. Do this by adding
|
|
the ``ICACHE_RAM_ATTR`` attribute on the function definition. If this
|
|
attribute is not present, the sketch will crash when it attempts to
|
|
``attachInterrupt`` with an error message.
|
|
|
|
.. code:: cpp
|
|
|
|
ICACHE_RAM_ATTR void gpio_change_handler(void *data) {...
|
|
|
|
* Interrupts must not call ``delay()`` or ``yield()``, or call any routines
|
|
which internally use ``delay()`` or ``yield()`` either.
|
|
|
|
* Long-running (>1ms) tasks in interrupts will cause instabilty or crashes.
|
|
WiFi and other portions of the core can become unstable if interrupts
|
|
are blocked by a long-running interrupt. If you have much to do, you can
|
|
set a volatile global flag that your main ``loop()`` can check each pass
|
|
or use a scheduled function (which will be called outside of the interrupt
|
|
context when it is safe) to do long-running work.
|
|
|
|
* Memory operations can be dangerous and should be avoided in interrupts.
|
|
Calls to ``new`` or ``malloc`` should be minimized because they may require
|
|
a long running time if memory is fragmented. Calls to ``realloc`` and
|
|
``free`` must NEVER be called. Using any routines or objects which call
|
|
``free`` or ``realloc`` themselves is also forbidden for the same reason.
|
|
This means that ``String``, ``std::string``, ``std::vector`` and other
|
|
classes which use contiguous memory that may be resized must be used with
|
|
extreme care (ensuring strings aren't changed, vector elements aren't
|
|
added, etc.).
|
|
|
|
Digital IO
|
|
----------
|
|
|
|
Pin numbers in Arduino correspond directly to the ESP8266 GPIO pin
|
|
numbers. ``pinMode``, ``digitalRead``, and ``digitalWrite`` functions
|
|
work as usual, so to read GPIO2, call ``digitalRead(2)``.
|
|
|
|
Digital pins 0—15 can be ``INPUT``, ``OUTPUT``, or ``INPUT_PULLUP``. Pin
|
|
16 can be ``INPUT``, ``OUTPUT`` or ``INPUT_PULLDOWN_16``. At startup,
|
|
pins are configured as ``INPUT``.
|
|
|
|
Pins may also serve other functions, like Serial, I2C, SPI. These
|
|
functions are normally activated by the corresponding library. The
|
|
diagram below shows pin mapping for the popular ESP-12 module.
|
|
|
|
.. figure:: esp12.png
|
|
:alt: Pin Functions
|
|
|
|
Pin Functions
|
|
|
|
Digital pins 6—11 are not shown on this diagram because they are used to
|
|
connect flash memory chip on most modules. Trying to use these pins as
|
|
IOs will likely cause the program to crash.
|
|
|
|
Note that some boards and modules (ESP-12ED, NodeMCU 1.0) also break out
|
|
pins 9 and 11. These may be used as IO if flash chip works in DIO mode
|
|
(as opposed to QIO, which is the default one).
|
|
|
|
Pin interrupts are supported through ``attachInterrupt``,
|
|
``detachInterrupt`` functions. Interrupts may be attached to any GPIO
|
|
pin, except GPIO16. Standard Arduino interrupt types are supported:
|
|
``CHANGE``, ``RISING``, ``FALLING``. ISRs need to have
|
|
``ICACHE_RAM_ATTR`` before the function definition.
|
|
|
|
Analog input
|
|
------------
|
|
|
|
ESP8266 has a single ADC channel available to users. It may be used
|
|
either to read voltage at ADC pin, or to read module supply voltage
|
|
(VCC).
|
|
|
|
To read external voltage applied to ADC pin, use ``analogRead(A0)``.
|
|
Input voltage range of bare ESP8266 is 0 — 1.0V, however some many
|
|
boards may implement voltage dividers. To be on the safe side, <1.0V
|
|
can be tested. If e.g. 0.5V delivers values around ~512, then maximum
|
|
voltage is very likely to be 1.0V and 3.3V may harm the ESP8266.
|
|
However values around ~150 indicates that the maximum voltage is
|
|
likely to be 3.3V.
|
|
|
|
To read VCC voltage, use ``ESP.getVcc()`` and ADC pin must be kept
|
|
unconnected. Additionally, the following line has to be added to the
|
|
sketch:
|
|
|
|
.. code:: cpp
|
|
|
|
ADC_MODE(ADC_VCC);
|
|
|
|
This line has to appear outside of any functions, for instance right
|
|
after the ``#include`` lines of your sketch.
|
|
|
|
Analog output
|
|
-------------
|
|
|
|
``analogWrite(pin, value)`` enables software PWM on the given pin. PWM
|
|
may be used on pins 0 to 16. Call ``analogWrite(pin, 0)`` to disable PWM
|
|
on the pin.
|
|
|
|
``value`` may be in range from 0 to 255 (which is the Arduino default).
|
|
PWM range may be changed by calling ``analogWriteRange(new_range)`` or
|
|
``analogWriteResolution(bits)``. ``new_range`` may be from 15...65535
|
|
or ``bits`` may be from 4...16.
|
|
|
|
**NOTE:** The default ``analogWrite`` range was 1023 in releases before
|
|
3.0, but this lead to incompatibility with external libraries which
|
|
depended on the Arduino core default of 256. Existing applications which
|
|
rely on the prior 1023 value may add a call to ``analogWriteRange(1023)``
|
|
to their ``setup()`` routine to retrurn to their old behavior. Applications
|
|
which already were calling ``analogWriteRange`` need no change.
|
|
|
|
PWM frequency is 1kHz by default. Call
|
|
``analogWriteFreq(new_frequency)`` to change the frequency. Valid values
|
|
are from 100Hz up to 40000Hz.
|
|
|
|
The ESP doesn't have hardware PWM, so the implementation is by software.
|
|
With one PWM output at 40KHz, the CPU is already rather loaded. The more
|
|
PWM outputs used, and the higher their frequency, the closer you get to
|
|
the CPU limits, and the fewer CPU cycles are available for sketch execution.
|
|
|
|
Timing and delays
|
|
-----------------
|
|
|
|
``millis()`` and ``micros()`` return the number of milliseconds and
|
|
microseconds elapsed after reset, respectively.
|
|
|
|
``delay(ms)`` pauses the sketch for a given number of milliseconds and
|
|
allows WiFi and TCP/IP tasks to run. ``delayMicroseconds(us)`` pauses
|
|
for a given number of microseconds.
|
|
|
|
Remember that there is a lot of code that needs to run on the chip
|
|
besides the sketch when WiFi is connected. WiFi and TCP/IP libraries get
|
|
a chance to handle any pending events each time the ``loop()`` function
|
|
completes, OR when ``delay`` is called. If you have a loop somewhere in
|
|
your sketch that takes a lot of time (>50ms) without calling ``delay``,
|
|
you might consider adding a call to ``delay`` function to keep the WiFi
|
|
stack running smoothly.
|
|
|
|
There is also a ``yield()`` function which is equivalent to
|
|
``delay(0)``. The ``delayMicroseconds`` function, on the other hand,
|
|
does not yield to other tasks, so using it for delays more than 20
|
|
milliseconds is not recommended.
|
|
|
|
Serial
|
|
------
|
|
|
|
``Serial`` object works much the same way as on a regular Arduino. Apart
|
|
from hardware FIFO (128 bytes for TX and RX) ``Serial`` has
|
|
additional 256-byte TX and RX buffers. Both transmit and receive is
|
|
interrupt-driven. Write and read functions only block the sketch
|
|
execution when the respective FIFO/buffers are full/empty. Note that
|
|
the length of additional 256-bit buffer can be customized.
|
|
|
|
``Serial`` uses UART0, which is mapped to pins GPIO1 (TX) and GPIO3
|
|
(RX). Serial may be remapped to GPIO15 (TX) and GPIO13 (RX) by calling
|
|
``Serial.swap()`` after ``Serial.begin``. Calling ``swap`` again maps
|
|
UART0 back to GPIO1 and GPIO3.
|
|
|
|
``Serial1`` uses UART1, TX pin is GPIO2. UART1 can not be used to
|
|
receive data because normally it's RX pin is occupied for flash chip
|
|
connection. To use ``Serial1``, call ``Serial1.begin(baudrate)``.
|
|
|
|
If ``Serial1`` is not used and ``Serial`` is not swapped - TX for UART0
|
|
can be mapped to GPIO2 instead by calling ``Serial.set_tx(2)`` after
|
|
``Serial.begin`` or directly with
|
|
``Serial.begin(baud, config, mode, 2)``.
|
|
|
|
By default the diagnostic output from WiFi libraries is disabled when
|
|
you call ``Serial.begin``. To enable debug output again, call
|
|
``Serial.setDebugOutput(true)``. To redirect debug output to ``Serial1``
|
|
instead, call ``Serial1.setDebugOutput(true)``.
|
|
|
|
You also need to use ``Serial.setDebugOutput(true)`` to enable output
|
|
from ``printf()`` function.
|
|
|
|
The method ``Serial.setRxBufferSize(size_t size)`` allows to define the
|
|
receiving buffer depth. The default value is 256.
|
|
|
|
Both ``Serial`` and ``Serial1`` objects support 5, 6, 7, 8 data bits,
|
|
odd (O), even (E), and no (N) parity, and 1 or 2 stop bits. To set the
|
|
desired mode, call ``Serial.begin(baudrate, SERIAL_8N1)``,
|
|
``Serial.begin(baudrate, SERIAL_6E2)``, etc.
|
|
|
|
A new method has been implemented on both ``Serial`` and ``Serial1`` to
|
|
get current baud rate setting. To get the current baud rate, call
|
|
``Serial.baudRate()``, ``Serial1.baudRate()``. Return a ``int`` of
|
|
current speed. For example
|
|
|
|
.. code:: cpp
|
|
|
|
// Set Baud rate to 57600
|
|
Serial.begin(57600);
|
|
|
|
// Get current baud rate
|
|
int br = Serial.baudRate();
|
|
|
|
// Will print "Serial is 57600 bps"
|
|
Serial.printf("Serial is %d bps", br);
|
|
|
|
| ``Serial`` and ``Serial1`` objects are both instances of the
|
|
``HardwareSerial`` class.
|
|
| I've done this also for official ESP8266 `Software
|
|
Serial <libraries.rst#softwareserial>`__
|
|
library, see this `pull
|
|
request <https://github.com/plerup/espsoftwareserial/pull/22>`__.
|
|
| Note that this implementation is **only for ESP8266 based boards**,
|
|
and will not works with other Arduino boards.
|
|
|
|
|
|
To detect an unknown baudrate of data coming into Serial use ``Serial.detectBaudrate(time_t timeoutMillis)``. This method tries to detect the baudrate for a maximum of timeoutMillis ms. It returns zero if no baudrate was detected, or the detected baudrate otherwise. The ``detectBaudrate()`` function may be called before ``Serial.begin()`` is called, because it does not need the receive buffer nor the SerialConfig parameters.
|
|
|
|
The uart can not detect other parameters like number of start- or stopbits, number of data bits or parity.
|
|
|
|
The detection itself does not change the baudrate, after detection it should be set as usual using ``Serial.begin(detectedBaudrate)``.
|
|
|
|
Detection is very fast, it takes only a few incoming bytes.
|
|
|
|
SerialDetectBaudrate.ino is a full example of usage.
|
|
|
|
Progmem
|
|
-------
|
|
|
|
The Program memory features work much the same way as on a regular
|
|
Arduino; placing read only data and strings in read only memory and
|
|
freeing heap for your application. The important difference is that on
|
|
the ESP8266 the literal strings are not pooled. This means that the same
|
|
literal string defined inside a ``F("")`` and/or ``PSTR("")`` will take
|
|
up space for each instance in the code. So you will need to manage the
|
|
duplicate strings yourself.
|
|
|
|
There is one additional helper macro to make it easier to pass
|
|
``const PROGMEM`` strings to methods that take a ``__FlashStringHelper``
|
|
called ``FPSTR()``. The use of this will help make it easier to pool
|
|
strings. Not pooling strings...
|
|
|
|
.. code:: cpp
|
|
|
|
String response1;
|
|
response1 += F("http:");
|
|
...
|
|
String response2;
|
|
response2 += F("http:");
|
|
|
|
using FPSTR would become...
|
|
|
|
.. code:: cpp
|
|
|
|
const char HTTP[] PROGMEM = "http:";
|
|
...
|
|
{
|
|
String response1;
|
|
response1 += FPSTR(HTTP);
|
|
...
|
|
String response2;
|
|
response2 += FPSTR(HTTP);
|
|
}
|
|
|
|
C++
|
|
----
|
|
|
|
- About C++ exceptions, ``operator new``, and Exceptions menu option
|
|
|
|
The C++ standard says the following about the ``new`` operator behavior when encountering heap shortage (memory full):
|
|
|
|
- has to throw a ``std::bad_alloc`` C++ exception when they are enabled
|
|
|
|
- will ``abort()`` otherwise
|
|
|
|
There are several reasons for the first point above, among which are:
|
|
|
|
- guarantee that the return of new is never a ``nullptr``
|
|
|
|
- guarantee full construction of the top level object plus all member subobjects
|
|
|
|
- guarantee that any subobjects partially constructed get destroyed, and in the correct order, if oom is encountered midway through construction
|
|
|
|
When C++ exceptions are disabled, or when using ``new(nothrow)``, the above guarantees can't be upheld, so the second point (``abort()``) above is the only ``std::c++`` viable solution.
|
|
|
|
Historically in Arduino environments, ``new`` is overloaded to simply return the equivalent ``malloc()`` which in turn can return ``nullptr``.
|
|
|
|
This behavior is not C++ standard, and there is good reason for that: there are hidden and very bad side effects. The *class and member constructors are always called, even when memory is full* (``this == nullptr``).
|
|
In addition, the memory allocation for the top object could succeed, but allocation required for some member object could fail, leaving construction in an undefined state.
|
|
So the historical behavior of Ardudino's ``new``, when faced with insufficient memory, will lead to bad crashes sooner or later, sometimes unexplainable, generally due to memory corruption even when the returned value is checked and managed.
|
|
Luckily on esp8266, trying to update RAM near address 0 will immediately raise an hardware exception, unlike on other uC like avr on which that memory can be accessible.
|
|
|
|
As of core 2.6.0, there are 3 options: legacy (default) and two clear cases when ``new`` encounters oom:
|
|
|
|
- ``new`` returns ``nullptr``, with possible bad effects or immediate crash when constructors (called anyway) initialize members (exceptions are disabled in this case)
|
|
|
|
- C++ exceptions are disabled: ``new`` calls ``abort()`` and will "cleanly" crash, because there is no way to honor memory allocation or to recover gracefully.
|
|
|
|
- C++ exceptions are enabled: ``new`` throws a ``std::bad_alloc`` C++ exception, which can be caught and handled gracefully.
|
|
This assures correct behavior, including handling of all subobjects, which guarantees stability.
|
|
|
|
History: `#6269 <https://github.com/esp8266/Arduino/issues/6269>`__ `#6309 <https://github.com/esp8266/Arduino/pull/6309>`__ `#6312 <https://github.com/esp8266/Arduino/pull/6312>`__
|
|
|
|
- New optional allocator ``arduino_new``
|
|
|
|
A new optional global allocator is introduced with a different semantic:
|
|
|
|
- never throws exceptions on oom
|
|
|
|
- never calls constructors on oom
|
|
|
|
- returns nullptr on oom
|
|
|
|
It is similar to arduino ``new`` semantic without side effects
|
|
(except when parent constructors, or member constructors use ``new``).
|
|
|
|
Syntax is slightly different, the following shows the different usages:
|
|
|
|
.. code:: cpp
|
|
|
|
// with new:
|
|
|
|
SomeClass* sc = new SomeClass(arg1, arg2, ...);
|
|
delete sc;
|
|
|
|
SomeClass* scs = new SomeClass[42];
|
|
delete [] scs;
|
|
|
|
// with arduino_new:
|
|
|
|
SomeClass* sc = arduino_new(SomeClass, arg1, arg2, ...);
|
|
delete sc;
|
|
|
|
SomeClass* scs = arduino_newarray(SomeClass, 42);
|
|
delete [] scs;
|