提问人:Vi Peeters 提问时间:4/30/2023 最后编辑:ndc85430Vi Peeters 更新时间:4/30/2023 访问量:566
我在 ESP32 上收到 Guru Meditation 错误
I'm getting a Guru Meditation error on an ESP32
问:
我正在尝试制作一个在 ESP32 上运行的带有中断的代码,但我总是得到一个 Guru Meditation
Guru Meditation 错误:核心 1 惊慌失措(CPU1 上的中断 wdt 超时)。 内核 1 寄存器转储: PC : 0x4008e6b4 PS : 0x00060c35 A0 : 0x8008d64e A1 : 0x3ffbefac A2 : 0x3ffb8a00 A3 : 0x3ffb8890 A4 : 0x00000004 A5 : 0x00060c23 A6 : 0x00060c23 A7 : 0x00000001 A8 : 0x3ffb8890 A9 : 0x00000018 A10 : 0x3ffb8890 A11 : 0x00000018 A12 : 0x3ffc42d4 A13 : 0x00060c23 A14 : 0x007bf158
A15 : 0x003fffff SAR: 0x0000000e EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x40089c09 借出 : 0x40089c19 LCOUNT : 0xfffffffc
核心 1 在 ISR 上下文中运行: EPC1 : 0x400dffeb EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x00000000 回溯:0x4008e6b1:0x3ffbefac |<-损坏 内核 0 寄存器转储: 聚碳酸酯 : 0x4008e833 PS : 0x00060035 A0 : 0x8008d277 A1 : 0x3ffbeaac A2 : 0x3ffbf158
A3
我使用的是Arduino IDE 2.1.0,因此无法使用异常解码器。这是我的代码,它仍在进行中。
#include <Wire.h>
#include <AS5600.h>
#include <WiFi.h>
#include <esp_now.h>
#define HES 19
#define LimitPins 18
#define TCA9548A_ADDR 0x70
#define N17AS5600 3
#define N23AS5600 2
#define AS5600_ADDR 0x36
volatile bool HESstate = true;
volatile bool LastHESState = true;
volatile int Count = 0;
volatile bool LimiteState = true;
volatile bool LastLimitState = true;
volatile bool N17Direction = false;
volatile int MainLoop = 1;
volatile int StartValue;
volatile int StopValue;
volatile int DistanceN17;
volatile long LastButtonPress = 0;
volatile bool FirstTimeN17 = false;
volatile bool HomeZeroN17 = false;
volatile bool GetTimeN17 = false;
volatile bool FirstTimeN23 = false;
volatile bool HomeZeroN23 = false;
int16_t Angle17;
int16_t Angle23;
int32_t Distance17;
int32_t Distance23;
int32_t OffsetD17;
int32_t OffsetD23;
AS5600 SensorN17;
AS5600 SensorN23;
uint8_t broadcastAddress[] = {0xC8, 0xF0, 0x9E, 0xA6, 0x08, 0xF0};
typedef struct struct_message {
int MSG;
} struct_message;
struct_message myData;
esp_now_peer_info_t peerInfo;
void TCA9548A(byte bus){
if(bus > 7) return;
Wire.beginTransmission(TCA9548A_ADDR);
Wire.write(1 << bus);
Wire.endTransmission();
}
void SetupInterrupts(){
pinMode(HES, INPUT_PULLUP);
attachInterrupt(HES, HallEffectSensor, FALLING);
pinMode(LimitPins, INPUT_PULLUP);
attachInterrupt(LimitPins, LimitSwitches, RISING);
}
void SetupTCA9548A(){
TCA9548A(N17AS5600);
SensorN17.begin(21, 22); // .begin(sda, scl) pour ESP32
TCA9548A(N23AS5600);
SensorN23.begin(21, 22); // .begin(sda, scl) pour ESP32
OffsetD23 = -1 * SensorN23.getCumulativePosition();
}
void SetupESP_NOW(){
WiFi.mode(WIFI_STA);
if(esp_now_init() != ESP_OK){
Serial.println("Error initializing ESP-NOW");
return;
}
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
if(esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
}
void setup() {
Serial.begin(9600);
Wire.begin();
SetupInterrupts();
SetupTCA9548A();
SetupESP_NOW();
delay(5000);
}
void loop() {
if(MainLoop == 1){
myData.MSG = 170; // 170: Nema17 va UP.
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
MainLoop = 11;
while(GetTimeN17){
Serial.print("Temps: ");
Serial.print(StopValue - StartValue);
Serial.print(" | Vitesse: ");
Serial.println(DistanceN17 / (StopValue - StartValue));
}
}
if(MainLoop == 2){
myData.MSG = 171; // 171: Nema17 va DOWN.
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
MainLoop = 22;
if(!FirstTimeN17){
StartValue = millis();
FirstTimeN17 = true;
}
}
if(MainLoop == 9){
myData.MSG = 179; // 170: Nema17 à l'arrêt.
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
MainLoop = 11;
if(!HomeZeroN17){
OffsetD17 = -1 * SensorN17.getCumulativePosition();
HomeZeroN17 = true;
MainLoop = 2;
}
}
//LastHESState = true;
LastLimitState = true;
}
void HallEffectSensor(){
/*if(LastHESState){
if(!N23Homed){
myData.MSG = 239; // 239: Nema23 à l'arrêt.
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
N23Homed = true;
}
//HESstate = !HESstate;
LastHESState = false;
}*/
}
void LimitSwitches(){
if(LastLimitState){
switch(MainLoop){
case 11:
MainLoop = 9;
case 22:
MainLoop = 1;
StopValue = millis();
DistanceN17 = SensorN17.getCumulativePosition();
GetTimeN17 = true;
default:
MainLoop = 0;
}
LastLimitState = false;
}
}
我尝试制作的代码是当我从引脚 18 和 19 获得外部触发器时,(我知道引脚 19 中断部分都已注释),变量 MainLoop 更改其值以访问主循环的某个部分。
感谢那些能看看我问题的人。晚安。
答:
您的代码至少存在两个主要问题。
首先,必须使用属性 定义中断处理程序。这会强制系统将它们保留在内存中。由于中断处理程序对时间非常敏感,因此系统无法像其他代码那样按需从闪存中读取它们。IRAM_ATTR
所以
void HallEffectSensor(){
应该是
void IRAM_ATTR HallEffectSensor(){
和
void LimitSwitches(){
应该是
void IRAM_ATTR LimitSwitches(){
其次,你在中断处理程序中做了太多的工作。
中断的作用与它们所称的完全相同。它们会以不可预测的方式中断您的代码流。这意味着它们可以在代码操作数据结构或控制硬件时中断代码,并且当中断处理程序运行时,数据结构或硬件控制器可能处于不一致状态。或者,中断处理程序可以在程序中其他位置的指令之间更改状态,而无需知道。
中断处理程序尽快返回也很重要,以便可以处理其他中断。
您的中断处理程序调用 ,这几乎可以保证使系统崩溃。它可以在运行时轻松进入 ESP-NOW 协议栈。你无法知道实现是什么;除非 ESP-IDF 明确表示从中断处理程序调用是安全的,否则您不能从中断处理程序调用它,除非您真的希望程序崩溃。HallEffectSensor()
esp_now_send()
esp_now_send()
同样,您的中断处理程序调用,从中断处理程序调用也几乎肯定是不安全的。LimitSwitches()
SensorN17.getCumulativePosition()
相反,除非你真的知道自己在做什么,否则你应该让每个中断处理程序设置一个变量来指示中断发生了,然后检查该变量是否存在并在那里执行工作。有更复杂的方法可以做到这一点,但它们都不涉及从实际的中断处理程序调用这些函数。volatile boolean
true
loop()
true
您的程序中可能存在其他问题,但除非您解决这些问题,否则它肯定无法可靠运行。
下一个:C.无法处理,我需要建议
评论