teemuatlut / TMC2130Stepper

Arduino library for Trinamic TMC2130 Stepper driver
MIT License
159 stars 50 forks source link

Stallguard with 2 nema #63

Closed joe318 closed 5 years ago

joe318 commented 5 years ago

Hello, First of all MERRY CHRISTMASSSSSSS ;)

I'm new with this tmc2130, i'm in project mode lol, i do one thing with 3 nema 17, first i put a4988, after i put drv8825, without problem, working well, sure with this crazy noise but working well, i discover this tmc2130 in internet and i decide to buy for update my project.

My problem is with stallguard, it was nice if can put it work with the 3 nema, i use 2 switch for now.

I try first ur simple example with a mega and 2 nema17 sure with 2 tmc, working well, i play little with the values, no problem, after that i try the stallguard example, no problem with one nema, but with twoo i have one problem, one work well, can read the values, but the second is here but he dont move, but i think he read the values, i don't know where is my mis coz sure it's my fault but idk where.

capture_tmc

like u see in the pic, the lr work well but the hr nothing, he is here but he dont move.

my sketch

/**
 * Author Teemu Mäntykallio
 * 
 * Plot TMC2130 motor load using the stallGuard value.
 * You can finetune the reading by changing the STALL_VALUE.
 * This will let you control at which load the value will read 0
 * and the stall flag will be triggered. This will also set pin DIAG1 high.
 * A higher STALL_VALUE will make the reading less sensitive and
 * a lower STALL_VALUE will make it more sensitive.
 * 
 * You can control the rotation speed with
 * 0 Stop
 * 1 Resume
 * + Speed up
 * - Slow down
 */
#define MAX_SPEED  40 // In timer value
#define MIN_SPEED  1000

#define STALL_VALUE 10 // [-64..63]

// Note: You also have to connect GND, 5V and VM.
//       A connection diagram can be found in the schematics.
#define EN_PIN    38  // Nano v3:  16 Mega:  38  //enable (CFG6)
#define DIR_PIN   55  //           19        55  //direction
#define STEP_PIN  54  //           18        54  //step
#define CS_PIN    40  //           17        64  //chip select

#define EN_PIN_HR    39  // Nano v3:  16 Mega:  38  //enable (CFG6)
#define DIR_PIN_HR   56  //      19      55  //direction
#define STEP_PIN_HR  57  //      18      54  //step
#define CS_PIN_HR    41  //      17      64  //chip select

#include <TMC2130Stepper.h>
#include <TMC2130Stepper_REGDEFS.h>
TMC2130Stepper driver = TMC2130Stepper(CS_PIN);
TMC2130Stepper driver_HR = TMC2130Stepper(CS_PIN_HR);
bool vsense;

uint16_t rms_current(uint8_t CS, float Rsense = 0.11) {
  return (float)(CS+1)/32.0 * (vsense?0.180:0.325)/(Rsense+0.02) / 1.41421 * 1000;
}

void setup() {
  //init serial port
  {
    Serial.begin(250000); //init serial port and set baudrate
    while(!Serial); //wait for serial port to connect (needed for Leonardo only)
    Serial.println("\nStart...");
    pinMode(EN_PIN, OUTPUT);
    pinMode(DIR_PIN, OUTPUT);
    pinMode(STEP_PIN, OUTPUT);
    pinMode(CS_PIN, OUTPUT);
    digitalWrite(EN_PIN, HIGH); //deactivate driver (LOW active)
    digitalWrite(DIR_PIN, LOW); //LOW or HIGH
    digitalWrite(STEP_PIN, LOW);
    digitalWrite(CS_PIN, HIGH);
    // ************** HR
    pinMode(EN_PIN_HR, OUTPUT);
    pinMode(DIR_PIN_HR, OUTPUT);
    pinMode(STEP_PIN_HR, OUTPUT);
    pinMode(CS_PIN_HR, OUTPUT);
    digitalWrite(EN_PIN_HR, HIGH); //deactivate driver (LOW active)
    digitalWrite(DIR_PIN_HR, LOW); //LOW or HIGH
    digitalWrite(STEP_PIN_HR, LOW);
    digitalWrite(CS_PIN_HR, HIGH);    
    SPI.begin();
    pinMode(MISO, INPUT_PULLUP);
  }

  //set TMC2130 config
  {
    driver.push();
    driver.toff(3);
    driver.tbl(1);
    driver.hysteresis_start(4);
    driver.hysteresis_end(-2);
    driver.rms_current(800); // mA
    driver.microsteps(16);
    driver.diag1_stall(1);
    driver.diag1_active_high(1);
    driver.coolstep_min_speed(0xFFFFF); // 20bit max
    driver.THIGH(0);
    driver.semin(5);
    driver.semax(2);
    driver.sedn(0b01);
    driver.sg_stall_value(STALL_VALUE);

    driver_HR.push();
    driver_HR.toff(3);
    driver_HR.tbl(1);
    driver_HR.hysteresis_start(4);
    driver_HR.hysteresis_end(-2);
    driver_HR.rms_current(800); // mA
    driver_HR.microsteps(16);
    driver_HR.diag1_stall(1);
    driver_HR.diag1_active_high(1);
    driver_HR.coolstep_min_speed(0xFFFFF); // 20bit max
    driver_HR.THIGH(0);
    driver_HR.semin(5);
    driver_HR.semax(2);
    driver_HR.sedn(0b01);
    driver_HR.sg_stall_value(STALL_VALUE);
  }

  // Set stepper interrupt
  {
    cli();//stop interrupts
    TCCR1A = 0;// set entire TCCR1A register to 0
    TCCR1B = 0;// same for TCCR1B
    TCNT1  = 0;//initialize counter value to 0
    OCR1A = 256;// = (16*10^6) / (1*1024) - 1 (must be <65536)
    // turn on CTC mode
    TCCR1B |= (1 << WGM12);
    // Set CS11 bits for 8 prescaler
    TCCR1B |= (1 << CS11);// | (1 << CS10);  
    // enable timer compare interrupt
    TIMSK1 |= (1 << OCIE1A);
    sei();//allow interrupts
  }

  //TMC2130 outputs on (LOW active)
  digitalWrite(EN_PIN, LOW);
  digitalWrite(EN_PIN_HR, LOW);

  vsense = driver.vsense();
    vsense = driver_HR.vsense();
}

ISR(TIMER1_COMPA_vect){
  PORTF |= 1 << 0;
  PORTF &= ~(1 << 0);
}

void loop()
{
  static uint32_t last_time=0;
  uint32_t ms = millis();

  while(Serial.available() > 0) {
    int8_t read_byte = Serial.read();
    if (read_byte == '0')      { TIMSK1 &= ~(1 << OCIE1A); digitalWrite( EN_PIN, HIGH );digitalWrite( EN_PIN_HR, HIGH ); }
    else if (read_byte == '1') { TIMSK1 |=  (1 << OCIE1A); digitalWrite( EN_PIN,  LOW );  digitalWrite( EN_PIN_HR,  LOW ); }
    else if (read_byte == '+') if (OCR1A > MAX_SPEED) OCR1A -= 20;
    else if (read_byte == '-') if (OCR1A < MIN_SPEED) OCR1A += 20;
  }

  if((ms-last_time) > 100) //run every 0.1s
  {
    last_time = ms;
    uint32_t drv_status = driver.DRV_STATUS();
    Serial.print("lr : 0 ");
    Serial.print((drv_status & SG_RESULT_bm)>>SG_RESULT_bp , DEC);
    Serial.print(" ");
    Serial.println(rms_current((drv_status & CS_ACTUAL_bm)>>CS_ACTUAL_bp), DEC);
        uint32_t drv_status_HR = driver_HR.DRV_STATUS();
    Serial.print("hr : 0 ");
    Serial.print((drv_status_HR & SG_RESULT_bm)>>SG_RESULT_bp , DEC);
    Serial.print(" ");
    Serial.println(rms_current((drv_status_HR & CS_ACTUAL_bm)>>CS_ACTUAL_bp), DEC);
  }
}

thank youuuuuuuu

teemuatlut commented 5 years ago

In the interrupt routine:

ISR(TIMER1_COMPA_vect){
  PORTF |= 1 << 0;
  PORTF &= ~(1 << 0);
}

You're still toggling the STEP pin only for the first driver. You can also use digitalWrite in there but it's slower and will limit your maximum stepping rate. But you need to determine if this is an issue for you in the first place.

joe318 commented 5 years ago

omg thank you can i bother you little more ? lol First ok yes was sure it's the fault or my skills, you don't have morre simple example ready for just read stallguard?

and i don't undesrtand what i need put in interrupt? can you help me please :)

teemuatlut commented 5 years ago

Interrupts provide a more consistent stepping rate and are needed to reliably read the value. If you were to just send the step pulses inside the Arduino loop, the step pulses would stop for the duration of SPI communication. This would then affect the readings.

joe318 commented 5 years ago

yes yes ok i know and understand ok i go ask to google more about interrupts, i'm little new with arduino, i'm old php sql javascript css but young arduino player lol

joe318 commented 5 years ago

omg wait don't lose time, i found you answer the solytion to another one, idn't know about this way to use the arduino port thanks

joe318 commented 5 years ago

i test it right now and post here, if someone need

joe318 commented 5 years ago

ok done it's working, but because you i need study more loool study this bitwise story.

message for newbie like me ahahah : PORTF |= 1 << 0; it's PF0 or A0 or pin 54 PORTF &= ~(1 << 0);

PORTF |= 1 << 3; it's PF3 or A3 or 57 PORTF &= ~(1 << 3);

and learn about bitwise here https://www.arduino.cc/reference/en/#structure for can understand.

joe318 commented 5 years ago

ok now i feel me a kid arduino not a newbie, but it's cool coz i love learn, let's go to play and learn. Thanks a lot