Homing sequence doesn't work

I have a Clearcore/clearpath combo meant to move a linear system to a desired length for cutting. The system needs a home reference and has a routine but will set the home reference no matter where it is. The limit switch is a NC switch as far as I know. Its connected via POS and Signal.

#include "ClearCore.h"

#define MOTOR_AT_HOME 1
#define MOTOR_NOT_AT_HOME 2
#define Home_pin A9  //Connect homing probe to A9

int HomeSensorState;

// Function to detect the state of the home sensor switch
void detectHomeSensorState();

// Function to set the state of the home sensor switch
void setHomeSensorState() {
  // Read the state of the limit switch connected to analog pin 9
  int switchState = analogRead(Home_pin);
  Serial.println(switchState);

  // If the switch is  triggered, set Motr at home
  if (switchState == LOW) {
    motor.MoveStopAbrupt();
    motor.PositionRefSet(0);
    Serial.println("Homed - interrupt");
    HomeSensorState = MOTOR_AT_HOME;
  }

  // If the switch is not triggered, motor is not home
  {
    HomeSensorState = MOTOR_NOT_AT_HOME;
  }
}

// Function to get the state of the home sensor switch
int getHomeSensorState() {
  return HomeSensorState;
}

// Function to initialize homing
void InitHoming() {
  // Set up the interrupt pin in digital input mode.
  pinMode(Home_pin, INPUT);

  // Set an ISR to be called when the state of the interrupt pin goes from
  // true to false.
  attachInterrupt(digitalPinToInterrupt(Home_pin), detectHomeSensorState, RISING);

  // Enable digital interrupts.
  interrupts();
}


//Put the bladesaw's state based on switch on and off on ClearCore
//SET MOTOR_AT_HOME or MOTOR_NOT_AT_HOME
void detectHomeSensorState() {

  // Read the state of the limit switch connected to digital pin 7
  int switchState = analogRead(Home_pin);

  // If the switch is  triggered, set Motr at home
  if (switchState < 2800) {
    motor.MoveStopAbrupt();
    motor.PositionRefSet(0);
    Serial.print("Homed - sensor, triggered at ");
    Serial.println(switchState);
    HomeSensorState = MOTOR_AT_HOME;
    delay(50);  //Testing, change to 50
  }

  // If the switch is not triggered, motor is not home
  else {
    HomeSensorState = MOTOR_NOT_AT_HOME;
  }
}

// Function to home the motor
void UserSeeksHome(void) {  //Check step direction, whether clockwise or anticlockwise is toward blade
                            /* Move towards the blade for homing, then repeat much more slowly to prevent blade deflection. Needs to be adjusted to use limit switch as probe */
  // Commands a speed of 10000 pulses/sec away from blade for 0.5 seconds

  Serial.println("Homing . . . Waiting for motor to finish");
  motor.MoveVelocity(10000);  //Move away from blade
  delay(500);
  motor.MoveVelocity(-12000);  //Move towards blade
  Serial.println("homing");

  delay(100);
  detectMotorStates(0);

  // Wait for the motor to stop and for the HLFB state to be asserted
  while (MotorRunState != MOTOR_STOPPED || motor.HlfbState() != MotorDriver::HLFB_ASSERTED) {

    detectHomeSensorState();
    detectMotorStates(0);

    continue;
  }

  //Back out after touching the probe, like 3D-printer homing
  motor.MoveVelocity(6400);
  delay(300);
  motor.MoveVelocity(-400);  //0.0625 revolutions per second

  delay(100);
  detectMotorStates(0);

  // Wait for the motor to stop and for the HLFB state to be asserted
  while (MotorRunState != MOTOR_STOPPED || motor.HlfbState() != MotorDriver::HLFB_ASSERTED) {

    detectHomeSensorState();
    detectMotorStates(0);

    continue;
  }

  return;
}


Here is the wiring Diagram

This should be a digitalRead():

int switchState = analogRead(Home_pin);

Even with changing it to digital, the issue persists

Is there some code missing?
Should you be using INPUT_PULLUP?

Can you post your entire sketch?

  1. It looks like you left out an else which results in HomeSensorState always set to MOTOR_NOT_AT_HOME when you call setHomeSensorState() :
  if (switchState == LOW) {
    motor.MoveStopAbrupt();
    motor.PositionRefSet(0);
    Serial.println("Homed - interrupt");
    HomeSensorState = MOTOR_AT_HOME;
  }

  // If the switch is not triggered, motor is not home
  {
    HomeSensorState = MOTOR_NOT_AT_HOME;
  }
  1. You have detectHomeSensorState() being called as an ISR and from other functions. In an ISR you should never use delay() or serial I/O.

@anon56112670 It is a ClearCore motion controller. https://teknic.com/products/io-motion-controller/

I'm not sure if pullup/down resistors are included for I/O points. It has a 32-bit ARM Cortex M4F processor.

It is a large set up sketches. Is there something in particular you'd like to see from it?

The part that doesn't work.

Srsly, if you have a code issue you can't see, anyone helping would need to sit down at your 'puter and start digging in.

Where you at, how long you gonna be up? :wink:

a7

1 Like

This is my .ino

Setup:
  Using Arduino IDE, compile and upload this program onto a Teknic Clearcore. 
  ***Make sure to have the Teknic libraries and board installed through their respective managers.
  Physical requirements:
    Clearcore Controller
    Clearpath Motor
    Limit switches mounted on clamp/bandsaw
    4D Systems Display
    Appropriate power and data cables
    Respective power supplies (24VDC for Clearcore, 75VDC for Clearpath)
  
  ***Before attempting to run this program, make sure the motor has been tuned to the load it will move
  ***This requires a programming cable and the ClearPath MSP software
  
  Connect motor to port labelled "M0" on the Clearcore
  4D systems display to COM1 via cat5 or better ethernet cable.
  Homing probe to A-9
  Bandsaw limit switch to DI-6

*/
#include "Blade_Saw.h"
#include "Servo_Motor.h"
#include "HomeSensor.h"
#include <genieArduinoDEV.h>
#include <ClearCore.h>

//
// User defined parameters. Defaults shown in comment
float OffsetMM = 116.02; //Current offset is 116.11 MM, measured from back of clamp to blade when homed.



Genie genie;

//----------------------------------------------------------------------------------------
// Define the ClearCore COM port connected to the HMI
// This must be done using both the Arduino wrapper "Serialx" and ClearCore library "ConnectorCOMx"
// because both interfaces are used below

#define SerialPort Serial1      // ClearCore UART Port, connected to 4D Display COM1
#define CcSerialPort ConnectorCOM1   // ClearCore UART Port, connected to 4D Display COM1

//----------------------------------------------------------------------------------------

// ClearCore Baud Rate, for 4D Display
#define baudRate 9600


int i, k;
char text[100];
int loops = 0;                        // Used for the Form0 animation sequence
int CurrentForm = -1;                 // The current Form/Page we are on right now
int PreviousForm = -1;                // The Form/Page we came from
int LEDDigitToEdit = -1;              // The LED Digit index which will be edited
int DigitsToEdit = -1;                // The number of digits in the LED Digit being edited

int MotorProgInputRes = 6400;         // Motor Programmed Input Resolution (Change this if you change the motor value in MSP)
int SecondsInMinute = 60;             // Seconds in a minute


//Stored Variables and defaults
int MoveDist = 0;
int MoveDistLast = 0;
bool fault = false;
int NextForm = 0;
int CutPosition = 0;
int PositionTarget = 0;
int UserDist = 0;
float UnitMM = 1256.7739391179;//steps per mm
float UnitIN = 31921.6922438822;
float UnitFactor = UnitMM;  //Default: Millimeters to steps
float LengthMin = OffsetMM*UnitMM;         //Offset to account for clamp depth and distance from blade
float LengthMax = 550000;               //Length in steps from blade
bool UserUnits = true;
String Units = "Millimeters";         //Default Units
float UnitMin = LengthMin/UnitMM; //Minimum length in millimeters, updated later
float UnitMax = LengthMax/UnitMM; //Maximum length in millimeters, updated later

//Genie Form Item indeces - These correspond to internal labels for the genie objects
int DistGenieNum = 0;
int StartProcessGenieNum = 0;
int faultLEDGenieNum = 0;
int ClrfaultGenieNum = 1;
int DistEditGenieNum = 2;
int UnitSwitchNum0 = 0;
int UnitSwitchNum1 = 1;

int StopMotionGenieNum = 3;

int GoMainGenieNum = 4;
int ClampConfirmGenieNum = 5;

int FinishedCuttingGenieNum = 6;

int CutSameGenieNum = 7;
int NewCutGenieNum = 8;

int EditInputDigitNum = 1;
int BackGenieNum = 9;
int KeypadGenieNum = 0;

char keyvalue[10];                    // Array to hold keyboard character values
int counter = 0;                      // Keyboard number of characters
int temp, sumTemp;                    // Keyboard Temp values


void setup() {
  InitMotorParams();
  InitHoming();

  // Sets up serial communication and waits up to 5 seconds for a port to open.
  // Serial communication is not required for this example to run.
  Serial.begin(baudRate);
  
  // Open the HMI serial port and wait until communication has been established
  ConnectorCOM1.RtsMode(SerialBase::LINE_OFF);
  SerialPort.ttl(true);     // Set the Clearcore UART to be TTL
  SerialPort.begin(baudRate); // Set up Serial1 using the Arduino Serial Class @ 9600 Baud
  Serial.println("Comms Open");
  while (!SerialPort) {
    continue;
  }

  delay(3000); // Delay to allow Terminal to wake up to capture first debug messages

  while (!genie.Begin(SerialPort));

  if (genie.IsOnline()) // When the display has responded above, do the following once its online
  {
    genie.AttachEventHandler(myGenieEventHandler); // Attach the user function Event Handler for processing events
    Serial.println("Genie attached"); 
  }
  resetMotor();

  genie.SetForm(0); // Change to Form 0 
  CurrentForm = 0;

  genie.WriteContrast(15); // Max Brightness (0-15 range)
}

void loop() {
  
  static unsigned long waitPeriod = millis();

  //Need to keep monitoring both home sensor and blade states
  detectMotorStates(CutPosition);
  detectBladeState();

  genie.DoEvents(); // This calls the library each loop to process the queued responses from the display

  // waitPeriod later is set to millis()+50, running this code every 50ms
  if (millis() >= waitPeriod)
  {
    CurrentForm = genie.GetForm(); // Check what form the display is currently on

    switch (CurrentForm)
    {
      /************************************* FORM 0 *********************************************/

      case 0:         // If the current Form is 0 - Splash Screen
        // Keeping the splash screen open for 5 seconds
        delay(1000);
        genie.SetForm(1); // Change to main screen
        break;

      /************************************* FORM actions *********************************************/
      
      case 1: //main screen
        if (UserDist != MoveDistLast)
          {
            genie.WriteObject(GENIE_OBJ_LED_DIGITS, DistGenieNum, UserDist); // Update Move Distance
            MoveDistLast = UserDist;
          }
          
        break;

      case 2: //Motor In Motion Screen 
        detectMotorStates(PositionTarget);
        if(MotorLocationState == MOTOR_IN_CUT_POSITION)
        {
          if(MotorRunState == MOTOR_STOPPED)
          {
            delay(500);
            genie.SetForm(NextForm); //Switch to whatever NextForm is
          }
        }   
        break;

      case 3: //Bolt Clamp Confirmation screen

        break;

      case 4://Start Cut Screen

        break;

      case 5: //Cut Finished Screen
        
        break;
      
      case 6: //Edit Length Screen
        
        break;
      
    }

      // If a new fault is detected, turn on the  fault LED
      if (motor.StatusReg().bit.AlertsPresent && !fault)
      {
        fault = true;
        Serial.println(" status: 'In Alert'");
        genie.WriteObject(GENIE_OBJ_USER_LED, 0, 1);//Set user led 1, to value 1(On)
      }
      // If the fault has sucessfully been cleared, turn off the  fault LED
      else if (!motor.StatusReg().bit.AlertsPresent && fault)
      {
        fault = false;
        genie.WriteObject(GENIE_OBJ_USER_LED, 1, 0);
      }

    waitPeriod = millis() + 50; // rerun this code in another 50ms time.
  }
}


void myGenieEventHandler(void)
{
  genieFrame Event;
  genie.DequeueEvent(&Event); // Remove the next queued event from the buffer, and process it below

  //If the cmd received is from a Reported Event (Events triggered from the Events tab of Workshop4 objects)
  if (Event.reportObject.cmd == GENIE_REPORT_EVENT)
  {
    if (Event.reportObject.object == GENIE_OBJ_4DBUTTON)              // If the Reported Message was from a 4DButton
    {

      /***************************** Form 4D Buttons **************************/
         //None used
    
    }

    if (Event.reportObject.object == GENIE_OBJ_ISWITCH)              // If the Reported Message was from a ISwitch
    {

      /***************************** Form Switch **************************/
        
      //Check for Switch Change
      if (Event.reportObject.index == UnitSwitchNum0)                         //the index of the Main Screen UnitSelect Switch 
      {
        UserUnits = genie.GetEventData(&Event); //Read the value of the UnitSelect switch
        // write object
        genie.WriteObject(GENIE_OBJ_ISWITCH, UnitSwitchNum1, UserUnits);
        //ON is Inches, Off is millimeters
        Serial.print("Units changed. ");
        if(UserUnits)
        {
          UnitFactor = UnitIN;//Inches to steps
          Units = "Inches";
          UnitMin = LengthMin/UnitFactor;//steps to inches
          UnitMax = LengthMax/UnitFactor;//steps to inches
          
        }else
        {
          UnitFactor = UnitMM;//Millimeters to steps
          Units   = "Millimeters";
          UnitMin = LengthMin/UnitFactor;//steps to mm
          UnitMax = LengthMax/UnitFactor;//steps to mm
        }
        Serial.print(Units);
        
        
      }else if (Event.reportObject.index == UnitSwitchNum1)                 //the index of the Edit Screen UnitSelect Switch
      {
        UserUnits = genie.GetEventData(&Event); //Read the value of the UnitSelect switch
        // write object
        genie.WriteObject(GENIE_OBJ_ISWITCH, UnitSwitchNum0, UserUnits);
        //ON is Inches, Off is millimeters
        Serial.print("Units changed. ");
        if(UserUnits)
        {
          UnitFactor = UnitIN;//Inches to steps
          Units = "Inches";
          UnitMin = LengthMin/UnitFactor;//steps to inches
          UnitMax = LengthMax/UnitFactor;//steps to inches
          
        }else
        {
          UnitFactor = UnitMM;//Millimeters to steps
          Units   = "Millimeters";
          UnitMin = LengthMin/UnitFactor;//steps to mm
          UnitMax = LengthMax/UnitFactor;//steps to mm
        }
        Serial.print(Units);
        
      }
    
    }

    if (Event.reportObject.object == GENIE_OBJ_WINBUTTON)             // If the Reported Message was from a WinButton
    {
      /*
      //check for back button press
        if (Event.reportObject.index == BackGenieNum)        // If Winbutton3 (Index = 3) - 0 Information Back
        {
          genie.SetForm(3);                                             // Change to Main Screen
        }
      */

      /***************************** Main Screen Winbuttons **************************/
        
        //Check for clear fault press
        if (Event.reportObject.index == ClrfaultGenieNum)                         //8 is the index of the clear fault button 
        {
          Serial.println(" Clearing fault if present");
          if (motor.StatusReg().bit.AlertsPresent)                     // If the ClearLink has an Alert present
          {
            if (motor.StatusReg().bit.MotorInFault)                    // Check if there also is a motor shutdown
            {
              InitMotorParams();
              motor.EnableRequest(false);
              delay(10);
              motor.EnableRequest(true);                               // Cycle the enable to clear the motor fault
            }
            motor.ClearAlerts();                                       // Clear the Alert
          }
        }
        
        //check for edit press
        else if (Event.reportObject.index == DistEditGenieNum)                        // If Winbutton6 (Index = 6) - 0 Move Distance Edit
        { Serial.println("Edit pressed");
          if (MotorRunState == MOTOR_STOPPED)
          {
            
            PreviousForm = 1;                                         // Always return to the main screen
            LEDDigitToEdit = DistGenieNum;                     // The LED Digit which will take this edited value
            DigitsToEdit = 5;                                             // The number of Digits (4 or 5)
            genie.WriteObject(GENIE_OBJ_LED_DIGITS, EditInputDigitNum, 0);               // Clear any previous data from the Edit Parameter screen //FIXME
            genie.SetForm(6);                                               // Change to Form 6 - Edit Parameter
            Serial.println("Edit passed");
          }//else alert user something here
        }

        //Check for Start Process press
        else if (Event.reportObject.index == StartProcessGenieNum)
        {
          if (!motor.StatusReg().bit.AlertsPresent && (MotorRunState == MOTOR_STOPPED) && (BladeState == BLADE_DOWN))
          {
            
            NextForm = 3; //Go to Clamp Confirmation after MotorMotion screen
            PositionTarget = LoadPosition;
            genie.SetForm(2);
            delay(1500);//Let user see the screen
            UserSeeksHome();
            Serial.print("Broke home loop, States: (Running,Location)");
            Serial.print(MotorRunState);
            Serial.println(MotorLocationState);
            delay(100);
            MoveAbsolutePosition((int)LoadPosition); //Move to Loading position
            Serial.println("Start passed");
            // Serial.println(NextForm);
          
          }
        }

      /***************************** Motor In Motion Screen Winbutton **************************/

      if (Event.reportObject.index == StopMotionGenieNum)                             // If the stop button is pressed
      {
        motor.MoveStopAbrupt(); //Immediately stop the motor
        genie.SetForm(1); //return to main screen
      }

      /***************************** Clamp Confirmation Screen Winbuttons **************************/
      if (Event.reportObject.index == GoMainGenieNum)                             // If 'Go Back' is pressed
      {
        if (MotorRunState == MOTOR_STOPPED)
        {
          genie.SetForm(1); //Return to main screen
        }
      }

      if (Event.reportObject.index == ClampConfirmGenieNum)                             // If Proceed is pressed
      {
        if (MotorRunState == MOTOR_STOPPED)
        {
          if (BladeState == BLADE_UP)
          {
            NextForm = 4; //go to Begin cutting screen after MotorMotion Screen
            CutPosition = abs(UserDist/100*UnitFactor-LengthMin);
            PositionTarget = CutPosition;
            genie.SetForm(2); //Motor in Motion Screen
            delay(1000);
            
            Serial.println(CutPosition);
            Serial.println(UserDist);
            Serial.println(UnitFactor);
            MoveAbsolutePosition((int)CutPosition); 
            /*
            Needs to be scaled from user input (Inches/millimeters) to steps
            CutPosition = UserDist*UnitFactor-LengthMin

            CutPosition - Value in steps of distance for bolt cutting (Int)
            UserDist    - Input from user, could be Inches/Millimeters (Int)
            UnitFactor  - Conversion from Inches/Millimeters to steps, dependent on UserUnit Value (Int)
            UserUnit    - Set by user on Main Screen, sets the value of UnitFactor (Bool)
            LengthMin   - Smallest Bolt that can be cut because of clamp depth and its distance to the blade (Int steps, predetermined)
            */
          }
        }

      }
      /***************************** Begin Cutting Screen Winbutton **************************/

      if (Event.reportObject.index == FinishedCuttingGenieNum)                             // If Finished cut is pressed
      {
        if (MotorRunState == MOTOR_STOPPED)
        {
          if (BladeState == BLADE_DOWN)
          {
            genie.SetForm(5);//Go to cut finished screen
          }
        }
      }

      /***************************** User Finished Screen Winbutton **************************/

      if (Event.reportObject.index == CutSameGenieNum)                             // If Cut same size is pressed
      {
        if (MotorRunState == MOTOR_STOPPED)
        {
          genie.SetForm(3); //Go back to Clamp Confirmation
        }
      }

      if (Event.reportObject.index == NewCutGenieNum)                             // If Cut same size is pressed
      {
        if (MotorRunState == MOTOR_STOPPED)
        {
          genie.SetForm(1); //Go back to main screen
        }
      }

      /***************************** Keypad Screen Winbuttons **************************/

      if (Event.reportObject.index == BackGenieNum)                             // If Cancel is pressed
      {
        if (MotorRunState == MOTOR_STOPPED)
        {
          //Clear any partially entered values from Keyboard, ready for next time
          for (int f = 0; f < 5; f++)
          {
            keyvalue[f] = 0;
          }
          counter = 0;
  
          genie.WriteObject(GENIE_OBJ_LED_DIGITS, EditInputDigitNum, 0);               // Undo changes visible on keypad
          genie.SetForm(PreviousForm);                                  // Change to Previous Form
        }
      }
    }

    /***************************** Form 5 Keyboard **************************/

    if (Event.reportObject.object == GENIE_OBJ_KEYBOARD)
    {
      if (Event.reportObject.index == 0)                                  // If keyboard0
      {
        temp = genie.GetEventData(&Event);                                // Store the value of the key pressed
        if (temp >= 48 && temp <= 57 && counter < DigitsToEdit)           // Convert value of key into Decimal, 48 ASCII = 0, 57 ASCII = 9, DigitsToEdit is 4 or 5 digits
        {
          keyvalue[counter] = temp;                                       // Append the decimal value of the key pressed, into an character array
          sumTemp = atoi(keyvalue);                                       // Convert the array into a number
          if (DigitsToEdit == 5)                                          // If we are dealing with a parameter which takes a 5 digit number
          {
            Serial.println(sumTemp);
            
            if (sumTemp > 65535)                                          // If the number is > 16 bits (the max a Genie LED Digit can be sent)
            {
              sumTemp = 65535;                                            // Limits the max value that can be typed in on a 5 digit parameter, to be 65535 (16 bit number)
            }
          }

          genie.WriteObject(GENIE_OBJ_LED_DIGITS, EditInputDigitNum, sumTemp);           // Prints to LED Digit 18 on Form 5 (max the LED digits can take is 65535)
          counter = counter + 1;                                          // Increment array to next position ready for next key press
        }
        else if (temp == 8)                                               // Check if 'Backspace' Key
        {
          if (counter > 0)
          {
            counter--;                                                    // Decrement the counter to the previous key
            keyvalue[counter] = 0;                                        // Overwrite the position in the array with 0 / null
            genie.WriteObject(GENIE_OBJ_LED_DIGITS, EditInputDigitNum, atoi(keyvalue));  // Prints the current array value (as an integer) to LED Digit 18 on Form 5
          }
        }
        else if (temp == 13)                                              // Check if 'Enter' Key
        {
          if(sumTemp > UnitMax*100)                                         // If entered value is above maximum length, default to maximum length
            {
              sumTemp = UnitMax*100;
              Serial.println(sumTemp);
              Serial.println(UnitMax);        
            }
            if(sumTemp < UnitMin*100)                                         // If entered value is below minimum length, default to minimum length
            {
              sumTemp = UnitMin*100;
              Serial.println(sumTemp);
              Serial.println(UnitMin);
            }
          int newValue = sumTemp;
          //Serial.println(newValue);                                     // for debug

          //Clear values ready for next time
          sumTemp = 0;
          for (int f = 0; f < 5; f++)
          {
            keyvalue[f] = 0;
          }
          counter = 0;

          UserDist = newValue; 
          
          genie.SetForm(PreviousForm);            // Return to the Form which triggered the Keyboard
        }
      }
    }
  }
}

Blade_Saw.h

/* 
 *  Assumes normally-closed blade state switch
*/
#include "ClearCore.h"

#define BLADE_UP 7
#define BLADE_DOWN 8
#define Blade_State_Pin DI6 //Connect Saw limit switch to DI6

int BladeState;


void setBladeState(int state) {
  BladeState = state;
}

int getBladeState() {
  return BladeState;
}



//Put the bladesaw's state based on switch on and off on ClearCore
//SET BLADE_UP or BLADE_DOWN
void detectBladeState() {
  // Read the state of the limit switch connected to digital I/O 16
  int switchState = digitalRead(Blade_State_Pin);

  // If the switch is not triggered, set BladeState to BLADE_UP
  if (switchState == LOW) {
    setBladeState(BLADE_UP);
  }
  // If the switch is triggered, set BladeState to BLADE_DOWN
  else {
    setBladeState(BLADE_DOWN);
  }
}

servo_motor.h

/* 
* This is the header file for the servo controls
* In short, this allows for motor setup and use based on user interactions 
* Motor speed can be defined by changing DesiredRPM. This only affects movement towards cutting position. 
* Homing has its own speed. Recommended maximum: 500 RPM
* WARNING: Do not exceed the maximum as high speeds are not tested for accuracy or stability
* Recommended value: 350 RPM or less
*/
#include "ClearCore.h"

#define MOTOR_IS_MOVING 3
#define MOTOR_STOPPED 4
#define MOTOR_IN_CUT_POSITION 5
#define MOTOR_NOT_IN_CUT_POSITION 6


// Specifies which connector the motor is on
//Make sure blue cable from motor connects to the M0 connector on the Clear Core
#define motor ConnectorM0


int MotorRunState;
int MotorLocationState;

int LoadPosition = 250000; //Arbitrary position away from blade, about 200 mm
int DesiredRPM = 350;

const uint8_t motorChannel = 0;
const uint8_t encoderChannel = 0;

void InitMotorParams() {

  // Sets the input clocking rate. This normal rate is ideal for ClearPath
  // step and direction applications.
  MotorMgr.MotorInputClocking(MotorManager::CLOCK_RATE_NORMAL);

  // Sets all motor connectors into step and direction mode.
  MotorMgr.MotorModeSet(MotorManager::MOTOR_ALL, Connector::CPM_MODE_STEP_AND_DIR);

  // Set the motor's HLFB mode to bipolar PWM
  motor.HlfbMode(MotorDriver::HLFB_MODE_HAS_BIPOLAR_PWM);
  // Set the HFLB carrier frequency to 482 Hz
  motor.HlfbCarrier(MotorDriver::HLFB_CARRIER_482_HZ);
  // Sets the maximum velocity for each move
  motor.VelMax(DesiredRPM*60*6400);//Conversion to Revolutions per second
  // Set the maximum acceleration for each move
  motor.AccelMax(80000);

  
}

//resetMotor cycles power on the motor. If this succesfully clears the fault state, the fault LED will go out
void resetMotor() {

  motor.EnableRequest(false);
  delay(10);
  motor.EnableRequest(true); 
  Serial.println("Motor Reset");
  delay(10);
}


void setMotorStates(int runState, int locationState) {
  MotorRunState = runState;
  MotorLocationState = locationState;
}

int getMotorRunState() {
  return MotorRunState;
}

int getMotorLocationState() {
  return MotorLocationState;
}

void detectMotorStates(int CutPosition)
{
  if(motor.PositionRefCommanded() == CutPosition) //Set state based on motor's reported position
    {
      MotorLocationState = MOTOR_IN_CUT_POSITION;
    }else
    {
      MotorLocationState = MOTOR_NOT_IN_CUT_POSITION;
    }
  if(motor.StatusReg().bit.StepsActive) //Set state based on motor's activity
    {
      MotorRunState = MOTOR_IS_MOVING;
    }else
    {
      MotorRunState = MOTOR_STOPPED;
    }
}



/*------------------------------------------------------------------------------
 * MoveAbsolutePosition
 *
 *    Command step pulses to move the motor's current position to the absolute
 *    position specified by "position"
 *    Prints the move status to the USB serial port
 *    Returns when HLFB asserts (indicating the motor has reached the commanded
 *    position)
 *
 * Parameters:
 *    int position  - The absolute position, in step pulses, to move to
 *
 * Returns: True/False depending on whether the move was successfully triggered.
 */

bool MoveAbsolutePosition(int position) {
    // Check if an alert is currently preventing motion
    if (motor.StatusReg().bit.AlertsPresent) {
        Serial.println("Motor status: 'In Alert'. Move Canceled.");
        return false;
    }

    Serial.print("Moving to absolute position: ");
    Serial.println(position);

    // Command the move of absolute distance
    motor.Move(position, MotorDriver::MOVE_TARGET_ABSOLUTE);
    return true;
}

This is everything, I apologize for being a noob. This project was dumped on me and I'm playing catch up lol

After studying this device it appears a switch should be connected using the G and S pins since there is an internal pullup connected to 5V. It looks like what you have done is put 24V on that input! Not sure if that will damage the input or not. It is always possible I have misunderstood something since I'm not a EE.

1 Like

I agree, the switch should connect the input line to ground, not to 24 volts.

Is your otiginal schematic correct?

There is a fair chance that the input pin will be ok, the 20K equivalent might limit the current and allow the port's build in protection mechanisms to function without failing.

If you could move that to another, unused, input, do that.

Or write a tiny sketch to test that input pin.

I am more interested in @ToddL1962's earlier observation in #5 above.

It does certainly look like there is a missing else - it seems to need to be there, and it is unusual for code that mostly looks like it is well written more or less for there to be random statements just placed inside { braces }.

If you read that logic snippet, you will appreciate the point.

a7

I added the else and removed the delay and serial from the ISR. Still no change

If I swapped the pins, do I need to swap from a "==LOW" to a "==HIGH"?

I believe this is the switch that is being used.

Only $111.72 a pop!

a7

OK, the switch is NC, normally closed.

The input is pulled up.

So the pin will normally read LOW, that is to be clear if you are not pressing that button, the digitalRead() will return LOW.

It looks like your code expects to see digital LOW mean

  if (switchState == LOW) {
    motor.MoveStopAbrupt();
    motor.PositionRefSet(0);
    Serial.println("Homed - interrupt");
    HomeSensorState = MOTOR_AT_HOME;
  }

that the motor is home, I think this means the switch will be being pressed upon.

Which we take to mean that yes, you shoukd look for HIGH to mean that button is being pressed.

Sry, gotta look through more code, as switchState may already have inverted the reading.

a7

Still no luck

The serial monitor is saying:
Units changed. MillimetersUnits changed. InchesEdit pressed

Edit passed

6

60

600

Homing . . . Waiting for motor to finish

homing

Broke home loop, States: (Running,Location)45

Moving to absolute position: 250000

Start passed

status: 'In Alert'

Clearing fault if present

status: 'In Alert'

Edit pressed

Edit passed

1

10

456

4.57

Clearing fault if present

Homing . . . Waiting for motor to finish

homing

Broke home loop, States: (Running,Location)45

Moving to absolute position: 250000

Start passed

Homing . . . Waiting for motor to finish

homing

Broke home loop, States: (Running,Location)45

Moving to absolute position: 250000

Start passed

I stopped it both times since it was about to run away. (it has no idea how far back it's able to go with the ref being off)

It's now not even setting a reference, I believe.

You should always do three things.

  1. describing what you have changed in the code
  2. describe the observed code- behaviour and the deviation from the wantedbehaviour
  3. The complete actual sketch
    Brs