encoder library doesn´t works with esp32 boards

Hi;

Board used HELTEC WIFI 8 encoder5 pin standard (rotatory and pulser) arduino ide (the last one) libraries and boards acuallized (i think that was the problem...)

I have done a program due Arduino IDE to this board using encoder.h library and it works ( more or less). A cup of months later I reopen the project in order to correct some bugs, and my surprise was that nothing works, it can’t compile; The error report:

In file included from C:\Proyectos terminados\Medidor Rotatory\Rotatory_esp32\Rotatory_esp32.ino:5:0:
C:\Users\Admin\Documents\Arduino\libraries\Encoder/Encoder.h:61:11: error: ‘IO_REG_TYPE’ does not name a type
volatile IO_REG_TYPE * pin1_register;
^
C:\Users\Admin\Documents\Arduino\libraries\Encoder/Encoder.h:62:11: error: ‘IO_REG_TYPE’ does not name a type
volatile IO_REG_TYPE * pin2_register;
^
[…Similar stuff…]

C:\Users\Admin\Documents\Arduino\libraries\Encoder/Encoder.h: In constructor ‘Encoder::Encoder(uint8_t, uint8_t)’:
exit status 1
Error compilando para la tarjeta Heltec WiFi LoRa 32(V2).

The code is the same, and if i try to compile it to an arduino board it compile perfect.

On the code i just try to put the line :

define ENCODER_DO_NOT_USE_INTERRUPTS

on the very beggining, I solved the no interrupts advise, (this one doesn´t appear on the old version) , but the actual list of errors apppear.

What can it be? maybe a new version of the board on arduino ide? A problem with the encoder.h library?

The example no interruptions that comes with the library have the same.issue.

Are you using the PJRC Encoder Library? Perhaps try updating the version in the IDE or download the latest from GitHub.

yes; i use this one, it´s on the last version, i tried to update it by both sides (arduino ide and git), then try the previous version, then i uninstall the wolle arduino ide, delete all folders and reinstall again. nothing change. But this is the same sketch i previously used to this hardware, and its working on the gadget, but now i can't reupload...

strange things...

Could be a problem in the code we can't see.

Well, the code have more than one problem by shure…
my proggramming skills are, let’s say, basics…
But the fact is that this code is already working on the device, i reopen it to solve some issues like when the device measure more than 220mm start to “discount” instead of count up, (overload issue, or maybe i should set the variables to zero in the middle of the measuring process, i don’t know)

But here is the full code (Sorry for the mess)

#include<ButtonV2.h>
#include <Arduino.h>
#include <U8g2lib.h>
#define ENCODER_DO_NOT_USE_INTERRUPTS
#include <Encoder.h>


#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif

#define numOfButtons 2

ButtonV2 Button1;
const byte ButtonPin = 13;
int laserPin = 15;



/*//////////////////////////////////////////////////timer con millis para pintar
  long startMillis = 0;
  unsigned long currentMillis;
  const unsigned long period = 1000;  //the value is a number of milliseconds
*/

////////////////////////////////////////timer para Velocidad
long VelStart = 0;
unsigned long VelPeriod = 2000;
unsigned int V = 1; //estes son dentro de Velocidad()
unsigned long TimeVel = 0;
unsigned long VelSalida = 0;
unsigned long VelCurrent = 0;

//////////////////////////////////////////////timer para la rueda
long startMillisWhell = 0;
unsigned long MilliscurrentWhell;
const unsigned long periodWhell = 200;
//constructor line
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ 16, /* clock=*/ 5, /* data=*/ 4);
String TextToDraw = "Txanquete";
///timer para Txanquete
long MillisTxanNow ;
long MillisTxanStart = 0;

//////////////////////////////////////////////// iniciando el encoder
Encoder myEnc(14, 12);
long counter = 0;
long newPosition;
long oldPosition  = -999;
int WhellButton = 13;
//encoder para direccion giro
int direccion = 0;
//posicion del menu
int Menupos = 0;
/////////////////Byte para Navegar
char navega = 'S';
int i, j, k = 0;

////////////////medidas
const int pase = 8246679;
long Medida = 0;
///Variables para iniciar a la segunda
unsigned int Laser = 1;
unsigned int Vol = 1;
unsigned int Vel = 1;



///////////////////////////////////////////Array menu
String MenuArray[4][4][2] = {
  {
    { "Medir", "Velocidad" }, //medir 0-0-0 menu0-0-1
    { "0", "Medir"},        //Medir 0-1-1
    { "0", "Resetear" },      //Restar 0-2-1
    { "0", "Ver Medida" }        //Ver Medida 0-3-1
  },
  {
    { "Laser", "on"},   //Laser 1-0-0 on 1-0-1
    { "0", "off"},        //off 1-1-1
    { "0", "Blink"},      //Blink 1-2-1
    { "TempPrint", "0" } //TempPrint 1-3-0
  },
  {
    { "Medidas", "Num 1" }, //Medidas 2-0-0; Num 1 2-0-1
    { "0", "Num 2",},          // Num 2 2-1-1
    { "0", "Num 3" },         // Num 3 2-2-1
    { "0", "Num 4" }          // Num 4 2-3-1
  },
  {
    { "Calculos" , "Vol Cubo"},  //Calculos 3-0-0 Volumen 3-0-1
    { "0", "Volumen Tubo"},               //Volumen Tubo 3-1-1
    { "0", "Radio perimetro"},             //Triangulo Lado 3-2-1
    { "0", "Txanquete"}             //Radio Perimetro 3-3-1
  },
};
void setup()
{
  //////////////////////////////////////////////pinMode(LEDpin, OUTPUT);
  Serial.begin(115200);
  //pinMode(LEDpin, OUTPUT);
  pinMode(ButtonPin, INPUT_PULLUP);
  Button1.SetStateAndTime(LOW);
  ///////////////////////////////////////////////millis rueda laser
  pinMode (laserPin, OUTPUT);
  //setup display

  u8g2.begin();

}

void loop()
{

  //ESCUCHA BOTON RUEDA
  Boton();

  //ESCUCHA DIRECCION RUEDA asi que pase el tiempo period
  MilliscurrentWhell = millis();  //get the current "time" (actually the number of milliseconds since the program started)
  if (MilliscurrentWhell - startMillisWhell >= periodWhell)  //test whether the period has elapsed
  {
    direccion_whell();
    startMillisWhell = MilliscurrentWhell;  //IMPORTANT to save the start time of the current LED state.
  }


  ////pinta optimizado, entra solo cuando cambia, para pintar cambiar coordenadas ijk,o su valor
  if (MenuArray[i][j][k] != TextToDraw) {
    Serial.println ("Pinta Dentro");
    Serial.println (TextToDraw);
    Serial.println (MenuArray[i][j][k]);
    TextToDraw = MenuArray[i][j][k];
    pinta();

  }
}

////////////////////////FUNCION BOTONES Envia directo a funcion navega segun el tipo de pulsacion
void Boton () {

  byte type = Button1.CheckButton(ButtonPin); // current time and length of time to press the button as many times as you can ie. 1.5 seconds
  switch (type)
  {
    case WAITING:

      break;
    case PRESSED:
      navega = 'D';
      Navega();
      Serial.println("pressed 1 time");

      break;
    case DOUBLE_PRESSED:
      navega = 'F';
      Navega();
      Serial.println("pressed 2 times");

      break;
    case MULTI_PRESSED:
      Serial.println("pressed 3 times");
      i = j = k = 0;
      break;
    case HELD:
      //Serial.println("Button uno HELD");

      break;
  }
}

//////////////////////DIRECCION DE LA RUEDA PARA MENU
int direccion_whell() {

  long newPosition = myEnc.read();
  if (newPosition == oldPosition) { //si no cambia la rueda direccion a 0
    direccion = 0;
  }
  if (newPosition != oldPosition) {
    if ((newPosition + 2) > oldPosition) {
      navega = 'S';
      Navega();
      Serial.println("Rueda arriba");
    }
    if ((newPosition - 2) < oldPosition) {
      navega = 'I';
      Navega();
      Serial.println("Rueda abajo");

    }
    oldPosition = newPosition;
  }

}

////////////////////////////FUNCIONES DE NAVEGACION
void Navega() {
  Serial.print("Dentro de navega; Navega Value: ");
  Serial.println(navega);


  Serial.print ("Valor i,j,k: " );
  Serial.print ( i);
  Serial.print (" , ");
  Serial.print (j);
  Serial.print (" , ");
  Serial.println (k);

  switch (navega) {
    case 'S'://Superior
      if (j == 0 && k == 0) {
        i = i + 1;
        if (i > 3) {
          i = 0;
        }
      }
      if (k == 1) {
        j = j + 1;
        if (j > 3) {
          j = 0;
        }
      }
      break;
    case 'I'://Inferior
      if (j == 0 && k == 0) {
        i = i - 1;
        if (i < 0) {
          i = 3;
        }
      }
      if (k == 1) {
        j = j - 1;
        if (j < 0) {
          j = 3;
        }
      }

      break;
    case 'D'://Dentro
      if (j == 0 && k == 0) {
        k = 1;
      }
      if (k == 1) {
        Serial.println("Desde pulsaciones hacia Ejecuta");
        Ejecuta();
        //Ejecuta posicion i,j,k actual
      }

      break;
    case 'F'://Fuera
      if (j == 0 && k == 0) {
        TextToDraw = "No Hay Superior";
        pinta();
      }
      if (k == 1) {
        k = 0;
        j = 0;
      }
      break;
  }
}

This is the rest of the code, too long for a post.
If this is usefull for see what happend, ok, because as an programming example for somebody i don’t think so, this can make sheeps cry. :’(

/////FUNCIONES DE EJECUTAR
void Ejecuta() {
  //Hay 14 diferentes acciones a ejecutar, se corresponden a las posiciones
  //001;011;021;031;101;111;201;211;221;231;301;311;321;331
  if (i == 0 && j == 0 && k == 1) { //Funcion Velocidad
    if (Vel == 2) {
      counter = 0;
      Velocidad();
      Vel = 1;
    } else (Vel = Vel + 1);
  }
  if (i == 0 && j == 1 && k == 1) { //Funcion Medir
    Serial.println("Dentro de ejecuta, a Mediciones");
    counter = 0;
    mediciones();
  }
  if (i == 0 && j == 2 && k == 1) { //Funcion Resetear
    resetear();
  }
  if (i == 0 && j == 3 && k == 1) {  //Funcion VerMedida
    VerMedida();
  }
  if (i == 1 && j == 0 && k == 1) { //Funcion paralaser on

    if (Laser == 2) {
      digitalWrite(laserPin, HIGH);
      Laser = 1;
    }

    else (Laser = Laser + 1);

  }
  if (i == 1 && j == 1 && k == 1) { //Funcion paralaser off
    digitalWrite(laserPin, LOW);
  }
  if (i == 1 && j == 2 && k == 1) { //Funcion para Blink 1-1-2
    Blink();
  }
  if (i == 2 && j == 0 && k == 1) { //Funcion paramedidas 1
  }
  if (i == 2 && j == 1 && k == 1) { //Funcion paramedidas 2
  }
  if (i == 2 && j == 2 && k == 1) { //Funcion paramedidas 3
  }
  if (i == 2 && j == 3 && k == 1) { //Funcion paramedidas 4
  }
  if (i == 3 && j == 0 && k == 1) { //Funcion paraVol cubo
    TextToDraw = "Empezamos";
    pinta();
    if (Vol == 2) {
      VolCubo();
      Vol = 1;
    }
    else (Vol = Vol + 1);

  }
  if (i == 3 && j == 1 && k == 1) { //Funcion paraVol cilindro
  }
  if (i == 3 && j == 2 && k == 1) { //Funcion paraRadio/perimetro
  }
  if (i == 3 && j == 3 && k == 1) { //Funcion Txanquete
     Txanquete ();
  }

}

//////////////////////MEDICIONES
long mediciones() {
  do {
    delay (10);
    //Serial.println("dentro while");
    digitalWrite(laserPin, HIGH);
    long newPosition = myEnc.read();
    if (newPosition != oldPosition) {
      counter = counter + (int (newPosition) - int (oldPosition));
      Serial.print ("Counter inside :");
      Serial.println (counter);
      Serial.print ("New Position :" );
      Serial.println (newPosition);
      Serial.print ("Old Position : ");
      Serial.println (oldPosition);
      oldPosition = newPosition;

    }
  } while (digitalRead (WhellButton) == HIGH);//al pulsar el boton rueda para la medicion para de medir

  digitalWrite(laserPin, LOW);
  //Cuenta de pasos a milimetros:
  Medida = (counter * pase);
  Medida = (Medida / 10000000); ///evitar decimales, pasa a milimetros
  //grabar la medicion en donde corresponda
  unsigned int Donde = 0;

  if (MenuArray [2][3][1] == "Num 4") {
    Donde = 4;
  } else {
    Donde = 5;
  }
  if (MenuArray [2][2][1] == "Num 3") {
    Donde = 3;

  }
  if (MenuArray [2][1][1] == "Num 2") {
    Donde = 2;
  }
  if (MenuArray [2][0][1] == "Num 1") {
    Donde = 1;
  }

  switch (Donde) {
    case 1:

      MenuArray[2][0][1] = (String(Medida) + " mm");
      i = 2; j = 0; k = 1;
      break;
    case 2:
      MenuArray[2][1][1] = (String(Medida) + " mm");
      i = 2; j = 1; k = 1;
      break;
    case 3:
      MenuArray[2][2][1] = (String(Medida) + " mm");
      i = 2; j = 2; k = 1;
      break;
    case 4:
      MenuArray[2][3][1] = (String(Medida) + " mm");
      i = 2; j = 3; k = 1;
      break;
    case 5:
      resetear();
      MenuArray[2][0][1] = (String(Medida) + " mm");
      i = 2; j = 0; k = 1;
      break;
  }

  Serial.println( "Posicion de salida ");
  Serial.println (counter);
  Serial.println ("Medidas; cuenta; int");
  Serial.println (Medida);
  Medida = int(Medida);
  Serial.println("medidas interizado");
  Serial.println(Medida);
}
//funcion resetear
void resetear() {
  MenuArray[2][0][1] = "Num 1";
  MenuArray[2][1][1] = "Num 2";
  MenuArray[2][2][1] = "Num 3";
  MenuArray[2][3][1] = "Num 4";
}
//Funcion Txanquete
void Txanquete () {
  MenuArray[1][3][0] = "Que bueno";
  i = 1; j = 3; k = 0;
  pinta();
  delay(5000);
  MenuArray[1][3][0] = "que soy ;-)";
  pinta();

}

//Funcion laser Blink
void Blink() {
  do {
    Serial.println("Blinking");
    digitalWrite(laserPin, HIGH);
    delay (500);
    digitalWrite(laserPin, LOW);
    delay (500);
  }
  while (digitalRead (WhellButton) == HIGH);//al pulsar el boton rueda para la medicion para de medir

}
//Funcion Volumen cubo (Reset-medir lado, medir lado, medir alto
void VolCubo() {
  resetear();
  mediciones();
  delay(400);
  MenuArray[1][3][0] = "Siguiente lado";
  i = 1; j = 3; k = 0;
  TextToDraw = MenuArray[1][3][0];
  pinta();
  Serial.println ("Vol Cubo uno");
  counter = 0;

  mediciones();
  delay(400);
  MenuArray[1][3][0] = "Siguiente lado";
  i = 1; j = 3; k = 0;
  TextToDraw = MenuArray[1][3][0];
  pinta();
  Serial.println ("Vol Cubo uno");
  counter = 0;

  mediciones();
  delay(400);
  MenuArray[1][3][0] = "Altura";
  i = 1; j = 3; k = 0;
  TextToDraw = MenuArray[1][3][0];
  pinta();
  Serial.println ("Vol cubo dos");

  int volumen = ( MenuArray[2][0][1].toInt() * MenuArray[2][1][1].toInt() * MenuArray[2][2][1].toInt());
  // volumen = volumen / 1000;
  Serial.print ("Volumen ");
  Serial.println (volumen);
  MenuArray[1][3][0] = (String(volumen) + "mL");
}

//funcion velocidad
void Velocidad() {
  Serial.println ("Dentro Velocidad");

  do {
    delay (10);
    //Serial.println("dentro while");
    digitalWrite(laserPin, HIGH);
    long newPosition = myEnc.read();
    if (newPosition != oldPosition) {
      if (V == 1) {
        VelStart = millis();
        V = V + 1;
      }
      VelCurrent = millis();
      counter = counter + (int (newPosition) - int (oldPosition));
      Serial.print ("Vel Start :");
      Serial.println (VelStart);
      Serial.print ("Vel Current:" );
      Serial.println (VelCurrent);
      Serial.print ("Cuenta Current-period: ");
      Serial.println ( (VelCurrent +  VelPeriod));
      Serial.print ("Actual millis: ");
      Serial.println (millis());
      oldPosition = newPosition;
    }
  } while (millis() < ( VelCurrent +  VelPeriod)); //Para en un periodo sin movimiento
  digitalWrite(laserPin, LOW);
  //tiempo cambiando, desde q inicia, hasta que pasa el period sin cambios(que lo resto igualmente)
  TimeVel = VelCurrent - (VelStart - VelPeriod);
  TimeVel = (TimeVel / 1000);
  Serial.print ("Vel TimeVel : ");
  Serial.println (TimeVel);
  Serial.print ("Time Vel cuenta: ");
  Serial.println (VelCurrent - (VelStart - VelPeriod));
  //Cuenta de pasos a milimetros:
  Medida = (counter * pase);
  Medida = (Medida / 10000000); ///evitar decimales, pasa a milimetros
  VelSalida = (Medida / TimeVel); //mm/seg
  Serial.print ("Vel salida pre int");
  Serial.println (VelSalida);

  delay(400);
  MenuArray[1][3][0] = (String(VelSalida) + " mm/seg");
  i = 1; j = 3; k = 0;
  TextToDraw = MenuArray[1][3][0];
  pinta();
  V = 1;
}
// Ver medida funcion
void VerMedida() {
  do {
    delay (10);
    //Serial.println("dentro while");
    digitalWrite(laserPin, HIGH);
    long newPosition = myEnc.read();
    if (newPosition != oldPosition) {
      counter = counter + (int (newPosition) - int (oldPosition));
      oldPosition = newPosition;
      Medida = (counter * pase);
      Medida = (Medida / 10000000); ///evitar decimales, pasa a milimetros
      MenuArray[1][3][0] = (String(Medida) + " mm");
      i = 1; j = 3; k = 0;
      TextToDraw = MenuArray[1][3][0];
      pinta();

    }
  } while (digitalRead (WhellButton) == HIGH);//al pulsar el boton rueda para la medicion para de medir
  Medida = 0;
  digitalWrite(laserPin, LOW);
  //Cuenta de pasos a milimetros:

}

//pantalla funcion dibujar
void draw(String TextToDraw) {

  //Serial.println("dentro draw funct");
  u8g2.setFont(u8g2_font_ncenB12_tr);
  u8g2.setCursor (0, 18);
  //u8g2.print("Position: ");
  u8g2.print(TextToDraw);
}
//
void pinta() {
  u8g2.firstPage();
  do {
    draw(TextToDraw);
  } while (u8g2.nextPage());
}

Hi, Have you googled

encoder esp32

There are couple of libraries for the ESP32 and quadrature encoders.

Have you developed this code in stages? Did you write code JUST to get the encoder input working? If not, then for the moment forge your code and write a [u]NEW code that JUST uses and reads the encoder[/u]. Disconnect everything else and prove that you can read the encoder before doing other coding.

It looks like you have written a lot of code before finding the encoder library doesn't work.

Tom.... :)

Hi, thanks for your time, seriously, i appreciate a lot all your help.

But the code works.
At least it works a cup of months ago, same code, same board, same Arduino ide (not same version, sure)

To be shure it was not a problem with the code i try to compile,to this board (heltec wifi lora v2); even with any other esp board, the examples provide by the library.

Pease if somebody have some time, just try it;
Arduino ide
heltec wifi lora v2 (or similar happend the same)
example “noninterrups”

code from the example (just copy-paste from arduino examples):

/* Encoder Library - NoInterrupts Example
 * http://www.pjrc.com/teensy/td_libs_Encoder.html
 *
 * This example code is in the public domain.
 */

// If you define ENCODER_DO_NOT_USE_INTERRUPTS *before* including
// Encoder, the library will never use interrupts.  This is mainly
// useful to reduce the size of the library when you are using it
// with pins that do not support interrupts.  Without interrupts,
// your program must call the read() function rapidly, or risk
// missing changes in position.
#define ENCODER_DO_NOT_USE_INTERRUPTS
#include <Encoder.h>

// Beware of Serial.print() speed.  Without interrupts, if you
// transmit too much data with Serial.print() it can slow your
// reading from Encoder.  Arduino 1.0 has improved transmit code.
// Using the fastest baud rate also helps.  Teensy has USB packet
// buffering.  But all boards can experience problems if you print
// too much and fill up buffers.

// Change these two numbers to the pins connected to your encoder.
//   With ENCODER_DO_NOT_USE_INTERRUPTS, no interrupts are ever
//   used, even if the pin has interrupt capability
Encoder myEnc(5, 6);
//   avoid using pins with LEDs attached

void setup() {
  Serial.begin(9600);
  Serial.println("Basic NoInterrupts Test:");
}

long position  = -999;

void loop() {
  long newPos = myEnc.read();
  if (newPos != position) {
    position = newPos;
    Serial.println(position);
  }
  // With any substantial delay added, Encoder can only track
  // very slow motion.  You may uncomment this line to see
  // how badly a delay affects your encoder.
  //delay(50);
}

hi; If somebody have similar problem:

The problem was solved changing the board from heltec wifi lora v2 (the real board i use is HELTEC WIFI 8) for a generic ESP8266 board on the arduino ide (this is the real chipset board have) And its done, all the problems with the compilation and uploasd solved.

Thanks anyway by your help!