0% found this document useful (0 votes)
7 views3 pages

Arduino Motor Control with Limit Switches

Uploaded by

Trường Quang
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views3 pages

Arduino Motor Control with Limit Switches

Uploaded by

Trường Quang
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

#include <TimerOne.

h>

// Define pin numbers


const int enablePin = 22;
const int dirPin = 48;
const int pulPin = 50;
const int lmswPin1 = 44; // Limit switch pin 1
const int lmswPin2 = 46; // Limit switch pin 2

// Define motor steps per revolution


const int stepsPerRevolution = 6400; // Replace 6400 with the actual steps per
revolution of your motor

// Variables to keep track of the motor state


volatile bool isRunning = false;

// Variables to store the current position of the motor


volatile int currentPosition = 0;

// Variable to store the number of steps to send


volatile int stepsToSend = 0;

// Variable to check if limit switch was pressed


volatile bool limitSwitchPressed = false;
volatile bool limitSwitchDirection = true;

// Variables to store the previous state of the limit switches


bool previousLmswState1 = HIGH;
bool previousLmswState2 = HIGH;

// Flag to indicate if handleLimitSwitch is being executed


volatile String cocheck = "off";

void setup() {
// Set pin modes
pinMode(enablePin, OUTPUT);
pinMode(dirPin, OUTPUT);
pinMode(pulPin, OUTPUT);
pinMode(lmswPin1, INPUT_PULLUP); // Use internal pull-up resistor for limit
switch pin 1
pinMode(lmswPin2, INPUT_PULLUP); // Use internal pull-up resistor for limit
switch pin 2

// Enable the motor


digitalWrite(enablePin, LOW);

[Link](115200);

[Link](10000);
[Link](stepMotor);

rotateMotor(true);
}
String previousCocheck = "off";
void loop() {

String cocheckCopy = String(cocheck.c_str());


if (cocheckCopy != previousCocheck) {

[Link](cocheckCopy);

previousCocheck = cocheckCopy;
}
if (cocheckCopy == "on" && [Link]() > 0) {
String command = [Link]('\n');
[Link]("ACK");
if (command == "a") {

rotateMotor(true);
} else if (command == "b") {

rotateMotor(false);
} else if (command == "c" || command == "None") {
// Stop the motor
isRunning = false;
[Link](); // Stop the timer interrupt
}

delay(10);
}

// Check the limit switch state in the main loop


bool currentLmswState1 = digitalRead(lmswPin1);
if (currentLmswState1 == LOW && previousLmswState1 == HIGH) {
handleLimitSwitch(true);
}
previousLmswState1 = currentLmswState1;

bool currentLmswState2 = digitalRead(lmswPin2);


if (currentLmswState2 == LOW && previousLmswState2 == HIGH) {
handleLimitSwitch(false);
}
previousLmswState2 = currentLmswState2;
}

void stepMotor() {
// Check the limit switch state
bool currentLmswState1 = digitalRead(lmswPin1);
if (currentLmswState1 == LOW && previousLmswState1 == HIGH) {
handleLimitSwitch(true);
cocheck = "on";
}
previousLmswState1 = currentLmswState1;
bool currentLmswState2 = digitalRead(lmswPin2);
if (currentLmswState2 == LOW && previousLmswState2 == HIGH) {
handleLimitSwitch(false);
cocheck = "on";
}
previousLmswState2 = currentLmswState2;

if (isRunning || limitSwitchPressed) {
// Check limit switch state
if (limitSwitchPressed) {
// Set direction pin based on limit switch direction
digitalWrite(dirPin, limitSwitchDirection ? HIGH : LOW);
}

// Generate a pulse
digitalWrite(pulPin, HIGH);
delayMicroseconds(5);
digitalWrite(pulPin, LOW);
delayMicroseconds(5);

currentPosition += (digitalRead(dirPin) == HIGH) ? 1 : -1; // Update current


position

if (--stepsToSend <= 0) {
// Stop the motor after sending the required steps
isRunning = false;
limitSwitchPressed = false; // Reset limit switch flag
[Link]();
cocheck = "on";
}
}
}

// Function to handle limit switch


void handleLimitSwitch(bool direction) {
limitSwitchPressed = true;
limitSwitchDirection = direction;
currentPosition = direction ? 0 : stepsPerRevolution; // Reset currentPosition
based on direction

// Set the new number of steps here, for example:


stepsToSend = 3200; // Change this value to the new number of steps you want to
move when hitting the limit

isRunning = false; // Stop the motor


[Link](); // Start the timer
cocheck = "off";
// After finishing the limit switch handling, reset cocheck
}

// Function to rotate the motor


void rotateMotor(bool clockwise) {
isRunning = true;
digitalWrite(dirPin, clockwise ? HIGH : LOW); // Set direction pin
stepsToSend = stepsPerRevolution; // Set steps to full revolution
[Link]();
}

// Function to convert steps to angle


int stepsToAngle(int steps) {
int angle = map(steps, 0, stepsPerRevolution, 0, 360);
return angle;
}

// Function to convert angle to steps


int angleToSteps(int angle) {
float steps = (float)angle / 360.0 * stepsPerRevolution;
return (int)steps;
}

Common questions

Powered by AI

The motor's current position is managed using the volatile variable currentPosition, which tracks the number of steps moved from a starting reference. During each step in the stepMotor function, currentPosition is updated by incrementing or decrementing based on the direction of movement (clockwise or counter-clockwise). The handleLimitSwitch function also plays a role in resetting this position to 0 or stepsPerRevolution when a limit switch is activated, depending on movement direction, ensuring that position tracking remains accurate within the mechanical limits of the system .

When a limit switch is activated, the handleLimitSwitch function is called, which sets the limitSwitchPressed flag to true and stops the motor by setting isRunning to false. This also involves stopping the timer interrupt with Timer1.stop(). The currentPosition is reset based on motor movement direction, either to 0 or stepsPerRevolution. These actions ensure that the motor does not move beyond its physical limits, preventing potential hardware damage .

The motor direction is controlled by setting the dirPin, which is dictated by the rotateMotor function. If the parameter 'clockwise' is true, the dirPin is set HIGH, otherwise, it is set LOW. This ensures that the motor rotates in the desired direction, either clockwise or counter-clockwise, during its operation. The rotateMotor function initializes the motor's direction and starts the movement for a predetermined number of steps .

The number of steps for a full revolution is determined by the stepsPerRevolution variable, which is set to 6400 in this system. The rotateMotor function sets the stepsToSend variable to stepsPerRevolution, indicating that each command to rotate the motor will attempt to move it through a full revolution. The motor direction is set using the dirPin and is controlled by setting this pin HIGH for clockwise movement and LOW for counter-clockwise .

Serial communication is integrated to allow command inputs via Serial.readStringUntil('\n'), which the system checks when cocheck is "on." Commands such as "a" or "b" start the motor in different directions, while "c" or "None" stops it, reflecting dynamic interaction with the motor's operational state. Upon receipt of a command, an "ACK" response ensures acknowledgement of the action. This mechanism allows real-time control and monitoring of the motor system without direct hardware manipulation, enhancing user interaction and system adaptability .

The cocheck variable acts as a flag to control the motor operation stages. Initially set to "off," it changes to "on" when a limit switch is activated, which is handled inside stepMotor upon detecting a limit switch change. Commands received via Serial communication check this flag and respond only when cocheck is "on." As commands are processed, like starting or stopping motor movements, cocheck's state is printed out, allowing for debug visibility. Post limit switch handling, cocheck is re-set to "off," indicating normal condition resumption .

The limit switch state is monitored using digitalRead on two limit switch pins (lmswPin1 and lmswPin2) with INPUT_PULLUP configuration to use internal pull-up resistors. The main loop and the stepMotor function both check the current state of these pins against their previous states. If a change from HIGH to LOW is detected, indicating the limit switch has been pressed, the handleLimitSwitch function is called with a direction argument (true for one direction, false for the other). This function sets the limitSwitchPressed flag to true, determines the motor's direction based on the limitSwitchDirection variable, and resets the currentPosition variable to 0 or stepsPerRevolution depending on the direction .

The system uses Timer1 to handle interrupts, which are set up in the setup function using Timer1.initialize(10000) and Timer1.attachInterrupt(stepMotor). The interrupt service routine, stepMotor, is called at regular intervals. Within this function, steps are executed by generating pulses on the pulPin while checking the limit switches for possible changes in status. The interrupts ensure precise timing for the stepper motor's operation, allowing it to run smoothly and respond quickly to limit switch events .

The system is designed to handle limit switch activations by stopping the motor and resetting necessary variables. However, its robustness against errors such as debounce or switch mechanical failure isn't explicitly managed in the presented code. While the internal pull-up resistors help reduce noise issues, the absence of software debounce mechanisms or redundant switch checks could lead to erroneous behavior if a switch fails to register accurately. Thus, while functional, further enhancements like software debouncing or additional error-checking logic are recommended to increase reliability .

The system utilizes two functions: stepsToAngle and angleToSteps. The stepsToAngle function maps a given number of steps to an angle using the formula angle = map(steps, 0, stepsPerRevolution, 0, 360), translating steps into degrees relative to a full 360-degree rotation. Conversely, angleToSteps converts an angle into steps using the calculation float steps = (float)angle / 360.0 * stepsPerRevolution, rounding to the nearest integer. These transformations are crucial for precise control of the motor's position in applications requiring angular movements rather than arbitrary steps .

You might also like