Quantcast
Channel: ADI Trinamic Blog
Viewing all articles
Browse latest Browse all 66

Explore and tune StallGuard2 with the TMC5160-EVAL + Arduino Mega 2560 in step and direction mode

$
0
0

In this blog article we wire up a Arduino Mega2560 with a TMC5160-EVAL board to run in it STEP/DIR mode, use a timer to generate a fixed frequency for the STEP input. The diagnostic diag0 output pin of the TMC5160 will be used to indicate a defined load condition we want to react on. In this case we stop the motor respectively stop the step output of the Arduino.

Only ten wires are required to control the TMC5160-EVAL with your Arduino. Here are the steps to get started.

Preparation

If your Arduino is a 5V type you have to desolder one resistor on the TMC5130-EVAL from position R211 and solder it to position R212. This sets the logic level of the TMC5130 to +5V as seen in the circuitry below.

Illustration 1 – TMC5160-EVAL – Voltage selection

While by default the resistor is soldered to the lower position, you have to move it to the upper position as shown in the red area below for 5V operation.

Illustration 2 – TMC5160-EVAL resistor selector for logic supply voltage

Wiring

The wiring is very simple. You will need 10 jumper wires. To make the wiring more easy you can print out the TMC5130-EVAL_Pinning.pdf and cut out the template to mount it on the connector header of the TMC5160-EVAL (As seen on illustration 4). As a reference you can use the TMC5160-EVAL schematic. Here you’ll find the signals that are on each pin. The configuration is documented in the comment section of the Arduino code.

Illustration 3 – Pin header of TMC5160-EVAL

TMC5160 setup wiring with Arduino Mega
Illustration 4 – Arduino Mega 2560 wired up to TMC5160-EVAL for STEP/DIR mode

Cable colors of illustration 4
+5V –> red
GND –> blue
SDO –> yellow
SDI –> orange
SCK –> white
CSN –> grey
DRV_ENN –> black
CLK16 –> green

Using the internal CLK of the TMC5160

This example uses the internal CLK of the TMC5160. To use the internal CLK simply connect the CLK16 pin to GND.

Step pulse generation

To generate the step pulses a timer is used with a pre scaler of 1024. With a system CLK of the Arduino ATMEGA2560 of 16MHz that results in a 7.8125kHz frequency. As there is no ramping a jump start from velocity 0 to 7812.5 pps is done which should work with most motors. If not a acceleration ramp needs to be implemented.

The TMC5160 offers an internal Motion Controller that can be used as described with the TMC5130 blog post. As some people like to start with a step direction approach this blog post does cover this. Usually when people do try out the Motion Controller they will see the big benefits and make use of it. It does take off a lot of software work! The TMC5160 either starting in step direction and then explore the Motion Controller or directly evaluate the Motion Controller is a great procedure.

Arduino Code

The Arduino Code below does not need any additional libraries. The SPI library comes with the Arduino IDE. The program initializes the TMC5160. Please use either the TMC5160 datasheet or the TMCL IDE as a reference for the different registers.

#include <SPI.h>

/* The trinamic TMC5160 motor controller and driver operates through an 
 *  SPI interface.  Each datagram is sent to the device as an address byte
 *  followed by 4 data bytes.  This is 40 bits (8 bit address and 32 bit word).
 *  Each register is specified by a one byte (MSB) address: 0 for read, 1 for 
 *  write.  The MSB is transmitted first on the rising edge of SCK.
 *  
 * Arduino Pins   Eval Board Pins
 * 51 MOSI        32 SPI1_SDI
 * 50 MISO        33 SPI1_SDO
 * 52 SCK         31 SPI1_SCK
 * 25 CS          30 SPI1_CSN
 * 
 * 17 DIO         8 DIO0 (DRV_ENN)
 * 11 DIO         REFL_STEP pin header
 * 4 DIO          22 SPI_MODE
 * 5 DIO          20 SD_MODE
 * 20 DIO         DIAG0 pin header
 * GND            2 GND
 * +5V            5 +5V
 */

#define diag0_interrupt

int chipCS = 25;
const byte STEPOUT = 11;
int enable = 17;
int SPImode = 4;
int SDmode = 5;
int DIAG0interruptpin = 20;
unsigned long SGvalue = 0;
unsigned long SGflag = 0;
int cnt = 0;

void setup()
{
  // put your setup code here, to run once:
  pinMode(SPImode,OUTPUT);
  pinMode(SDmode,OUTPUT);
  pinMode(chipCS,OUTPUT);
  pinMode(STEPOUT,OUTPUT);
  pinMode(enable, OUTPUT);
  digitalWrite(SPImode,HIGH);
  digitalWrite(SDmode,HIGH);
  digitalWrite(chipCS,HIGH);
  digitalWrite(enable,HIGH);

  #ifdef diag0_interrupt
    pinMode(DIAG0interruptpin, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(DIAG0interruptpin), stallguardstop, FALLING);
  #endif

  //set up Timer1 for step generation
  TCCR1A = bit (COM1A0);                // toggle OC1A on Compare Match
  TCCR1B = bit (WGM12)                  // CTC, no prescaling
    | bit (CS10)
    | bit (CS12);                       // Pre scaler set to 1024 resulting in 7.8125kHz
  OCR1A = 0;                            // output every cycle

  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV8);
  SPI.setDataMode(SPI_MODE3);
  SPI.begin();

  Serial.begin(9600);

  sendData(0x80,0x00000080);      // GCONF -> Activate diag0_stall (Datasheet Page 31)
  sendData(0xED,0x00000000);      // SGT -> Needs to be adapted to get a StallGuard2 event
  sendData(0x94,0x00000040);      // TCOOLTHRS -> TSTEP based threshold = 55 (Datasheet Page 38)
  sendData(0x89,0x00010606);      // SHORTCONF
  sendData(0x8A,0x00080400);      // DRV_CONF
  sendData(0x90,0x00080303);      // IHOLD_IRUN
  sendData(0x91,0x0000000A);      // TPOWERDOWN
  sendData(0xAB,0x00000001);      // VSTOP
  sendData(0xBA,0x00000001);      // ENC_CONST
  sendData(0xEC,0x15410153);      // CHOPCONF
  sendData(0xF0,0xC40C001E);      // PWMCONF

  digitalWrite(enable,LOW);
}

void loop()
{
  SGvalue = sendData(0x6F,0x00000000);    // Read DRV_STATUS register
  SGflag = (SGvalue & 0x1000000) >> 24;   // Check SG2 flag
  SGvalue = (SGvalue & 0x3FF);            // Extract SG2 value bits
  Serial.print("StallGuard2 value: ");
  Serial.println(SGvalue, DEC);
  Serial.print("StallGuard2 event:");
  Serial.println(SGflag);
}

unsigned long sendData(unsigned long address, unsigned long datagram)
{
  //TMC5130 takes 40 bit data: 8 address and 32 data
  unsigned long i_datagram = 0;

  digitalWrite(chipCS,LOW);
  delayMicroseconds(10);

  SPI.transfer(address);

  i_datagram |= SPI.transfer((datagram >> 24) & 0xff);
  i_datagram <<= 8;
  i_datagram |= SPI.transfer((datagram >> 16) & 0xff);
  i_datagram <<= 8;
  i_datagram |= SPI.transfer((datagram >> 8) & 0xff);
  i_datagram <<= 8;
  i_datagram |= SPI.transfer((datagram) & 0xff);
  digitalWrite(chipCS,HIGH);
  
  Serial.print("Received: ");
  Serial.println(i_datagram,HEX);
  Serial.print(" from register: ");
  Serial.println(address,HEX);

  return i_datagram;
}

void stallguardstop()
{
  cnt++;  // To avoid false detection. When motor starts diag0 pin goes low.
  if(cnt > 1)
  {
    TCCR1B &= (0 << CS12);
    TCCR1B &= (0 << CS11);
    TCCR1B &= (0 << CS10);
  }
}

Download

The TMC5160-EVAL_Arduino.zip file includes the pinning template, the TMC5160-EVAL schematic and the Arduino project.

Related Pages


Viewing all articles
Browse latest Browse all 66

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>