How to disable 'interrupt watchdog' in ESP32 OR increase ISR time limit? - arduino

I am using ESP32 DEVKIT link and Adafruit VS1053 Codec + MicroSD Breakout - MP3/WAV/MIDI/OGG Play + Record - v4 link to record and then play the sound. I am using Arduino IDE for coding.
I am facing an issue right now that the module uses hardware interrupt for playing purposes. But ESP32 is resetting again and again when I try to play a sound track. The debug log says:
Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1)
Core 1 register dump:
PC : 0x400d1280 PS : 0x00060834 A0 : 0x800d128f A1 : 0x3ffc0bb0
A2 : 0x3ffc241c A3 : 0x3ffb1f20 A4 : 0x800d1779 A5 : 0x3ffb1f00
A6 : 0x3ffc241c A7 : 0x3f400f9c A8 : 0x800d1280 A9 : 0x3ffc0b90
A10 : 0x0000002b A11 : 0x3f401067 A12 : 0x800d1691 A13 : 0x3ffb1ed0
A14 : 0x3ffc241c A15 : 0x00000000 SAR : 0x0000001f EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xffffffff
Core 1 was running in ISR context:
EPC1 : 0x400d4123 EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x400d1280
Backtrace: 0x400d1280:0x3ffc0bb0 0x400d128c:0x3ffc0bd0 0x40080e21:0x3ffc0bf0 0x400817d5:0x3ffc0c10 0x400d3ae5:0x00000000
Core 0 register dump:
PC : 0x400ee86e PS : 0x00060934 A0 : 0x8008656c A1 : 0x3ffc7910
A2 : 0x00000008 A3 : 0x00000000 A4 : 0x00000001 A5 : 0x3ffc7f4c
A6 : 0x00000000 A7 : 0x00000001 A8 : 0x3ffc3404 A9 : 0x3ffc33e8
A10 : 0x00000000 A11 : 0x00000001 A12 : 0x00000000 A13 : 0x00000001
A14 : 0x00060b20 A15 : 0x00000000 SAR : 0x00000000 EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000
Backtrace: 0x400ee86e:0x3ffc7910 0x40086569:0x3ffc7930
Rebooting...
ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:952
load:0x40078000,len:6084
load:0x40080000,len:7936
entry 0x40080310
Adafruit VS1053 Simple Test
VS1053 found
The line Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1) indicates that its interrupt wdt.
I searched ways to disable interrupt WDT but no help. The file esp_int_wdt.h in ~Documents\Arduino\hardware\espressif\esp32\tools\sdk\include\esp32 provides two functions for enabling interrupt WDT for both or one CPU. There is no function to disable it.
How to disable ESP32 interrupt WDT?

#include "soc/rtc_wdt.h"
rtc_wdt_protect_off();
rtc_wdt_disable();
Or turn it off in menuconfig. I agree with other posters though, you should not turn it off, instead, you can also feed it with the following function:
rtc_wdt_feed();
I usually create a lowest priority FreeRTOS task that just loops and calls the feed method with a delay less then the timeout, giving enough time for higher priority "business logic" to run. Example:
Set timeout to 250 ms in menuconfig or in code:
rtc_wdt_set_length_of_reset_signal(RTC_WDT_SYS_RESET_SIG, RTC_WDT_LENGTH_3_2us);
rtc_wdt_set_stage(RTC_WDT_STAGE0, RTC_WDT_STAGE_ACTION_RESET_SYSTEM);
rtc_wdt_set_time(RTC_WDT_STAGE0, 250);
Then do this in your task:
while(true) {
rtc_wdt_feed();
vTaskDelay(pdMS_TO_TICKS(100));
}
This will feed both the FreeRTOS WDT and the RTC WDT and reset your system if it gets stuck in a loop or doesn't processes within your time requirements. You'll need to play with the timeout and how often you feed the timer to get it right for your system.Keep in mind the Wifi, PHY, and BT are not deterministic so you'll have a lot of unpredictability in timing if you are dependent on DAQ from from "the net".

I don't know how to disable watchdog using arduino, but I can tell you how to disable it using esp-idf and its make menuconfig
Open menuconfig: make menuconfig
Enter component config
Enter ESP32-specific
Remove star from interrupt watchdog
P.S. According to esp-idf docs void esp_int_wdt_init() is used to init interrupt watchdog. This function is called when IWDT enabled in menuconfig. So you can try to find call of this function and remove it ;)
BUT:
I advise you to not disable watchdog. Instead of this, try to use FreeRTOS tasks to execute large amount of code on interrupt.
Im not sure how to do it exactly in arduino platform, but I can tell how I did it using esp-idf
First, create interrupt handler with signature void f(void*)
void MyHandler(void* pData){
/* Your code here */
vTaskDelete(NULL); // delete current taks, must have
}
Second, in interrupt handler you have to create new task, using xTaskCreate or xTaskCreatePinnedToCore. For example, xTaskCreate(MyHandler, "int_handler", 256, NULL, 4, NULL); (Check out api reference)
That's all, now you can run big code on your interrupt. In addition to this, I advise you to not create too many tasks. System may hang.
P.S. If you need to handle tonns of interurpt requests per second, try to use FreeRTOS queues

The watchdog timer plays an important role in system stability.
Rather than disabling the watchdog timer, try to make sure that you don't stay in loop() for too long. You should always structure your code so that you do the least work you can in loop() and let it return. When it returns the software that supports your ESP32 application gets to do important housekeeping tasks, and reset the watchdog timer.
For instance, you should never write:
void loop() {
while(1) {
do_some_work();
}
}
and instead you should write:
void loop() {
do_some_work();
}
If you absolutely have to do more work in loop() than the watchdog timer allows for, make sure you call yield() or delay() occasionally from your code; this will allow the system to catch up on things it needs to do. yield() will return immediately after doing any needed housekeeping work; delay(milliseconds) will return milliseconds later after doing any needed work.
So rather than write
void loop() {
unsigned long start_time = millis();
while(millis() - start_time < 10*1000) { }
do_some_work();
}
which would cause the watchdog timer to go off, you'd want to write
void loop() {
delay(10*1000);
do_some_work();
start_time = millis();
}
or even better, if your loop may be servicing multiple needs:
void loop() {
static unsigned long start_time1 = millis();
static unsigned long start_time2 = millis();
if(millis() - start_time >= 10*1000) {
do_some_work1();
start_time1 = millis();
}
if(millis() - start_time >= 20*1000) {
do_some_work2();
start_time2 = millis();
}
}

I use HELTEC ESP32 LORA.
Board selected in arduino HELTEC WIFI LORA 32 (V2)
My firmware works fine, but same firmware one year later the esp32 start to reset in the interrupt.
the message in the terminal
Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1).
I checked the :
1.- Watch dog, it did not work
2.- decrease the program inside the interrupt, it did not work.
Finally, the solution WAS...
Downgrade the ESp32 by expressive system library from 2.0.6 to 2.0.3
I hope it be useful
Bye

Related

ESP32 Unable to send Telegram message in interrupt method

I'm working on my first ESP32 project using a DFRobot Firebeetle 2 (ESP32-WROOM-32E) and the Arduino IDE (configured as per DFRobot's instructions). I'm trying creating a Telegram bot which will send a message when the temperature exceeds a certain value. This part is working in the loop() method, but now I'm trying to add a 'status button' which triggers an interrupt to send a status message. I plan to use the ESP32's sleep function, hence using an interrupt rather than checking the button in loop() - I am aware that loop() doesn't execute when using sleep. The problem is sending a message in the interrupt method is causing an error, but I don't know how to resolve it.
If I reduce minStatusMsgInterval to 250 and call SendStatusMessage(); at the end of setup() I receive the message, so the function works, just not when it's called from an interrupt. The error mentions wdt timeout so I'm thinking bot.sendMessage() is taking too long? But if that is the case, I can't make it any quicker, so is there another way to achieve this? or have I misinterpreted the error completely?
#include <WiFi.h>
#include "WiFiClientSecure.h"
#include <ESP32Time.h>
#include <DFRobot_DHT11.h>
#include <UniversalTelegramBot.h>
//WiFi
#define WLAN_SSID "ESP32Test"
#define WLAN_PASS "*********"
//WiFiFlientSecure for SSL/TLS support
WiFiClientSecure client;
//Time
ESP32Time rtc(0); // offset in seconds; 0 = GMT, 3600 = GMT+1
//Telegram
#define TELEGRAM_TOKEN "*********:*************************"
#define CHAT_ID "**********"
UniversalTelegramBot bot(TELEGRAM_TOKEN, client);
//Temperature
DFRobot_DHT11 DHT;
#define DHT11_PIN D11
//Buttons
#define ONBOARD_BUTTON_PIN 27 //ESP32 pin 27
#define STATUS_BUTTON_PIN D10 //ESP32 pin 12
int StatusButtonLastInterrupt = 0;
//Alerts
int alertValue = 27;
bool alertSent = false;
int minStatusMsgInterval = 5000;
void IRAM_ATTR SendStatusMessage() {
if (millis() - StatusButtonLastInterrupt < minStatusMsgInterval) return; //Prevent executing multiple times per button press or more frequent than required
String message = "Temperature Monitor Status\n\n";
message += "Internal temperature: " + String(DHT.temperature) + "C\n";
message += "Internal humidity: " + String(DHT.humidity) + "%\n";
//message += "System time: " + rtc.getDateTime(); // Causes ESP to crash and reset. Error: abort() was called at PC 0x40084cf7 on core 1
//TODO: Check WiFi is connected first - will need to connect when woken from sleep
bot.sendMessage(CHAT_ID, message, ""); // Causes ESP to crash and reset. Error: Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1).
StatusButtonLastInterrupt = millis();
}
void SyncNTP() {
Serial.print("Retrieving time: ");
configTime(0, 3600, "time.google.com"); // get UTC time via NTP
time_t now = time(nullptr);
while (now < 24 * 3600)
{
Serial.print(".");
delay(100);
now = time(nullptr);
}
rtc.setTime(now); //Set the time on the realtime clock
Serial.println(rtc.getDateTime());
}
void setup() {
pinMode(ONBOARD_BUTTON_PIN, INPUT_PULLUP);
pinMode(STATUS_BUTTON_PIN, INPUT);
Serial.begin(115200);
//Interrupts
attachInterrupt(STATUS_BUTTON_PIN, SendStatusMessage, FALLING);
// Connect to WiFi access point.
Serial.println(); Serial.println();
Serial.print("Connecting to ");
Serial.println(WLAN_SSID);
WiFi.mode(WIFI_MODE_STA);
WiFi.begin(WLAN_SSID, WLAN_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
//Serial.print(".");
Serial.print("WiFi Status: ");
Serial.println(WiFi.status());
}
Serial.println();
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
client.setCACert(TELEGRAM_CERTIFICATE_ROOT); // Add root certificate for api.telegram.org
SyncNTP();
}
void loop() {
DHT.read(DHT11_PIN);
Serial.print("temp:");
Serial.print(DHT.temperature);
Serial.print(" humi:");
Serial.println(DHT.humidity);
if (DHT.temperature >= alertValue)
{
if (!alertSent)
{
bot.sendMessage(CHAT_ID, "TEMPERATURE ALERT: Internal temperature is: " + String(DHT.temperature), "");
alertSent = true;
}
} else {
if (alertSent)
{
bot.sendMessage(CHAT_ID, "Alert Cleared: Internal temperature is: " + String(DHT.temperature), "");
alertSent = false; //Reset the flag when temperature drops below alertValue
}
}
delay(1000);
}
Serial Monitor Output:
Connecting to ESP32Test
WiFi Status: 6
WiFi Status: 6
WiFi Status: 6
WiFi Status: 6
WiFi Status: 3
WiFi connected
IP address: 192.168.1.2
Retrieving time: ....................Sun, Feb 19 2023 22:23:38
temp:25 humi:57
temp:24 humi:53
temp:24 humi:60
temp:24 humi:60
temp:24 humi:60
temp:24 humi:60
Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1).
Core 1 register dump:
PC : 0x40090362 PS : 0x00060f34 A0 : 0x8008f47e A1 : 0x3ffbeb00
A2 : 0x3ffde700 A3 : 0x3ffbd994 A4 : 0x00000004 A5 : 0xb33fffff
A6 : 0x00000001 A7 : 0x00000001 A8 : 0x3ffbd994 A9 : 0x3ffbd994
A10 : 0x00000019 A11 : 0x00000019 A12 : 0x3ffc3afc A13 : 0xb33fffff
A14 : 0x00000001 A15 : 0x00000001 SAR : 0x0000000f EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x400896b0 LEND : 0x400896c6 LCOUNT : 0xffffffff
Core 1 was running in ISR context:
EPC1 : 0x400e8e33 EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x40090362
Backtrace:0x4009035f:0x3ffbeb000x4008f47b:0x3ffbeb20 0x4008de7c:0x3ffbeb40 0x40106ab7:0x3ffbeb80 0x400f408f:0x3ffbeba0 0x401071c5:0x3ffbebd0 0x40107464:0x3ffbebf0 0x400f379d:0x3ffbec40 0x400d49d2:0x3ffbec60 0x400d472d:0x3ffbeed0 0x400d483e:0x3ffbef00 0x400d6c31:0x3ffbef20 0x400d7ece:0x3ffbef80 0x400d8406:0x3ffbf000 0x4008139e:0x3ffbf070 0x400d93f5:0x3ffbf0d0 0x40084a8d:0x3ffbf0f0 0x40173c7f:0x3ffc78f0 0x400e82e9:0x3ffc7910 0x4008e417:0x3ffc7930
Core 0 register dump:
PC : 0x40090522 PS : 0x00060634 A0 : 0x8008fc1b A1 : 0x3ffb3290
A2 : 0x3ffbf108 A3 : 0x3ffb32ac A4 : 0x00060623 A5 : 0xb33fffff
A6 : 0x0000cdcd A7 : 0x0000abab A8 : 0x0000abab A9 : 0x0000abab
A10 : 0x3ffde770 A11 : 0x000000d0 A12 : 0x3ffc6948 A13 : 0xb33fffff
A14 : 0x00000001 A15 : 0x00000001 SAR : 0x00000011 EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x400896b0 LEND : 0x400896c6 LCOUNT : 0xffffffff
Backtrace:0x4009051f:0x3ffb32900x4008fc18:0x3ffb32d0 0x4008dd9c:0x3ffb32f0 0x401069c0:0x3ffb3330 0x40106d0e:0x3ffb3350 0x400f56bb:0x3ffb3370 0x400f5739:0x3ffb3390 0x400f812c:0x3ffb33b0 0x400f8211:0x3ffb33e0 0x40108557:0x3ffb3400 0x400f3f19:0x3ffb3420
ELF file SHA256: 0000000000000000
Rebooting...
ets Jul 29 2019 12:21:46
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1412
load:0x40078000,len:13400
load:0x40080400,len:3672
entry 0x400805f8
Connecting to ESP32Test
In general, interrupt handlers need to do as little as possible and return as quickly as possible. Doing too much or calling unsafe functions (which almost all functions will be) leads to programs crashing exactly the way you saw.
Interrupts, as the name indicates, interrupt whatever code is running and execute the interrupt's handler. The handler has no idea what state the code that was interrupted is in. It could easily be in an inconsistent state while it's performing a computation; calling it while it's in an inconsistent state is likely to corrupt memory or cause it to crash or behave erratically. Unless software is specifically designed to be called from an interrupt handler you must assume it's not safe to do so.
As you noticed, the ESP32 requires an interrupt handler to be marked with the IRAM_ATTR attribute - this tells the ESP32 to always keep this code in "Instruction RAM" so that it's always available to execute. The ESP32 isn't able to pull code in from flash storage on demand to service an interrupt. That means that not only does the interrupt handler have to be in IRAM, all functions it calls must be as well. IRAM is a scarce resource, so you want to use as little of it as possible - calling Telegram from an interrupt handler means that not only does all of the Telegram code need to be in IRAM but the entire TCP/IP network stack needs to be. Which also means you'd have to modify every single function in the TelegramBot and network stack to be declared IRAM_ATTR.
Obviously that's not going to work.
Unless you really know what you're doing, the safest way to code an interrupt handler is to set a flag variable indicating there's work to be done, store any data that needs to be saved for the work in other variables and return.
In your case it would look something like this:
volatile boolean should_send_telegram_message = false;
void IRAM_ATTR SendStatusMessage() {
if (millis() - StatusButtonLastInterrupt < minStatusMsgInterval)
return; //Prevent executing multiple times per button press or more frequent than required
should_send_telegram_message = true;
}
void loop() {
if(should_send_telegram_message) {
should_send_telegram_message = false;
String message = "Temperature Monitor Status\n\n";
message += "Internal temperature: " + String(DHT.temperature) + "C\n";
message += "Internal humidity: " + String(DHT.humidity) + "%\n";
//message += "System time: " + rtc.getDateTime(); // Causes ESP to crash and reset. Error: abort() was called at PC 0x40084cf7 on core 1
//TODO: Check WiFi is connected first - will need to connect when woken from sleep
bot.sendMessage(CHAT_ID, message, ""); // Causes ESP to crash and reset. Error: Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1).
StatusButtonLastInterrupt = millis();
}
// do other loop() stuff
}
The volatile attribute on should_send_telegram_message tells the compiler that this variable may unexpectedly have its value changed (as the interrupt handler may do) so that the compiler will avoid doing certain optimizations that depend on the variable not unexpectedly changing.

How to use custom pins for SPI on ESP32 (pico-v3-02)

I trying to use custom pins for SPI on the pico-mini-02 board. The board has esp32 (pico-v3-02). I'm using Arduino IDE (with arduino-esp32) and windows 10.
When I try to use the SPI example (multiple buses example), I'm getting Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled. error. I have decoded the exception backtrace
0x40080f31: __pinMode at C:\Users\newto\OneDrive\Documents\ArduinoData\packages\esp32\hardware\esp32\1.0.5\cores\esp32\esp32-hal-gpio.c line 115
0x400d0f3a: spiAttachSCK at C:\Users\newto\OneDrive\Documents\ArduinoData\packages\esp32\hardware\esp32\1.0.5\cores\esp32\esp32-hal-spi.c line 87
0x400d0db2: SPIClass::begin(signed char, signed char, signed char, signed char) at C:\Users\newto\OneDrive\Documents\ArduinoData\packages\esp32\hardware\esp32\1.0.5\libraries\SPI\src\SPI.cpp line 57
0x400d0c2b: setup() at C:\Users\newto\OneDrive\Documents\ArduinoData\packages\esp32\hardware\esp32\1.0.5\libraries\SPI\examples\SPI_Multiple_Buses/SPI_Multiple_Buses.ino line 67
0x400d190a: loopTask(void*) at C:\Users\newto\OneDrive\Documents\ArduinoData\packages\esp32\hardware\esp32\1.0.5\cores\esp32\main.cpp line 32
0x40085fa5: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143
The full error message:
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 271414342, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:10124
load:0x40080400,len:5856
entry 0x400806a8
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x40080f31 PS : 0x00060730 A0 : 0x800d0f3d A1 : 0x3ffb1f30
A2 : 0x0000000e A3 : 0x00000002 A4 : 0x3ffb8364 A5 : 0x00000001
A6 : 0x00000000 A7 : 0x00000004 A8 : 0x3f400674 A9 : 0xaaaaaaaa
A10 : 0xaaaaaaaa A11 : 0x00000030 A12 : 0x3ffb82cc A13 : 0x00000000
A14 : 0x00000000 A15 : 0x00000000 SAR : 0x00000009 EXCCAUSE: 0x0000001c
EXCVADDR: 0xaaaaaaaa LBEG : 0x400d1258 LEND : 0x400d1265 LCOUNT : 0x00000000
ELF file SHA256: 0000000000000000
Backtrace: 0x40080f31:0x3ffb1f30 0x400d0f3a:0x3ffb1f50 0x400d0db2:0x3ffb1f70 0x400d0c2b:0x3ffb1f90 0x400d190a:0x3ffb1fb0 0x40085fa5:0x3ffb1fd0
Rebooting...
ets Jul 29 2019 12:21:46
Any help would be appreciated.
The sketch:
/* The ESP32 has four SPi buses, however as of right now only two of
* them are available to use, HSPI and VSPI. Simply using the SPI API
* as illustrated in Arduino examples will use VSPI, leaving HSPI unused.
*
* However if we simply intialise two instance of the SPI class for both
* of these buses both can be used. However when just using these the Arduino
* way only will actually be outputting at a time.
*
* Logic analyser capture is in the same folder as this example as
* "multiple_bus_output.png"
*
* created 30/04/2018 by Alistair Symonds
*/
#include <SPI.h>
// Define ALTERNATE_PINS to use non-standard GPIO pins for SPI bus
#ifdef ALTERNATE_PINS
#define VSPI_MISO 2
#define VSPI_MOSI 4
#define VSPI_SCLK 0
#define VSPI_SS 33
#define HSPI_MISO 26
#define HSPI_MOSI 27
#define HSPI_SCLK 25
#define HSPI_SS 32
#else
#define VSPI_MISO MISO
#define VSPI_MOSI MOSI
#define VSPI_SCLK SCK
#define VSPI_SS SS
#define HSPI_MISO 12
#define HSPI_MOSI 13
#define HSPI_SCLK 14
#define HSPI_SS 15
#endif
static const int spiClk = 1000000; // 1 MHz
//uninitalised pointers to SPI objects
SPIClass * vspi = NULL;
SPIClass * hspi = NULL;
void setup() {
//initialise two instances of the SPIClass attached to VSPI and HSPI respectively
vspi = new SPIClass(VSPI);
hspi = new SPIClass(HSPI);
//clock miso mosi ss
#ifndef ALTERNATE_PINS
//initialise vspi with default pins
//SCLK = 18, MISO = 19, MOSI = 23, SS = 5
vspi->begin();
#else
//alternatively route through GPIO pins of your choice
vspi->begin(VSPI_SCLK, VSPI_MISO, VSPI_MOSI, VSPI_SS); //SCLK, MISO, MOSI, SS
#endif
#ifndef ALTERNATE_PINS
//initialise hspi with default pins
//SCLK = 14, MISO = 12, MOSI = 13, SS = 15
hspi->begin();
#else
//alternatively route through GPIO pins
hspi->begin(HSPI_SCLK, HSPI_MISO, HSPI_MOSI, HSPI_SS); //SCLK, MISO, MOSI, SS
#endif
//set up slave select pins as outputs as the Arduino API
//doesn't handle automatically pulling SS low
pinMode(VSPI_SS, OUTPUT); //VSPI SS
pinMode(HSPI_SS, OUTPUT); //HSPI SS
}
// the loop function runs over and over again until power down or reset
void loop() {
//use the SPI buses
vspiCommand();
hspiCommand();
delay(100);
}
void vspiCommand() {
byte data = 0b01010101; // junk data to illustrate usage
//use it as you would the regular arduino SPI API
vspi->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0));
digitalWrite(VSPI_SS, LOW); //pull SS slow to prep other end for transfer
vspi->transfer(data);
digitalWrite(VSPI_SS, HIGH); //pull ss high to signify end of data transfer
vspi->endTransaction();
}
void hspiCommand() {
byte stuff = 0b11001100;
hspi->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0));
digitalWrite(HSPI_SS, LOW);
hspi->transfer(stuff);
digitalWrite(HSPI_SS, HIGH);
hspi->endTransaction();
}
Hi Mate I tried the code and it works. I have selected AI Thinker ESP32 that matches my board,and I have selected Flash Mode QIO and also DIO: both working fine. If you may still have the issue I would suggest to select DOUT or DIO.
Basically please check if your board matches the one selected on Tools->Board and check also the selection of 'Flash mode'.
Not all chips support all of these modes. The datasheet is the best source to know what supports what.
DIO - SPI host uses the "Dual I/O Fast Read" command (BBh). Two SPI pins are used to write the flash address part of the command, and to read flash data out. Therefore these phases need half the clock cycles compared to standard SPI.
DOUT - SPI host uses the "Dual Output Fast Read" command (3Bh). Two SPI pins are used to read flash data out. Slightly slower than DIO, because the address is written via the single MOSI data pin.
QIO - SPI host uses the "Quad I/O Fast Read" command (EBh). Four SPI pins are used to write the flash address part of the command, and to read flash data out. Therefore these phases need a quarter the clock cycles compared to standard SPI.
QOUT - SPI host uses the "Quad Output Fast Read" command (6Bh). Four SPI pins are used to read the flash data out. Slightly slower than QIO, because the address is written via the single MOSI data pin.
ESP-IDF defaults to DIO because some flash chips use a mode bit to enable QIO & QOUT support, and this can vary between manufacturers.
If using DIO/DOUT mode, GPIOs 9 & 10 are available for other uses. However note that if they are wired to the SPI flash chip (as they are in WROOM, for example) then the SPI flash chip may use them for other pin functions. Consult the SPI flash chip data sheet to be sure.
Very interesting discussion on this subject here: https://www.esp32.com/viewtopic.php?t=1250
Hope this helps. All the best.

I am getting this watchdog Timer error while doing a simple task in arduino with esp32

i have seen a lot of forums where this problem is dicussed but nothing seems to work. I am working with esp32 and it was all fine untill out of nowhere this watch dog timer error came up. I am new to it so i cant really fix this.
I have another code but i copied a very simple chunk of it and created a new file but watch dog timer error is appearing here too. I dont know what the issue.
it said idle0 is not resetting watach dog timer and "wifi" task is running on cpu0.
ERROR LOG
E (42418) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (42418) task_wdt: - IDLE0 (CPU 0)
E (42418) task_wdt: Tasks currently running:
E (42418) task_wdt: CPU 0: wifi
E (42418) task_wdt: CPU 1: IDLE1
E (42418) task_wdt: Aborting.
abort() was called at PC 0x400d96f7 on core 0
Backtrace: 0x4008c470:0x3ffbe270 0x4008c6a1:0x3ffbe290 0x400d96f7:0x3ffbe2b0 0x400815dd:0x3ffbe2d0 0x40136087:0x00000000
Rebooting...
ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1100
load:0x40078000,len:10088
load:0x40080400,len:6380
entry 0x400806a4
I have tried running my task on cpu1 or core 1 too but wifi is automatically running on cpu or core0. And getting the same error.
have also tried adding delays but nothing works.
char *wssid = "PTCL-TB";
char *wpassword = "pakistan";
bool connected2Wifi = false;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
delay(10);
Serial.println('\n');
WiFi.begin(wssid, wpassword); // Connect to the network
Serial.print("Connecting to ");
Serial.print(wssid);
while (WiFi.status() != WL_CONNECTED) { // Wait for the Wi-Fi to connect
delay(500);
Serial.print('.');
}
Serial.println('\n');
Serial.println("Connection established!");
Serial.print("IP address:\t");
Serial.println(WiFi.localIP());
}
void loop() {
// put your main code here, to run repeatedly:
} ```
I want to connect to wifi in this task. It's very simple and i have also copied it from a reliable source whose code was running. but the error seems to be rigid.
Go to Tools -> CPU Frequency and set it to 160, 80 or 240 MHz (the ones that support WiFi/BT).

Error on sending AT+CWJAP_DEF commands to ESP8266

I am trying to send AT commands to ESP8266 to get connected with internet with the Wifi.
When I am sending AT and AT+RST command on serial monitor then I am getting OK and ready response which seems perfect.
Then I am sending AT+CWLAP to get list of available wifi networks which is also executing correctly.
AT+CWLAP
+CWLAP:(3,"Moto",-42,"a4:70:d6:7a:fa:6c",1,25,0)
+CWLAP:(4,"PRANJAL",-95,"1c:a5:32:3d:f5:c4",1,-16,0)
+CWLAP:(2,"VIHAN",-94,"c8:3a:35:2f:1d:81",1,-21,0)
+CWLAP:(3,"Tenda",-93,"c8:3a:35:20:a9:b1",9,-4,0)
OK
Then I sent AT+CWMODE? which is also perfect.
AT+CWMODE?
+CWMODE:1
OK
Now I am trying to connect ESP8266 with above listed Wifi with this command, it is sending an ERROR on serial monitor.
AT+CWJAP_DEF="Moto","reset1234"
Error
⸮=IRe"Moto","reset1234"
ERROR
Can anyone suggest me what could be the reason of this issue ?
#include "SoftwareSerial.h"
SoftwareSerial esp8266(2, 3); // RX, TX
void setup()
{
Serial.begin(9600); // serial port used for debugging
esp8266.begin(9600); // your ESP's baud rate might be different
}
void loop()
{
if(esp8266.available()) // check if the ESP is sending a message
{
while(esp8266.available())
{
char c = esp8266.read(); // read the next character.
Serial.write(c); // writes data to the serial monitor
}
}
if(Serial.available())
{
delay(10); // wait to let all the input command in the serial buffer
// read the input command in a string
String cmd = "";
while(Serial.available())
{
cmd += (char)Serial.read();
}
// send to the esp8266
esp8266.println(cmd);
}
}
The current official AT command set seems to be documented on https://github.com/espressif/ESP8266_AT/wiki/AT_Description
http://espressif.com/sites/default/files/documentation/4a-esp8266_at_instruction_set_en.pdf
https://www.itead.cc/wiki/ESP8266_Serial_WIFI_Module#AT_Commands
If the module is to be configured as a client, i.e. to connect to an access point, the following AT commands have to be sent (11500 baud 8N1, CR-LF line termination):
AT+RST
AT+CWMODE=3 (1 is "Station" only (wifi client), 3 is mixed mode "Station and Access-Point", both should work)
AT+CWJAP="Moto","reset1234"
AT+CWJAP_CUR="Moto","reset1234" (temporary) or
AT+CWJAP_DEF="Moto","reset1234" (stored)
For reference, a "success story" (ESP8266 module with USB-UART, Software: HTerm, Access Point with WPA2 (both TKIP / CCMP tested)):
AT<\r><\r><\n><\r><\n>
OK<\r><\n>
AT+RST<\r><\r><\n><\r><\n>
OK<\r><\n>
<\r><\n>
ets Jan 8 2013,rst cause:2, boot mode:(3,6)<\r><\n>
<\r><\n>
load 0x40100000, len 1856, room 16 <\r><\n>
tail 0<\r><\n>
chksum 0x63<\r><\n>
load 0x3ffe8000, len 776, room 8 <\r><\n>
tail 0<\r><\n>
chksum 0x02<\r><\n>
load 0x3ffe8310, len 552, room 8 <\r><\n>
tail 0<\r><\n>
chksum 0x79<\r><\n>
csum 0x79<\r><\n>
<\r><\n>
2nd boot version : 1.5<\r><\n>
SPI Speed : 40MHz<\r><\n>
SPI Mode : DIO<\r><\n>
SPI Flash Size & Map: 32Mbit(512KB+512KB)<\r><\n>
jump to run user1 # 1000<\r><\n>
<\r><\n>
??r?d?l<18>?<31><\0><\f>?l`<3>??s?l?<28>?<19>?<4><4><4>$ <2>??r?$<4>??<27>?<4><4>ll`<3>r$?<18>?"<\0>????"<4>l?cs|<\f>?`?22???<27>BB<18>c??o??<18>NN?<16><2><\0><2>d$??<2>d??<\0>?<4>d??<\0>ll????d??l`<2>?<2>N?<\0>????"<4>d??<28>p<4><4><2><2>???"b<4>$<4>?"prlrl<\r><\n>
Ai-Thinker Technology Co. Ltd.<\r><\n>
<\r><\n>
ready<\r><\n>
WIFI DISCONNECT<\r><\n>
AT+CWMODE?<\r><\r><\n>+CWMODE:3<\r><\n>
<\r><\n>
OK<\r><\n>
AT+CWJAP_CUR="Moto","reset1234"<\r><\r><\n>
WIFI CONNECTED<\r><\n>
WIFI GOT IP<\r><\n>
<\r><\n>
OK<\r><\n>
AT+CIFSR<\r><\r><\n>+CIFSR:APIP,"0.0.0.0"<\r><\n>
+CIFSR:APMAC,"00:00:00:00:00:00"<\r><\n>
+CIFSR:STAIP,"0.0.0.0"<\r><\n>
+CIFSR:STAMAC,"00:00:00:00:00:00"<\r><\n>
<\r><\n>
OK<\r><\n>
AT+GMR<\r><\r><\n>AT version:1.1.0.0(May 11 2016 18:09:56)<\r><\n>
SDK version:1.5.4(baaeaebb)<\r><\n>
Ai-Thinker Technology Co. Ltd.<\r><\n>
Jun 13 2016 11:29:20<\r><\n>
OK<\r><\n>
This also works with mode=1.
Major rewrite.
Questions and ideas to test:
what is your module firmware version?
access point issues (e.g. MAC address restrictions)?
power supply good?
might there be any old configuration or other code running on the module?
what is the byte code of ⸮ in the error message - Is it two bytes 0x2E2E?
are you using the Arduino serial monitor for communication?
in contrast to my comment, maybe the arduino does have an influence (timing?). Try to rule this out by
doing the pass-through character-based instead of line-based, e.g.:
(end of list, no code possible otherwise:)
loop(){
if( esp8266.available() )
Serial.write(esp8266.read());
if( Serial.available() )
esp8266.write(Serial.read());
}
keeping the AVR in reset and connecting the ESP8266 serial lines directly to the USB-UART converter
Alright! I just tried to connect with different wifi and it got connected with it. It was some kinda issue with mobile hotspot.

Interfacing with SparkFun mpu-6050 with a Texas Instruments TM4C123G LaunchPad

I am trying to interface with the MPU-6050 as part of a robotics project using the Texas Instruments TM4C123G LaunchPad. I am uploading code onto this from Energia and am using the serial monitor to see the raw data output, however I am only receiving the following output when I upload it to the micro controller and run it:
Initialising I2C devices...
Here is the code that I am trying to run:
#include <Wire.h>
#include <I2Cdev.h>
#include <MPU6050.h>
MPU6050 accelgyro;
void Setup_MPU6050()
{
Wire.begin();
Serial.println("Initialising I2C devices...");
accelgyro.initialize();
Serial.println("Testing device connections...");
Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
}
void Update_MPU6050()
{
int16_t ax, ay, az;
int16_t gx, gy, gz;
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
Serial.print("i");Serial.print("\t");
Serial.print(ax);Serial.print("\t");
Serial.print(ay);Serial.print("\t");
Serial.print(az);Serial.print("\t");
Serial.print(gx);Serial.print("\t");
Serial.print(gy);Serial.print("\t");
Serial.println(gz);
Serial.print("\n");
}
void setup()
{
Serial.begin(115200);
Setup_MPU6050();
}
void loop()
{
Update_MPU6050();
}
The pins on the breakout board are connected to the Launchpad as follows:
VDD -> Pin 1 (3.3v)
GND -> Pin 12 (GND)
INT -> Pin 34 (PF0)
FSYNC -> None
SCL -> Pin 13 (PD0)
SDA - > Pin 14 (PD1)
VIO -> None
CLK -> None
ASCL -> None
ASDA -> None
I have got the MPU6050 and I2Cdev libraries from GitHub and have got the Wire library from github.com/codebendercc/arduino-library-files/blob/master/libraries/Wire/Wire.h but am thinking that either the wire.begin() or accelgyro.initialize() methods are not functioning properly? I am a relative beginner when it comes to programming in this language but I am undertaking an ambitious task to create a robot for a scholarship that I am applying for, and would therefore appreciate some assistance on this subject area.
I just met the same question as you. Here is a useful linkage:
enter link description here
I referred it and added some code before
Wire.begin()
--just like this
enter image description here
then I upload it and run, it works perfectly. And there is another thing to be minded that you can't connect INT pin when you don't use DMP but when you use DMP then you must connect INT pin.
I try to explain it.
Why should we add the two lines codes? The Library is from Arduino, although Energia is compatible with Arduino programming in most cases but not always. So we should explictly acclaim something.
And why should we pay attention the interruption. Because when we use DMP we use it, if we don't connect the INT pin, it willn't work normally.

Resources