我正在try 编写一个在ESP32上运行的带有中断的代码,但我总是得到一个大师冥想

Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1). Core 1 register dump: 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 LEND : 0x40089c19 LCOUNT : 0xfffffffc
Core 1 was running in ISR context: EPC1 : 0x400dffeb EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x00000000 Backtrace:0x4008e6b1:0x3ffbefac |<-CORRUPTED Core 0 register dump: PC : 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&amp;19获得外部触发器时(我知道插针19的中断部分都被注释了),变量MainLoop改变它的值以访问主循环的特定部分.

感谢那些能看到我的问题的人.晚安.

推荐答案

您的代码至少存在两个主要问题.

首先,必须使用属性IRAM_ATTR定义中断处理程序.这迫使系统将它们保存在内存中.由于中断处理程序对时间非常敏感,因此系统无法像读取其他代码那样按需从闪存中读取它们.

所以

void HallEffectSensor(){

应该是

void IRAM_ATTR HallEffectSensor(){

void LimitSwitches(){

应该是

void IRAM_ATTR LimitSwitches(){

Second, you're doing way too much work in the interrupt h和lers.

Interrupts do exactly what they're called. They interrupt the flow of your code - unpredictably. That means they can interrupt your code while it's manipulating a data structure or while it's controlling hardware, 和 the data structure or the hardware controller can be in an inconsistent state when the interrupt h和ler runs. Or the interrupt h和ler can change the state in between instructions elsewhere in your program without that being known.

It's also important that interrupt h和lers return as quickly as possible so that other interrupts can be h和led.

Your interrupt h和ler HallEffectSensor() calls esp_now_send(), which is almost guaranteed to crash the system. It can easily enter the ESP-NOW protocol stack while it's already running. You can't know what the implementation of esp_now_send() is; unless ESP-IDF explicitly says it's safe to call from an interrupt h和ler you must not call it from one unless you really want your program to crash.

Likewise your interrupt h和ler LimitSwitches() calls SensorN17.getCumulativePosition() which is also almost certainly not safe to call from an interrupt h和ler.

Instead, unless you really know what you're doing, you should have each interrupt h和ler set a volatile boolean variable to true to indicate that the interrupt happened, then in loop() check if the variable is true 和 do the work there. There are more sophisticated ways to do this but none of them involve calling these functions from the actual interrupt h和ler.

您的程序中可能还有其他问题,但除非您解决这些问题,否则它肯定不会可靠地运行.

C++相关问答推荐

根据工具链文件中的定义替换单个函数定义

数组元素的编号索引

是否可以在C中进行D3 D12申请?

如何创建由符号组成的垂直结果图形?

数据包未从DPDK端口传输到内核端口

为什么C语言允许你使用var =(struct NAME){

我无法让LLDB正确运行我的可执行文件

具有交换链获取和命令缓冲区提交的同步-危险-读后写错误

获取每个循环迭代结束时的当前时间

为什么memcpy进入缓冲区和指向缓冲区的指针工作相同?

为什么用非常数指针变量改变常量静态变量时会出现分段错误?

处理来自浏览器的HTTP请求

C代码可以在在线编译器上运行,但不能在Leetcode上运行

为什么GCC-O1优化破解了这个代码,为了一个GameBoy高级只读存储器而修改了VRAM的循环?

程序如何解释变量中的值

我编写这段代码是为了判断一个数字是质数、阿姆斯特朗还是完全数,但由于某种原因,当我使用大数时,它不会打印出来

RISC-V GCC编译器错误编译ASM代码

在C中使用字符串时是否不需要内存分配?

通过修改c中的合并排序对数组的偶数索引进行排序

int 与 size_t 与 long