PID speed control using ESP32 Error

I'm trying to implement PID speed control with esp32(Type c from Sparkfun). When I run the code with the line "currentRPM = computerpm();" uncommented and try to print the xValue received wirelessly , I get this error message

117
118
Guru Meditation Error: Core  1 panic'ed (Interrupt wdt timeout on CPU1). 

Core  1 register dump:
PC      : 0x400d41a4  PS      : 0x00060b35  A0      : 0x800d27b0  A1      : 0x3ffca580  
A2      : 0x00000002  A3      : 0x00000001  A4      : 0x0e4e1c00  A5      : 0x00000000  
A6      : 0x033ec68f  A7      : 0x00000001  A8      : 0x800d4c09  A9      : 0x3ffca560  
A10     : 0x00000002  A11     : 0x003fffff  A12     : 0x80083e03  A13     : 0x3ffca470  
A14     : 0x00000001  A15     : 0x3ffc8680  SAR     : 0x00000002  EXCCAUSE: 0x00000006  
EXCVADDR: 0x00000000  LBEG    : 0x400892e4  LEND    : 0x400892fa  LCOUNT  : 0xffffffff  




ELF file SHA256: b68223eb1c70c665

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:1184
load:0x40078000,len:13260
load:0x40080400,len:3028
entry 0x400805e4
118
119

I do get the data displayed like on top of the error message like "117,118" but I get that error after it. Can anyone point out the mistake i'm doing.

NOTE; I'm able to print the values correctly if I comment out the rpm calculation line. Here's the full code:

//ESP32 receiver side code
// Include Libraries
#include <esp_now.h>
#include <WiFi.h>

const int encoderPinA = 2;
const int pwmPin = 4;   
const int dirPin = 53;  // Motor DIR (Direction Control) pin

long int rps_Ton, rps_Toff;
float rps_time, rps;
int RPM, currentRPM;

bool interrupted;

unsigned long currentTime, previousTime;
double elapsedTime;

// PID declaration
double kp = 0.06;   //proportional gain
double ki = 0.1;    //integral gain
double kd = 0.082;  //derivative gain

double error;
double lastError;
double input, output;
int setPoint;
double cumError, rateError;

// Define a data structure
typedef struct struct_message {
  char a[32];
  int b;
  int c;
  int d;
} struct_message;

// Create a structured object
struct_message myData;


// Callback function executed when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
  memcpy(&myData, incomingData, sizeof(myData));
  //Serial.print("Character Value: ");
  //Serial.println(myData.a);
  //Serial.print("Vx Value: ");
  Serial.println(myData.b); //xValue
  //Serial.print("Vy Value: ");
  //Serial.println(myData.c);
  //Serial.print("Sw Value: ");
  //Serial.println(myData.d);
}

void setup() {
  // Set up Serial Monitor
  Serial.begin(115200);
  pinMode(encoderPinA, INPUT_PULLUP);
  pinMode(pwmPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(encoderPinA), encoder, RISING);
  // Set ESP32 as a Wi-Fi Station
  WiFi.mode(WIFI_STA);

  // Initilize ESP-NOW
  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  } 
  // Register callback function
  esp_now_register_recv_cb(OnDataRecv);
}
 
void loop() {
  setPoint = 50;
  currentRPM = computerpm();
  //output = computePID();
  //analogWrite(pwmPin, output);

  delay(5);
}

void encoder() {
  interrupted = true;
}

double computerpm() {
  noInterrupts();
  rps_Ton = pulseIn(encoderPinA, HIGH);  // calculate ON time of RPus pulse input
  rps_Toff = pulseIn(encoderPinA, LOW);  // calculate OFF time of RPus pulse input
  rps_time = rps_Ton + rps_Toff;         // calculate total time(microseconds)
  rps = rps_time / 1000;                 // calculate frequency that is RPms
  RPM = 60000 * (1 / (96 * rps));        // Update current RPM
  //Serial.print("currentRPM; ");
  //Serial.println(rps);

  interrupted = false;
  interrupts();
  return RPM;
}


double computePID() {
  currentTime = millis();                              //get current time
  elapsedTime = (double)(currentTime - previousTime);  //compute time elapsed from previous computation

  error = setPoint - currentRPM;                  // determine error
  cumError += error * elapsedTime;                // compute integral
  rateError = (error - lastError) / elapsedTime;  // compute derivative

  double out = kp * error + ki * cumError + kd * rateError;  //PID output

  lastError = error;           //remember current error
  previousTime = currentTime;  //remember current time

  return out;  //return PID output - PWM
//end of program
}

The reason may be because I'm doing long calculations inside the nointerupt(), but if I remove the noInterrupt() then my PID calculation is not smooth at high speeds, which I believe is caused by unstable rpm calculation.

I'm not sure but the reason of the reset may be the pulseIn() timeout.

Attention: interrupted must be volatile

BTW, I don't see you using that variable other than to set and reset it (?!)

My estimation is that the two calls to

in combination with noInterrupts()
take too much time because they have a looong timeout

You should replace using the pulseIn-function with using an interrupt to the rpm with code that measures the time between two pulses.

You should post an additional information about your project:
what is the highest rpm that can occur?

And it is always a good idea to give an overview about your project.
And describe the final purpose of controlling the rpm.

There is a good chance that the final purpose can be done in different ways.

best regards Stefan

So I'm trying to control the speed of dc motor using the joystick data received wirelessly from another esp32, in addition it is pid speed control. So could you give a sample code of what your approach would be to calculate the rpm without pulseIn function? Or any other alternative approach to achieve my final Objective? Highest rpm is around 550-600rpm

No I don't have such a code at hand.
Measuring rpm can be done with any library that measures frequency.

600 rpm means 600 / 60 = 10 rotations per second which is rather slow.
Should be doable with a lot of ESP32 frequency measuring libraries.

Google is always worth a 5 to 10 minute search
keywords are

github arduino ESP32 frequency measuring

best regards Stefan

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.