Creating point cloud using arduino serial data and Python programming

Hi all,

I am creating a code a code to move the stepper motor by 1mm get the sensor measurements adn then repeat the scanning process every 1 mm. I am having trouble with stepper movement as the counter clockwise movement doesn't work as intended. After the stepper motor is done homing it should rotate counter clockwise but the counter clockwise movement is very slow and inconsistent no matter what accelstepper library function I try.

//initialising libraries

#include "AS5600.h"
#include "Wire.h"
#include <AccelStepper.h>
#include <MultiStepper.h>

//setting up pins

AS5600 sensor;             //  use default Wire (direction pin is 4)
AccelStepper m1(1, 8, 7);  // (m1 Driver mode, Pulse Pin, Direction Pin)
AccelStepper m2(1, 9, 6);  //  motor for coconut rotation

#define home_switch 2
#define limitDown 3
#define dirPin 4
#define m1Enable 12
#define m2Enable 13


//initializing variables
int moveFinish = 1;
long initial_homing = -1;  // Used to Home m1 at startup
int mSpeed = 1000;

byte values[7] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
const byte read[] = { 0x01, 0x04, 0x00, 0x00, 0x00, 0x02, 0x71, 0xCB };
const byte mode[] = { 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, 0x60, 0x0A };
const byte baud[] = { 0x01, 0x04, 0x00, 0x0E, 0x00, 0x02, 0x10, 0x08 };

const byte set_type_continuous[] = { 0x01, 0x10, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x01, 0x67, 0x90 };
const byte set_speed_high[] = { 0x01, 0x10, 0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x02, 0x26, 0x40 };

// // Initializing arrays
const int arraySize = 5000;  // Adjust the size according to your requirements
float angleArray[arraySize];
float fresultArray[arraySize];
int currentIndex = 0;

void setup() {

  Serial.begin(115200);
  Serial3.begin(115200);

  //magnetic encoder
  sensor.begin(dirPin);                    //  set direction pin.
  sensor.setDirection(AS5600_CLOCK_WISE);  // default, just be explicit.
  Serial.println(sensor.getAddress());
  Serial.print("Connect: ");
  Serial.println(sensor.isConnected());
  delay(200);

  //laser

  delay(200);
  Serial3.write(set_type_continuous, sizeof(set_type_continuous));
  delay(200);
  Serial3.write(set_speed_high, sizeof(set_speed_high));
  delay(200);

  //motor

  pinMode(home_switch, INPUT_PULLUP);
  pinMode(limitDown, INPUT_PULLUP);
  pinMode(12,LOW);
  pinMode(13,HIGH);
  attachInterrupt(digitalPinToInterrupt(home_switch), home, CHANGE);
  attachInterrupt(digitalPinToInterrupt(limitDown), terminate, LOW);

  m1.setMaxSpeed(5000);
  m1.setAcceleration(500);
  Serial.println("Vertical Stepper Motor is Homing!");

  while (digitalRead(home_switch)) {
    m1.moveTo(initial_homing);
    m1.setSpeed(5000);
    m1.runSpeed();
    initial_homing--;
  }
  m1.setCurrentPosition(0);
  Serial.println("Homing Complete!");
  delay(25);
  Serial.println("Moving Motor!");
}

void loop() {

  int inDist = 5;
  long steps = 1600;
  moveFinish = 0;
  static uint32_t lastTime = 0;
  float fresult = 0;
  float angle = 0;

  if (inDist < 0 || inDist > 400) {
    Serial.println("Invalid Travel Distance!");
    return;
  }
  if (inDist >= 0 && inDist <= 400) {
    m1.moveTo(length(inDist, steps));
    m1.setSpeed(1000);
    m1.setAcceleration(500);
    mRun();
    moveFinish = 1;
  }
  if (moveFinish == 1 && Serial3.available() > 0 && sensor.isConnected() == 1) {
    m2.setSpeed(mSpeed);
    m2.setAcceleration(500);
    m2.run();
    fresult = laser();
    angle = magEn();
    Serial.print("Coordinate ");
    Serial.print(currentIndex);
    Serial.print(" : ");
    Serial.print(fresult);
    Serial.print("\t");
    Serial.println(angle);

    // Store values in arrays
    angleArray[currentIndex] = angle;
    fresultArray[currentIndex] = fresult;
    currentIndex = (currentIndex + 1) % arraySize;
  }
}

long length(long x, long y) {
  return x * y*-1;
}

void home() {
}

void terminate() {
  m1.disableOutputs();
  m1.stop();
}

void mRun() {

  if (m1.distanceToGo() != 0) {
    m1.runToPosition();
  } else {
    m1.disableOutputs();
    m1.stop();
  }
}

float laser() {

  float x = 0;
  if (Serial3.write(read, sizeof(read))) {
    for (byte i = 0; i < 7; i++) {
      values[i] = Serial3.read();
    }

    Serial3.flush();

    if (values[0] == 0x01 && values[1] == 0x04 && values[2] == 0x04) {
      unsigned long int result = ((long)values[3] << 32) | ((long)values[4] << 16) | ((long)values[5] << 8) | (long)values[6];
      x = result / 1000.0;
    }
  }
  return x;
}

float magEn() {

  float d = 0;
  d = sensor.rawAngle() * AS5600_RAW_TO_DEGREES;
  return d;
}

I want to make the stepper motor move as intended previously do the scanning for 3 seconds and then repeat the 1 mm movement. I will atach a picture of how the wiring is done with a rough sketch in a comment .

mods please keep this code seperate from the previous post I made as I made a lot of changes to the code.

any advice on how I can change the code to make this work?

The motor I want to change the control of is the m1 motor as I have the m2 motor figured out.
I am using a tb600 stepper driver and the motor is US-17HS4401.

The homing is done through a limit switch connected to pin 2 mentioned in the code

In the drawing You have a GND symbol for ENA-, PUL- and DIR-. It needs to be connected to controller GND. Did You do that?
Is it a TB6600 driver? I use such drivers. What current limit is set?
Please post a link to the datasheet of the exact stepper model You use.

I'm sure this is not doing what you think. What you have actually done is set pin 12 to an input and pin 13 to an output.

TB660 driver link : https://bulkman3d.com/wp-content/uploads/2019/06/TB6600-Stepper-Motor-Driver-BM3D-v1.1.pdf

yes it is connected to the controller ground, I have fixed the issue and the loop. The current is set at 2.8-2.9. The only code line I had to change is the m1.runtoposition and it had to be the m1.runtonewposition.

#include "AS5600.h"
#include "Wire.h"
#include <AccelStepper.h>
#include <MultiStepper.h>

AS5600 sensor;
AccelStepper m1(1, 8, 7);
AccelStepper m2(1, 9, 6);

#define home_switch 2
#define limitDown 3
#define dirPin 4

int moveFinish = 1;
long initial_homing = -1;
int mSpeed = 1000;

byte values[7] = { 0 };
const byte read[] = { 0x01, 0x04, 0x00, 0x00, 0x00, 0x02, 0x71, 0xCB };
const byte set_type_continuous[] = { 0x01, 0x10, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x01, 0x67, 0x90 };
const byte set_speed_high[] = { 0x01, 0x10, 0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x02, 0x26, 0x40 };

bool running = false;
unsigned long startTime = 0;
unsigned long endTime = 0;
const uint32_t totalDuration = 6000;

void setup() {
  Serial.begin(115200);
  Serial3.begin(115200);

  sensor.begin(dirPin);
  sensor.setDirection(AS5600_CLOCK_WISE);
  Serial.println(sensor.getAddress());
  Serial.print("Connect: ");
  Serial.println(sensor.isConnected());
  delay(200);

  delay(200);
  Serial3.write(set_type_continuous, sizeof(set_type_continuous));
  delay(200);
  Serial3.write(set_speed_high, sizeof(set_speed_high));
  delay(200);

  pinMode(home_switch, INPUT_PULLUP);
  pinMode(limitDown, INPUT_PULLUP);
  m1.setEnablePin(12);
  m2.setEnablePin(13);
  attachInterrupt(digitalPinToInterrupt(home_switch), home, CHANGE);
  // attachInterrupt(digitalPinToInterrupt(limitDown), terminate, LOW);

  m1.enableOutputs();
  m1.setMaxSpeed(5000);
  m1.setAcceleration(1000);
  Serial.println("Vertical Stepper Motor is Homing!");

  while (digitalRead(home_switch)) {
    m1.moveTo(initial_homing);
    m1.setSpeed(-5000);
    m1.runSpeed();
    initial_homing--;
  }

  m1.setCurrentPosition(0);
  Serial.println("Homing Complete!");
  delay(25);
  Serial.println("Moving Motor!");
}

void loop() {
  int tsteps = 0;

  m2.enableOutputs();
  m2.setSpeed(3000);
  m2.setAcceleration(1000);
  m2.runSpeed();

  while (tsteps <= 450000) {
    startTime = millis();
    endTime = startTime;

    while ((endTime - startTime) <= totalDuration) {
      m1.setSpeed(mSpeed);
      m1.setAcceleration(500);
      m1.runToNewPosition(tsteps);
      moveFinish = 1;

      while (moveFinish == 1) {
        Serial.print("Coordinate : ");
        Serial.print(laser());
        Serial.print("\t");
        Serial.println(magEn());
        endTime = millis();

        if (endTime - startTime <= totalDuration) {
          moveFinish = 1;
        } else {
          moveFinish = 0;
        }
      }
    }
    tsteps = tsteps + 1600;
  }
  terminate();
}

void home() {
  // Home function implementation
}

void terminate() {
  m1.disableOutputs();
  m1.stop();
  m2.disableOutputs();
  m2.stop();
}


float laser() {
  float x = 0;
  if (Serial3.write(read, sizeof(read))) {
    for (byte i = 0; i < 7; i++) {
      values[i] = Serial3.read();
    }
    Serial3.flush();

    if (values[0] == 0x01 && values[1] == 0x04 && values[2] == 0x04) {
      unsigned long int result = ((long)values[3] << 32) | ((long)values[4] << 16) | ((long)values[5] << 8) | (long)values[6];
      x = result / 1000.0;
    }
  }
  return x;
}

float magEn() {
  float d = 0;
  d = sensor.rawAngle() * AS5600_RAW_TO_DEGREES;
  return d;
}


here is the updated code, now I am looking to transfer the data I read on the serial monitor to a python script to create a point cloud file. http://pointclouds.org/documentation/tutorials/pcd_file_format.html

i intend to use this point cloud file through the open 3d library to create a 3d mesh of the object created by the coordinates.

thank you for pointing that out I have changed the lines of coding now, but I am unable to understand how the low and high commands make the pin 12 and 13 a input and an output, could you please explain. thank you.

Take a look at the Arduino reference page for pinMode() and consider the values assigned to the symbols for "mode".

ok thank you

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