Hi everyone,
I'm working on a project involving a linear actuator with an integrated quadrature Hall sensor and a BTS7960 motor driver, all controlled via an Arduino Mega. The goal is to accurately track position using pulse counts and enable calibrated movement over a 300 mm stroke.
Hardware Setup:
Arduino Mega 2560
BTS7960 motor driver
- RPWM: Pin 5
- LPWM: Pin 6
- REN: Pin 7
- LEN: Pin 8
Linear actuator with Hall sensor (Stroke of 300mm) (5V, GND, Hall_1, Hall_2) - Hall_1: Pin 2 (interrupt)
- Hall_2: Pin 3 (interrupt)
- 24V power supply for the actuator, passed through BTS7960
- Datasheet :
Instruction manual-电动推杆使用说明书(1) (1).pdf (1.3 MB)
Objectives:
- Accurately calculate pulse counts (increment and decrement based on direction)
- Eventually convert these pulses to millimeters for position tracking over 300 mm
Issue with the current code I'm working with provides me with inconsistent final readings, what should I look for to change and what sources should I go through to better understand the working logic to build a code to read a consistent maximum amount of pulses at the range of 0-300mm, so that I can derive how much pulses it takes to traverse 1mm.
This is what I have up to now in the code :
// Motor driver pins
#define RPWM 5
#define LPWM 6
#define REN 7
#define LEN 8
// Hall sensor pins
#define HALL_1 2
#define HALL_2 3
volatile long pulseCount = 0;
int speedPWM = 250;
void setup() {
Serial.begin(115200);
// Motor driver setup
pinMode(RPWM, OUTPUT);
pinMode(LPWM, OUTPUT);
pinMode(REN, OUTPUT);
pinMode(LEN, OUTPUT);
digitalWrite(REN, HIGH);
digitalWrite(LEN, HIGH);
analogWrite(RPWM, 0);
analogWrite(LPWM, 0);
// Hall sensor setup
pinMode(HALL_1, INPUT_PULLUP);
pinMode(HALL_2, INPUT_PULLUP);
// Count only rising edges on HALL_1
attachInterrupt(digitalPinToInterrupt(HALL_1), countPulse, CHANGE);
Serial.println("Ready. Use: f=forward, b=backward, s=stop/reset");
}
void loop() {
if (Serial.available()) {
char command = Serial.read();
if (command == 'f') {
analogWrite(RPWM, speedPWM);
analogWrite(LPWM, 0);
Serial.println("Motor Forward");
}
else if (command == 'b') {
analogWrite(RPWM, 0);
analogWrite(LPWM, speedPWM);
Serial.println("Motor Backward");
}
else if (command == 's') {
analogWrite(RPWM, 0);
analogWrite(LPWM, 0);
pulseCount = 0;
Serial.println("Stopped and Reset Count");
}
}
// Print current state
Serial.print("Pulse Count: ");
Serial.print(pulseCount);
Serial.print(" | HALL_1: ");
Serial.print(digitalRead(HALL_1));
Serial.print(" | HALL_2: ");
Serial.println(digitalRead(HALL_2));
delay(200);
}
// Interrupt service routine
void countPulse() {
pulseCount++;
}