Using this guide (Build the Muffsy Relay Input Selector - Muffsy Phono Kits) I built a ESP32 based relay switch selector using the "ESP-WROOM-32" specifically I just modified the code that was provided a bit to incorporate an LCD screen to Display the selected input. I will say I am a bit of a novice so any help will be greatly appreciated ! When turning the rotary encoder too many times it present me with this crash in the serial monitor:
Rotational encoder turned clockwise
E (18906) timer_group: timer_enable_intr(382): HW TIMER NEVER INIT ERROR
E (18906) timer_group: timer_get_config(329): HW TIMER NEVER INIT ERROR
E (18907) timer_group: timer_get_alarm_value(167): HW TIMER NEVER INIT ERROR
E (18914) timer_group: timer_isr_callback_add(227): HW TIMER NEVER INIT ERROR
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x40081652 PS : 0x00060033 A0 : 0x400846e4 A1 : 0x3ffbef4c
A2 : 0x3ffb8ee8 A3 : 0x3ffbdcb4 A4 : 0x00000000 A5 : 0x400880f0
A6 : 0x00000003 A7 : 0x00060c23 A8 : 0x00000001 A9 : 0x3ffbef0c
A10 : 0x00000001 A11 : 0x3ffc1c08 A12 : 0x3ffc1c0c A13 : 0x00060023
A14 : 0x00060021 A15 : 0x00000001 SAR : 0x00000020 EXCCAUSE: 0x0000001c
EXCVADDR: 0x000000a1 LBEG : 0x400861a4 LEND : 0x400861af LCOUNT : 0xffffffff
Backtrace:0x4008164f:0x3ffbef4c |<-CORRUPTED
ELF file SHA256: 0000000000000000
Rebooting...
ets Jun 8 2016 00:22:57
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:1344
load:0x40078000,len:13516
load:0x40080400,len:3604
entry 0x400805f0
I will also include the code to help with finding the issue, I do apologize if the formatting of this post is off.
/* Relay Input Selector
*
* Control relays using IR and rotary encoder
* Control external power to amp using IR and push button
*
*/
/*
* powerState:
*
* 0: Boot
* powerOn()
* startup procedure
* read NVRAM (relayCount)
* set relays to off (previousRelay = relayCount)
* set power amp to off, SSR = LOW
*
* 1: Powered ON
* turn on power button LED
* set power amp to on, SSR = HIGH
* trigger relayOn(): previousRelay = relayCount + 1
* rotaryEncoder()
* increases or decreases relayCount depending on rotational direction
* pushbutton: Power ON/OFF
* does only Power ON if powerState == 2
* irRemote()
* input up/down
* input direct (buttons 1-5)
* power on/off
* does only Power ON if powerState == 2
* relayOn()
* activates relays based on the relayCount
* handles relayCount too high or low
* powerControl()
* read power button, set powerState accordingly
*
* 2: Powered OFF
* turn off all relays
* set power amp to off (SSR = LOW)
* powerControl()
* read power button, set powerState == 1 if pushed
* irRemote()
* read power button, set powerState == 1 if pushed
*/
// Libraries
#include <IRremote.h> // IR Remote Library
#include <EEPROM.h> // EEPROM Library
#include <Wire.h> // I2C Connection
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);//Setting LCD up
// Size: 1 (relayCount)
#define EEPROM_SIZE 1
// Variables, pin definitions
// Onboard LED/Power LED
#define LED 2
// IR Receiver pin and setup
#define IR_Recv 36
IRrecv irrecv(IR_Recv);
decode_results results;
// Power button
#define poweronButton 5
// Pins for the rotary encoder:
#define rotaryA 35 // DT
#define rotaryB 34 // CLK
// Relays
#define R1 16
#define R2 12
#define R3 27
#define R4 33
#define R5 32
//Solid State Relay
#define SSR 17
// Mute LED
#define muteLed 4
// Rotary Encoder variables
int counter = 0;
int previous = 0;
int aState;
int aPreviousState;
// Relay Array
int relays[] = {16, 12, 27, 33, 32};
// Relay variables
int relayCount;
int previousRelay;
int relayNumber;
// Power/Mute variables
int powerState;
int buttonState = 1; // the current reading from the input pin
int lastButtonState = 1; // the previous reading from the input pin
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers
int mute = 0; // Mute on/off (1/0)
// Setup
void setup() {
// Initializing LCD
lcd.init();
// Clearing anything on the LCD
lcd.clear();
// Power button
pinMode (poweronButton,INPUT_PULLUP);
// Onboard LED
pinMode (LED,OUTPUT);
// Mute LED
pinMode (muteLed,OUTPUT);
// Rotary Encoder
pinMode (rotaryA,INPUT);
pinMode (rotaryB,INPUT);
// Reads the initial state of the rotaryA
aPreviousState = digitalRead(rotaryA);
// Relays
pinMode (R1,OUTPUT);
pinMode (R2,OUTPUT);
pinMode (R3,OUTPUT);
pinMode (R4,OUTPUT);
pinMode (R5,OUTPUT);
pinMode (SSR,OUTPUT);
// Relay variables
EEPROM.begin(EEPROM_SIZE);
relayCount = EEPROM.read(0);
previousRelay = relayCount + 1; // Start out not matching relayCount???
//Start the IR Receiver
pinMode(IR_Recv, INPUT_PULLDOWN);
irrecv.enableIRIn(true); // Starts the receiver
/*
* powerStates:
* 0: Powering on
* 1: Powered on
* 2: Powered off
*/
powerState = 0;
mute = 0; // Mute on/off (1/0)
// Serial monitor
Serial.begin (115200);
}
/*
* Main program
*/
void loop() {
if (powerState == 0) {
powerOn();
} else if (powerState == 1){
relayOn();
rotaryEncoder();// Include Push = MUTE
LCD(); //Display input source
//lcd.backlight();
powerControl(); // Read power button
irRemote(); // Up, Down, Direct, Volume, MUTE, Power
} else {
rotaryEncoder(); // Rotary push button is temporarily power button???
powerControl(); // Read power button
irRemote(); // Power on/off only
}
}
/*
* Turn on current relay
*/
void relayOn() {
// If relayCount has changed: Turn on the selected relay (next, previous, direct)
// If previousRelay has changed: Turn on the last selected relay
if (relayCount != previousRelay) {
// Rollover 3 or 0
if (relayCount > 3) {
relayCount = 0;
} else if (relayCount < 0) {
relayCount = 3;
}
// Turn off all relays, then turn on relayCount
relayOff();
digitalWrite(relays[relayCount], HIGH);
// Stop IR, write relayCount to memory, start IR
irrecv.enableIRIn(false);
EEPROM.write(0,relayCount);
EEPROM.commit();
irrecv.enableIRIn(true);
Serial.print(" Written \"relayCount = ");
Serial.print(relayCount);
Serial.println("\" to save slot 0");
// Reset counters, output relayNumber
previousRelay = relayCount;
relayNumber = relayCount + 1;
Serial.print("Activated relay #");
Serial.println(relayNumber);
Serial.println();
// If circuit is muted, unmute
if (mute == 1) {
digitalWrite(muteLed,HIGH);
Serial.println("Waiting 1.5 seconds before turning off mute");
delay(1500);
toggleMute();
}
}
}
/*
* Power on amplifier
*/
void powerOn() { // Only called if powerState is 0 (Powering on)
Serial.println("The Relay Input Selector has woken up!\n");
Serial.print(" ** Reading saved relay state from NVRAM: ");
Serial.println(relayCount);
digitalWrite(relays[4],LOW);
mute = 1;
Serial.println("\n ** Mute Relay turned ON");
Serial.println(" ** All input relays are turned OFF");
relayOff();
Serial.println(" ** Solid State Relay is turned OFF\n");
digitalWrite (SSR,LOW);
Serial.println(" ** Startup completed - waiting for Power ON\n");
Serial.println(" -------------------------\n");
// Set powerState to 2 (Powered off):
powerState = 2;
}
/*
* Read powerbutton, turn on or off
*/
void toggleMute() {
if (mute == 0) {
Serial.println(" Mute relay turned ON\n");
digitalWrite(relays[4],LOW);
if (powerState == 1){
digitalWrite(muteLed,HIGH);
}
mute = 1;
} else {
Serial.println(" Mute relay turned OFF\n");
digitalWrite(relays[4],HIGH);
digitalWrite(muteLed,LOW);
mute = 0;
}
}
/*
* Read powerbutton, turn on or off
*/
void powerControl() {
int reading = digitalRead(poweronButton);
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer than the debounce
// delay, so take it as the actual current state:
// if the button state has changed:
if (reading != buttonState) {
buttonState = reading;
// only toggle the LED if the new button state is HIGH
if (buttonState == 1) {
Serial.println(" Power button pushed");
if (powerState == 1) { // Turning power OFF: All relays OFF, power amp OFF
powerState = 2;
digitalWrite (SSR,LOW);
digitalWrite (LED,LOW);
lcd.noBacklight();
relayOff();
if (mute == 0) {
toggleMute();
}
Serial.println(" Solid State Relay OFF");
Serial.println(" Power OFF\n");
} else if (powerState == 2) { // Turning power ON: Last selected relay ON, power amp ON
powerState = 1;
digitalWrite (SSR,HIGH);
lcd.backlight();
digitalWrite (LED,HIGH);
previousRelay = relayCount + 1; // Trigger relayOn()
Serial.println(" Power ON");
Serial.println(" Solid State Relay ON\n");
}
}
}
}
lastButtonState = reading;
}
/*
* IR Remote
*/
void irRemote() { // Start irRemote function
// Decode the infrared input
// Decodes the infrared input
if (irrecv.decode(&results)) {
long int decCode = results.value;
Serial.print(" Received IR code: ");
Serial.print(decCode);
Serial.println();
// Switch case to use the selected remote control button
switch (results.value) { // Start switch/case
case 16724175: // Relay 1
{
Serial.println(" Button \"1\"");
if (powerState == 1) {
relayCount = 0;
} else {
Serial.println(" Powered off, doing nothing...\n");
}
break;
}
case 16718055: // Relay 2
{
Serial.println(" Button \"2\"");
if (powerState == 1) {
relayCount = 1;
} else {
Serial.println(" Powered off, doing nothing...\n");
}
break;
}
case 16743045: // Relay 3
{
Serial.println(" Button \"3\"");
if (powerState == 1) {
relayCount = 2;
} else {
Serial.println(" Powered off, doing nothing...\n");
}
break;
}
case 16716015: // Relay 4
{
Serial.println(" Button \"4\"");
if (powerState == 1) {
relayCount = 3;
} else {
Serial.println(" Powered off, doing nothing...\n");
}
break;
}
case 16769565: // Mute
{
Serial.println(" Button \"Mute\"");
if (powerState == 1) {
toggleMute();
} else {
Serial.println(" Powered off, doing nothing...\n");
}
break;
}
case 16748655: // Channel UP
{
Serial.println(" Button \"UP\"");
if (powerState == 1) {
relayCount++;
} else {
Serial.println(" Powered off, doing nothing...\n");
}
break;
}
case 16754775: // Channel DOWN
{
Serial.println(" Button \"DOWN\"");
if (powerState == 1) {
relayCount--;
} else {
Serial.println(" Powered off, doing nothing...\n");
};
break;
}
case 16753245: // Power button
{
Serial.println("Button \"POWER\"");
if (powerState == 1) {
powerState = 2;
digitalWrite (SSR,LOW);
digitalWrite (LED,LOW);
lcd.noBacklight();
relayOff();
if (mute == 0) {
toggleMute();
}
Serial.println(" Solid State Relay OFF");
Serial.println(" Power OFF\n");
} else {
powerState = 1;
digitalWrite (SSR,HIGH);
digitalWrite (LED,HIGH);
lcd.backlight();
previousRelay = relayCount + 1; // Trigger relayOn()
Serial.println(" Power ON");
Serial.println("Solid State Relay ON\n");
}
break;
}
default:
{
Serial.println("Going back to waiting for IR remote keypress\n");
}
} // End switch/case
irrecv.resume(); // Receives the next value from the button you press
}
} // End irRemote function
/*
* Mute (turn off all relays)
*/
void relayOff() {
for (int off = 0; off <= 3; off++) {
digitalWrite(relays[off], LOW);
}
}
void LCD(){
if (relayCount == 0){
// Serial.println("Bluetooth Input");
lcd.clear();
lcd.setCursor(4,0);
lcd.print("BLUETOOTH");
//delay(10);
}
if (relayCount == 1){
//Serial.println("Optical 1 Input ");
lcd.clear();
lcd.setCursor(7,0);
lcd.print("OPT1");
//delay(10);
}
if (relayCount == 2){
//Serial.println("Optical 2 Input ");
lcd.clear();
lcd.setCursor(7,0);
lcd.print("OPT2");
//delay(10);
}
if (relayCount == 3){
//Serial.println("RCA Input ");
lcd.clear();
lcd.setCursor(7,0);
lcd.print("RCA");
//delay(10);
}
}
/*
* Rotary Encoder Control of Relays
*/
void rotaryEncoder() {
aState = digitalRead(rotaryA); // Reads the "current" state of the rotaryA
// If the previous and the current state of the rotaryA are different, that means a Pulse has occured
if (aState != aPreviousState){
// If the rotaryB state is different to the rotaryA state, that means the encoder is rotating clockwise
if (digitalRead(rotaryB) != aState) {
counter ++;
} else {
counter --;
}
}
// What to do if rotating Right of Left
if (previous != counter) {
if (counter > 1) { // Since the encoder gives two signals when turning
Serial.print(" Rotational encoder turned ");
Serial.println("clockwise");
if (powerState == 1) {
// Increase relayCount
relayCount++;
} else {
Serial.println(" Powered off, doing nothing...\n"); // Powered off???
}
} else if (counter < -1) { // Since the encoder gives two signals when turning
Serial.print(" Rotational encoder turned ");
Serial.println("counter-clockwise");
if (powerState == 1) {
// Increase relayCount
relayCount--;
} else {
Serial.println("Powered off, doing nothing...\n"); // Powered off???
}
}
}
// Reset counters
previous = counter;
if (counter < -1) {
counter = 0;
previous = 0;
} else if (counter > 1){
counter = 0;
previous = 0;
}
// Updates the previous state of the rotaryA with the current state
aPreviousState = aState;
}