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.