Seesaw Rotary Encoder

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
JoeyG1973
 
Posts: 4
Joined: Sun Dec 12, 2021 12:34 am

Seesaw Rotary Encoder

Post by JoeyG1973 »

This is my first time working with an Arduino. I have a Mega 2560. Can someone take a look at the code below and explain why the x rotary encoder is only randomly registering a turn of the encoder? IE: I turn it 5 clicks and it may register 0-5 clicks. The i2c seesaw encoder appears to be asynchronous. I need to call the stepper runspeed each loop and cannot put a delay on the loop. If the encoder is asynchronous it means, as per the example code provided with the seesaw library, needs a delay to catch the signal from the seesaw.

Is there any way to read the encoder on each loop without the delay in the code?

Code: Select all

#include <Adafruit_seesaw.h>
#include <seesaw_neopixel.h>
#include <AccelStepper.h>
#include <MultiStepper.h>
#include <Bounce2.h>

#define SS_SWITCH 24
#define SS_NEOPIX 6
#define NUM_OF_ENC 2
#define BUTTON_PIN 52
#define X_STEP_PIN 11
#define X_DIR_PIN 12
#define X_ENA_PIN 13
#define X_SPEED_MULTIPLIER 100
#define X_MAX_CONSTRAINT 20

#define Y_STEP_PIN 8
#define Y_DIR_PIN 9
#define Y_ENA_PIN 10
#define SEESAW_BASE_ADDR 0x36


Adafruit_seesaw Xencoder;
Adafruit_seesaw Yencoder;
seesaw_NeoPixel Xpixel(1, SS_NEOPIX, NEO_GRB + NEO_KHZ800);
seesaw_NeoPixel Ypixel(1, SS_NEOPIX, NEO_GRB + NEO_KHZ800);

uint32_t Xencoder_position = 0;
uint32_t Yencoder_position = 0;

Bounce2::Button limit_switch = Bounce2::Button();

AccelStepper Xstepper(1, X_STEP_PIN, X_DIR_PIN);
AccelStepper Ystepper(1, Y_STEP_PIN, Y_DIR_PIN);


uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if (WheelPos < 85) {
    return seesaw_NeoPixel::Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if (WheelPos < 170) {
    WheelPos -= 85;
    return seesaw_NeoPixel::Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return seesaw_NeoPixel::Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

void setup()
{
  Serial.begin(115200);
  limit_switch.attach( BUTTON_PIN, INPUT_PULLUP );
  limit_switch.interval(5);
  limit_switch.setPressedState(LOW);

  Xstepper.setMaxSpeed(X_SPEED_MULTIPLIER * X_MAX_CONSTRAINT);
  Xstepper.setSpeed(0);
  Ystepper.setMaxSpeed(1000);

  Serial.println("Setting up Adafruit SeeSaw X rotary encorder");
  if (! Xencoder.begin(SEESAW_BASE_ADDR) || ! Xpixel.begin(SEESAW_BASE_ADDR)) {
    Serial.println("Couldn't find X seesaw on default address");
    while (1) delay(10);
  }

  Serial.println("Setting up Adafruit SeeSaw Y rotary encorder");
  if (! Yencoder.begin(SEESAW_BASE_ADDR + 1) || ! Ypixel.begin(SEESAW_BASE_ADDR + 1)) {
    Serial.println("Couldn't find Y seesaw on default address");
    while (1) delay(10);
  }

  Xencoder.pinMode(SS_SWITCH, INPUT_PULLUP);
  Xencoder_position = Xencoder.getEncoderPosition();
  Xencoder.setGPIOInterrupts((uint32_t)1 << SS_SWITCH, 1);
  Xencoder.enableEncoderInterrupt();
  Xpixel.setBrightness(30);
  Xpixel.show();

  Yencoder.pinMode(SS_SWITCH, INPUT_PULLUP);
  Yencoder_position = Yencoder.getEncoderPosition();
  Yencoder.setGPIOInterrupts((uint32_t)1 << SS_SWITCH, 1);
  Yencoder.enableEncoderInterrupt();
  Ypixel.setBrightness(30);
  Ypixel.show();

}

void loop()
{
  limit_switch.update();

  int16_t currSpeed = Xstepper.speed();

  int32_t new_position = Xencoder.getEncoderPosition();
  uint8_t constrained_position = constrain(new_position, 0, X_MAX_CONSTRAINT);
  if (Xencoder_position != constrained_position) {
    Xencoder_position = constrained_position;
    Xpixel.setPixelColor(0, Wheel((constrained_position * 4) & 0xFF));
    Xpixel.show();

    if (currSpeed < 0) {
      Xstepper.setSpeed(-constrained_position * X_SPEED_MULTIPLIER);
    } else {
      Xstepper.setSpeed(constrained_position * X_SPEED_MULTIPLIER);
    }
    Serial.println(currSpeed);
  }
  Xencoder.setEncoderPosition(constrained_position);
  if (limit_switch.pressed() ) {
    Serial.println("The limit_switch is pressed");
    Xstepper.stop();
    Xstepper.setSpeed(-currSpeed);
    delay(500);
  }
  Xstepper.runSpeed();
}

User avatar
adafruit_support_bill
 
Posts: 88144
Joined: Sat Feb 07, 2009 10:11 am

Re: Seesaw Rotary Encoder

Post by adafruit_support_bill »

If the encoder is asynchronous it means, as per the example code provided with the seesaw library, needs a delay to catch the signal from the seesaw.
No. Asynchronous means that it will update regardless of what your code is doing. You do not need a delay.

The reason you are losing steps is because you keep resetting the encoder position to constrained_position. This means that even if the encoder asynchronously updates between the time you read it and the time you set it, you will lose steps.

You should only force-write the constrained_position if you have determined that the encoder has exceeded the constraints.

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”