Go Down

Topic: A4988 microstepping (Read 767 times) previous topic - next topic

boraboy

Evening folks,

I am trying to run a tachometer from the CAN bus off a 1.8 turbo Golf (transplanted into a Corrado)

I have it working but I'm still not happy with it.

The stepper is the same used by VW in their golf 4 clusters (havent found the exact spec yet but appears to be 180 steps)
The stepper drive is an A4988 (cheap from UK ebay)
The CAN sheild is from sparkfun
Arduino board is a mega

As part of the motor setup the dial does a full sweep when switched on.
Full sweep (0 - 8000 rpm) takes 125 steps and I have set the driver to 1/16 so the sweep command is +2000 steps then -2000 steps. This makes me think the micro stepping works because it doesnt hit the stops.

But, when the program loop is running the needle moves every 65 rpm which looks like the driver is running 1/1 !

I need a bit of help to work out why it isnt micro stepping :)

The code below is a cut down version of my full cluster display code but it does the same :(





Code: [Select]
#include "Arduino.h"
#include <mcp_can.h>
#include "A4988.h"

/***************CAN*********************/
const int SPI_CS_PIN = 53; //53 for the mega -- 10 (on uno )
MCP_CAN CAN(SPI_CS_PIN);
/***************************************/

/*********CAN masking and filters*******/
#define CAN_MASK_1 0x81
#define CAN_MASK_2 0x81

#define TACHO 0x280

#define ACCEPT1 TACHO
#define ACCEPT2 0x000
#define ACCEPT3 0x000
#define ACCEPT4 0x000
#define ACCEPT5 0x000
#define ACCEPT6 0x000
/***************************************/


/***************MicroStepper************/
#define MOTOR_STEPS 180
#define RPM 60
#define DIR 8
#define STEP 9
#define ENABLE 13
#define MS1 10
#define MS2 11
#define MS3 12
int MOTOR_ACCEL = 500; // Acceleration and deceleration values are always in FULL steps / s^2
int MOTOR_DECEL = 500;
#define MICROSTEPS 16// Microstepping mode 1/16
A4988 stepper(MOTOR_STEPS, DIR, STEP, ENABLE, MS1, MS2, MS3);

/***************************************/
static void setUpCAN(void);
static void setUpStepper(void);
static void processRPM(const unsigned char MSB, const unsigned char LSB);
static void processCANMessage(void);



void setup() {

setUpCAN();
Serial.begin(9600); //serial comms for USB
setUpStepper();
}

void loop() {

if (CAN_MSGAVAIL == CAN.checkReceive())
{
processCANMessage();
}
}
static void setUpCAN(void)
{
/*setup CAN controller -- We need to light a LED or something if its stuck in this loop*/
while (CAN_OK != CAN.begin(CAN_500KBPS))
{
delay(10);
}

/* load CAN masks */
CAN.init_Mask(0, 0, CAN_MASK_1);
CAN.init_Mask(1, 0, CAN_MASK_2);
/* load CAN acceptance filters */
CAN.init_Filt(0, 0, ACCEPT1);
CAN.init_Filt(1, 0, ACCEPT2);
CAN.init_Filt(2, 0, ACCEPT3);
CAN.init_Filt(3, 0, ACCEPT4);
CAN.init_Filt(4, 0, ACCEPT5);
CAN.init_Filt(5, 0, ACCEPT6);
}

static void processCANMessage(void) {

static uint16_t ID;
unsigned char len = 0;
unsigned char buf[8];
/* there is data in the buffer so read it */
CAN.readMsgBuf(&len, buf);
/* Get the ID */
ID = CAN.getCanId();
/* now we can switch to process that data */

switch (ID)
{

case TACHO:
processRPM(buf[3], buf[2]); //
break;
}
}


static void setUpStepper(void)
{
stepper.begin(RPM, MICROSTEPS);
stepper.enable();
stepper.setSpeedProfile(stepper.LINEAR_SPEED, MOTOR_ACCEL, MOTOR_DECEL);
stepper.move(2000);    // forward revolution 16*125steps
delay(100);
stepper.move(-2000);   // backward revolution to zero point

}

static void processRPM(const unsigned char MSB, const unsigned char LSB)
{
uint16_t EngineSpeed;
uint16_t tacho;
static uint16_t old_tacho = 0;
int16_t result;

EngineSpeed = (uint16_t) (((MSB << 8) + LSB)/4); //standard input scaled for VW cluster
tacho = (uint16_t)(EngineSpeed)/4; //scaled for stepper motor
result = tacho - old_tacho; //delta to move stepper motor
stepper.move(result); //send to stepper
old_tacho = tacho; //update tacho value

Serial.println (result);
}

Robin2

I have not come across a library called A4988.h previously. What does it do? Where does it come from?

If the micro-step pins on the A4988 board are correctly set it will microstep. There is no need for the Arduino code to do anything. You can control them with software but it is seldom necessary.

...R
Stepper Motor Basics
Simple Stepper Code
Two or three hours spent thinking and reading documentation solves most programming problems.

boraboy

Thanks for your answer

Typically, after putting this on here I thought about it a bit more and then adjusted down the current supply on the A4899 which seems to have improved it.

There is still a small amount of sudden jumps almost as if it sends a larger negative value so I would appreciate it if anyone has any suggestions to improve the code


The CAN message is being sent every 10ms, Is there a way to average the rpm over say 250ms then out put that ?



I got the A4988.h from github

https://github.com/laurb9/StepperDriver/blob/master/src/A4988.h


Robin2

Have you tried the AccelStepper library that is more widely used?

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

MorganS

Sure. Wait for 25 CAN messages and then change your output to the average of what you got.
"The problem is in the code you didn't post."

jremington

#5
Feb 13, 2018, 01:54 am Last Edit: Feb 13, 2018, 01:56 am by jremington
Quote
Typically, after putting this on here I thought about it a bit more and then adjusted down the current supply on the A4899 which seems to have improved it.
The current limit must be adjusted correctly for microstepping to work.

What motor and power supply are you using, and to what value did you set the current limit?

Go Up