Electronics project notes/ESP notes

From Helpful
(Redirected from ESP8266)
Jump to navigation Jump to search

⚠ This is for beginners and very much by a beginner / hobbyist

It's intended to get an intuitive overview for hobbyist needs. It may get you started, but to be able to do anything remotely clever, follow a proper course or read a good book.

Some basics and reference: Volts, amps, energy, power · batteries · resistors · transistors · fuses · diodes · capacitors · inductors and transformers · ground

Slightly less basic: amplifier notes · varistors · changing voltage · baluns · frequency generation · Transmission lines · skin effect

And some more applied stuff:

IO: Input and output pins · wired local IO · wired local-ish IO · ·  Various wireless · 802.11 (WiFi) · cell phone

Sensors: General sensor notes, voltage and current sensing · Knobs and dials · Pressure sensing · Temperature sensing · humidity sensing · Light sensing · Movement sensing · Capacitive sensing · Touch screen notes

Actuators: General actuator notes, circuit protection · Motors and servos · Solenoids

Noise stuff: Stray signals and noise · sound-related noise names · electronic non-coupled noise names · electronic coupled noise · ground loop · strategies to avoid coupled noise · Sampling, reproduction, and transmission distortions

Audio and video notes: See avnotes

Platform specific

Arduino and AVR notes · (Ethernet)
Microcontroller and computer platforms ··· ESP series notes · STM32 series notes

Less sorted: Ground · device voltage and impedance (+ audio-specific) · electricity and humans · Common terms, useful basics, soldering · landline phones · pulse modulation · signal reflection · Project boxes · resource metering · SDR · PLL · vacuum tubes · Multimeter notes Unsorted stuff

Some stuff I've messed with: Avrusb500v2 · GPS · Hilo GPRS · JY-MCU · DMX · Thermal printer ·

See also Category:Electronics.

See also Electronics project notes/Microcontroller and computer platforms

Hardware, and the minimal boards

WiFi-capable microcontrollers.

You can run code on the microconroller, alongside the wifi code.

It is also sometimes used standalone, with another microcontroller using it for the wifi.

See Electronics_project_notes/Microcontroller_and_computer_platforms#ESP_series for wider context.



  • Based on Xtensa LX106 microprocessor (a 32-bit RISC CPU)
  • ~160KB SRAM
often at 80 MHz (can be run faster at 160MHz though people report this breaks code that didn't expect that)
  • WiFi b/g/n (no bluetooth)
apparently people have got it to send on the order of ~10mbit/s but don't count on that
The given SDK effectively shares the CPU cooperative-multitasking style, and you must yield time to the wifi code at least every few hundred ms and preferably more often(verify)
  • 17 GPIO, 2 SPI, 2 I2S, 2 UART, 1 I2C, and a 10-bit ADC (pin overlap)
  • no hardware PWM (though you get a decent rate out of via timers)

ESP8266 itself is a SMD IC and you probably want to get it on a board helping you along, (see e.g. http://esp8266.net/ for details), because at the least you'll want it connected to flash. It's hard to get it without unless you buy just the chip in bulk, though.

Initially from espressif, who had board variants called ESP-WROOM-something.

More common are the Ai-Thinker ones, and derivatives, often one of:

  • ESP-01 - exposes little useful IO, used mostly as a "add WiFi to existing project" board
  • ESP-05 - also exposes little IO. Allows better antenna than 01. Discontinued?(verify)
  • ESP-12 - exposes more things, making it more useful as a standalone uC
though physically it's not so easy to use by itself, it is the core of various larger PCBs
  • ESP-201 - easier to use on a breadboard
...and yeah, a bunch more of these exist.

You now may prefer more complete prototyping boards, such as the NodeMCU or WeMOS or HUZZAH

Most build on the ESP-12, and add things like USB-to-serial and voltage regulation. (see below)

The size of flash will vary.


Compatible with ESP8266, but smaller because it has flash integrated (1MiB for ESP8285N08, 2MiB for ESP8285H16).

There seem to be some variant boards here too, at least:(verify)

ESP-M1 - antenna connector
ESP-M2 - onboard antenna
ESP-M3 - onboard antenna



This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

The earlier variants we saw (no particular signifier(verify))

but note: pin overlap, and boards may not break out everything
because they use things internally, like GPIO used to access flash
because they are smaller
because there are just a bunch of boards out there. Also makes finding pinouts slightly interesting.


CPU: single-core Tensilica Xtensa LX7, up to 240MHz
(no Bluetooth (verify))
some variants have 2MByte(verify) embedded PSRAM (R2 in ESP32 model name, e.g. ESP32-S2R2, ESP32-S2FN4R2, but it's less obvious to tell by the board)


CPU: single-core RISC-V, up to 160 MHz
Bluetooth 5 LE


CPU: dual-core Tensilica Xtensa LX7, up to 240MHz
Bluetooth 5 LE
WiFi (b/g/n)
variants with 2, 8, or 16MB internal PSRAM
USB OTG (verify)


Bluetooth 5 LE
WiFi 802.11ax (also b/g/n support)
CPU: RISC-V core (up to 160MHz) and low-power RISC-V core (up to 20MHz)


Bluetooth 5 LE
802.15.4 (zigbee)
(no wifi)
CPU: RISC-V, up to 96MHz

See also:

see also

Some DIYer-geared ESP8266 boards

May add

  • breakout into something easier to solder
exceptions include the Huzzah
  • Regulator from 5V input -- particularly if it has USB, to be powered off it
  • Reset button, GPIO (boot related) button


A Huzzah, and some poor soldering skills

Adafruit huzzah:

Based on ESP-12


  • The board has a 500mA LDO regulator that you should feed 4-6V
V+ and Vbat both go to this LDO, separated via Schottky diodes
and V+ is also on FTDI header, so that you stably can power the chip while programming it (...from a powered hub / port)
if you have your own regulation, you can bypass the LDO regulator by connecting the LDO pin to ground


  • TX and RX are used for bootloading, and for serial control (exposed in two places on this board, to make FTDI plug easier)
RX is 5V safe (and Vcc goes to the regulator) so you can use a generic 5V serial cable

Note: no USB


Wemos D1 (where I removed the barrel jack for some reason)
and size of the D1 mini (this might be a non-WeMOS copy?)

WeMos D1 is a Arduino-sized board, partially compatible

and a revision "D1 R2", with minor difference in pins between the two.

Wemos D1 Mini are smaller boards, specifically:

D1 Mini Lite
ESP-8285 based,
1MB Flash
PCB antenna
D1 Mini
ESP-8266EX based
4MB Flash
PCB antenna
D1 Mini Pro
ESP-8266EX based
16MB Flash
Lithium battery pin, charger chip
PCB antenna + Antenna connector


NodeMCU devkit

NodeMCU itself refers to the firmware. It'll run on any ESP based board, really.

For clarification, there is also a breadboardable piece of hardware called the The 'NodeMCU Devkit' is the name of a specific board [1],

There seem to be three board that carry this name. Image on the right from this post: [2].(verify)


Some DIYer-geared ESP32 boards

Wemos ESP32

D32, based on ESP32

Lithium battery pin, charger chip
D32 Pro
Lithium battery pin, charger chip
MicroSD socket

(with some revisions)



ESP32 DevKit-C



There's a bunch of ebay/aliexpress boards that are perhaps best distinguished by some physical things like pin count, (lack of) antenna overhang, and such

Consider e.g. these: https://www.studiopieters.nl/esp32-pinout/



D1 Mini ESP32




On firmware

Flashing new firmware

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

nodemcu pyflasher

basic GUI that is a wrapper around esptool.py
easier to use
you need to install wxpython and pyserial (e.g. through pip install wxpython pyserial)


came from the community, now also adopted by espressif
you need to install python

ESP Flash Download tool

in theory more flexible, but the interface is hard to understand

See also:

On flash mode

Apparently [3]

ESP8266 ESP-12 boards uses DIO
most other ESP8266 board (e.g. ESP-01 and ESP-07) use QIO
ESP8285 uses DOUT
ESP32 uses DIO

Since this is about wiring, you can't be entirely use until something fails to flash.

Is this just about upload speed or also about execution speed?(verify)

On some bare-bones boards you may need to manually get it into programming mode.

e.g. on ESP8266-01 you need to tie GPIO0 to Gnd (verify) at reset time. Various boards will have two buttons to make this easier.

What's this address stuff?

In basic cases you put the firmware at the start of flash (0x0),

If you have distinct blocks to go to specific addresses, you'll probably get instructions for it.

Firmware alternatives

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

Everything shares the same SDK underneath, but what is added on top, and the thing you interact with, varies.

AT commands firmware

The AT commands firmware (Espressif?) is useful if you want to use the ESP as a separate board that does WiFi for you.

You communicate over it via serial (RX and TX serial pins), and controlling how it communicates.

You'll still need to manage how it connects to access points, and set up TCP and UDP connection.



https://bbs.espressif.com/viewtopic.php?f=10&t=362 - for espressif firmware?


NodeMCU firmware (Lua)

The NodeMCU firmware wraps Espressif's SDK (and primarily for the ESP8266) with a Lua interpreter, which hooks into a bunch of C libraries and pure-lua libraries.

There is now also an RTOS variant for the ESP32 (and not ESP8266, because of the higher memory use) which

There are a whole bunch of C libraries you can add.

A little more controlled, but more work, is https://github.com/nodemcu/nodemcu-firmware
The easier way for tinkerers is to use the online build service: https://nodemcu-build.com/

Including more modules will increase the flash size (you usually don't care) but often also the RAM size

Lua coding for that firmware

You can use one of various tools to upload lua files, which itself is (relatively basic) serial-port stuff. Options include:


java based IDE, fiddly but it works

luatool [4]

uploads Lua files to ESP8266 modules running nodemcu firmware


up/down lua files, manage filesystem

esp8266 lualoader [5]

...and various other tools people have built.

See also:

Other interpreters people have built onto the SDK

this page lists variants on idea of the interpreting firmware but for other languages, like python, JS, Basic, Forth, Lisp, and support from some other embedded platforms.

The idea ends up being the same - flash its firmware, later upload code via the serial port (and possibly over the air)



Lua firmware notes

Some lowish level notes

Keep in mind that some standard Lua modules (e.g. io, os, debug) are removed, and others provide similar function (e.g. node, file).

So some Lua code you find around (e.g. for raspberry Pi) will need changes, with some specific knowledge of the argument differences.
And since debug is missing, debug mostly consists of print statements.
There are other practical differences, like that print(string) is mainly just uart.write(0, string)

Running code off flash is done with cached memory mapping, which is basically why there is one SPI interface you cannot use

The event/tasking system is roughly three queues, a high priority one (for hardware related tasks), medium (for timer and event stuff), and low (everything else)

no task can pre-empt others (priority isn't relevant once it's started),
so ideally no task should run longer than a dozen milliseconds
if you want things like wifi (or any other code-mediated hardware) to work smoothly
and sometimes less so that your own tasks work smoothly but this can be less critical
if a task takes over 500ms it'll trigger the watchdog (unless you explicitly feed it, but in most cases that is bad design)

(there are also ISRs in C for time-critical stuff but you probably don't want to touch that. They can interrupt tasks, but only up to ~10usec)

Calling various functions in net, tmr, wifi, and some others will (in part because they are C) amount to queueing their code as tasks. So

They will not run until after the current lua task is done.

L They will not necessarily be the next task (but many will be high priority so this is moderately likely)

being in that queue uses a little RAM until they actually execute
(which is one of a few reasons why event/callback style coding is recommended)

Errors will trigger a panic, which then leads to triggering the watchdog, and a reboot

this is useful for recovery
but not always for debugging because even just a typo may cause a reboot before any error gets printed

Flash not used for firmware is provided via file

classically SPIFFS, now moving to LittleFS
(Confusingly, LFS, Lua Flash System, is a different thing https://nodemcu.readthedocs.io/en/release/lfs/ )
note that file can also be used to read/write SD cards

The float versus int builds:

working in float is more to specs, and generally recommended
working in integers is faster but breaks the specs a little, so also some code.

The SDK triggers startup code,

which initializes lua,
runs init.lua
listens interactively to UART0
defaults to 9600 baud. ESPlorer changes speed by sending a uart.setup() command, then attempting to reconnect (verify)

Coding using events, timers, and coroutines

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

Tasks run to completion and cannot be pre-empted.

Running too long will trigger the watchdog, and before that will make wifi code break or be choppier.

So it's suggested to try keeping tasks under 10ms, also for the responsiveness of responding to events.

In general, try to do things event-based, using callbacks.

It's generally useful to put code in a timer, or use a timer as an event loop checker

Note that since timers and callbacks are tasks that don't pre-empt (and that timers are software timers), they may get scheduled later than you think. Also, don't set timers faster than they'll take.

Longer calculations are probably best done in smaller chunks

Can you use coroutines?(verify)

Keep ISRs under 10us, or wifi will break.

I2S canbe DMA'd, no other peripherals can(verify)

"Waiting answer from ESP - Timeout reached. Command aborted"

(in ESPlorer)

This can be

  • a bug related to use of CR-style newlines[6] (where the firmware expects CRLF(verify)), but only on specific commands.
It's particularly file transfers that will be broken.
This could be fixed on both sides, but the easier may be to get a newer firmware build (verify)

  • the serial connection crapping out for some reason (verify)
I seemed to have it one one board, possibly power problems?

modules, packages, and compilation

On reboots

boot/reset cause

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

If you catch enough of the next boot's output, you'll see something like:

rst cause:2, boot mode:(3,6)

boot mode

The last part, the boot mode is rarely very interesting. It indicates

  • where we booted from (which is based on GPIO pin state at boot), and
  • how exactly.


In most cases this will be 3 (Flash), (rather than SD or UART)[7]
...and if it's not, and not booting as expected, chances are the relevant GPIO pins (GPIO15, GPIO0, GPIO2(verify)) are not in the state they should be. (If you put hardware on these pins, this needs extra care to not affect boot)
...or it's the first watchdog reset after a firmware download and soft reboot(verify), which can trigger it trying to do a firmware download again (e.g. 1,7) (verify), once.(verify)


0x13 seems to mean SPI_FAST_FLASH_BOOT, which seems typical
0x03 seems to mean programming mode (specific variant?)

rst cause

⚠ I've seen some conflicting lists - TODO: figure out

While the rst cause seems to be the list from

0  unknown reason
1  'Reset due to power-on event', which is effectively normal boot
2  External reset using reset pin (not for ESP8266?)
3  Software reset (esp_restart?)
4  Hardware watchdog (WDT) reset / 

...there is a slightly more informative value you get via node.bootreason(). It returns

rawcode, reason [, exccause, epc1, epc2, epc3, excvaddr, depc ]

That is, it usually returns two values:

  • the second is the extended reset cause, which is one of:
0  power-on
1  hardware watchdog reset
2  exception reset
3  software watchdog reset
4  software restart
5  wake from deep sleep
6  external reset

..but in the case of exception reset, it also returns more exception information, the first of which is tells you exception cause and the rest of which may be useful to for an actual debugger (if you built the image yourself).

I mostly run into 2 4 where 4, software reset, which seems to include the software watchdog(verify) (confusingly enough).

4 1 is the hardware watchdog(verify)


Solving and avoiding reboot loops

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

If you manage to get an exception in early code, or trigger the hardware watchdog fairly early, then you may not be able to get the control you need to fix that.

There's always flashing the firmware again, and then wiping the flash. But that's a bunch of work, annoying during coding/debugging.

One way around that I like is to have init.lua contain something like:

abort = 0
function load_main()
   if abort ~= 0 then
      print("aborting startup")
      if file.exists('main.lua') then
        print("main.lua does not exist")
print("send  abort=1  to stop boot")
_start_timer = tmr.create()
_start_timer:register(1500, tmr.ALARM_SINGLE, load_main)

...and put your real code in main.lua.

That way, you have a little over a second before anything happens, in which time you can stop startup by sending abort=1 via serial


On watchdogs

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

There is both a

  • hardware watchdog
on by default, can be disabled (but there is rarely good reason to disable it)
part of the ESP's hardware
configured at approximately 6 seconds(verify)

  • software watchdog
on by default
C code that digs into the SDK, and amounts to a timer that decrements a counter and, if that counter reaches zero, calls system_restart()
accessible in Lua via tmr.softwd() to set a time, and tmr.wdclr() to feed it
apparently a value like 0.5 sec [8], 1.5 sec, or 3.2 sec (reports are mixed; TODO: figure out)

It seems that the SDK's system_soft_wdt_feed() feeds both.

tmr.wdclr() in Lua, and ESP.wdtFeed() in arduino(verify), mostly call system_soft_wdt_feed()
tmr.delay calls system_soft_wdt_feed while it is counting down (but is otherwise a wait loop, so long ones will mess with wifi{{verify||)
some libraries will also reset the watchdog in some places

The short version is that if code does not

call tmr.wdclr(), OR
call something that implies tmr.wdclr(), OR
returns to let the ESP idle

...for a significant time (between 0.5 or 6 seconds, see above), it will cause a reset.

Which makes sense. If you have code that takes more than 500ms without yielding in any way, you are likely breaking other things, not least of which the WiFi code, which can stutter (in smaller ways) if any task takes longer than approx 15ms.

If you do need to do a lot of processing, just make sure you yield occasionally so that that housekeeping can happen. This may mean rewriting to do small chunks at a time.

In Lua this is sometimes simple, because when you code in an event/callback style the idle task gets control regularly (and its feeds the dog(verify) and does the necessary housekeeping(verify)).

Keep in mind that it's not too hard to defeated the watchdog (e.g. feed it each loop but get into your own infinite loop) and can make things hang forever, and/or break wifi and other library code.

The likeliest problems that trigger the watchdog seem to be

  • an exception in the code
if you're me, largely variable typos and nil values you should be checking
presumably stops the current task so the watchdog
to avoid hanging forever, this is cause for reset (via watchdog?)
  • triggering a watchdog by having code hang, or take too long to complete
  • running out of heap space

Your own watchdogs

I have found reasons to have code like "if we didn't manage to do a HTTP fetch in a minute, for any reason, we probably want to reset"

...just because there are more reasons for that (that I can't easily check), and most of them will be rare enough that a reset is the easiest clean slate.

You will want to decide which method of reset you prefer.

manual reset

If you have an ESP with USB, it probably has its DTR/RTS wired to GPIO0 and RST, there so you can get it into flash programming mode. [9], but you could also self-reset by wiring a GPIO pin to RST and do the same.

In some ways it's the cleanest, because apparently there are a few issues around some internal registers not being reset unless it's a hardware reset.(verify). But check that you don't get stray signals.

If you're not bothered by said register problems, then software resets probably using node.restart() is also an option.


TCP server

UDP server

HTTP requests

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

The http module is quite convenient.


          "", -- headers
          function(code, data)
            if (code < 0) then
              print("HTTP request failed")
              print(code, data)

Note that concurrent requests are not supported.

(I think an issue of mine (reported as HTTP client: DNS error code -1, I think) was that I was effectively doing this.)


The http module can use the tls module which is basically mbed TLS.

That means you can give it https links and it'll do the TLS part too. (Alternatively, you can do a TLS connection, and e.g. do a bare HTTP 1.0 request over it. See examples using tls.createConnection())

However, you basically don't have enough RAM to guarantee that large certificates, or large chains, can be processed properly - the process may easily need 30KByte or 40KByte of heap, which is usually most of what you have. Also, there is no real SNI support.

So you cannot guarantee all HTTPS requests to arbitrary servers will work, and the best workaround is to only ever send to a server you have precise control over the certificates being send, and possibly self-sign.

Arduino firmware notes

Some notes

Current draw and sleep

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

(this is broadly true for ESP8266, ESP32, just get get a sense of the ballpark. When specifics matter, look them up for a specific board)


Startup might be up to ~400mA for ~40ms[10] (RF calibration maybe?)
just once and short
~200mA actively transmitting radio (though Tx power can be lowered)
<100mA actively receiving radio (it helps that it tries to be smart with DTIM(verify))
CPU but no RF on (i.e. modem sleep)
15mA to 70mA, depending on core frequency, amount of cores, ESP variant, readymade board you bought (often on the lower, 25mA end of that?(verify))
~1mA with light-sleep (varying a little with DTIM interval)
wakeup takes a few milliseconds
~0.1mA with deep-sleep, which roughly amounts to 'everything off, waiting to be rebooted from a pulse on RST pin'
takes regular boot time, and note that a cold connect to wifi tends to take a few seconds

Note that the ESP32 variants vary on CPU use and sleep details, but RF power is basically just determined by range.

On the sleep modes:

  • no sleep / active mode
ESP32: ~200mA if transmitting, ~100mA if not
  • modem sleep
keeps the CPU on, keeps the wifi on but only listening, and can be woken by DTIM
since it times the sleep between AP beacons, this applies only once connected to an AP
should average maybe ~20mA when not transmitting
going to modem sleep is automatic once set (and possible), so firmware seems to enable this by default(verify)
NodeMCU: seems to apply automatically once we're connected to an AP(verify)
  • light sleep - pauses modem, system clock, CPU
~1mA ? (verify)
cannot enter light sleep if wifi suspended
woken via configured GPIO or timer(verify)
ESP32 can wake up via touch sensitive GPIO(verify)
modem and CPU are sleeping but can be woken by GPIO, or DTIM(verify)
wakeup takes ~3ms
NodeMCU: node.sleep()
  • deep sleep leaves on the RTC and almost nothing else
~0.01mA or 0.2mA ? (verify)
can apply when not maintaining a WiFi connection.
you can only explicitly tell it to go to deep sleep (not an automatic thing)
only the RTC is still powered (and can be used to wake up),
woken up a pulse on RST, which can come from our own RTC (if GPIO16/WAKE/D0 is wired to RST)
so the call is "deep sleep for this many microseconds" (in an uint32, which implies a 71 minute maximum [11]
there are flags controlling
whether wifi will be initialised after such a sleep (you can avoid a current spike if you don't need it)
whether a calibration will be done (which you want after longer sleeps(verify))
NodeMCU: node.dsleep()
  • hibernation (ESP32)
~3uA ? (verify)
deep sleep on the ESP32 leaves on a low-power coprocessor and the oscillator it needs, hibernation does not. (verify)

Note that

  • I need to look up the difference between ESP8266, ESP32
  • these currents are the ratings of the ESP itself, things like regulators will add to this.
  • These figures are often the use of the raw circuit. If powered via a linear regulator, your will waste more energy. Battery users will care.




Voltage and damage

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

Power should be 3.3V. (Powering from 5V power won't fry it immediately, but is likely to shorten lifespan, some people report sooner rather than later (and seemingly it's the flash that often fails first)

The ADC gets damaged by voltages above 1V, so you probably always want a voltage divider. And possibly a diode to protect it.

"Are ESPs 5V tolerant?"

Officially, no.

Can you get away with it?


There is transient higher-voltage detection - basically ESD above 6V - quoth the datasheet" "All digital IO pins are protected from over-voltage with a snap-back circuit connected between the pad and ground. The snap back voltage is typically about 6V, and the holding voltage is 5.8V. This provides protection from over-voltages and ESD. The output devices are also protected from reversed voltages with diodes."

However, 5V tolerance is more about continuous current/heat the entire structure can deal with. There's no mention of it, so the short answer is no.

The ESD protection diodes will probably help a little, and people have experimentally determined that putting 5V on these inputs only sinks a few microamps,

Perhaps the simplest halfway-decent solution is a voltage divider. Though it comes with 'assuming it does not affect your use' footnote. Particularly high-speed communication often needs a little more care, so when you're prepared to throw some components at it, there are also other options - see level shifting.

Note that using our 3.3V GPIO to output to things expecting 5V levels can be safe -- but note it's not great if the 5V side engages a pullups (rather than pulldown). (As in general, it may not always work due to voltage levels -- 5V TTL is high is above 2V so fine. 5V CMOS is high above 3.7V so won't work. Thresholds can vary a little per device anyway, so check datasheets.).

On WiFi

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

Having it be stable

For wifi to be stable, task should yield after ~15ms or so (quoth the SDK(verify)).

More may still work because it'll recover, but wifi will be choppier.

When you think tasks may take longer, think some more about event, timer, and corouting style programming.

I also tend to add a "can I DNS-resolve things" test, so that it can reconnect, or switch APs, when one does not work for some reason.

(...which I can still mess up by spamming the ESP with UDP packets)

How to tell it about APs

The basic way to do credentials is hardcoding one, or maybe a few that code loops through a few stored APs. This works until you move it, or replace your AP, at which point you have to put in new credentials, probably via usb-serial.

The fancier thing to do is a wifi manager that, if it can't find one of the previously configured AP's, puts the ESP into soft AP mode with a webserver, and lets you set AP via a simple web interface.

For NodeMCU: https://github.com/gfnord/lua_wifimanager

For arduino: https://github.com/tzapu/WiFiManager (slightly nicer)

Wifi current draw





serial.serialutil.SerialException: Cannot configure port, something went wrong. Original message: PermissionError(13, 'A device attached to the system is not functioning.', None, 31)

...when uploading a sketch.

For me this seemed caused by esptool not finding the device in the right state - presumably because I had selected the wrong board variant?

I did get it to work by holding the boot button.

Which is a problem and solution possibly very specific to my case.