add machine readablke data format for TMC status for the processing sketch to tune
authorJim Morris <morris@wolfman.com>
Mon, 16 Nov 2015 22:22:43 +0000 (14:22 -0800)
committerJim Morris <morris@wolfman.com>
Mon, 16 Nov 2015 22:22:43 +0000 (14:22 -0800)
src/libs/StepperMotor.h
src/modules/utils/motordrivercontrol/MotorDriverControl.cpp
src/modules/utils/motordrivercontrol/MotorDriverControl.h
src/modules/utils/motordrivercontrol/drivers/TMC26X/TMC26X.cpp
src/modules/utils/motordrivercontrol/drivers/TMC26X/TMC26X.h

index 0bf847d..893dbcc 100644 (file)
@@ -27,7 +27,8 @@ class StepperMotor {
 
         inline void enable(bool state) { en_pin.set(!state); };
 
-        bool is_moving() { return moving; }
+        bool is_moving() const { return moving; }
+        bool which_direction() const { return direction; }
         void move_finished();
         StepperMotor* move( bool direction, unsigned int steps, float initial_speed= -1.0F);
         void signal_move_finished();
index bf2b5e8..977f234 100644 (file)
@@ -231,7 +231,7 @@ void MotorDriverControl::on_gcode_received(void *argument)
         } else if(gcode->m == 911) {
             // set or get raw registers
             // M911 will dump all the registers and status of all the motors
-            // M911.1 Pn (or A0) will dump the registers and status of the selected motor
+            // M911.1 Pn (or A0) will dump the registers and status of the selected motor. X0 will request format in processing machine readable format
             // M911.2 Pn (or B0) Rxxx Vyyy sets Register xxx to value yyy for motor nnn, xxx == 255 writes the registers, xxx == 0 shows what registers are mapped to what
             // M911.3 Pn (or C0) will set the options based on the parameters passed as below...
             // TMC2660:-
@@ -247,11 +247,11 @@ void MotorDriverControl::on_gcode_received(void *argument)
             if(gcode->subcode == 0 && gcode->get_num_args() == 0) {
                 // M911 no args dump status for all drivers, M911.1 P0|A0 dump for specific driver
                 gcode->stream->printf("Motor %d (%c)...\n", id, designator);
-                dump_status(gcode->stream);
+                dump_status(gcode->stream, true);
 
             }else if(gcode->get_value('P') == id || gcode->has_letter(designator)) {
                 if(gcode->subcode == 1) {
-                    dump_status(gcode->stream);
+                    dump_status(gcode->stream, !gcode->has_letter('X'));
 
                 }else if(gcode->subcode == 2 && gcode->has_letter('R') && gcode->has_letter('V')) {
                     set_raw_register(gcode->stream, gcode->get_value('R'), gcode->get_value('V'));
@@ -343,7 +343,7 @@ void MotorDriverControl::enable(bool on)
     }
 }
 
-void MotorDriverControl::dump_status(StreamOutput *stream)
+void MotorDriverControl::dump_status(StreamOutput *stream, bool b)
 {
     switch(chip) {
         case DRV8711:
@@ -351,7 +351,7 @@ void MotorDriverControl::dump_status(StreamOutput *stream)
             break;
 
         case TMC2660:
-            tmc26x->dumpStatus(stream);
+            tmc26x->dumpStatus(stream, b);
             break;
     }
 }
index cba4c02..627f02c 100644 (file)
@@ -31,7 +31,7 @@ class MotorDriverControl : public Module {
         void set_current( uint32_t current );
         uint32_t set_microstep( uint32_t ms );
         void set_decay_mode( uint8_t dm );
-        void dump_status(StreamOutput*);
+        void dump_status(StreamOutput*, bool);
         void set_raw_register(StreamOutput *stream, uint32_t reg, uint32_t val);
         void set_options(Gcode *gcode);
 
index 0da0265..ab320bf 100644 (file)
@@ -32,7 +32,8 @@
 #include "StreamOutput.h"
 #include "Kernel.h"
 #include "libs/StreamOutputPool.h"
-
+#include "Robot.h"
+#include "StepperMotor.h"
 
 //! return value for TMC26X.getOverTemperature() if there is a overtemperature situation in the TMC chip
 /*!
@@ -190,7 +191,7 @@ void TMC26X::init()
     setConstantOffTimeChopper(7, 54, 13, 12, 1);
 #else
     // for 1.5amp kysan @ 12v
-    setSpreadCycleChopper(5, 2, 5, 0, 0);
+    setSpreadCycleChopper(5, 54, 5, 0, 0);
     // for 4amp Nema24 @ 12v
     //setSpreadCycleChopper(5, 2, 4, 0, 0);
 #endif
@@ -423,6 +424,8 @@ void TMC26X::setConstantOffTimeChopper(int8_t constant_off_time, int8_t blank_ti
     } else {
         blank_value = 0;
     }
+    this->blank_time = blank_time;
+
     if (fast_decay_time_setting < 0) {
         fast_decay_time_setting = 0;
     } else if (fast_decay_time_setting > 15) {
@@ -484,6 +487,11 @@ void TMC26X::setConstantOffTimeChopper(int8_t constant_off_time, int8_t blank_ti
 
 void TMC26X::setSpreadCycleChopper(int8_t constant_off_time, int8_t blank_time, int8_t hysteresis_start, int8_t hysteresis_end, int8_t hysteresis_decrement)
 {
+    h_start = hysteresis_start;
+    h_end = hysteresis_end;
+    h_decrement = hysteresis_decrement;
+    this->blank_time = blank_time;
+
     //perform some sanity checks
     if (constant_off_time < 2) {
         constant_off_time = 2;
@@ -503,6 +511,7 @@ void TMC26X::setSpreadCycleChopper(int8_t constant_off_time, int8_t blank_time,
     } else {
         blank_value = 0;
     }
+
     if (hysteresis_start < 1) {
         hysteresis_start = 1;
     } else if (hysteresis_start > 8) {
@@ -537,6 +546,7 @@ void TMC26X::setSpreadCycleChopper(int8_t constant_off_time, int8_t blank_time,
     chopper_config_register |= ((unsigned long)hysteresis_end) << HYSTERESIS_LOW_SHIFT;
     //set the hystereis decrement
     chopper_config_register |= ((unsigned long)hysteresis_decrement) << HYSTERESIS_DECREMENT_SHIFT;
+
     //if started we directly send it to the motor
     if (started) {
         send262(chopper_config_register);
@@ -846,9 +856,9 @@ bool TMC26X::isCurrentScalingHalfed()
     }
 }
 
-void TMC26X::dumpStatus(StreamOutput *stream)
+void TMC26X::dumpStatus(StreamOutput *stream, bool readable)
 {
-    if (this->started) {
+    if (readable) {
         readStatus(TMC26X_READOUT_POSITION); // get the status bits
 
         stream->printf("Chip type TMC26X\n");
@@ -900,6 +910,70 @@ void TMC26X::dumpStatus(StreamOutput *stream)
         stream->printf(" stall guard2 current register: %08lX(%ld)\n", stall_guard2_current_register_value, stall_guard2_current_register_value);
         stream->printf(" driver configuration register: %08lX(%ld)\n", driver_configuration_register_value, driver_configuration_register_value);
         stream->printf(" motor_driver_control.xxx.reg %05lX,%05lX,%05lX,%05lX,%05lX\n", driver_control_register_value, chopper_config_register, cool_step_register_value, stall_guard2_current_register_value, driver_configuration_register_value);
+
+    } else {
+        // TODO hardcoded for X need to select ABC as needed
+        bool moving = THEKERNEL->robot->actuators[0]->is_moving();
+        // dump out in the format that the processing script needs
+        if (moving) {
+            stream->printf("#sg%d,p%lu,k%u,r,", getCurrentStallGuardReading(), THEKERNEL->robot->actuators[0]->get_stepped(), getCoolstepCurrent());
+        } else {
+            readStatus(TMC26X_READOUT_POSITION); // get the status bits
+            stream->printf("#s,");
+        }
+        stream->printf("d%d,", THEKERNEL->robot->actuators[0]->which_direction() ? 1 : -1);
+        stream->printf("c%u,m%d,", getCurrent(), getMicrosteps());
+        // stream->printf('S');
+        // stream->printf(tmc26XStepper.getSpeed(), DEC);
+        stream->printf("t%d,f%d,", getStallGuardThreshold(), getStallGuardFilter());
+
+        //print out the general cool step config
+        if (isCoolStepEnabled()) stream->printf("Ke+,");
+        else stream->printf("Ke-,");
+
+        stream->printf("Kl%u,Ku%u,Kn%u,Ki%u,Km%u,",
+                       getCoolStepLowerSgThreshold(), getCoolStepUpperSgThreshold(), getCoolStepNumberOfSGReadings(), getCoolStepCurrentIncrementSize(), getCoolStepLowerCurrentLimit());
+
+        //detect the winding status
+        if (isOpenLoadA()) {
+            stream->printf("ao,");
+        } else if(isShortToGroundA()) {
+            stream->printf("ag,");
+        } else {
+            stream->printf("a-,");
+        }
+        //detect the winding status
+        if (isOpenLoadB()) {
+            stream->printf("bo,");
+        } else if(isShortToGroundB()) {
+            stream->printf("bg,");
+        } else {
+            stream->printf("b-,");
+        }
+
+        char temperature = getOverTemperature();
+        if (temperature == 0) {
+            stream->printf("x-,");
+        } else if (temperature == TMC26X_OVERTEMPERATURE_PREWARING) {
+            stream->printf("xw,");
+        } else {
+            stream->printf("xe,");
+        }
+
+        if (isEnabled()) {
+            stream->printf("e1,");
+        } else {
+            stream->printf("e0,");
+        }
+
+        //write out the current chopper config
+        // stream->printf("Cm");
+        // stream->printf(chopperMode, DEC);
+        stream->printf("Co%d,Cb%d,", constant_off_time, blank_time);
+        if ((chopper_config_register & CHOPPER_MODE_T_OFF_FAST_DECAY) == 0) {
+            stream->printf("Cs%d,Ce%d,Cd%d,", h_start, h_end, h_decrement);
+        }
+        stream->printf("\n");
     }
 }
 
@@ -963,48 +1037,48 @@ void TMC26X::send262(unsigned long datagram)
 #define GET(X) (options.at(X))
 bool TMC26X::set_options(const options_t& options)
 {
-    bool set= false;
+    bool set = false;
     if(HAS('O') || HAS('Q')) {
         // void TMC26X::setStallGuardThreshold(int8_t stall_guard_threshold, int8_t stall_guard_filter_enabled)
-        int8_t o= HAS('O') ? GET('O') : getStallGuardThreshold();
-        int8_t q= HAS('Q') ? GET('Q') : getStallGuardFilter();
+        int8_t o = HAS('O') ? GET('O') : getStallGuardThreshold();
+        int8_t q = HAS('Q') ? GET('Q') : getStallGuardFilter();
         setStallGuardThreshold(o, q);
-        set= true;
+        set = true;
     }
 
     if(HAS('H') && HAS('I') && HAS('J') && HAS('K') && HAS('L')) {
         //void TMC26X::setCoolStepConfiguration(unsigned int lower_SG_threshold, unsigned int SG_hysteresis, uint8_t current_decrement_step_size, uint8_t current_increment_step_size, uint8_t lower_current_limit)
         setCoolStepConfiguration(GET('H'), GET('I'), GET('J'), GET('K'), GET('L'));
-        set= true;
+        set = true;
     }
 
     if(HAS('S')) {
-        uint32_t s= GET('S');
-        if(s==0 && HAS('U') && HAS('V') && HAS('W') && HAS('X') && HAS('Y')) {
+        uint32_t s = GET('S');
+        if(s == 0 && HAS('U') && HAS('V') && HAS('W') && HAS('X') && HAS('Y')) {
             //void TMC26X::setConstantOffTimeChopper(int8_t constant_off_time, int8_t blank_time, int8_t fast_decay_time_setting, int8_t sine_wave_offset, uint8_t use_current_comparator)
             setConstantOffTimeChopper(GET('U'), GET('V'), GET('W'), GET('X'), GET('Y'));
-            set= true;
+            set = true;
 
-        }else if(s==1 && HAS('U') && HAS('V') && HAS('W') && HAS('X') && HAS('Y')) {
+        } else if(s == 1 && HAS('U') && HAS('V') && HAS('W') && HAS('X') && HAS('Y')) {
             //void TMC26X::setSpreadCycleChopper(int8_t constant_off_time, int8_t blank_time, int8_t hysteresis_start, int8_t hysteresis_end, int8_t hysteresis_decrement);
             setSpreadCycleChopper(GET('U'), GET('V'), GET('W'), GET('X'), GET('Y'));
-            set= true;
+            set = true;
 
-        }else if(s==2 && HAS('Z')) {
+        } else if(s == 2 && HAS('Z')) {
             setRandomOffTime(GET('Z'));
-            set= true;
+            set = true;
 
-        }else if(s==3 && HAS('Z')) {
+        } else if(s == 3 && HAS('Z')) {
             setDoubleEdge(GET('Z'));
-            set= true;
+            set = true;
 
-        }else if(s==4 && HAS('Z')) {
+        } else if(s == 4 && HAS('Z')) {
             setStepInterpolation(GET('Z'));
-            set= true;
+            set = true;
 
-        }else if(s==5 && HAS('Z')) {
+        } else if(s == 5 && HAS('Z')) {
             setCoolStepEnabled(GET('Z') == 1);
-            set= true;
+            set = true;
         }
     }
 
index a79893c..63c7b4f 100644 (file)
@@ -406,7 +406,7 @@ public:
      * \brief Prints out all the information that can be found in the last status read out - it does not force a status readout.
      * The result is printed via Serial
      */
-    void dumpStatus(StreamOutput *stream);
+    void dumpStatus(StreamOutput *stream, bool readable= true);
     bool setRawRegister(StreamOutput *stream, uint32_t reg, uint32_t val);
 
     using options_t= std::map<char,int>;
@@ -414,6 +414,12 @@ public:
     bool set_options(const options_t& options);
 
 private:
+    //helper routione to get the top 10 bit of the readout
+    inline int getReadoutValue();
+    // SPI sender
+    inline void send262(unsigned long datagram);
+    std::function<int(uint8_t *b, int cnt, uint8_t *r)> spi;
+
     unsigned int resistor{50}; // current sense resitor value in milliohm
 
     //driver control register copies to easily set & modify the registers
@@ -425,18 +431,20 @@ private:
     //the driver status result
     unsigned long driver_status_result;
 
-    //helper routione to get the top 10 bit of the readout
-    inline int getReadoutValue();
-
     //status values
-    bool started; //if the stepper has been started yet
     int microsteps; //the current number of micro steps
-    int8_t constant_off_time; //we need to remember this value in order to enable and disable the motor
-    uint8_t cool_step_lower_threshold; // we need to remember the threshold to enable and disable the CoolStep feature
-    bool cool_step_enabled; //we need to remember this to configure the coolstep if it si enabled
 
-    // SPI sender
-    std::function<int(uint8_t *b, int cnt, uint8_t *r)> spi;
-    inline void send262(unsigned long datagram);
+    // only beeded for the tuning app report
+    struct {
+        int8_t blank_time:8;
+        int8_t constant_off_time:5; //we need to remember this value in order to enable and disable the motor
+        int8_t h_start:4;
+        int8_t h_end:4;
+        int8_t h_decrement:3;
+        bool cool_step_enabled:1; //we need to remember this to configure the coolstep if it si enabled
+        bool started:1; //if the stepper has been started yet
+    };
+
+    uint8_t cool_step_lower_threshold; // we need to remember the threshold to enable and disable the CoolStep feature
 };