Error pada ESP32: Guru Meditation Error: Core 1 panic’ed (Interrupt wdt timeout on CPU1).

Salah satu pesan kesalahan yang dapat muncul pada ESP32 adalah “Guru Meditation Error: Core 1 panic’ed (Interrupt wdt timeout on CPU1)”. Salah satu penyebabnya adalah memanggil Serial.print() dari interupsi

Berikut ini pesan kesalahan yang muncul pada ESP32

Guru Meditation Error: Core  1 panic'ed (Interrupt wdt timeout on CPU1). 
 
Core  1 register dump:
 PC      : 0x4008ab86  PS      : 0x00060535  A0      : 0x80089afe  A1      : 0x3ffbf19c  
 A2      : 0x3ffbd448  A3      : 0x3ffbd2d8  A4      : 0x00000004  A5      : 0x00060523  
 A6      : 0x00060523  A7      : 0x00000001  A8      : 0x3ffbd2d8  A9      : 0x00000018  
 A10     : 0x3ffbd2d8  A11     : 0x00000018  A12     : 0x00000004  A13     : 0x00060523  
 A14     : 0x007bf318  A15     : 0x003fffff  SAR     : 0x0000000a  EXCCAUSE: 0x00000006  
 EXCVADDR: 0x00000000  LBEG    : 0x400863f9  LEND    : 0x40086409  LCOUNT  : 0xfffffffe  
 Core  1 was running in ISR context:
 EPC1    : 0x400db223  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x00000000
 
 
 Backtrace: 0x4008ab83:0x3ffbf19c |<-CORRUPTED
 
 
 Core  0 register dump:
 PC      : 0x4008ad1b  PS      : 0x00060035  A0      : 0x80089727  A1      : 0x3ffbea3c  
 A2      : 0x3ffbf318  A3      : 0xb33fffff  A4      : 0x0000abab  A5      : 0x00060023  
 A6      : 0x00060021  A7      : 0x0000cdcd  A8      : 0x0000abab  A9      : 0xffffffff  
 A10     : 0x3ffc1f58  A11     : 0x00000000  A12     : 0x3ffc1f54  A13     : 0x00000007  
 A14     : 0x007bf318  A15     : 0x003fffff  SAR     : 0x0000001d  EXCCAUSE: 0x00000006  
 EXCVADDR: 0x00000000  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000  
 
 
 Backtrace: 0x4008ad18:0x3ffbea3c |<-CORRUPTED
 
 
 
 
 ELF file SHA256: e85d33667e5fa1a7
 
 Rebooting...

Berikut ini contoh program yang menyebabkan kesalahan tersebut.

// https://www.arduino.cc/reference/en/libraries/esp32timerinterrupt/
#define LED_BUILTIN 22

hw_timer_t *My_timer = NULL;

int kerja_counter = 0;
int print_job = 0;
long int timer_delay = 1000000L;  // clock timer= 1 MHz

void IRAM_ATTR onTimer() {
  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
  kerja_counter++;
  Serial.print("Test ");
  Serial.println(kerja_counter); // bad practice
}

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  Serial.begin(115200);
  Serial.print(__FILE__);
  Serial.print(F("\nStarting TimerInterruptTest on "));
  Serial.println(ARDUINO_BOARD);
  Serial.print(F("CPU Frequency = "));
  Serial.print(F_CPU / 1000000);
  Serial.println(F(" MHz"));
  pinMode(LED_BUILTIN, OUTPUT);
  My_timer = timerBegin(0, 80, true);  // prescaler
  timerAttachInterrupt(My_timer, &onTimer, true);
  timerAlarmWrite(My_timer, timer_delay, true);
  timerAlarmEnable(My_timer);  //Just Enable
}

// the loop function runs over and over again forever
void loop() {
}

Solusi: Serial.print() dipanggil dari fungsi loop(), sedangkan interupsi hanya mempersiapkan datanya saja, atau menaruh data ke dalam suatu FIFO buffer.

Berikut ini contoh hasil modifikasi program di atas.

// https://www.arduino.cc/reference/en/libraries/esp32timerinterrupt/
#define LED_BUILTIN 22

hw_timer_t *My_timer = NULL;

int kerja_counter = 0;
int print_job = 0;
long int timer_delay = 1000000L;  // clock timer= 1 MHz

void IRAM_ATTR onTimer() {
  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
  kerja_counter++;
  print_job=1;
}

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  Serial.begin(115200);
  Serial.print(__FILE__);
  Serial.print(F("\nStarting TimerInterruptTest on "));
  Serial.println(ARDUINO_BOARD);
  Serial.print(F("CPU Frequency = "));
  Serial.print(F_CPU / 1000000);
  Serial.println(F(" MHz"));

  pinMode(LED_BUILTIN, OUTPUT);

  My_timer = timerBegin(0, 80, true);  // prescaler
  timerAttachInterrupt(My_timer, &onTimer, true);
  timerAlarmWrite(My_timer, timer_delay, true);
  timerAlarmEnable(My_timer);  //Just Enable
  sei();
}

// the loop function runs over and over again forever
void loop() {
  if (print_job == 1) {
    print_job = 0;
    Serial.print("Test ");
    Serial.println(kerja_counter);   
  }
}

Simulasi Kendali Digital

Simulasi Kendali Digital dengan Matlab Simulink

Problem: “Design the gain for the antenna azimuth position control system shown in
Figure 13.30(b) to yield a closed-loop damping ratio of 0.5. Assume a sampling interval
of T ˆ 0:1 second.”

Blok diagram sistem dengan simulink sebagai berikut:

Fungsi transfer sistem dimasukkan ke blok “Transfer Fcn”

Respon sistem terhadap input step adalah sebagai berikut

respon sistem kendali zoh

 

 

Transformasi Bilinear

Respon Frekuensi LPF orde 1

Percobaan melihat pengaruh frekuensi sampling terhadap fungsi transfer sistem orde 1 low pass

Fungsi transfer sistem = 1/(s+1)

Time constant = 1, sehingga frekuensi cut off adalah 0.159 Hz

Gambar ilustrasi fungsi transfer untuk filter analog dan filter digital.

Filter digital dicoba dengan beberapa frekuensi sampling: 10 Hz, 100 Hz, 1000 Hz

import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
%matplotlib inline

B = [0, 1]
A = [1, 1]

fs10= 10
fs100= 100
fs1000= 1000

fs10_z   = signal.bilinear(B,A,fs10)
fs100_z  = signal.bilinear(B,A,fs100)
fs1000_z = signal.bilinear(B,A,fs1000)

fs10_a  =fs10_z[1]
fs10_b  =fs10_z[0]

fs100_a =fs100_z[1]
fs100_b =fs100_z[0]

fs1000_a=fs1000_z[1]
fs1000_b=fs1000_z[0]
# displaying
plt.figure(figsize=(10, 8))
Om, fs10_Hd   = signal.freqz(fs10_b  , fs10_a, worN=1024)
f10 = Om * fs10 / (2 * np.pi)

Om, fs100_Hd  = signal.freqz(fs100_b , fs100_a, worN=2048)
f100 = Om * fs100 / (2 * np.pi)

Om, fs1000_Hd = signal.freqz(fs1000_b, fs1000_a, worN=16384) # 1000 Hz mesti lebih banyak sampelnya
f1000 = Om * fs1000 / (2 * np.pi)

tmp, H = signal.freqs(B, A, worN=f1000 * Om)
f = Om * f1000 / (2 * np.pi)

plt.semilogx(f, 20 * np.log10(np.abs(H)), label=r"$|H(j \omega)|$ of analog filter")
plt.semilogx(f10, 20 * np.log10(np.abs(fs10_Hd)), label=r"$|H_d(e^{j \Omega})|$ of digital filter 10")
plt.semilogx(f100, 20 * np.log10(np.abs(fs100_Hd)), label=r"$|H_d(e^{j \Omega})|$ of digital filter 100")
plt.semilogx(f1000, 20 * np.log10(np.abs(fs1000_Hd)), label=r"$|H_d(e^{j \Omega})|$ of digital filter 1000")
plt.semilogx(0.159, 20 * np.log10(0.707), marker='o',label="cutoff")
plt.axvline(x = 10/2,   linestyle="--", label = '5 Hz')
plt.axvline(x = 100/2,  linestyle="--", label = '50 Hz')
plt.axvline(x = 1000/2, linestyle="--", label = '500 Hz')
plt.xlabel(r"$f$ in Hz")
plt.ylabel(r"dB")
plt.axis([0.01, 600, -80, 3])
plt.legend()
plt.grid()
plt.savefig("first-order.jpg",dpi=200)
# https://www.geeksforgeeks.org/plot-a-vertical-line-in-matplotlib/

Analisis

  • frekuensi warping kelihatan di frekuensi yang makin dekat dengan 1/2 frekuensi sampling
  • frekuensi cut off tidak terpengaruh

Respon Step Low Pass Filter orde 1

LPF step response bilinear

Respon Frekuensi High Pass Filter orde 1

first order HPF frequency responseKesimpulan:

  • perubahan frekuensi sampling tidak mengubah banyak respon frekuensi filter

Respon Step High Pass Filter orde 1

first order HPF step responseKesimpulan:

  • perubahan frekuensi sampling tidak banyak mengubah bentuk sinyal, kecual pada fs = 10 Hz