Stepper motor issue

I have placed some sensors on my stepper motor with an arduino which is transmitting the data to my laptop python program, however when I run this code the motor blocks for a fraction of milliseconds due to the calculation of the sensor values. Is there a way to incorporate a multithread in this code so as the motor run smoothly?

Here is the code:#include <AccelStepper.h>
#include <Adafruit_MLX90614.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>
#include <SPI.h>
#include <RF24.h>

#define dirPin 2
#define stepPin 3
#define motorInterfaceType 1

// Create a new instance of the AccelStepper class:
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified();

unsigned long previousMillis = 0; // Stores the last time temperature and current were read
const long interval = 1000; // Interval at which to read temperature and current (milliseconds)

const int analogInPin = A0; // Analog input pin that the current sensor is attached to
int sensorValue = 0; // Value read from the sensor
float voltage = 0; // Variable to store the voltage
float current = 0; // Variable to store the current

enum TaskState {
READ_TEMP,
READ_CURRENT,
READ_ACCEL,
PRINT_ALL,
TRANSMIT_ACCEL,
IDLE
};

TaskState taskState = IDLE;
float ambientTemp = 0.0;
float objectTemp = 0.0;
float acceleration_magnitude = 0.0;

void setup() {
Serial.begin(9600);
while (!Serial);

// Attempt to initialize MLX90614
if (!mlx.begin()) {
    //Serial.println("Error connecting to MLX sensor. Check wiring.");
}

// Attempt to initialize ADXL345
if (!accel.begin()) {
   // Serial.println("No valid ADXL345 sensor found");
}

stepper.setMaxSpeed(20000); // Maximum speed in steps per second
stepper.setSpeed(10000);    // Initial speed in steps per second

}

void loop() {
unsigned long currentMillis = millis();

// Non-blocking state machine for reading and transmitting data
switch (taskState) {
    case READ_TEMP:
        if (mlx.begin()) {
            ambientTemp = mlx.readAmbientTempC();
            if (isnan(ambientTemp)) {
                ambientTemp = 0;
            }

            objectTemp = mlx.readObjectTempC();
            if (isnan(objectTemp)) {
                objectTemp = 0;
            }
        }
        taskState = READ_CURRENT;
        break;

    case READ_CURRENT:
        sensorValue = analogRead(analogInPin);
        voltage = sensorValue * 5.0 / 1023.0;
        current = (voltage - 2.5) / 0.185;
        taskState = READ_ACCEL;
        break;

    case READ_ACCEL:
        if (accel.begin()) {
            sensors_event_t event;
            accel.getEvent(&event);
            acceleration_magnitude = sqrt(event.acceleration.x * event.acceleration.x +
                                          event.acceleration.y * event.acceleration.y +
                                          event.acceleration.z * event.acceleration.z);
            if (isnan(acceleration_magnitude)) {
                acceleration_magnitude = 0;
            }
        }
        taskState = PRINT_ALL;
        break;

    case PRINT_ALL:
        // Print all sensor values on a single line
        Serial.print(ambientTemp);
        Serial.print(",");
        Serial.print(objectTemp);
        Serial.print(",");
        Serial.print(current);
        Serial.print(",");
        Serial.print(acceleration_magnitude);
        Serial.println();
        taskState = TRANSMIT_ACCEL;
        break;

    case TRANSMIT_ACCEL:
        // Placeholder for transmitting acceleration data
        // Add your transmission code here
        taskState = IDLE;  // Go back to IDLE after transmission
        break;

    case IDLE:
        // Do nothing, wait for the next interval
        break;
}

// Check if it's time to read and print temperature and current
if (taskState == IDLE && (currentMillis - previousMillis >= interval)) {
    previousMillis = currentMillis;
    taskState = READ_TEMP;
}

// Check for serial input to adjust the motor speed
if (Serial.available() > 0) {
    String input = Serial.readStringUntil('\n');
    float newSpeed = input.toFloat();
    stepper.setSpeed(newSpeed);
   // Serial.print("Motor speed set to: ");
   // Serial.println(newSpeed);
}

// Continuous motor run
stepper.runSpeed();

}

Even though i remove this line, it continues to block. Is there a multithreading option?

Use a much higher Baud rate for serial.Print(). Only print if something changes from the previous value.

Be sure to format and post your code using the < CODE > button... your posted code should look like this:

#include <AccelStepper.h>
#include <Adafruit_MLX90614.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>
#include <SPI.h>
#include <RF24.h>

#define dirPin 2
#define stepPin 3
#define motorInterfaceType 1

// Create a new instance of the AccelStepper class:
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified();

unsigned long previousMillis = 0; // Stores the last time temperature and current were read
const long interval = 1000; // Interval at which to read temperature and current (milliseconds)
const int analogInPin = A0; // Analog input pin that the current sensor is attached to
int sensorValue = 0; // Value read from the sensor
float voltage = 0; // Variable to store the voltage
float current = 0; // Variable to store the current

enum TaskState {
  READ_TEMP,
  READ_CURRENT,
  READ_ACCEL,
  PRINT_ALL,
  TRANSMIT_ACCEL,
  IDLE
};
TaskState taskState = IDLE;

float ambientTemp = 0.0;
float objectTemp = 0.0;
float acceleration_magnitude = 0.0;

void setup() {
  Serial.begin(9600);
  while (!Serial);
  // Attempt to initialize MLX90614
  if (!mlx.begin()) {
    //Serial.println("Error connecting to MLX sensor. Check wiring.");
  }
  // Attempt to initialize ADXL345
  if (!accel.begin()) {
    // Serial.println("No valid ADXL345 sensor found");
  }
  stepper.setMaxSpeed(20000); // Maximum speed in steps per second
  stepper.setSpeed(10000);    // Initial speed in steps per second
}

void loop() {
  unsigned long currentMillis = millis();
 
  // Non-blocking state machine for reading and transmitting data
  switch (taskState) {
    case READ_TEMP:
      if (mlx.begin()) {
        ambientTemp = mlx.readAmbientTempC();
        if (isnan(ambientTemp)) {
          ambientTemp = 0;
        }
        objectTemp = mlx.readObjectTempC();
        if (isnan(objectTemp)) {
          objectTemp = 0;
        }
      }
      taskState = READ_CURRENT;
      break;
    case READ_CURRENT:
      sensorValue = analogRead(analogInPin);
      voltage = sensorValue * 5.0 / 1023.0;
      current = (voltage - 2.5) / 0.185;
      taskState = READ_ACCEL;
      break;
    case READ_ACCEL:
      if (accel.begin()) {
        sensors_event_t event;
        accel.getEvent(&event);
        acceleration_magnitude = sqrt(event.acceleration.x * event.acceleration.x +
                                      event.acceleration.y * event.acceleration.y +
                                      event.acceleration.z * event.acceleration.z);
        if (isnan(acceleration_magnitude)) {
          acceleration_magnitude = 0;
        }
      }
      taskState = PRINT_ALL;
      break;
    case PRINT_ALL:
      // Print all sensor values on a single line
      Serial.print(ambientTemp);
      Serial.print(",");
      Serial.print(objectTemp);
      Serial.print(",");
      Serial.print(current);
      Serial.print(",");
      Serial.print(acceleration_magnitude);
      Serial.println();
      taskState = TRANSMIT_ACCEL;
      break;
    case TRANSMIT_ACCEL:
      // Placeholder for transmitting acceleration data
      // Add your transmission code here
      taskState = IDLE;  // Go back to IDLE after transmission
      break;
    case IDLE:
      // Do nothing, wait for the next interval
      break;
  }
 
  // Check if it's time to read and print temperature and current
  if (taskState == IDLE && (currentMillis - previousMillis >= interval)) {
    previousMillis = currentMillis;
    taskState = READ_TEMP;
  }
  // Check for serial input to adjust the motor speed
  if (Serial.available() > 0) {
    String input = Serial.readStringUntil('\n');
    float newSpeed = input.toFloat();
    stepper.setSpeed(newSpeed);
    // Serial.print("Motor speed set to: ");
    // Serial.println(newSpeed);
  }
  // Continuous motor run
  stepper.runSpeed();
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.