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.