Whats with the love of the ESP32?

The esp32 is a complicated device compared to an arduino uno. Transitioning to an esp32 is more than a step up, more like 5 steps. The arduino core tries to simplify using the board but it's still a 32 bit, full featured micro that uses a real time o.s. I guess what I am trying to say is that there is a learning curve associated with it. Also, that it has an built-in RTOS is one of its strengths.

My biggest problem is taking information I find on the Web as gospel and designing stuff around that. I must stop doing that.

I have found that more and more libraries and online content either are outdated, incorrect or just simply don't work.

I need to get the datasheets for the base components and design up from there. That webpage above for the ESP32 Wroom 32 is technically wrong then in the truth table, as that is two people who have had issues with pin 25.

Yet... if you look at the ESP32 datasheet, it doesn't show any issue with GPIO25. No idea why that occurs.

Yeahhhh, not so much!
There are a lot of people posting online who have no idea what they're talking about. I mean, I make mistakes from time to time, but at least what I say has some basis in reality.

I love it because of these:

  1. I have bunch of projects that needs running both WiFi and BLE stacks (Big Thanks to PSRAM) , ESP32 comes in play, pretty cheaper compared to standard Pi

  2. I have couple of few smart water dispensing devices on remote fields, and the software updates are done completely over the air, via a cellular modem (SIM800L) or locally via WiFi

  3. This web site here ( with bunch of pages in it with lots of encoded images and icons ) is hosted offline on the ESP32 with insane 16 MBytes flash on it

STM32 is in deed no match for ESP32

Well I have decided to abandon ESP32's... just causing me too much grief.

If I add a pair of interrupts for my rotary encoder, the ESP32 just constantly reboots.
Tried various pins, and it just continually loops at boot.

Might be a clash with the wire library apparently?
Bah

How do I implement a rotary encoder on these tempermental IC's?
This just constantly reboots. It appears to be constantly going straight to the interrupt routine even though the input pins are held high with INPUT_PULLUP and an external 10k.

I read you needed to use IRAM_ATTR for ESP32 interrupts? But this doesn't work at all.

Tried multiple input pins... same issue.

Code is now a mess with me faffing around with it.... Ignore all the font stuff, that is me trying various ideas.

The MCP23017 is working fine. Half operates some LEDS and the other half is 7x button inputs (because I didn't have enough pins).
The TFT screen also works fine

The issue is the interrupt. Comment out the interrupt setup line and it boots fine.

#include <Arduino.h>
#include <Adafruit_GFX.h>    // Core graphics library
#include <Wire.h>
#include <MCUFRIEND_kbv.h>   // Hardware-specific library
MCUFRIEND_kbv tft;

//------------------- Rotary encoder setup -------------------

#define rotary_encoder_A_pin 1
#define rotary_encoder_B_pin 3
#define rotary_encoder_button 39

//------------------------------------------------

byte Inputstate;                                                   // Value incoming from the MCP23017
byte OldInputstate;
byte Outputvalue;                                                  // Value to send to the MCP23017 to operate the LEDS

bool togglestate;                                                  // Switch logic
bool armkeystate;

byte xhome = 30;                                                   // Screen start position
byte yhome = 23;

byte mins = 0;                                                     // Timer values
byte secs = 0;
byte msecs = 0;
byte timesetstatus = 0;                                            // 0=off. 1=minutes. 2=seconds. 3=Milliseconds

byte Quadrant = 1;
int Quad_counter;                         //Counter for the comms sfx
int Quad_State;                           //Variables to read the comms rotary encoders
int Quad_LastState;

//----------------- FONTS ----------------------------------------------------------------------------------------------------------------------

#include <Fonts/basic_sans_serif_75pt7b.h>
#include <Fonts/basic_sans_serif_78pt7b.h>
#include <Fonts/basic_sans_serif_710pt7b.h>
#include <Fonts/basic_sans_serif_712pt7b.h>
#include <Fonts/basic_sans_serif_715pt7b.h>
#include <Fonts/basic_sans_serif_720pt7b.h>
#include <Fonts/basic_sans_serif_730pt7b.h>
#include <Fonts/basic_sans_serif_735pt7b.h>
#include <Fonts/basic_sans_serif_740pt7b.h>
#include <Fonts/basic_sans_serif_745pt7b.h>
#include <Fonts/basic_sans_serif_750pt7b.h>

#include <Fonts/monoMMM_55pt7b.h>
#include <Fonts/monoMMM_58pt7b.h>
#include <Fonts/monoMMM_510pt7b.h>
#include <Fonts/monoMMM_512pt7b.h>
#include <Fonts/monoMMM_515pt7b.h>
#include <Fonts/monoMMM_520pt7b.h>
#include <Fonts/monoMMM_525pt7b.h>
#include <Fonts/monoMMM_526pt7b.h>
#include <Fonts/monoMMM_528pt7b.h>
#include <Fonts/monoMMM_530pt7b.h>
#include <Fonts/monoMMM_535pt7b.h>
#include <Fonts/monoMMM_540pt7b.h>
#include <Fonts/monoMMM_545pt7b.h>
#include <Fonts/monoMMM_550pt7b.h>                                   // ########################################## REMOVE UNUSED TEXT SIZES #############################################

#include <FreeDefaultFonts.h>

#define WHITE   0xFFFF
#define GREY    0x8410
#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF


//=============================================================================================================================================
void setup(void)
{
  pinMode(rotary_encoder_A_pin, INPUT_PULLUP);
  pinMode(rotary_encoder_B_pin, INPUT_PULLUP);
  pinMode(rotary_encoder_button, INPUT_PULLUP);

  attachInterrupt(rotary_encoder_A_pin, encodermoved, FALLING);
  attachInterrupt(rotary_encoder_B_pin, encodermoved, FALLING);
  
  Serial.begin(115200);
  Wire.begin();


  //----------------------------------Set up the multiplexers----------------------------

  Wire.beginTransmission(0x20);                                                                                   // Setup for first MCP23017 controller for banks A and B as inputs
  Wire.write(0x06);                                                                                               // Set to pin direction setting mode
  Wire.write(0xFF);                                                                                               // Set controller IODIR0 to all input
  Wire.write(0xFF);                                                                                               // Set controller IODIR1 to all input
  Wire.endTransmission();

  delay(200);

  Wire.beginTransmission(0x20);                                                                                   // Setup MCP23017 controller for bank A to be inputs
  Wire.write(0x00); // IODIRA register
  Wire.write(0xFF); // set all of portA to inputs
  Wire.endTransmission();

  Wire.beginTransmission(0x20);                                                                                   // Setup MCP23017 controller for bank B to be outputs
  Wire.write(0x01); // IODIRB register
  Wire.write(0x00); // set all of portB to outputs
  Wire.endTransmission();

  read_mcp23017();                                                                                                // Get current input value

  //----------------------------------- Turn on LEDS ------------------------------------

  for (int i = 0; i < 5; i++) {                        // Turn leds on sequentially
    bitWrite(Outputvalue, i, 1);
    Setleds();
    delay(50);
  }

  for (int i = 5; i >= 0; i--) {                       // Turn leds off sequentially
    bitWrite(Outputvalue, i, 0);
    Setleds();
    delay(50);
  }

  bitWrite(Outputvalue, 0, 1);        
  bitWrite(Outputvalue, 1, 1);        
  bitWrite(Outputvalue, 2, 1);        
  bitWrite(Outputvalue, 3, 1);       
  Setleds();

  //-------------------------------Set up screen and graphics----------------------------

  uint16_t ID = tft.readID();
  Serial.print("Found screen ID = 0x");
  Serial.println(ID, HEX);
  if (ID == 0xD3D3) ID = 0x9481;
  tft.begin(ID);

  tft.setRotation(1);                                             // Set screen to landscape

  tft.fillScreen(BLACK);
  tft.setTextSize(0);

  tft.drawRect(xhome, yhome, 290, 157, GREY);                     // Actual size of available screen area to use
  tft.drawLine(xhome, yhome + 15, xhome + 290, yhome + 15, GREY);
  tft.drawLine(xhome, yhome + 142, xhome + 290, yhome + 142, GREY);

  tft.setFont(&monoMMM_526pt7b);                                  // Large text
  tft.setTextColor(YELLOW);

  tft.setCursor(xhome + 10, yhome + 85);                          // Timer text position
  tft.print("00:00:00");

  tft.setFont(&monoMMM_58pt7b);                                   // Small text
  //tft.setFont(&basic_sans_serif_78pt7b);
  tft.setCursor(xhome + 18, yhome + 122);
  tft.print("TEST");

  tft.drawRect(xhome + 100, yhome + 105, 100, 24, YELLOW);        // Centre text box

}

//#################################################################################################################################################
void loop(void)
{

  read_mcp23017();
  delay(1);


}
//#################################################################################################################################################

void IRAM_ATTR encodermoved() {

  Quad_State = digitalRead(rotary_encoder_A_pin);

  if (Quad_State != Quad_LastState) {

    Quad_counter++;

    if (digitalRead(rotary_encoder_B_pin) != Quad_State) {
      Quadrant --; if (Quadrant < 1) {
        Quadrant = 50;
      }
    } else {
      Quadrant ++; if (Quadrant > 50) {
        Quadrant = 1;
      }
    }
  }

  Quad_LastState = Quad_State;
  Serial.println(Quadrant);

}

//----------------------------------- Signal meter -----------------------------------------

void signalmeter() {
}


//------------------------------------ Set timer -------------------------------------------

void settimer() {
}


//-------------------------------- Read MCP23017 Input value -------------------------------

void read_mcp23017 () {

  Wire.beginTransmission(0x20);              // Select first device
  Wire.write(0x12);                          // Request the value of the inputs - bank A
  Wire.endTransmission();
  delay(50);
  Wire.requestFrom(0x20, 1);                 // Request the state of the GP0 inputs
  Inputstate = Wire.read();

  if ((OldInputstate) != (Inputstate)) {
    OldInputstate = Inputstate;

    if (bitRead(Inputstate, 0) == 1) {
      Serial.println("B1");
    }

    if (bitRead(Inputstate, 1) == 1) {
      Serial.println("B2");
    }

    if (bitRead(Inputstate, 2) == 1) {
      Serial.println("B3");
    }

    if (bitRead(Inputstate, 3) == 1) {
      Serial.println("B4");
    }

    if (bitRead(Inputstate, 4) == 1) {
      Serial.println("B5");
    }

    if (bitRead(Inputstate, 5) == 1) {
      Serial.println("B6");
    }

    if (bitRead(Inputstate, 6) == 1) {
      Serial.println("B7");
    }

    if (bitRead(Inputstate, 7) == 1) {
      Serial.println("B8");
    }
  }
}

//-------------------------------- Set MCP23017 Output value -------------------------------

void Setleds() {

  Wire.beginTransmission(0x20);                                                                                // Set the outputs
  Wire.write(0x13);                                                                                            // Address PORT A
  Wire.write(Outputvalue);                                                                                     // Value to send
  Wire.endTransmission();
}

You use Serial.print in interrupt context.

Which means?

I have several ESP32 Encoder libraries here that also have serial.print in the routine and they seem to work (kind of).

This looks like an issue with the Wire library

That was my last try.

You seem to be resistant to advice,
good luck with your project.

Eh? what advice.... I don't understand what advice you are trying to give me.

This is the library I am trying at the moment.

#include <ESP32Encoder.h> // https://github.com/madhephaestus/ESP32Encoder.git 
 
#define CLK 3 // CLK ENCODER 
#define DT 1  // DT ENCODER 
 
ESP32Encoder encoder;
 
void setup () { 
  encoder.attachHalfQuad ( DT, CLK );
  encoder.setCount ( 0 );
  Serial.begin ( 115200 );
}
 
void loop () {    
  long newPosition = encoder.getCount() / 4;
  Serial.println(newPosition);
} 

It only counts upwards no matter which way you turn the encoder.

Are you saying don't serial print within the interrupt loop

Moved over to a Pro-Micro.

All issues resolved.
Thanks for the advice

What's with the angry bee :slight_smile:

Unless I need wifi, I do not use ESP modules. Arduino is always comfortable.

:smiley: just some logo

Which is it ?
Do they work or not ?

It has Wifi.
it has more pins than an ESP8266.
It has BT.
it has CAN.
it's cheap.
And regarding the limitations which/when IO to use, take it easy and RTFM.
As you refer to the Nano, well, ... take A6/A7 and ask yourself "why it can't be used like the other Ax".

???
What Wire lib has to do with encoders?

I agree with @Whandall that you don't listen to advices. It is well known that you should not use serial print, delays and work with millis in interrupts. And this applies not only to esp32, but also to most other arduino boards.

At the beginning of the topic I supported you in your attitude to esp32 - but now I see that your problem is not that esp32 is a bad board - but in the absence of knowledge and unwillingness to learn.