ESP32 vs ESP8266 – Pros and Cons

What’s the difference between ESP32 and ESP8266? Should you use the ESP32 or the ESP8266 in your projects? In this article, we’ll compare the ESP32 with the ESP8266 and cover the pros and cons of each board.

The ESP32 and ESP8266 are cheap Wi-Fi modules perfectly suited for DIY projects in the Internet of Things (IoT) and Home Automation fields.

Both chips have a 32-bit processor. The ESP32 is a dual-core 160MHz to 240MHz CPU, whereas the ESP8266 is a single-core processor that runs at 80MHz.

These modules come with GPIOs that support various protocols like SPI, I2C, UART, ADC, DAC, and PWM. The best part is that these boards come with wireless networking included, which makes them apart from other microcontrollers like the Arduino. This means that you can easily control and monitor devices remotely via Wi-Fi or Bluetooth (in the case of ESP32) for a very low price.

Alternatively, if you don’t need to use its wireless capabilities, you can use the ESP32/ESP8266 to control inputs and outputs as you would do with an Arduino. However, you should take into account that whereas the Arduino works with 5V logic, the ESP32 and ESP8266 work at 3.3V.

Specifications: ESP32 vs ESP8266

The ESP32 is the ESP8266 successor. It adds an extra CPU core, faster Wi-Fi, more GPIOs, and supports Bluetooth 4.2 and Bluetooth low energy. Additionally, the ESP32 comes with touch-sensitive pins that can be used to wake up the ESP32 from deep sleep, a built-in hall effect sensor, and a built-in temperature sensor (recent versions of the ESP32 don’t come with a built-in temperature sensor anymore).

Both boards are cheap, but the ESP32 costs slightly more. While the ESP32 can cost around $6 to $12, the ESP8266 can cost $4 to $6 (but it really depends on where you get them and what model you’re buying).

The following table shows the main differences between the ESP8266 and the ESP32 chips (table adapted from AMICA_IO).

Xtensa Single-core 32-bit L106
Xtensa Dual-Core 32-bit LX6 with 600 DMIPS
802.11 b/g/n Wi-Fi
Bluetooth 4.2 and BLE
Typical Frequency
80 MHz
160 MHz
Hardware /Software PWM
None / 8 channels
None / 16 channels
Ethernet MAC Interface
Touch Sensor
Temperature Sensor
(old versions)
Hall effect sensor
Working Temperature
-40ºC to 125ºC
-40ºC to 125ºC
$ (3$ – $6)
$$ ($6 – $12)
Where to buy

Using ESP32 or ESP8266 bare chips is not easy or practical, especially when testing and prototyping. Most of the time, you’ll want to use ESP32 and ESP8266 development boards. These boards come with all the needed circuitry to power the chip, connect it to your computer, a circuit to upload code easily, pins to connect peripherals, built-in power and control LEDs, and other useful features.

The ESP32 and ESP8266 development boards we use more often are the ESP32 DEVKIT DOIT Development board and the ESP8266 ESP-12E NodeMCU Kit and these are the ones we recommend for beginners. However, there are many other models of development boards that you can choose from. We recommend that you read the following guides:

More GPIOs on the ESP32

The ESP32 has more GPIOs than the ESP8266, and you can decide which pins are UART, I2CSPI—you need to set that on the code. This is possible due to the ESP32 chip’s multiplexing feature that allows you to assign multiple functions to the same pin.

If you don’t set them on the code, they will be on the pins defined by default, as shown in the following figure (this is an example for the ESP32 DEVKIT V1 DOIT board (version with 36 GPIOS)—the pin location can change depending on the manufacturer).

To learn more about the ESP32 GPIOs and how to use them, read:

For means of comparison, here’s the pinout diagram for the ESP8266 ESP-12E NodeMCU Kit.

To learn more about the ESP8266 GPIOs and how to use them, read:

PWM, ADC, and More

You can set PWM signals in any GPIO with configurable frequencies and duty cycle set on the code.

When it comes to the analog pins, these are static, but the ESP32 supports measurements on 18 channels (analog-enabled pins) versus just one 10-bit ADC pin on the ESP8266. The ESP32 also supports two 8-bit DAC channels.

Moreover, the ESP32 contains 10 capacitive sensing GPIOs, that detect touch and can be used to trigger events, or wake-up the ESP32 from deep sleep, for example.

The ESP32 supports Bluetooth communication protocol by default, while the ESP8266 doesn’t.

Arduino IDE – ESP32 vs ESP8266

There are many ways to program the ESP32 and ESP8266 boards. Both boards can be programmed with the Arduino core using the Arduino IDE or other IDEs (like VS Code with the PlatformIO extension).

These are good news, especially for those used to program the Arduino board and are familiar with the Arduino “programming language”.

Getting started with the ESP32 or ESP8266 using Arduino IDE and have your first project running is very simple. You can follow these guides:

Although you can program both boards using Arduino IDE, they might not be compatible with the same libraries and functions. Some libraries are just compatible with one of the boards. This means that most of the time, your ESP8266 code will not be compatible with the ESP32. However, usually, you need to make a few modifications.

We have a dedicated list of free tutorials and projects for the ESP32 and ESP8266 boards using the Arduino IDE that you might found useful:

MicroPython Firwmare – ESP32 vs ESP8266

Another popular way of programming the ESP32 and ESP8266 boards is using MicroPython firmware.

MicroPython is a re-implementation of Python 3 targeted for microcontrollers and embedded systems. MicroPython is very similar with regular Python. So, if you already know how to program in Python, you also know how to program in MicroPython.

In MicroPython, most Python scripts are compatible with both boards (unlike when using Arduino IDE). This means that most of the time, you can use the same script for ESP32 and ESP8266.

You can get started with MicroPython firmware on the ESP32 and ESP8266 very quickly by following our free guides:

We also have a list of free projects using MicroPython with the ESP32 and ESP8266 boards:

Need Resources to Get Started?

If you want to get started with the ESP32 or ESP8266, you can take a look at our courses and projects:

ESP32 or ESP8266?

So, at this point you may be wondering: Should I get an ESP8266 or an ESP32?

It really depends on what you want to do. There is space for both boards, and both have pros and cons.

The ESP8266 is cheaper than the ESP32. Although it doesn’t have as many functionalities, it works just fine for most simple DIY IoT projects. However, it has some limitations in the GPIO mapping, and it might not have enough pins for what you intend to do. If that’s the case, you should get an ESP32.

The ESP32 is much more powerful than the ESP8266, comes with more GPIOs with multiple functions, faster Wi-Fi, and supports Bluetooth. However, many people think that the ESP32 is more difficult to deal with than the ESP8266 because it is more complex. On the contrary, in our opinion, it is as easy to program the ESP32 as the ESP8266, especially if you intend to program it using the “Arduino language” or MicroPython.

The ESP32 has some cons too. The ESP32 is more expensive than the ESP8266. So, if you’re building a simple IoT project, the ESP8266 might do the trick for a lower price. Additionally, because the ESP8266 is “older” than the ESP32, some libraries and features are better developed for the ESP8266, and you’ll find more resources (forums, people with the same issues, and how to solve them, etc.). However, as time goes by, the ESP32 is being widely adopted, and these differences in terms of development and libraries won’t be noticeable.

My personal experience: in 2021, I use almost exclusively the ESP32 for IoT projects. It is more versatile, and it comes with much more functionalities like Bluetooth, different wake-up sources, many peripherals, and much more. Additionally, the price difference is not a big deal, in my opinion. Once you move to the ESP32, you won’t want to go back to the ESP8266.

Wrapping Up

We hope you’ve found our analysis ESP32 vs ESP8266 useful.

Just to wrap up the main differences between the ESP32 and ESP8266:

  • The ESP32 is faster than the ESP8266;
  • The ESP32 comes with more GPIOs with multiple functions;
  • The ESP32 supports analog measurements on 18 channels (analog-enabled pins) versus just one 10-bit ADC pin on the ESP8266;
  • The ESP32 supports Bluetooth while the ESP8266 doesn’t;
  • The ESP32 is dual-core, and the ESP8266 is single core;
  • The ESP8266 is cheaper than the ESP32;
  • The ESP8266 has a wider community (although we don’t think that at this point, the difference is that relevant);
  • For many IoT and Wi-Fi projects, the ESP8266 can do the job for a lower price;
  • Both boards can be programmed with the Arduino core using Arduino IDE or other supported IDEs.
  • Both boards support MicroPython firmware.

You might like reading the following ESP8266 and ESP32 related articles to have an idea of the selection of the most popular ESP32 and ESP8266 development boards:

So, if you’re a beginner, should you get started with the ESP32 or the ESP8266? At this point, we definitely recommend getting started with the ESP32 instead of the ESP8266. However, if you already have an ESP8266 board, you can get started with that board and then make the shift to the ESP32.

We have a vast selection of projects with these boards in the Random Nerd Tutorials blog to help you get started:

Thanks for reading.

Analog JoyStick with Arduino

The Analog Joystick is similar to two potentiometers connected together, one for the vertical movement (Y-axis) and other for the horizontal movement (X-axis). The joystick also comes with a Select switch. It can be very handy for retro gaming, robot control or RC cars. So let’s understand how it works!dsc09428.jpg


The Arduino Uno or any other Arduino board that uses Atmega328 as the Microcontroller has ADC resolution of 10 bits. Hence the values on each analog channel can vary from 0 to 1023. Now connecting the VRx to A0 and VRy to A1 analog inputs respectively should show values as shown in the image below.

Joy diagram.jpeg

The home position for the stick is at ( x,y:511,511). If the stick is moved on X axis from one end to the other, the X values will change from 0 to 1023 and similar thing happens when moved along the Y axis. On the same lines you can read position of the stick anywhere in upper half hemisphere from combination of these values.


0 Joystick with Arduino bb.png

So let’s print the values on the terminal so that we can verify the working!

Raw Sketch

  1. #define joyX A0
  2. #define joyY A1
  4. void setup() {
  5. Serial.begin(9600);
  6. }
  8. void loop() {
  9. // put your main code here, to run repeatedly:
  10. xValue = analogRead(joyX);
  11. yValue = analogRead(joyY);
  13. //print the values with to plot or view
  14. Serial.print(xValue);
  15. Serial.print(\t);
  16. Serial.println(yValue);
  17. }


It is usually not enough to read the analog values, you might want to map it to a display or any other interface. So let’s map these these values to a 8×8 led matrix. So that we can move the pixel with the joystick. You can easily change this to map to a graphic or a OLED display.Matrx LED and Joystick with Arduino bb.png

  1. #include “LedControl.h”
  2. #define joyX A0
  3. #define joyY A1
  5. int xMap, yMap, xValue, yValue;
  6. LedControl lc=LedControl(12,11,10,1);
  8. void setup() {
  9. Serial.begin(115200);
  11. lc.shutdown(0,false);
  12. /* Set the brightness to a medium values */
  13. lc.setIntensity(0,8);
  14. /* and clear the display */
  15. lc.clearDisplay(0);
  16. }
  18. void loop() {
  19. // put your main code here, to run repeatedly:
  20. xValue = analogRead(joyX);
  21. yValue = analogRead(joyY);
  22. xMap = map(xValue, 0,1023, 0, 7);
  23. yMap = map(yValue,0,1023,7,0);
  24. lc.setLed(0,xMap,yMap,true);
  25. lc.clearDisplay(0);
  27. }

So as you see in the code above, the map() function can be used to map the ranges as you wish. Also notice that the Y axis map is inverted! So much to learn with a simple interface! Do checkout the retro ping-pong game built with the same setup.




int VRx = A0;
int VRy = A1;
int SW = 2;

int xPosition = 0;
int yPosition = 0;
int SW_state = 0;
int mapX = 0;
int mapY = 0;

void setup() {
  pinMode(VRx, INPUT);
  pinMode(VRy, INPUT);
  pinMode(SW, INPUT_PULLUP); 

void loop() {
  xPosition = analogRead(VRx);
  yPosition = analogRead(VRy);
  SW_state = digitalRead(SW);
  mapX = map(xPosition, 0, 1023, -512, 512);
  mapY = map(yPosition, 0, 1023, -512, 512);
  Serial.print("X: ");
  Serial.print(" | Y: ");
  Serial.print(" | Button: ");


Mac 安裝Secp256k1 no secp256k1 in java.library.path


no secp256k1 in java.library.path


  1. 使用 brew 安裝構建依賴項
    brew install autoconf automake libtool berkeley-db4 pkg-config openssl boost boost-build libevent
  2. 下載secp256k1
    git clone
  3. 構建secp256k1
    #以下步驟都在clone的secp256k1 中進行
    1. sh 
    #這一步與github 中的不同,github 的還是會出錯,視情況輸入命令吧
    2. ./configure --enable-module-recovery --enable-jni --enable-module-ecdh --enable-experimental
    3. make 
    4. make check 
    5. sudo make install


Why Go is my favorite programming language

I strive to respect everybody’s personal preferences, so I usually steer clear of debates about which is the best programming language, text editor or operating system.

However, recently I was asked a couple of times why I like and use a lot of Go, so here is a coherent article to fill in the blanks of my ad-hoc in-person ramblings :-).

My background

I have used C and Perl for a number of decently sized projects. I have written programs in Python, Ruby, C++, CHICKEN Scheme, Emacs Lisp, Rust and Java (for Android only). I understand a bit of Lua, PHP, Erlang and Haskell. In a previous life, I developed a number of programs using Delphi.

I had a brief look at Go in 2009, when it was first released. I seriously started using the language when Go 1.0 was released in 2012, featuring the Go 1 compatibility guarantee. I still have code running in production which I authored in 2012, largely untouched.

1. Clarity


Go code, by convention, is formatted using the gofmt tool. Programmatically formatting code is not a new idea, but contrary to its predecessors, gofmt supports precisely one canonical style.

Having all code formatted the same way makes reading code easier; the code feels familiar. This helps not only when reading the standard library or Go compiler, but also when working with many code bases — think Open Source, or big companies.

Further, auto-formatting is a huge time-saver during code reviews, as it eliminates an entire dimension in which code could be reviewed before: now, you can just let your continuous integration system verify that gofmt produces no diffs.

Interestingly enough, having my editor apply gofmt when saving a file has changed the way I write code. I used to attempt to match what the formatter would enforce, then have it correct my mistakes. Nowadays, I express my thought as quickly as possible and trust gofmt to make it pretty (example of what I would type, click Format).

High-quality code

I use the standard library (docssource) quite a bit, see below.

All standard library code which I have read so far was of extremely high quality.

One example is the image/jpeg package: I didn’t know how JPEG worked at the time, but it was easy to pick up by switching between the Wikipedia JPEG article and theimage/jpeg code. If the package had a few more comments, I would qualify it as a teaching implementation.


I have come to agree with many opinions the Go community holds, such as:

Few keywords and abstraction layers

The Go specification lists only 25 keywords, which I can easily keep in my head.

The same is true for builtin functions and types.

In my experience, the small number of abstraction layers and concepts makes the language easy to pick up and quickly feel comfortable in.

While we’re talking about it: I was surprised about how readable the Go specification is. It really seems to target programmers (rather than standards committees?).

2. Speed

Quick feedback / low latency

I love quick feedback: I appreciate websites which load quickly, I prefer fluent User Interfaces which don’t lag, and I will choose a quick tool over a more powerful tool any day. The findings of large web properties confirm that this behavior is shared by many.

The authors of the Go compiler respect my desire for low latency: compilation speed matters to them, and new optimizations are carefully weighed against whether they will slow down compilation.

A friend of mine had not used Go before. After installing the RobustIRC bridge using go get, they concluded that Go must be an interpreted language and I had to correct them: no, the Go compiler just is that fast.

Most Go tools are no exception, e.g. gofmt or goimports are blazingly fast.

Maximum resource usage

For batch applications (as opposed to interactive applications), utilizing the available resources to their fullest is usually more important than low latency.

It is delightfully easy to profile and change a Go program to utilize all available IOPS, network bandwidth or compute. As an example, I wrote about filling a 1 Gbps link, and optimized debiman to utilize all available resources, reducing its runtime by hours.

3. Rich standard library

The Go standard library provides means to effectively use common communications protocols and data storage formats/mechanisms, such as TCP/IP, HTTP, JPEG, SQL, …

Go’s standard library is the best one I have ever seen. I perceive it as well-organized, clean, small, yet comprehensive: I often find it possible to write reasonably sized programs with just the standard library, plus one or two external packages.

Domain-specific data types and algorithms are (in general) not included and live outside the standard library, e.g. The namespace also serves as a staging area for new code before it enters the standard library: the Go 1 compatibility guarantee precludes any breaking changes, even if they are clearly worthwhile. A prominent example is, which had to break existing code to establish a more secure default.

4. Tooling

To download, compile, install and update Go packages, I use the go get tool.

All Go code bases I have worked with use the built-in testing facilities. This results not only in easy and fast testing, but also in coverage reports being readily available.

Whenever a program uses more resources than expected, I fire up pprof. See this blog post about pprof for an introduction, or my blog post about optimizing Debian Code Search. After importing the net/http/pprof package, you can profile your server while it’s running, without recompilation or restarting.

Cross-compilation is as easy as setting the GOARCH environment variable, e.g. GOARCH=arm64 for targeting the Raspberry Pi 3. Notably, tools just work cross-platform, too! For example, I can profile gokrazy from my amd64 computer: go tool pprof ~/go/bin/linux_arm64/dhcp http://gokrazy:3112/debug/pprof/heap.

godoc displays documentation as plain text or serves it via HTTP. is a public instance, but I run a local one to use while offline or for not yet published packages.

Note that these are standard tools coming with the language. Coming from C, each of the above would be a significant feat to accomplish. In Go, we take them for granted.

Getting started

Hopefully I was able to convey why I’m happy working with Go.

If you’re interested in getting started with Go, check out the beginner’s resources we point people to when they join the Gophers slack channel. See


Of course, no programming tool is entirely free of problems. Given that this article explains why Go is my favorite programming language, it focuses on the positives. I will mention a few issues in passing, though:

  • If you use Go packages which don’t offer a stable API, you might want to use a specific, known-working version. Your best bet is the dep tool, which is not part of the language at the time of writing.
  • Idiomatic Go code does not necessarily translate to the highest performance machine code, and the runtime comes at a (small) cost. In the rare cases where I found performance lacking, I successfully resorted to cgo or assembler. If your domain is hard-realtime applications or otherwise extremely performance-critical code, your mileage may vary, though.
  • I wrote that the Go standard library is the best I have ever seen, but that doesn’t mean it doesn’t have any problems. One example is complicated handling of comments when modifying Go code programmatically via one of the standard library’s oldest packages, go/ast.