Slider doesn't work on Servo - Help

I'm recharging my battery for the servo driver as of the moment. Will see if it does make a difference.

Update.

It works now, it turns out there was not enough power for PCA9685. Now, I'm adding more servo and see how it will turn out. I'll be back when I get another problem. Thank you, guys!

1 Like

So, here's the thing the code works but I've notice there were too much data when sliding the slider which makes it go unstable, perhaps because of the bluetooth too much data going in.

I found this from you @ABG. Is this right thing to do? is this for MIT or Arduino?

This is for the AI2 blocks, because that's where the slider is.

blocks - 2024-03-20T111738.990


This code slightly limits data sending. Only integer values will be sent, and only if their value actually changes.

2 Likes

The @Patryk_F approach is simpler than the Clock approach.
I would go with that.

1 Like

The best solution is to use slider tools or something similar extension and send the data on touch up.

1 Like

What's the Clock approach do and what's the difference between @Patryk_F approach?

Also, I somehow manage to alleviate the problem. I just set the delay() much lower. I looked up and it said it is better for accuracy and responsiveness, though it also said I might break the servo.

It's the pseudocode from Nov '20 you posted earlier in this thread.
It uses a Clock Timer, and the other approach doesn't.

Does the tempValue depends on the maximum slider I want to use?

Initialize tempValue with the same value as you initialize in the ThumbPosition slider. In my case I set both values to 60.

Hey, guys. I'm back. Thanks for all your help. Now, what I'm trying to implement is adding a stepper motor, I have already made a code for it but I having confusion on how to make it in MIT app similar to @Patryk_F aid. Can someone help me how to make the block code for this?

if (state.startsWith("S:")) {
      String stateS = state.substring(2, state.length());
      int targetPosition = stateS.toInt();
      int currentPosition = stepper.currentPosition();
      moveStepperToPosition(currentPosition, targetPosition);
    }
    stepper.run();  // Move the stepper motor
  }
void moveStepperToPosition(int currentPosition, int targetPosition) {
  // Determine the direction to move the stepper motor
  bool moveClockwise = targetPosition > currentPosition;
  // Calculate the number of steps to move
  int numSteps = abs(targetPosition - currentPosition);
  // Move the stepper motor step by step
  if (moveClockwise) {
    stepper.moveTo(targetPosition);
  } else {
    stepper.moveTo(-targetPosition);
  }
}


Here's the code.

The blocks will be the same. Only instead of "s5", there will be "S:".

Ah yes. I got it working now but for some reason, when I use the slider it only moves clockwise no matter, I tried to put back to slider backward it just only rotates clockwise.

Here's the full code:

#include <AccelStepper.h>
#include <MultiStepper.h>

#define STEPPER_STEP_PIN 5
#define STEPPER_DIR_PIN 4

AccelStepper stepper(AccelStepper::DRIVER, STEPPER_STEP_PIN, STEPPER_DIR_PIN);

void setup() {

  stepper.setMaxSpeed(1000);
}

void loop() {
  if (Serial.available() > 0) {
    state = Serial.readStringUntil('\n'); // Read the data as a string
    Serial.print(state + "\n");

    // If the slider has changed value - Move Stepper Motor
    if (state.startsWith("S:")) {
      String stateS = state.substring(2, state.length()); // Extract only the number, e.g. from "S:1120" to "1120"
      int targetPosition = stateS.toInt(); // Convert the string to an integer

      int currentPosition = stepper.currentPosition(); // Get the current position of the stepper motor

      // Move the stepper motor to the target position
      moveStepperToPosition(currentPosition, targetPosition);
    }
  }

  stepper.run(); // Move the stepper motor
}

void moveStepperToPosition(int currentPosition, int targetPosition) {
  // Determine the direction to move the stepper motor
  bool moveClockwise = targetPosition < currentPosition;

  // Calculate the number of steps to move
  int numSteps = abs(targetPosition - currentPosition);

  // Move the stepper motor step by step
  if (moveClockwise) {
    stepper.moveTo(targetPosition);
  } else {
    stepper.moveTo(-targetPosition);
  }
}

I got it work somehow, I've changed the code. Now, my problem is the responsiveness and the delay of the stepper motor.

Here's the code:

const int dirPin = 4;
const int stepPin = 5;
unsigned int stepsPerRevolution = 1;
int stepDelay = 20;

 //Base Rotation
    if (state.startsWith("s0")) {
      String stateS = state.substring(2, state.length());
      stpr0Pos = stateS.toInt();
      if (stpr0PPos > stpr0Pos) {
        baseRotateLeft();
        // delay(0.1);
      }
      if (stpr0PPos < stpr0Pos) {
        baseRotateRight();
        // delay(0.1);
      }
    }
    stpr0PPos = stpr0Pos;
  }

void baseRotateLeft() {
  //clockwise
  digitalWrite(dirPin, HIGH);
  // Spin motor
  for (int x = 0; x < stepsPerRevolution; x++) {
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(stepDelay);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(stepDelay);
  }
   delay(0.1);  // Wait a second
}

void baseRotateRight() {

  //counterclockwise
  digitalWrite(dirPin, LOW);
  // Spin motor
  for (int x = 0; x < stepsPerRevolution; x++) {
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(stepDelay);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(stepDelay);
    
  }
  delay(0.1);  // Wait a second
}

Was the servo working OK without delay? Because if it was then the delay probably caused by the stepper driving functions. Look into thoose functions how do they work. You can write your own based on that.

As also @Usane has already suggested, please be careful in using the Arduino delay() function because it stops completely the CPU therefore avoiding any other activity to be performed, even the interrupts and the I2C.

Futhermore the delay() function gets as a parameter a (unsigned long) number of milliseconds, so delay(0.1) isn't // wait a second.

To avoid the CPU blocking you'd rather make your own Delay() function, such as:

void Delay(unsigned long TimeToWait)
{
unsigned long now = millis();
while((millis()-now) < TimeToWait) ; // do nothing but leaving alive theCPU
}
use case:
Delay(1000); // wait one second

Best wishes.

I got it somehow working guys, I'm using the millis way, though there is still a quite delay when I swiftly change to another slider but it does work, it doesn't bug out the app and still continues.

Well,
if you have the Delay(1000); still active in your baseRotateRight() and baseRotateLeft(), this will delay any new BT incoming data handling.
Since you use a "for" instruction to perform the complete movement of the stepper motor, I guess that you don't need the Delay(1000); at the end of every movement. If you remove the Delay the responsiveness of the whole system shall increase.