Stepper motor servo with attiny412

Hi,
Im building a small servo for a tiny rc car, that uses one of these micro stepper from aliexpress with a tiny M1 lead screw. My problem is that after homing the motor turns until it hits the other end instead of the expected behavior, which is moving according to the input PWM signal from a deltang receiver. I've narrowed the problem down to likely being an issue with pulseIn or the pin that I'm using as input, as when I swap out the pulseIn for random(1000,2000) the motor moves as expected. The stepper motor is driven by a DRV8833 and that is connected to an attiny412. Here is the schematic:


And here is the code Im running:

#include <Arduino.h>
#include <Stepper.h>

class MicroStepper : public Stepper{
public:
  MicroStepper(int steps,int pin1,int pin2,int pin3,int pin4);
  void move(const int steps);
  void stop();
  void moveTo(const int targetPos);
  void setCurrentPos(const int pos);
  void setMaxSpeed(const unsigned int speed);
  long getCurrentPos() const;
private:
  int currentPos=0;
  unsigned int maxSpeed=1000;
};

MicroStepper::MicroStepper(int steps, int pin1, int pin2, int pin3, int pin4)
    : Stepper(steps, pin1, pin2, pin3, pin4) {
}
void MicroStepper::move(const int steps){
  currentPos+=steps;
  step(steps);
}
void MicroStepper::stop(){
  setSpeed(0);
}
void MicroStepper::moveTo(const int targetPos){ 
  int errorPos = targetPos - currentPos;
  int speed=abs(errorPos)*20;
  speed=constrain(speed,0,maxSpeed);
  setSpeed(speed);
  move(errorPos);
}
void MicroStepper::setCurrentPos(const int pos){
  currentPos=pos;
}
void MicroStepper::setMaxSpeed(const unsigned int speed){
  maxSpeed=speed;
}
long MicroStepper::getCurrentPos() const{
  return currentPos;
}

#define AIN1 PIN_PA1
#define AIN2 PIN_PA2
#define BIN1 PIN_PA7
#define BIN2 PIN_PA3
#define PWM_PIN PIN_PA6

#define stepsPerRevolution 20
MicroStepper stepper(stepsPerRevolution, AIN1, AIN2, BIN1, BIN2);
//micro stepper has 20 steps per revolution
//lead screw pitch 0.25mm
#define REV_RANGE 18
const unsigned int MAX_POS = stepsPerRevolution*REV_RANGE;


const float alpha = 0.1; // Smoothing factor, between 0 and 1
unsigned int filteredPWM = 0;

unsigned int getPWMIn() {
  unsigned int rawPWM = pulseIn(PWM_PIN, HIGH);
  if(rawPWM==0)
      return filteredPWM;
  filteredPWM = (alpha * rawPWM) + ((1 - alpha) * filteredPWM);
  return filteredPWM;
}
void homeStepper() {
  //10 revolutions are half the range
  stepper.setSpeed(600);
  stepper.setMaxSpeed(1500);
  stepper.move(MAX_POS/2);//moves CW
  delay(1000);
  stepper.setCurrentPos(0);
}
void setup() {
  
  pinMode(PWM_PIN, INPUT_PULLUP);
  filteredPWM = pulseIn(PWM_PIN, HIGH); // Initialize with first reading
  homeStepper();
}

void loop() {
  unsigned int targetPWM = getPWMIn();
  long targetPos = map(targetPWM,1000,2000,0,MAX_POS);
  stepper.moveTo(-targetPos);
}

`
Thanks in advance for any help.

I just replaced the pulseIn with an interrupt to measure the pulse length and that works. No idea why pulseIn behaves differently.

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