Testprogram for TMC2209-Library. Uses Speed-Control via VACTUAL instead of Step/Dir

Dependencies:   TMCStepper mRotaryEncoder-os

main.cpp

Committer:
charly
Date:
2021-12-11
Revision:
10:376299814a3b
Parent:
9:babbfb61d347

File content as of revision 10:376299814a3b:

#include "mbed.h"
#include "platform/mbed_thread.h"
#include "TMCStepper.h"
#include "mRotaryEncoder.h"

/*
 Testprogram for TMCStepper-Library
 TMCStepper based on https://github.com/teemuatlut/TMCStepper for Arduino
 by https://github.com/teemuatlut
 +++++
 Tested with https://github.com/bigtreetech/BIGTREETECH-TMC2209-V1.2
*/


DigitalOut ledCW(LED1);  // Show rotation clockwise // Gren LED LD3
DigitalOut ledCCW(NC); // Show rotation counterclockwise // no more LEDs on L432

//Virtual serial port over USB with 15200 baud 8N1
static BufferedSerial host(USBTX, USBRX,115200);

//mRotaryEncoder(PinName pinA, PinName pinB, PinName pinSW, PinMode pullMode=PullUp, int debounceTime_us=1000)
mRotaryEncoder  wheel(D2, D3, D6,PullUp,3000); // default 1500
  //D7, D8 not available on L432KC with default solder bridges

// hardware parameters:
// MOTOR Steps per Revolution ( 1/8 Microsteps, 200Steps per Rev / 1.8 degrees per FullStep)
#define MSPR 1600
// Gear Ratio
#define GR 288

#define DRIVER_ADDRESS 0b00 // TMC2209 Driver address according to MS1 and MS2
#define R_SENSE 0.11f   // R-Sense in OHM. Match to your driver
#define MICROSTEPS 256  // # of microsteps
#define RMSCURRENT 800  // RMS current of Stepper Coil in mA
#define MAXSPEED 5500   // Maximaum speed (5500 with RMS800 @12V/0.6Amax)

// A TMCStepper-object with UART and given address and R-Sense
//RX, TX, RS, Addr 
TMC2209Stepper stepper(D0, D1, R_SENSE, DRIVER_ADDRESS);

InterruptIn diag(D12);
DigitalOut enn(D11);

volatile bool enc_pressed = false;      // Button of rotaryencoder was pressed
volatile bool enc_rotated = false;      // rotary encoder was totaded left or right
volatile bool enc_action  = false;      // any change happened
volatile bool diag_event  = false;      // DIAG-Pin of TMC
int lastGet;
int thisGet;

//interrup-Handler for button on rotary-encoder
void trigger_sw() {
    enc_pressed = true;               // just set the flag, rest is done outside isr
}

//interrup-Handler for rotary-encoder rotation
void trigger_rotated() {
    enc_rotated = true;               // just set the flag, rest is done outside isr
}

//interrup-Handler for TMC2209-DIAG-Pin
void trigger_diag() {
    diag_event = true;               // just set the flag, rest is done outside isr
}

// Assumes little endian
void printBits(size_t const size, void const * const ptr)
{
    unsigned char *b = (unsigned char*) ptr;
    unsigned char byte;
    int i, j;
//    puts("#");
    for (i = size-1; i >= 0; i--) {
        for (j = 7; j >= 0; j--) {
            byte = (b[i] >> j) & 1;
            printf("%u", byte);
        }
    }
//    puts("#");
}
 
 int main()
 {
    printf("\r\nConnected to mbed\r\n");
    printf("This is Mbed OS %d.%d.%d.\n", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION);
    //Intitiallize RotaryEncoder
    // call trigger_sw() when button of rotary-encoder is pressed
    wheel.attachSW(&trigger_sw);
    // call trigger_rot() when the shaft is rotaded left or right
    wheel.attachROT(&trigger_rotated);
    lastGet = 0;
    // set enc_rotated, so startup
    enc_rotated = true;
    enc_action = true;
    ledCW = 1;
    ledCCW = 1;
    
    // disable Driver
    enn=1;
    // wait for Hhardware to settle
    ThisThread::sleep_for(100ms);
        
    // Initialize Stepper
    printf("connecting to TMC-Module...\r\n");
    stepper.begin();                    // UART: Init SW UART (if selected) with default baudrate
    
    //read and check version - must be 0x21
    uint8_t tmc_version = stepper.version();
    printf("TMC-Version: %02X\r\n",tmc_version);
    if (tmc_version != 0x21) {
            printf("Wrong TMC-Version(not 0x21) or communication error!! STOPPING!!!\r\n");
            if (stepper.CRCerror) {
                printf("CRC-Error!!!\r\n");
            }
            while (1) {
                ledCW = 1;
                ledCCW = 0;
                ThisThread::sleep_for(50ms);
                ledCW = 0;
                ledCCW = 1;
                ThisThread::sleep_for(50ms);
            };
    }
    
    stepper.push();                     // initialize all registers??? required?
    
    stepper.toff(3);                    // Enables driver in software - 3, 5 ????
    stepper.rms_current(RMSCURRENT);    // Set motor RMS current in mA / min 500 for 24V/speed:3000
                                        // 1110, 800
                                        // working: 800 12V/0,6Amax,  Speed up to 5200=4U/min
                                        
    stepper.microsteps(MICROSTEPS);   // Set microsteps to 1:Fullstep ... 256: 1/256th
    stepper.en_spreadCycle(true);     // Toggle spreadCycle on TMC2208/2209/2224: default false, true: much faster!!!!
    stepper.pwm_autoscale(true);      // Needed for stealthChop
    
    // enable driver
    enn = 0;
    
    uint8_t gstat = stepper.GSTAT();
    printf("GSTAT(): "); printBits(sizeof(gstat),&gstat);printf("\r\n");
    
    uint32_t gconf = stepper.GCONF();
    printf("GCONF(): "); printBits(sizeof(gconf),&gconf);printf("\r\n");
    
    uint32_t status = stepper.DRV_STATUS();
    printf("DRV_STATUS(): "); printBits(sizeof(status),&status);printf("\r\n");
    
    uint32_t ioin = stepper.IOIN();        
    printf("IOIN(): "); printBits(sizeof(ioin),&ioin);printf("\r\n");
    
    uint8_t ihold = stepper.ihold();
    printf("IHOLD(): "); printBits(sizeof(ihold),&ihold);printf("\r\n");
    
    uint8_t irun = stepper.irun();
    printf("IRUN(): "); printBits(sizeof(irun),&irun);printf("\r\n");
    
    uint8_t iholddelay = stepper.iholddelay();
    printf("IHOLDDELAY(): "); printBits(sizeof(iholddelay),&iholddelay);printf("\r\n");
    
    // do a peep by setting vactual to a too high speed
    
    //stepper.VACTUAL(50000*MICROSTEPS);
    //ThisThread::sleep_for(1s);
    
    // initialize Automatic tunig (Chap 6.1)
    printf("Start automatic tunig Chap6.1 .....");
    stepper.VACTUAL(1);
    stepper.VACTUAL(0);
    ThisThread::sleep_for(100ms);
    stepper.VACTUAL(500*MICROSTEPS);
    ThisThread::sleep_for(2s);
    stepper.VACTUAL(0);
    printf("done\r\n");
    
    diag.rise(&trigger_diag);
    
    //bool shaft = false;  //direction CW or CCW
    
    while(1) {
/*  Spped-UP/Down-Cycles      
//        printf("TSTEP(): %i\r\n", stepper.TSTEP());
        uint32_t status = stepper.DRV_STATUS();
        printf("DRV_STATUS(): "); printBits(sizeof(status),&status);printf("\r\n");
        uint32_t ioin = stepper.IOIN();        
        printf("IOIN(): "); printBits(sizeof(ioin),&ioin);printf("\r\n");
//        uint32_t otp = stepper.OTP_READ();
//        printf("OTP_READ(): ");printBits(sizeof(otp),&otp);printf("\r\n");
      
        printf("VACTUAL(): %zu \r\n", stepper.VACTUAL());
        // increase
        uint32_t maxspeed = 3000; //max 3400 or 3000
        uint32_t actspeed = 0;
        while (actspeed < maxspeed) {
            actspeed += 200;
            if (actspeed > maxspeed) {
                actspeed = maxspeed;
            }
            printf("actspeed: %i",actspeed);
            stepper.VACTUAL(actspeed*MICROSTEPS);// Set Speed to value
            ThisThread::sleep_for(25ms); //wait
        }
        printf("VACTUAL(): %zu \r\n", stepper.VACTUAL());
        ThisThread::sleep_for(5s); 
        // decrease
        maxspeed = 0;
        while (actspeed > maxspeed) {
            actspeed -= 200;
            if (actspeed < 0) {
                actspeed = 0;
            }
            printf("actspeed: %i",actspeed);
            stepper.VACTUAL(actspeed*MICROSTEPS);// Set Speed to value
            ThisThread::sleep_for(25ms); //wait
        }

//        stepper.VACTUAL(400*MICROSTEPS);// Set Speed to value
        ThisThread::sleep_for(5s); //wait 
        // inverse direction
        shaft = !shaft;
        stepper.shaft(shaft);
        // Read Interace-Count
        printf("IFCNT(): %zu \r\n",stepper.IFCNT());
        printf("...\r\n");
*/
////// Control motor-speed by rotary-encoder
    
    // DIAG-PIN showed Error-Condition?
    if (diag_event) {
        diag_event = false;
        printf("DIAG occured!\r\n");
        gstat = stepper.GSTAT();
        printf("GSTAT(): "); printBits(sizeof(gstat),&gstat);printf("\r\n");
        status = stepper.DRV_STATUS();
        printf("DRV_STATUS(): "); printBits(sizeof(status),&status);printf("\r\n");
        //safty turn off friver
        printf("Shutting Down Motordriver...\r\n");
        enn=1;
        stepper.toff(0);
        status = stepper.DRV_STATUS();
        printf("DRV_STATUS(): "); printBits(sizeof(status),&status);printf("\r\n");
        ioin = stepper.IOIN();        
        printf("IOIN(): "); printBits(sizeof(ioin),&ioin);printf("\r\n");
        ihold = stepper.ihold();
        printf("IHOLD(): "); printBits(sizeof(ihold),&ihold);printf("\r\n");
        irun = stepper.irun();
        printf("IRUN(): "); printBits(sizeof(irun),&irun);printf("\r\n");
        iholddelay = stepper.iholddelay();
        printf("IHOLDDELAY(): "); printBits(sizeof(iholddelay),&iholddelay);printf("\r\n");
        printf("stopping programm - manual RESET required!!!!!!\r\n");
        while (1) {
            ledCW = 1;
            ledCCW = 1;
            ThisThread::sleep_for(200ms);
            ledCW = 0;
            ledCCW = 0;
            ThisThread::sleep_for(200ms);
        };
        
    }
    
    // shaft has been rotated?
    if (enc_rotated) {
        enc_rotated = false;
        enc_action = true;
        thisGet = wheel.Get();
        if (thisGet*100 > MAXSPEED) { //on upper limit?
            wheel.Set( MAXSPEED/100);
            thisGet = wheel.Get();
        }
        if (thisGet*100 < MAXSPEED*(-1)) { //on lower limit?
            wheel.Set( MAXSPEED*(-1)/100);
            thisGet = wheel.Get();
        } 
        stepper.VACTUAL(thisGet*100*MICROSTEPS);// Set Speed to value
        printf("actspeed: %i\r\n",thisGet*100);
        
    }
    // Button pressed?
    if (enc_pressed) {
        enc_pressed = false;
        enc_action = true;
        wheel.Set(0);
        thisGet = wheel.Get();
        stepper.VACTUAL(thisGet*100*MICROSTEPS);// Set Speed to value
        printf("actspeed: %i\r\n",thisGet*100);
        
        gstat = stepper.GSTAT();
        printf("GSTAT(): "); printBits(sizeof(gstat),&gstat);printf("\r\n");
        gconf = stepper.GCONF();
        printf("GCONF(): "); printBits(sizeof(gconf),&gconf);printf("\r\n");
        status = stepper.DRV_STATUS();
        printf("DRV_STATUS(): "); printBits(sizeof(status),&status);printf("\r\n");
        ioin = stepper.IOIN();        
        printf("IOIN(): "); printBits(sizeof(ioin),&ioin);printf("\r\n");
        ihold = stepper.ihold();
        printf("IHOLD(): "); printBits(sizeof(ihold),&ihold);printf("\r\n");
        irun = stepper.irun();
        printf("IRUN(): "); printBits(sizeof(irun),&irun);printf("\r\n");
        iholddelay = stepper.iholddelay();
        printf("IHOLDDELAY(): "); printBits(sizeof(iholddelay),&iholddelay);printf("\r\n");

    }        
    // anything changed?
    if (enc_action) {
        enc_action = false;
        // show direction of motor on leds
        if (thisGet > 0) {
            ledCW = 1;
            ledCCW= 0;
        }
        if (thisGet < 0) {
            ledCW = 0;
            ledCCW= 1;
        }
        if (thisGet == 0) {
            ledCW = 1;
            ledCCW= 1;
        }
    }
   } // while 1
 }