SeeSaw Encoder lag

For other supported Arduino products from Adafruit: Shields, accessories, etc.

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 Encoder lag

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. It catches the press of the directional switch/button I have directly attached to the Arduino just fine. I know the encoders are using a software bus but it can't be that slow can it?

Also I am trying to figure out how to flip the encoder so that turning right causes a positive return from the encoder and I am a bit stumped.

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
JoeyG1973
 
Posts: 4
Joined: Sun Dec 12, 2021 12:34 am

Re: SeeSaw Encoder lag

Post by JoeyG1973 »

So after much banging my head against the wall, you NEED to have the following lines in your loop:

yield();
delay(10);

Without this, the encoders only register clicks randomly. The yield and the delay won't work when you need stepper.runSpeed() every loop, otherwise the stepper is going to delay 10 ms all the time.

I don't know how i2c works but you would think the supplied Arduino library and the code on the chip for the rotary encoder would have a syn ack logic but no. So I am hoping someone can help me understand how to code so that the stepper continues to run and can also read the encoder at the same time.

User avatar
JoeyG1973
 
Posts: 4
Joined: Sun Dec 12, 2021 12:34 am

Re: SeeSaw Encoder lag

Post by JoeyG1973 »

Bump

Any help would be appreciated here.

Seesaw on i2c appears to be asynchronous.

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

Return to “Other Arduino products from Adafruit”