Go Down

Topic: Problem with rotary encoders staying within bounds (Read 159 times) previous topic - next topic

notgwb

I'm using an Arduino Mega with 8 for the Keyes 040 rotary encoders. I having a hard time keeping each encoder within its bounds (int encoderMax[] & encoderMinimum[]). Each one will go one over the max and one under the minimum.

I had an older version of the code that kept the encoders within bounds, but the logic no longer works after I put the encoders into arrays


New code with bounds not working
Code: [Select]
#include <Arduino.h>
#include <TM1637Display.h>
#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h>
#include <Rotary.h>
hd44780_I2Cexp lcd;
using namespace std;


TM1637Display display(6,7); //TOP display
TM1637Display display2(8,9);  //BOTTOM display

#define ENCODER1_PIN_A 53
#define ENCODER1_PIN_B 52
#define ENCODER2_PIN_A 51
#define ENCODER2_PIN_B 50
#define ENCODER3_PIN_A 49
#define ENCODER3_PIN_B 48
#define ENCODER4_PIN_A 47
#define ENCODER4_PIN_B 46
#define ENCODER5_PIN_A 45
#define ENCODER5_PIN_B 44
#define ENCODER6_PIN_A 42
#define ENCODER6_PIN_B 43
#define ENCODER7_PIN_A 40
#define ENCODER7_PIN_B 41
#define ENCODER8_PIN_A 39
#define ENCODER8_PIN_B 38


int encoderAmount = 8;

int encoderDelta[] = {0,0,0,0,0,0,0,0};
int encoderPosition[] = {0,0,0,0,0,0,0,0};
int encoderMax[] = {31, 16, 23, 8, 21, 29, 26, 30};
int encoderMinimum[] = {0,0,0,0,0,0,0,0};

Rotary encoder1 = Rotary(ENCODER1_PIN_A, ENCODER1_PIN_B);
Rotary encoder2 = Rotary(ENCODER2_PIN_A, ENCODER2_PIN_B);
Rotary encoder3 = Rotary(ENCODER3_PIN_A, ENCODER3_PIN_B);
Rotary encoder4 = Rotary(ENCODER4_PIN_A, ENCODER4_PIN_B);
Rotary encoder5 = Rotary(ENCODER5_PIN_A, ENCODER5_PIN_B);
Rotary encoder6 = Rotary(ENCODER6_PIN_A, ENCODER6_PIN_B);
Rotary encoder7 = Rotary(ENCODER7_PIN_A, ENCODER7_PIN_B);
Rotary encoder8 = Rotary(ENCODER8_PIN_A, ENCODER8_PIN_B);

Rotary encoderArray[]= {encoder1, encoder2, encoder3, encoder4, encoder5, encoder6, encoder7, encoder8};




void setup()
{
  Serial.begin(9600);
}

void loop()
{
  display.setBrightness(0x0f);
  display2.setBrightness(0x0f);

  for(int i = 0; i < encoderAmount; i++)
  {
    static int encoderLastPosition = 999;
    unsigned char encoderState = encoderArray[i].process();
         
    if (encoderState == DIR_NONE)
    {
      //Do nothing
    }
    else if (encoderState == DIR_CW)
    {
      encoderDelta[i] = 1;
      encoderPosition[i]++;
      Serial.print("encoderData CW: "[i]);
      Serial.print(encoderPosition[i]);
      display.showNumberDec(i);
      display2.showNumberDec(encoderPosition[i]);
    }
    else if (encoderState == DIR_CCW)
    {
      encoderDelta[i] = -1;
      encoderPosition[i]--;
      Serial.print("encoderData CCW: "[i]);
      Serial.print(encoderPosition[i]);
      display.showNumberDec(i);
      display2.showNumberDec(encoderPosition[i]);
    }
    if (encoderPosition[i] < encoderMinimum[i])
    {
     encoderPosition[i] = encoderMinimum[i];
    }   
    if (encoderPosition[i] > encoderMax[i])
    {
     encoderPosition[i]= encoderMax[i];
    }
   
    encoderLastPosition = encoderPosition[i];
 
  }   
   
}




Old code with encoder boundaries working
Code: [Select]
#include <Arduino.h>
#include <TM1637Display.h>
#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h>
#include <Rotary.h>
//MIDI_CREATE_DEFAULT_INSTANCE();
hd44780_I2Cexp lcd;
using namespace std;


TM1637Display display(6,7); //TOP display
TM1637Display display2(8,9);  //BOTTOM display

#define ENCODER_PIN_A 53
#define ENCODER_PIN_B 52
#define ENCODER2_PIN_A 51
#define ENCODER2_PIN_B 50

int current_encoder_position = 0;
int current_encoder_delta = 0;
int current_encoder2_position = 0;
int current_encoder2_delta = 0;

int encoder1Max= 31;
int encoder2Max= 22;

Rotary encoder = Rotary(ENCODER_PIN_A, ENCODER_PIN_B);
Rotary encoder2 = Rotary(ENCODER2_PIN_A, ENCODER2_PIN_B);


void setup()
{
  Serial.begin(9600);

}

void loop()
{
  display.setBrightness(0x0f);
  display2.setBrightness(0x0f);
  if(encoderPositionUpdated()) printEncoderInfo();
  if(encoder2PositionUpdated()) printEncoder2Info();
}

void printEncoderInfo()
{
  Serial.print("CURRENT encoder_position: ");
  Serial.print(current_encoder_position);
  display.showNumberDec(current_encoder_position);
  Serial.print(", delta: ");
  Serial.print(current_encoder_delta);
  display2.showNumberDec(current_encoder_delta);
  Serial.print(", direction: ");
  if(current_encoder_delta>0) Serial.println("right");
  else Serial.println("left");
}




/////////////////////////////////////////////////////////////////////
//NEW
void printEncoder2Info()
{
  Serial.print("CURRENT encoder2_position: ");
  Serial.print(current_encoder2_position);
  display.showNumberDec(current_encoder2_position);
  Serial.print(", 2delta: ");
  Serial.print(current_encoder2_delta);
  display2.showNumberDec(current_encoder2_delta);
  Serial.print(", 2direction: ");
  if(current_encoder2_delta>0) Serial.println("2right");
  else Serial.println("2left");
}

bool encoderPositionUpdated()
{
  static int last_position = -999;
  unsigned char result = encoder.process();

  if (result == DIR_NONE)
  {
    // do nothing
  }
  else if (result == DIR_CW)
  {
    current_encoder_delta = 1;
    current_encoder_position++;
  }
  else if (result == DIR_CCW)
  {
    current_encoder_delta = -1;
    current_encoder_position--;
  }
 
  if (current_encoder_position < 0)
  {
   current_encoder_position= 0;
  }
  if (current_encoder_position > encoder1Max)
  {
   current_encoder_position= encoder1Max;
  }
 
  bool updated = (current_encoder_position != last_position);
  last_position = current_encoder_position;

  return updated;
}


////////////////////////////////////////////////////////////////////
//NEW
bool encoder2PositionUpdated()
{
    //NEW
   static int last_position2 = -999;
  unsigned char result2 = encoder2.process();

  if (result2 == DIR_NONE)
  {
    // do nothing
  }
  else if (result2 == DIR_CW)
  {
    current_encoder2_delta = 1;
    current_encoder2_position++;
  }
  else if (result2 == DIR_CCW)
  {
    current_encoder2_delta = -1;
    current_encoder2_position--;
  }
 
  if (current_encoder2_position < 0)
  {
    current_encoder2_position= 0;
  }
  if (current_encoder2_position > encoder2Max)
  {
   current_encoder2_position= encoder2Max;
  }

  bool updated2 = (current_encoder2_position != last_position2);
  last_position2 = current_encoder2_position;

  return updated2;

}

AWOL

Something went wrong with your second set of code tags; everything came out in bold

johnwasser

You put the 'Serial' and 'display' calls BEFORE the code that constrains the value.
You can use the constrain() function to add a constrain before the display code:

For example:
Code: [Select]
    else if (encoderState == DIR_CCW) 
    {
      encoderDelta[i] = -1;
      encoderPosition[i]--;
      encoderPostion[i] = constrain(encoderPostion[i], encoderMinimum[i], encoderMax[i]);
      Serial.print("encoderData CCW: "[i]);
      Serial.print(encoderPosition[i]);
      display.showNumberDec(i);
      display2.showNumberDec(encoderPosition[i]);
    }
Send Bitcoin tips to: 1G2qoGwMRXx8az71DVP1E81jShxtbSh5Hp

notgwb

You put the 'Serial' and 'display' calls BEFORE the code that constrains the value.
You can use the constrain() function to add a constrain before the display code:

For example:
Code: [Select]
    else if (encoderState == DIR_CCW)
    {
      encoderDelta[i] = -1;
      encoderPosition[i]--;
      encoderPostion[i] = constrain(encoderPostion[i], encoderMinimum[i], encoderMax[i]);
      Serial.print("encoderData CCW: "[i]);
      Serial.print(encoderPosition[i]);
      display.showNumberDec(i);
      display2.showNumberDec(encoderPosition[i]);
    }

Hi John, I thought this might be the issue. Honestly, I should have double checked before submitting, but I was eager for an answer. Thanks a lot for mentioning the constrain function, very cool bit of code I wasn't aware of before.

Thanks so much for the help guys!

Go Up