What does ESP8266 rst cause: 2 mean?

Sometimes you will see a message like

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 3460, room 16 
tail 4
chksum 0xcc
load 0x3fff20b8, len 40, room 4 
tail 4
chksum 0xc9
csum 0xc9
v0007e100
~ld
7

on the ESP8266 serial line.

rst cause: 2 means that the ESP was restarted from the firmware using

ESP.restart();

Typically such a restart is intentional. Look for ESP.restart() calls in your firmware. It’s not straightforward to identify which ESP.restart() call caused the reset. I recommend to insert Serial.println() statements describing the reset cause before every call to ESP.restart(), for example:

Serial.println("Resetting due to Wifi not connecting...");
ESP.restart();

 

Posted by Uli Köhler in Electronics, ESP8266/ESP32, PlatformIO

How to fix ESP8266 PlatformIO error: WIFI_STA was not declared in this scope

Problem:

When compiling your PlatformIO firmware, you see an error message like

src/main.cpp: In function 'void setup()':
src/main.cpp:49:10: error: 'class WiFiClass' has no member named 'mode'
   49 |     WiFi.mode(WIFI_STA);
      |          ^~~~
src/main.cpp:49:15: error: 'WIFI_STA' was not declared in this scope
   49 |     WiFi.mode(WIFI_STA);
      |               ^~~~~~~~

Solution:

You included WiFi.h instead of the correct ESP8266WiFi.h. This will cause multiple issues like reboots on WiFi.begin() even if it compiles correctly.

Replace

#include <WiFi.h>

with

#include <ESP8266WiFi.h>

everywhere in your source code and does not support

WiFi.mode(WIFI_STA);

For more details, see our previous post on How to fix PlatformIO ESP8266 WiFi.h: No Such File or Directory

Posted by Uli Köhler in Electronics, ESP8266/ESP32, PlatformIO

How I fixed ESP8266 WiFi.begin() rst cause 4 on PlatformIO

I faced an issue with my PlatformIO ESP8266 firmware causing a rst cause 4 reset a few seconds after calling WiFi.begin():

ets Jan  8 2013,rst cause:4, boot mode:(3,2)

wdt reset
load 0x4010f000, len 3460, room 16 
tail 4
chksum 0xcc
load 0x3fff20b8, len 40, room 4 
tail 4
chksum 0xc9
csum 0xc9
v0007e660
~ld
7

and a subsequent reboot of the firmware. The issue repeated ad infinitum.

In my case, the issue was that I had listed WiFi as lib_deps dependency in platformio.ini:

lib_deps =
    WiFi

instead of including #include <ESP8266WiFi.h> instead of #include <WiFi.h>. See How to fix PlatformIO ESP8266 WiFi.h: No Such File or Directory for more details.

Posted by Uli Köhler in Electronics, ESP8266/ESP32, PlatformIO

How to install ArduinoOTA for ESP8266/ESP32 on PlatformIO (platformio.ini and lib_deps)

As the ESP Arduino framework already includes ArduinoOTA, there is no need to explicitly install or require ArduinoOTA.

You do not need to add anything to platformio.ini or lib_deps in order to use ArduinoOTA on the ESP8266 or ESP32.

In order to use ArduinoOTA, the minimum you need to to is to include it:

#include <ArduinoOTA.h>

then call

ArduinoOTA.begin();

in your setup() function and then call

ArduinoOTA.handle();

periodically (for example, in your loop() function).

For a more complete example, see:

Posted by Uli Köhler in ESP8266/ESP32, PlatformIO

Minimal PlatformIO ESP8266 ArduinoOTA example

This simple firmware will connect to Wifi and enable over-the-air update (OTA) using ArduinoOTA on any ESP8266 module. Use it as a starting point for your own firmware to enable OTA.

#include <Arduino.h>
#include <ArduinoOTA.h>
#include <ESP8266WiFi.h>

void setup() {
  Serial.begin(115200);
  /**
   * Connet to Wifi
   */
  WiFi.begin("MyWifiSSID", "MyWifiPassword");
  uint32_t notConnectedCounter = 0;
  while (WiFi.status() != WL_CONNECTED) {
      delay(100);
      Serial.println("Wifi connecting...");
      notConnectedCounter++;
      if(notConnectedCounter > 150) { // Reset board if not connected after 5s
          Serial.println("Resetting due to Wifi not connecting...");
          ESP.restart();
      }
  }
  Serial.print("Wifi connected, IP address: ");
  Serial.println(WiFi.localIP());
  /**
   * Enable OTA update
   */
  ArduinoOTA.begin();
}

void loop() {
  // Check for over the air update request and (if present) flash it
  ArduinoOTA.handle();
}
[env:d1_mini]
platform = espressif8266
board = d1_mini
framework = arduino
monitor_speed = 115200

[env:d1_mini_ota]
extends = env:d1_mini
upload_protocol = espota
upload_port = 192.168.178.166

For more details on how the two targets (d1_mini and d1_mini_ota) work, see How to handle both OTA and serial upload in platformio.ini. Note that you need to enter the ESP8266’s IP address or mDNS name in order for OTA to work.

The firmware will print the Wifi IP address on the serial port, so you can use PlatformIO’s Monitor feature to view it.

Posted by Uli Köhler in Electronics, Embedded, ESP8266/ESP32, PlatformIO

How to handle both OTA and serial upload in platformio.ini

When you’re writing a PlatformIO firmware that can be uploaded using both ArduinoOTA and over the serial port, I recommend this platformio.ini setup:

Start with your normal config for serial upload:

[env:d1_mini]
platform = espressif8266
board = d1_mini
framework = arduino
monitor_speed = 115200

And now add a new OTA target that extends the serial config, effectively inheriting the complete build configuration including the lib_deps:

[env:d1_mini_ota]
extends = env:d1_mini
upload_protocol = espota
upload_port = 192.168.178.166

In upload_port you need to enter either the IP address or the mDNS name of the board that shall be flashed. The IP address we entered (192.168.178.166) is just an example.

Also note that depending on the name of your original build target, change

extends = env:d1_mini

to the name of your original target (including env:)

Complete platformio.ini example

[env:d1_mini]
platform = espressif8266
board = d1_mini
framework = arduino
monitor_speed = 115200

[env:d1_mini_ota]
extends = env:d1_mini
upload_protocol = espota
upload_port = 10.9.1.106

 

Posted by Uli Köhler in Electronics, ESP8266/ESP32, PlatformIO

How to fix PlatformIO ESP8266 ArduinoOTA error: stopAll is not a member of WiFiUDP

Problem:

When compiling your PlatformIO firmware, you see an error message like

/home/uli/.platformio/packages/framework-arduinoespressif8266/libraries/ArduinoOTA/ArduinoOTA.cpp: In member function 'void ArduinoOTAClass::_runUpdate()':
/home/uli/.platformio/packages/framework-arduinoespressif8266/libraries/ArduinoOTA/ArduinoOTA.cpp:268:12: error: 'stopAll' is not a member of 'WiFiUDP'
  268 |   WiFiUDP::stopAll();
      |            ^~~~~~~

Solution:

Remove WiFi from the lib_deps secton of your platform.ini. Before the fix:

lib_deps =
    ESP Async [email protected]
    [email protected]
    WiFi

After the fix:

lib_deps =
    ESP Async [email protected]
    [email protected]

Now check your source code and replace any

#include <WiFi.h>

by

#include <ESP8266WiFi.h>

in order to prevent the WiFi.h: No Such File or Directory  issue as outlined in How to fix PlatformIO ESP8266 WiFi.h: No Such File or Directory

Now you need to completely remove the .pio folder from your project directory in order to ensure a clean build:

rm -rf .pio

After that, recompile your firmware.

Posted by Uli Köhler in Arduino, Electronics, ESP8266/ESP32, PlatformIO

How to fix PlatformIO ESP8266 WiFi.h: No Such File or Directory

Problem:

When compiling your PlatformIO firmware, you see an error message like

src/main.cpp:2:10: fatal error: WiFi.h: No such file or directory

**************************************************************
* Looking for WiFi.h dependency? Check our library registry!
*
* CLI  > platformio lib search "header:WiFi.h"
* Web  > https://platformio.org/lib/search?query=header:WiFi.h
*
**************************************************************

    2 | #include <WiFi.h>

Solution:

Instead of

#include <WiFi.h>

use

#include <ESP8266WiFi.h>

Now delete the .pio folder from the project directory to ensure a clean build by using:

rm -rf .pio

In case that doesn’t help, see our article on how to fix this issue by adding the WiFi library to the dependencies: How to fix PlatformIO WiFi.h: No Such File or Directory

Posted by Uli Köhler in Arduino, Electronics, ESP8266/ESP32, PlatformIO

How to fix PlatformIO multiple definition of `WiFi’ error

Problem:

When compiling your PlatformIO firmware, you see an error message like

Linking .pio/build/d1_mini_lite/firmware.elf
/home/uli/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: .pio/build/d1_mini_lite/libbc0/libWiFi.a(WiFi.cpp.o):(.bss.WiFi+0x0): multiple definition of `WiFi'; .pio/build/d1_mini_lite/libd39/libESP8266WiFi.a(ESP8266WiFi.cpp.o):(.bss.WiFi+0x0): first defined here
collect2: error: ld returned 1 exit status
*** [.pio/build/d1_mini_lite/firmware.elf] Error 1

Solution:

Move WiFi in the lib_deps section in platformio.ini to the top of the list. Before the fix:

lib_deps =
    ESP Async [email protected]
    [email protected]
    WiFi

After the fix:

lib_deps =
    WiFi
    ESP Async [email protected]
    [email protected]

Now you need to completely remove the .pio folder from your project directory:

rm -rf .pio

After that, recompile your firmware.

Complete platformio.ini example after fixing the issue:

[env:d1_mini_lite]
platform = espressif8266
board = d1_mini_lite
framework = arduino
monitor_speed = 115200
lib_deps =
    WiFi
    ESP Async [email protected]
    [email protected]

 

Posted by Uli Köhler in Arduino, Electronics, PlatformIO

How to fix PlatformIO WiFi.h: No Such File or Directory

Important note: On the ESP8266, this solution is not recommended. See How to fix PlatformIO ESP8266 WiFi.h: No Such File or Directory instead

Problem:

When compiling your PlatformIO firmware, you see an error message like

src/main.cpp:2:10: fatal error: WiFi.h: No such file or directory

**************************************************************
* Looking for WiFi.h dependency? Check our library registry!
*
* CLI  > platformio lib search "header:WiFi.h"
* Web  > https://platformio.org/lib/search?query=header:WiFi.h
*
**************************************************************

    2 | #include <WiFi.h>

Solution:

Add WiFi to the lib_deps in platformio.ini (create lib_deps if it is not present already):

lib_deps =
    WiFi

and then recompile.

Complete platformio.ini example:

[env:d1_mini_lite]
platform = espressif8266
board = d1_mini_lite
framework = arduino
monitor_speed = 115200
lib_deps =
    ESP Async [email protected]
    [email protected]
    WiFi

 

Posted by Uli Köhler in Arduino, Electronics, PlatformIO

How to fix PlatformIO SPI.h: No Such File or Directory

Problem:

When compiling your PlatformIO firmware, you see an error message like

In file included from .pio/libdeps/esp32dev/Adafruit BusIO/Adafruit_BusIO_Register.h:2:0,
                 from .pio/libdeps/esp32dev/Adafruit INA219/Adafruit_INA219.h:21,
                 from .pio/libdeps/esp32dev/Adafruit INA219/Adafruit_INA219.cpp:31:
.pio/libdeps/esp32dev/Adafruit BusIO/Adafruit_SPIDevice.h:6:17: fatal error: SPI.h: No such file or directory

*************************************************************
* Looking for SPI.h dependency? Check our library registry!
*
* CLI  > platformio lib search "header:SPI.h"
* Web  > https://platformio.org/lib/search?query=header:SPI.h
*
*************************************************************

Solution:

Add SPI to the lib_deps in platformio.ini, for example, before:

lib_deps =
    adafruit/Adafruit INA219 @ ^1.1.1

After:

lib_deps =
    adafruit/Adafruit INA219 @ ^1.1.1
    SPI

and then recompile.

Posted by Uli Köhler in Arduino, Electronics, PlatformIO

How to fix PlatformIO Adafruit_BusIO_Register.h: No Such File or Directory

Problem:

When compiling your PlatformIO firmware, you see an error message like

In file included from .pio/libdeps/esp32dev/Adafruit INA219/Adafruit_INA219.cpp:31:0:
.pio/libdeps/esp32dev/Adafruit INA219/Adafruit_INA219.h:21:37: fatal error: Adafruit_BusIO_Register.h: No such file or directory

*********************************************************************************
* Looking for Adafruit_BusIO_Register.h dependency? Check our library registry!
*
* CLI  > platformio lib search "header:Adafruit_BusIO_Register.h"
* Web  > https://platformio.org/lib/search?query=header:Adafruit_BusIO_Register.h
*
*********************************************************************************

Solution:

Add adafruit/Adafruit BusIO @ ^1.9.3 to the lib_deps in platformio.ini, for example, before:

lib_deps =
    adafruit/Adafruit INA219 @ ^1.1.1

After:

lib_deps =
    adafruit/Adafruit INA219 @ ^1.1.1
    adafruit/Adafruit BusIO @ ^1.9.3

and then recompile.

Posted by Uli Köhler in Arduino, Electronics, PlatformIO

How to fix PlatformIO Wire.h: No Such File or Directory

Problem:

When compiling your PlatformIO firmware, you see an error message like

In file included from .pio/libdeps/esp32dev/Adafruit INA219/Adafruit_INA219.cpp:31:0:
.pio/libdeps/esp32dev/Adafruit INA219/Adafruit_INA219.cpp:29:18: fatal error: Wire.h: No such file or directory

**************************************************************
* Looking for Wire.h dependency? Check our library registry!
*
* CLI  > platformio lib search "header:Wire.h"
* Web  > https://platformio.org/lib/search?query=header:Wire.h
*
**************************************************************

Solution:

Add Wire to the lib_deps in platformio.ini, for example, before:

lib_deps =
    adafruit/Adafruit INA219 @ ^1.1.1

After:

lib_deps =
    adafruit/Adafruit INA219 @ ^1.1.1
    Wire

and then recompile.

Posted by Uli Köhler in Arduino, Electronics, PlatformIO

How to compute parallel resistor values in Wolfram Alpha

In Wolfram Alpha, you can just enter X parallel Y

9.75Ohm parallel 120Ohm

to compute the equivalent value of two resistors. In order to use Kiloohm or Megaohm, just use SI prefixes like k and M:

9.75kOhm parallel 120kOhm

 

Posted by Uli Köhler in Electronics

What is the typical & maximum clock frequency for XY2-100?

XY2-100 typically operates at 2.0 MHz clock rate. This is due to the typical 100 kHz frame rate, with 20 bits being transmitted per frame, hence 20\cdot{}100 \text{kHz} = 2.0 \text{MHz}.

The maximum clock frequency is rarely specified but Raylase lists it as 10 MHz.

Source: Raylase

Posted by Uli Köhler in Electronics

Which line driver should one use for XY2-100 and XY3-100?

Raylayse recommends in this manual to use

UA9638CD

as a line driver. Note that each UA9638CD contains two separate driver circuits while you need five drivers (CLK, SYNC, X, Y & Z), so you need to use three UA9638CD chips to be able to drive a XY2-100 interface.

In general, any RS422 or RS485 driver (with RS485 drivers being operated in fixed transmit mode with the driver being disabled) will do the job. However there are certain considerations:

  • The driver must be able to operate at 15 MBaud / 15 MHz input speed. Some (although few) RS485/RS422 drivers are slew rate limited, i.e. they cannot drive any signal faster than X kBaud/MBaud. I recommend not to use a driver that is slew rate limited. Most RS485/RS422 drivers are able to drive 15 MBaud and this is fine for XY2-100.
  • The driver should be able to withstand ESD surges, as usual in industrial equipment
  • Only ever use drivers with internal short circuit protection. Almost all line drivers do that anyway, but it’s really important in guaranteeing the robustness of your equipment
  • When using multiple separate driver chips, always use only one type of driver chip, as the receiver could experience skew between the different signals which might lead to bad received data. Never ever use different types of driver chips.
  • In general, drivers driven by 5V instead of 3.3V (or even 1.8V) provide a higher current into a given resistance, leading to high signal to noise ratios, plus they are quite expensive. Use 3.3V or 1.8V RS485/RS422 drivers only if not possible otherwise, but always check if the logic level of the MCU driving the line driver fits the input logic level of the line driver.

My opinion is that you should go with the following specs for most products:

  • Use three dual RS422 drivers with 15 MBaud speed capability
  • Use drivers with 5V supply with 3.3V compatible logic level
  • Use only drivers with at least ±8kV ESD (HBM), preferred ±15kV, and internal short circuit protection. These are reasonably robust.

My recommendation of finding a suitable receiver is to first search on the manufacturer’s websites because they provide more appropriate filters for this usecase:

  • Texas Instruments
  • ST Microelectronics
  • Maxim Integrated
  • Intersil

(it’s usually best to google for e.g. Texas Instruments RS422 to get directly to the correct page) and then check on Octopart etc if the part has sufficient stock quantities (at least 1k).

and, if searching on the manufacturer’s sites doesn’t yield any suitable result, search on DigiKey, Mouser and Farnell for other (typically smaller) manufacturers or different models that you might have missed.

In my case, I identified the Maxim MAX22508E as an excellent choice, since it supports high datarates up to 50 Mbps (leading to slightly more EMI but also possibly better signal integrity since the eye patterns is more open when using a much faster transceiver, leading to more accuracy in detecting the timing of the flank, leading to lower error rates). While it is somewhat expensive (2.50€/pc at small qtys), this is fine for many laser applications.

Posted by Uli Köhler in Electronics

Does the i.MX RT1060 / Teensy 4.x support Bit-Banding?

The i.MX RT1060 is a Cortex M7 microcontroller. Cortex M7 microcontrollers do not support bitbanding. Hence, the i.MX RT106x series (including the Teensy 4.0 and 4.1 boards) do not support bitbanding. See this ARM forum post for more details.

Posted by Uli Köhler in Electronics, Embedded, Teensy

How to install VirtualBox on Ubuntu in 3 minutes

wget -q https://www.virtualbox.org/download/oracle_vbox_2016.asc -O- | sudo apt-key add -
wget -q https://www.virtualbox.org/download/oracle_vbox.asc -O- | sudo apt-key add -
echo "deb [arch=amd64] https://download.virtualbox.org/virtualbox/debian $(lsb_release -c -s) contrib" | sudo tee /etc/apt/sources.list.d/virtualbox.list
sudo apt -y update
sudo apt -y install virtualbox-6.1
sudo usermod -a -G vboxusers $USER

If needed, you can download the extension pack from Oracle here.

Posted by Uli Köhler in Linux

How to enable Teensy 4.x GPT timer in free running mode

In this example, we’ll use direct register access to enable the GPT1 timer module at 8 MHz counter frequency in free-running mode. Free-running mode means that the timer will just roll over once it has reached 0xFFFFFFFF (maximum 32 bit value).

How to configure the timer

CCM_CCGR1 |= CCM_CCGR1_GPT1_BUS(CCM_CCGR_ON); // Enable clock to GPT1 module
GPT1_CR = 0; // Disable for configuration
GPT1_PR = 3 - 1; // Prescale 24 MHz clock by 3 => 8 MHz
GPT1_CR = GPT_CR_EN /* Enable timer */
  | GPT_CR_CLKSRC(1) /* 24 MHz peripheral clock as clock source */
  | GPT_CR_FRR /* Free-Run, do not reset */;

Full example

This example works in PlatformIO without any external libraries, but you need to set monitor_speed = 115200 in platformio.ini so the serial port is read at the correct speed.

#include <Arduino.h>

void setup()
{
    // Setup USB serial port so we can print the timer value
    Serial.begin(115200);

    // Enable timer    
    CCM_CCGR1 |= CCM_CCGR1_GPT1_BUS(CCM_CCGR_ON); // Enable clock to GPT1 module
    GPT1_CR = 0; // Disable for configuration
    GPT1_PR = 3 - 1; // Prescale 24 MHz clock by 3 => 8 MHz
    GPT1_CR = GPT_CR_EN /* Enable timer */
      | GPT_CR_CLKSRC(1) /* 24 MHz peripheral clock as clock source */
      | GPT_CR_FRR /* Free-Run, do not reset */;
}

void loop()
{
    // Print the timer count every ~100 ms
    Serial.println(GPT1_CNT);
    delay(100);
}

 

Posted by Uli Köhler in Electronics, Embedded, Teensy

Teensy 4.1 interrupts at multi-MHz speed using TeensyTimerTool

As shown in our example Teensy 4.1 PlatformIO 2MHz Timer interrupt GPIO output you can use TeensyTimerTool to generate multi-MHz timer interrupts. In our experiments, we could generate GPIO-toggling interrupts up to 4 MHz:

The trick here is to use std::chrono time literals. The TeensyTimerTools PeriodicTimer example only shows us how to use microsecond resolution:

t1.begin(callback, 250'000); // 250ms

but we can simply use 250ns to obtain nanosecond resolution:

t1.begin(callback, 250ns);

Here’s our observation what works and what doesn’t:

  • Multi-MHz GPIO-toggling interrupts as shown in our example only work on GPT1 and GPT2, they do NOT work on PIT and TMRx. We did not investigate the precise reasoning behind this, and there might also be ways to
  • As usual, the interrupt must only contain a small number of instructions. We’re using digitalWriteFast(), but using direct register access would be even faster.
Posted by Uli Köhler in Electronics, Embedded, PlatformIO, Teensy
This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Cookie settingsACCEPTPrivacy &amp; Cookies Policy