0

I am using an ADM00308 development board from MicroChip. The board has a PIC16F883 processor. The code example can be downloaded from their website. I am using a nanotec steppermotor ST4118m0706 with a step 1.8 degree. I've calculated the max speed of the stepper motor:

enter image description here

from this website

RPMmax = 24V/(2⋅0,032mh⋅0,5A) = 3,75n/s (3,75⋅60 = 225rpm)

Minimum time per step = (2⋅0,032mh⋅0,5)/24V = 0,00133 seconds.

So in theory, the stepper motor should be able to handle 225rpm without oscillating. Now the software.

The code example provides a variable speed up to around 45rpm. This is too slow, since my target is 130rpm. Here is the original code:

Pulse width, Max speed and scan

// Prescale: Must change both values together - PRESCALE Divisor and BIT MASK */
// 1 = 0b00000000, 2 = 0b00010000, 4 = 0b00100000, 8 = 0b00110000
//#define REF_PWM_PRESCALE 8
//#define REF_PWM_PRESCALE_MASK 0b00110000
// The Rollover Count is the period of the timer.
// The timer period = 0 - Rollover Count.
//#define REF_PWM_PERIOD =  ((float) ((1.0 / (((float)_XTAL_FREQ) / 4.0)) * (REF_PWM_PRESCALE * REF_RWM_ROLLOVER_COUNT)))
//#define REF_FREQ ((float) (1.0 / REF_PERIOD) )
// Set minimum speed by (65535 - MAX_SPEED_COUNT) * usec per bit
// 12 msec =
#define MIN_MOTOR_PULSEWIDTH (0.015)
#define MAX_SPEED_COUNT  ((unsigned int) (65535.0 - ((float) ((MIN_MOTOR_PULSEWIDTH / (1.0 / (((float)_XTAL_FREQ) / 4.0))) /  (ROTATION_PRESCALE * 2)))))
#define SPEED_INPUT_SPAN ((unsigned int) 900)
#define SPEED_INPUT_COUNTS_PER_BIT ((unsigned int) (MAX_SPEED_COUNT / SPEED_INPUT_SPAN))

#define ROTATION_ROLLOVER_COUNT (MAX_SPEED_COUNT + 100)
#define ROTATION_PRESCALE 8
#define ROTATION_PRESCALE_MASK 0b00110000
#define ROTATION_PERIOD =  ((float) ((1.0 / (((float)_XTAL_FREQ) / 4.0)) * (ROTATION_PRESCALE * ROTATION_ROLLOVER_COUNT)))
#define ROTATION_FREQ ((float) (1.0 / ROTATION_PERIOD) )

SpeedUpdate

FaultTypeEnum SpeedUpdate(void)
{
  FaultTypeEnum Fault;
  unsigned int Speed;

  Fault = NO_FAULT;
  if (SpeedInput < 65)
  {
    /* open/shorted(GND) speed input */
    Speed = 0;
    Fault = SPEED_INPUT_LOW;
  }
  else if (SpeedInput < 100)
  {
    Speed = 0;
    Fault = NO_FAULT;
  }
  else if (SpeedInput > 950)
  {
    Speed = 0;
    Fault = SPEED_INPUT_HIGH;
  }
  else if (SpeedInput > 900)
  {
    /* open/shorted(VDD) speed input */
    Speed = MAX_SPEED_COUNT;
    Fault = NO_FAULT;
  }
  else
  {
    Speed = (SpeedInput - 100) * SPEED_INPUT_COUNTS_PER_BIT;
    Fault = NO_FAULT;
  }

  RotationTimerRolloverCount = MAX_SPEED_COUNT - Speed;

  /* setup the next timer reload value */
  T1CON = 0b00000000; /* Temporarily pause the PWM timer */
    /* use variables to reload timer faster in interrupt routine */
  RotationTimerReloadHi =  (unsigned )(RotationTimerRolloverCount >> 8);
  RotationTimerReloadLo = (unsigned short) RotationTimerRolloverCount;
  T1CON = 0b00000001 | ROTATION_PRESCALE_MASK; // Re-enable PWM timer, set prescale

  return Fault;
}

Timer

 /* Rotation Timer.  Must be fast. */
  if (PIR1bits.TMR1IF)
  {
    PIR1bits.TMR1IF = 0;
    TMR1H = RotationTimerReloadHi;
    TMR1L = RotationTimerReloadLo;

    /* Calculate next stepper rotation state */
    /* HOLD switch sets min_rotation_state = max_rotation_state */
    /* SINGLE STEP switch sets min_rotation_state = max_rotation_state */
    if (System.Bits.Stop)
    {
      /* no current output */
      RotationData.All = ROTATION_STOP;
    }
    else
    {
      /* update stepper driver with last calculated data */
      PORTB = ((PORTB & 0b11000000) | RotationData.All);

I managed to change the speed to 146rpm by changing:

#define MIN_MOTOR_PULSEWIDTH (0.015)

to for testing

#define MIN_MOTOR_PULSEWIDTH (0.006)

The stepper rotates at a speed of 98rpm with the potentio completely rotated to the left. Lowering the value to 0.004 will get a speed of 146rpm with good torque on a 24v supply(torque will suffer on a 12v supply). Lowering the value even more, will oscillate the motor (you can hear the motor but it doesn't rotate anymore). Which is strange since the max rpm is supposed to be 225rpm. However, the main problem is that I can't seem to reach a rpm of 130. Changing the value to 0.005, 0.0045, etc doesn't increase the speed more than 98 until 0.004. It also seems that the potentiometer has some kind of presets. By turning the potentiometer, it changes from 146rpm to 98rpm, to 73rpm, etc. It doesn't change the speeds fluently, if you get my point. Hence I am getting the idea it's programmed in presets, which I also tried to change.

Firmware and information can be downloaded on the original site

Clifford
  • 88,407
  • 13
  • 85
  • 165
  • 1
    You should never using floating point on such a lousy low-end MCU. It has no FPU and will just completely choke on the float numbers, resulting in a software library implementation which will explode your ROM (you only have 7 kib!) and kill execution speed. Possibly also resulting in silent floating point library function calls behind the lines, which is a great thing with PIC's lousy call stack depth, right? Notably, this whole code can be implemented with fixed point integers. Probably the person who wrote it was some PC programmer who have never worked with microcontrollers. – Lundin May 22 '18 at 11:51
  • (And yes you don't even want to use float numbers even when they are only used in pre-processor, because they will often require a different standard lib to get linked to your project. By default, 8 bit MCUs don't use such libs because they are bloated.) – Lundin May 22 '18 at 11:55
  • You don't seem to have a question anywhere in your text. What are you looking for help with? What is not working or do you want changed? – Ross May 22 '18 at 13:35
  • @Ross The reason why I can't reach the 130rpm even though I changed many variables. How can I solve it and what is the culprit? – Capt. Frost May 22 '18 at 15:58
  • @Lundin I didn't know the float numbers would ruin my ROM! I'll try to seek for a substitute. I want to program the speed first. – Capt. Frost May 22 '18 at 16:11
  • 1
    @Capt.Frost : He did not mean the ROM would literally "explode". Simply that the ROM usage would increase significantly. – Clifford May 22 '18 at 22:32
  • 1
    I think it's a timer resolution problem. I'll use integers, try to look into the frequency for the timer and implement decay for the motor. – Capt. Frost May 25 '18 at 05:51

0 Answers0