ESP32: Migrating from version 2.x to 3.0 (Arduino IDE)

Recently the ESP-IDF has been updated and with this new major version, there are some breaking changes in the API. In this guide, you’ll learn about all changes in the API and how you can migrate to the latest version.

This guide covers the changes from ESP32 board add-on versions 2.X (based on ESP-IDF 4.4) to version 3.0 (based on ESP-IDF 5.1) of the Arduino ESP32 core – you can find more information in the official migration guide.

ESP32 Migrating from version 2.x to 3.0 Arduino IDE Core

If you’ve recently updated your ESP32 boards add-on to version 3.0 and now you get compilation errors in your code, then you need to check this guide.

Checking Your ESP32 Board Version Installed

First, you need to check which version of the ESP32 boards you have installed in your Arduino IDE. Go to Tools > Board and select the Boards Manager… option.

ESP32 Boards Add-on install ESP32 board

Then, search for “ESP32” by Espressif Systems and check which version you have installed in your Arduino IDE – if your installation is up to date, you should have version 3.0.X.

ESP32 Boards Add-on install ESP32 board version 3

Important: in the upcoming weeks, all the code available in our ESP32 Projects on Random Nerd Tutorials will be updated to be compatible with version 3.0. In the meantime, if your code is not compiling due to this recent change, you can downgrade your ESP32 boards add-on to version 2.0.17 to ensure your code compiles and runs properly.

ESP32 Boards Add-on install ESP32 board version 2

Table of Contents

Here’s a summary of the changes. For the complete list of changes, check the official migration guide.

ADC – Removed APIs

  • analogSetClockDiv
  • adcAttachPin
  • analogSetVRefPin

BLE – Changes in APIs

  • Changed APIs return and parameter type from std::string to Arduino style String.
  • Changed UUID data type from uint16_t to BLEUUID class.
  • BLEScan::start and BLEScan::getResults methods return type changed from BLEScanResults to BLEScanResults*.

LEDC – Removed API

  • ledcSetup
  • ledcAttachPin

LEDC – New APIs

The LEDC API has been changed to support the Peripheral Manager and make it easier to use, as LEDC channels are now automatically assigned to pins (learn more about the new LEDC API).

  • ledcAttach used to set up the LEDC pin (merged ledcSetup and ledcAttachPin functions).
  • ledcOutputInvert used to attach the interrupt to a timer using arguments.
  • ledcFade used to set up and start a fade on a given LEDC pin.
  • ledcFadeWithInterrupt used to set up and start a fade on a given LEDC pin with an interrupt.
  • ledcFadeWithInterruptArg used to set up and start a fade on a given LEDC pin with an interrupt using arguments.

You can now use analogWrite() to output a PWM signal. Pass as argument the GPIO, and the duty cycle.

void analogWrite(uint8_t pin, int value);

If using the ledcWrite() function, it now accepts only two arguments (the GPIO and the duty cycle).

bool ledcWrite(uint8_t pin, uint32_t duty);

You no longer need to assign a PWM channel. It will be automatically attributed. If you want to assign a specific PWM channel, use ledcAttachChannel().

bool ledcAttachChannel(uint8_t pin, uint32_t freq, uint8_t resolution, int8_t channel);

LEDC – Changes in APIs

  • ledcDetachPin renamed to ledcDetach.
  • In all functions, input parameter channel has been changed to pin.

Hall Sensor – Removed API

  • hallRead: Hall sensor is no longer supported.

WiFi – Functional Changes

  • In Arduino (and other frameworks) the method named flush() is intended to send out the transmit buffer content. WiFiClient and WiFiUDP method flush() won’t clear the receive buffer anymore. A new method called clear() is now used for that. Currently flush() does nothing in WiFiClient, WiFiClientSecure and WiFiUDP.
  • WiFiServer has functions accept() and available() with the same functionality. In Arduino, available() should work differently so it is now deprecated.
  • WiFiServer had unimplemented write functions inherited from Print class. These are now removed. Also unimplemented method stopAll() is removed. The methods were unimplemented because WiFiServer doesn’t manage connected WiFiClient objects for print-to-all-clients functionality.

WiFi Event Name – Changes

The names for the Wi-Fi events changed. These are the new events.

  • ARDUINO_EVENT_WIFI_READY
  • ARDUINO_EVENT_WIFI_SCAN_DONE
  • ARDUINO_EVENT_WIFI_STA_START
  • ARDUINO_EVENT_WIFI_STA_STOP
  • ARDUINO_EVENT_WIFI_STA_CONNECTED
  • ARDUINO_EVENT_WIFI_STA_DISCONNECTED
  • ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE
  • ARDUINO_EVENT_WIFI_STA_GOT_IP
  • ARDUINO_EVENT_WIFI_STA_LOST_IP
  • ARDUINO_EVENT_WPS_ER_SUCCESS
  • ARDUINO_EVENT_WPS_ER_FAILED
  • ARDUINO_EVENT_WPS_ER_TIMEOUT
  • ARDUINO_EVENT_WPS_ER_PIN
  • ARDUINO_EVENT_WIFI_AP_START
  • ARDUINO_EVENT_WIFI_AP_STOP
  • ARDUINO_EVENT_WIFI_AP_STACONNECTED
  • ARDUINO_EVENT_WIFI_AP_STADISCONNECTED
  • ARDUINO_EVENT_WIFI_AP_STAIPASSIGNED
  • ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED
  • ARDUINO_EVENT_WIFI_AP_GOT_IP6
  • ARDUINO_EVENT_WIFI_STA_GOT_IP6
  • ARDUINO_EVENT_ETH_START
  • ARDUINO_EVENT_ETH_STOP
  • ARDUINO_EVENT_ETH_CONNECTED
  • ARDUINO_EVENT_ETH_DISCONNECTED
  • ARDUINO_EVENT_ETH_GOT_IP
  • ARDUINO_EVENT_ETH_GOT_IP6
  • ARDUINO_EVENT_MAX
  • I2S – New API

    The I2S driver has been completely redesigned and refactored to use the new ESP-IDF driver – I2S API.

    RMT – Removed APIs

    • _rmtDumpStatus
    • rmtSetTick
    • rmtWriteBlocking
    • rmtEnd
    • rmtBeginReceive
    • rmtReadData

    RMT – New APIs

    For more information about the new RMT API.

    • rmtSetEOT
    • rmtWriteAsync
    • rmtTransmitCompleted
    • rmtSetRxMinThreshold

    RMT – Changes in APIs

    In all functions, input parameter rmt_obj_t* rmt has been changed to int pin.

    • rmtInit return parameter changed to bool.
    • rmtInit input parameter bool tx_not_rx has been changed to rmt_ch_dir_t channel_direction.
    • rmtInit new input parameter uint32_t frequency_Hz to set frequency of RMT channel (as function rmtSetTick was removed).
    • rmtWrite now sending data in blocking mode. It only returns after sending all data or through a timeout. For Async mode use the new rmtWriteAsync function.
    • rmtWrite new input parameter uint32_t timeout_ms.
    • rmtLoop renamed to rmtWriteLooping.
    • rmtRead input parameters changed to int pin, rmt_data_t* data, size_t *num_rmt_symbols, uint32_t timeout_ms.
    • rmtReadAsync input parameters changed to int pin, rmt_data_t* data, size_t *num_rmt_symbols.
    • rmtSetRxThreshold renamed to rmtSetRxMaxThreshold and input parameter uint32_t value has been changed to uint16_t idle_thres_ticks.
    • rmtSetCarrier input parameters uint32_t low, uint32_t high have been changed to uint32_t frequency_Hz, float duty_percent.

    SigmaDelta – Removed APIs

    • sigmaDeltaSetup
    • sigmaDeltaRead

    SigmaDelta – New APIs

    SigmaDelta has been refactored to use the new ESP-IDF driver – SigmaDelta API.

    • sigmaDeltaAttach used to set up the SigmaDelta pin (channel is acquired automatically).
    • timerGetFrequency used to get the actual frequency of the timer.
    • timerAttachInterruptArg used to attach the interrupt to a timer using arguments.

    SigmaDelta – Changes in APIs

    • sigmaDeltaDetachPin renamed to sigmaDeltaDetach.
    • sigmaDeltaWrite input parameter channel has been changed to pin.

    Timer – Removed APIs

    • timerGetConfig
    • timerSetConfig
    • timerSetDivider
    • timerSetCountUp
    • timerSetAutoReload
    • timerGetDivider
    • timerGetCountUp
    • timerGetAutoReload
    • timerAlarmEnable
    • timerAlarmDisable
    • timerAlarmWrite
    • timerAlarmEnabled
    • timerAlarmRead
    • timerAlarmReadMicros
    • timerAlarmReadSeconds
    • timerAttachInterruptFlag

    Timer – New APIs

    Timer has been refactored to use the new ESP-IDF driver and its API got simplified – new Timer API.

    • timerAlarm used to set up Alarm for the timer and enable it automatically (merged timerAlarmWrite and timerAlarmEnable functions).
    • timerGetFrequency used to get the actual frequency of the timer.
    • timerAttachInterruptArg used to attach the interrupt to a timer using arguments.

    Timer – Changes in APIs

    • timerBegin has now only 1 parameter (frequency). There is an automatic calculation of the divider using different clock sources to achieve the selected frequency.
    • timerAttachInterrupt has now only 2 parameters. The edge parameter has been removed.

    UART (HardwareSerial) – Changes in APIs

    • setHwFlowCtrlMode input parameter uint8_t mode has been changed to SerialHwFlowCtrl mode.
    • setMode input parameter uint8_t mode has been changed to SerialMode mode.

    UART (HardwareSerial) – Functional Changes

    • Default pins for some SoCs have been changed to avoid conflicts with other peripherals: * ESP32’s UART1 RX and TX pins are now GPIO26 and GPIO27, respectively; * ESP32’s UART2 RX and TX pins are now GPIO4 and GPIO25, respectively; * ESP32-S2’s UART1 RX and TX pins are now GPIO4 and GPIO5, respectively.
    • It is now possible to detach UART0 pins by calling end() with no previous call of begin().
    • It is now possible to call setPins() before begin() or in any order.
    • setPins() will detach any previous pins that have been changed.
    • begin(baud, rx, tx) will detach any previous attached pins.
    • setPins() or begin(baud, rx, tx) when called at first, will detach console RX0/TX0, attached in boot.
    • Any pin set as -1 in begin() or setPins() won’t be changed nor detached.
    • begin(baud) will not change any pins that have been set before this call, through a previous begin(baud, rx, tx) or setPin().
    • If the application only uses RX or TX, begin(baud, -1, tx) or begin(baud, rx) will change only the assigned pin and keep the other unchanged.

    Wrapping Up

    If you’re using Arduino IDE 2, you probably already updated your ESP32 boards installation to version 3.0. There were breaking changes from version 2 to version 3. So, your old codes may no longer compile with this new version.

    If that’s the case, you can try to use this guide to update your code to be compatible with the newest version, or you downgrade your installation to version 2.

    We’ll be updating all our examples to be compatible with version 3 in the upcoming weeks.



    Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
    Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

    Recommended Resources

    Build a Home Automation System from Scratch » With Raspberry Pi, ESP8266, Arduino, and Node-RED.

    Home Automation using ESP8266 eBook and video course » Build IoT and home automation projects.

    Arduino Step-by-Step Projects » Build 25 Arduino projects with our course, even with no prior experience!

    What to Read Next…


    Enjoyed this project? Stay updated by subscribing our newsletter!

    20 thoughts on “ESP32: Migrating from version 2.x to 3.0 (Arduino IDE)”

    1. It seems to me that the compiler has become even stricter again.
      Some third-party libraries don’t compile under v3 yet.

      Reply
    2. The ESP32 Cheap Yellow Display Board (ESP32‑2432S028R)

      Has the ESP WROOM-32 processor

      Which board do I select in the Arduino IDE?

      Reply
    3. V3 has broken the MAC address as you’ll get 00:00:00:00:00:00 if you call “WiFi.macAddress()”. Went back to 2.0.17 and all works fine.
      Just had a look and they have already got a 3.0.1 release as current build.
      Might wait a bit longer as early builds are always buggy.

      Reply
    4. Also beware that that callback signatures of the ESP-NOW feature has changed. For example, the receiver callback’s first parameter is no longer the sender’s MAC address, but is now incorporated into the “info” payload.

      Also beware that PlatformIO does not (yet?) support the version 3.0.0 framework so if you use both IDEs, as I do, you will be developing two versions of your code. So annoying.

      Reply
    5. My feedback for 3.0.1 board migration:
      I plan to migrate my esp32 projects from board version 2.0.17 to latest 3.0.1.
      I compiled two projects and they both are running under 3.0.1 too.

      My migration changes had been:
      1) analogSetClockDiv(1); –> api removed, so i commended the line
      2) considering the refactored timer interface

      Project 1 is using HardwareSerial, LittleFS, AsyncWebServer, HTTPClient, FTPServer, EEPROM, ArduinoOTA, WiFi, 1 ADC input reading
      Project 2 additioanl uses I2C with two MCP23017, one RTC3029, RCSwitch Library

      I measured the compile-time (project had been compiled at least two times as the first compiler run after arduino start lasts very long)
      I am mostly worrying about the consumed resources:

      Project 1 with 2.0.17: 1106733 Bytes (84%) Flash, 53364 Bytes (16%) RAM, compilation time 33s
      Project 1 with 3.0.1: 1240177 Bytes (94%) Flash, 53364 Bytes (16%) RAM, compilation time 52s
      Project 2 with 2.0.17: 1175833 Bytes (89%) Flash, 57024 Bytes (17%) RAM, compilation time 35s
      Project 2 with 3.0.1: 1295809 Bytes (98%) Flash, 54132 Bytes (16%) RAM, compilation time 53s

      flash usage in 3.0.1 increased very much! Possible i do have to consider the mensioned compiler flags “-MMD -c”, but do not know where to set up in arduino IDE.

      Reply
    6. It’s a good idea to update your tutorials but, please, leave the old 2.x versions available for download. I’m using some libraries in my projects that still need the old version. Do you have any idea how to setup ESP32 3.x parallel to ESP2.x on a Windows computer within the same user (using different Arduino 2.x setups ?) ?
      Greetings Michael

      Reply
      • Hi.
        You can go back and forth between versions. You just need to go to Tools > Boards Manager, search for ESP32 and unninstall/install the version you want to use at the time.
        Regards,
        sara

        Reply
        • Hi Sara, Of course I could switch between version 2.x and 3.x, but that takes a lot of time on my (older) PC. I would like to run a second Arduino 2.x on my PC that runs e.g. ESP32 version 3.x and the first Arduino 2.x runs ESP32 version 2.x. I did not find any solution to run both “in parallel” within one PC/Windows user instance. Do you know about a way to do so. And again – it would be fine if you have a (GitHub) place for the older 2.x tutorial source codes for people like me who have to stay on 2.x. Thanks again and greetings. Michael

          Reply
          • Hi.
            You don’t have to do anything special.
            You just need to install the two versions of the IDE.
            Then, on each IDE install the version you want to use.
            Regards,
            Sara

            Reply
            • We know all this. We are asking that you please leave up the old code.

              Archive it, whatever. But PLEASE leave it up where people can still use it.

              Thank you.

    7. Do you have updated code for ESPNOW?
      The data receive has changed as well as changing the MAC address.
      I am trying to port a sketch from Arduino 1.8.19 and ESP32 1.0.4 by Espressif Systems.

      Reply

    Leave a Comment

    Download Our Free eBooks and Resources

    Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.