Stepper motor control with OSC and AccelStepper issue

Hi all !

I'm trying to continuously control the movement of a stepper motor using OSC and the AccelStepper library with an Arduino MKR WIFI 1010.

Right now the setup is functionnal and i am able to receive OSC data and move the stepper accordingly. However when continuously reading the value for the position, the stepper rattles and stutters. My guess is there is a conflict when calling OscWiFi.update() and stepper.run(). It doesn't seem to be affected this bad when i use a potentiometer to move the stepper.

Testing with a simple example library code everything runs smoothly.

Here is the relevant code :

#include <AccelStepper.h>
#include <ArduinoOSCWiFi.h>
#include "secrets.h"


const long minPosition = 0;
const long maxPosition = -800;
float targetPositionOSC = 0; // Default starting value
float targetPositionA = 0;
const int maxSpeed = 2000;
const int acceleration = 500;

// Stepper setup
#define STEP_PIN 2
#define DIR_PIN 3
#define POT_PIN A5

AccelStepper stepper1(AccelStepper::DRIVER, STEP_PIN, DIR_PIN);

void setup() {
  ///WIFI stuff
  Serial.begin(115200);

  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    while (true);
  }

  WiFi.begin(ssid, pwd);
  Serial.println("Waiting for connection to WiFi");
  WiFi.config(ip, gateway, subnet);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }

  Serial.print("WiFi connected, IP = ");
  IPAddress ip = WiFi.localIP();
  Serial.println(ip);
  Serial.println("Connected to WiFi network.");

  /// Subscribe to OSC 
  OscWiFi.subscribe(recv_port, "/test", targetPositionOSC); 
  /// Set default stepper settings
  stepper1.setMaxSpeed(maxSpeed); 
  stepper1.setAcceleration(acceleration);
  stepper1.setCurrentPosition(0);
}

void loop() {

  // Read potentiometer and map to target position
  //int potValue = analogRead(POT_PIN);
  //long targetPositionA = map(potValue, 0, 1023, minPosition, maxPosition);

  OscWiFi.update();

  stepper1.moveTo(targetPositionOSC);
  // Run the stepper motor (non-blocking)
  stepper1.run();

}

A work around i found is to poll for OSC updates at intervals using

 unsigned long now = millis();

  // Delay OSC
  if (now - lastUpdate >= updateInterval) {
    OscWiFi.update(); 
    lastUpdate = now;
  }

Hover i'd like to continuously control the stepper, is there any way to do it without conflicting with the stepper.run() command ?

Thanks for your time !

What's OSC (link)?

If you observe differences between the intended and real motor position then you have to use stronger component (motor, supply. driver...).

Thank you, OSC is a multimedia networking protocol. In this case i use the ArduinoOSC library

There is no absolute position difference but the motor is slower to react to incoming data and rattles and jitters.

Then split your project into one controller for the stepper and another one for the OSC communication.

I think you call stepper1.moveTo(targetPositionOSC); too often. It doesn't make sense to call it faster then steps are generated. And if I remember correctly the run() function runs into problems if the target is changed too quickly.

how is updateInterval set in your workaround?

N.B. It doesn't make sense too to use a float variable as target position. The target position for a stepper can only be an integer.

Thanks, the updateInterval is set as a constant.
Here is my full code with the workaround. I have to use stepper1.runToPosition() instead of stepper1.run() . The movement is smooth but the updates cannot be very close together so realtime is not possible.

#include <AccelStepper.h>
#include <ArduinoOSCWiFi.h>
#include "secrets.h"


const long minPosition = 0;
const long maxPosition = -800;
float targetPositionOSC = 0; // Default starting value
float targetPositionA = 0;
const int maxSpeed = 2000;
const int acceleration = 500;

// Timing control
unsigned long lastUpdate = 0;
const unsigned long updateInterval = 1000; // ms between updates


// Stepper setup
#define STEP_PIN 2
#define DIR_PIN 3
#define POT_PIN A5

AccelStepper stepper1(AccelStepper::DRIVER, STEP_PIN, DIR_PIN);

void setup() {
  ///WIFI stuff
  Serial.begin(115200);

  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    while (true);
  }

  WiFi.begin(ssid, pwd);
  Serial.println("Waiting for connection to WiFi");
  WiFi.config(ip, gateway, subnet);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }

  Serial.print("WiFi connected, IP = ");
  IPAddress ip = WiFi.localIP();
  Serial.println(ip);
  Serial.println("Connected to WiFi network.");

  /// Subscribe to OSC 
  OscWiFi.subscribe(recv_port, "/test", targetPositionOSC); 
  /// Set default stepper settings
  stepper1.setMaxSpeed(maxSpeed); 
  stepper1.setAcceleration(acceleration);
  stepper1.setCurrentPosition(0);
}

void loop() {

  // Read potentiometer and map to target position
  //int potValue = analogRead(POT_PIN);
  //long targetPositionA = map(potValue, 0, 1023, minPosition, maxPosition);

  //Timing workaround
  unsigned long now = millis();
  if (now - lastUpdate >= updateInterval) {
    OscWiFi.update(); // Process incoming OSC messages
    lastUpdate = now;
  }

  //OscWiFi.update();

  stepper1.moveTo(targetPositionOSC);
  // Run the stepper motor (non-blocking)
  //stepper1.run();
  stepper1.runToPosition();

}

runToPosition is blocking.

You can try this ( untested ) and then vary updateIntervall to get the best compromise between fast reaction and smooth move.

void loop() {

  //Timing workaround
  unsigned long now = millis();
  if (now - lastUpdate >= updateInterval) {
    OscWiFi.update(); // Process incoming OSC messages
    lastUpdate = now;
    stepper1.moveTo(targetPositionOSC);
  }

  // Run the stepper motor (non-blocking)
  stepper1.run();

Hi, @emqs

Can you please post links to:
Stepper Motor
Stepper Driver
Power Supply

Can you please post a copy of your circuit, a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.

Can you post some images of your project?
So we can see your component layout.

What is the stepper motor load?

I know it is a lot, BUT we need to know if it is a basic hardware problem before hitting the software.

Thanks.. Tom.... :smiley: :+1: :coffee: :australia: