Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 18 of 18

Thread: TeensyStep reverse not working as it should be.

  1. #1
    Junior Member
    Join Date
    Nov 2021
    Posts
    11

    TeensyStep reverse not working as it should be.

    Hi Forum.

    @luni from teensyStep

    Please excuse me my ignorance.
    Having no technical background and totally no programming experience.

    Just a musician trying to engineer something useful. (i.e. grinding a bassoon reed. For reference a bassoon sounds like this: https://www.youtube.com/watch?v=ldMz94OGbIM)

    The situation:
    Using following stepper/servo motor: https://shop.cnc-technics.de/Integra...36-62-126.html
    (and the same problem arises with the other stepper motor I have for testing: https://shop.cnc-technics.de/IHSS60-...39-40-172.html

    Using a teensy 3.2 custom pcb from the same shop.

    Searched online and offline for a way to advance and reverse the given motor using following basic code:

    Code:
    #include "TeensyStep.h"
    Stepper motor (2,15);                   // Basic stepper
    StepControl controller;                 // Use default settings 
    
    void setup() {
      motor.setMaxSpeed(66000);
      motor.setAcceleration(60000);  
    }
    
    void loop() {
      Serial.println(millis());                         // Just so I know something is happening
    
      motor.setTargetAbs(10000);                    // motor advances clock wise
      controller.move(motor);
      delay(1000);
    
      motor.setTargetAbs(-10000);                   // I should expect motor reversing counter-clock wise, but it still advances. Examening the currentposition hower gives the startposition (i.e. 0)
      controller.move(motor);
      delay(1000);
    }
    The motor.setTargetAbs(10000) advances the motor clock-wise.
    I would excpect the statement "motor.setTargetAbs(-10000) to go counter-clockwise.

    Hower the motor just keeps advancing.

    In a more extended example, the motor.getPosition() before and after advancing gives a correct position but the motor is not physically reversing direction.

    Need some desperate help for this.

    Code:
    #include "TeensyStep.h"
    
    Stepper motor (2,15);                   // Basic stepper
    
    // Stepper GrindingMtr (2, 15);         // STEP pin: 2, DIR pin: 15
    // Stepper RotateMtr (3, 14);           // STEP pin: 3, DIR pin: 14
    
    StepControl controller;                 // Use default settings 
    RotateControl rotator;                  // Use default settings for the GrindingController
    
    const int rpm = 1600;
    const int spindlePPR = 3200;                                            // Hardware settings pulse per revolution (dip switches)
    const int spindleSPR = 200;                                             // steps per revolution (360/1.8)
    const int spindleAccel = 75000;                                         // spindle acceleration
    constexpr signed spindleSpeed = (rpm * spindlePPR) / 60;                // steps per second
    
    const int ledPin = 13;        // Led pin
    
    void setup()
    {
      Serial.begin(9600); // USB is always 12 or 480 Mbit/sec
      while (!Serial);
    
      // Define ledpin
      pinMode(ledPin, OUTPUT);
    
      // Parameter for the stepper motor
      motor
        .setAcceleration(spindleAccel)
        .setMaxSpeed(spindleSpeed);
    
      // H for HELP ME !
      Serial.println("h for help");
    }
    
    void loop() 
    {
      handleCommands();
    }
    
    void moveToPosition(int numberOfSteps)
    {
      int newPosition = motor.getPosition() + numberOfSteps;
      
      if (!controller.isRunning() && !rotator.isRunning())        // skip move command if motor is running already
      {
          printTxt("Requested number of steps: ", numberOfSteps);
          printTxt("             Resulting in (new) position  : ", newPosition);
          printTxt("             Moving from current position : ", motor.getPosition());
      
          // motor.setStepPinPolarity(HIGH);           // ????
          motor.setTargetAbs(newPosition);
          
          controller.move(motor);
          
          Serial.println("             Started Motor movement.");
          printTxt("             Motor now at position: ", motor.getPosition());
      }
      else
      {
          Serial.println("Ignored, Motor is already running");
      }
    }
    
    void handleCommands()
    {
        if (Serial.available() > 0)                 // skip if the serial buffer is empty
        {
            char cmd = Serial.read();               // get one char from the buffer...
            switch (cmd)                            // ... and analyze it
            {
              // ------------------
              // move command
              // ------------------
              case 'p':
                  moveToPosition(0);              
                  break;
                  
              case 'f':                               
                  moveToPosition(spindleSPR);         // forward is ok
                  break;
    
              // ------------------
              // Reverse move
              // ------------------
              case 'r':                               // reverse direction
                  moveToPosition(-spindleSPR/2);      // reverse is NOT OK. Position will be correct, but motor not spinning counter clock wise !
                  break;
                  
              // ------------------
              // Start to rotate at the given rpm (using the rotator control)
              // ------------------            
              case 'g':
                {
                  if (!rotator.isRunning() && !controller.isRunning())
                  {
                    // Async so the rotation motor can do its stuff
                    printTxt("Grinding process started at speed : ", rotator.getCurrentSpeed());
                    rotator.rotateAsync(motor);
                  
                    while(rotator.getCurrentSpeed() < spindleSpeed)
                    {
                      printTxt("              ", rotator.getCurrentSpeed());
                      delay(50);
                    }
                    
                    Serial.println("Full speed achieved.");
                    printTxt("Rotator currentspeed (MAX): ", rotator.getCurrentSpeed());
                  }
                  else
                  {
                    printTxt("Command to grind ignored. Spindle already running", "");
                  }
                }  
                
                break;
    
              // ------------------
              // Stop all movement
              // ------------------
              case 's':                               // stop command
                  if (controller.isRunning())
                  {
                    controller.stopAsync();             // initiate stopping procedure
                    Serial.println("Stopping motor");
                  }
                  
                  if (rotator.isRunning())
                  {
                    rotator.stopAsync();
                    Serial.println("Stopping rotator");
                  }
                  
                  break;
    
              // ------------------
              // Blink a while
              // ------------------
              case 'b':
                Blink(5);
    
              // ------------------
              // HELP ME
              // ------------------
              case 'h':                               // help / usage command
              case 'u':
                  Serial.println("\nUsage:");
                  Serial.println("  f: move Motor Forward.");
                  Serial.println("  r: move Motor Backward.");
                  Serial.println("  g: start grinding process. Spindle up to speed.");
                  Serial.println("  p: go to position 0.");
                  Serial.println("     --------------------------------------------");
                  Serial.println("  s: stop motor.");
                  Serial.println("     --------------------------------------------");
                  Serial.println("  b: blink the led.");
                  Serial.println("  h: display this help.");            
                  break;
      
              default:
                  break;
            }
        }
    }
    
    void printTxt(String t1, String t2)
    {
      Serial.print(t1);
      Serial.println(t2);
    }
    
    void Blink(int numberOfTimes)
    {
      if (numberOfTimes <= 0) numberOfTimes = 1;
    
      for (int i = 0; i < numberOfTimes; i++)
      {
        digitalWrite(ledPin, HIGH);     // turn the LED on (HIGH is the voltage level)
        delay(500);                     // wait for half a second
        
        digitalWrite(ledPin, LOW);      // turn the LED off by making the voltage LOW
        delay(500);                     // wait for half a second
      }
      
    }
    Last edited by krbek; 11-30-2021 at 03:49 PM.

  2. #2
    Junior Member
    Join Date
    Nov 2021
    Posts
    11
    And for completeness:

    Teensyduino v. 1.8.13
    Teensystep v. 2.3.1

  3. #3
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,815
    The code in your first example should definitely work. I assume some electrical issue. E.g. The datasheet of the motors you linked requires 5-24V signals. The 3.3V output might be too small to drive the opto-coupled inputs directly. You can check by connect the dir input manually to 5V / 0V and see if the direction changes. Can you post a schematic / sketch showing how you wired everything? Did you check the settings of the motor? Looks like it has different control modes which can be set by software...

  4. #4
    Junior Member
    Join Date
    Nov 2021
    Posts
    11
    Quote Originally Posted by luni View Post
    The code in your first example should definitely work. I assume some electrical issue. E.g. The datasheet of the motors you linked requires 5-24V signals. The 3.3V output might be too small to drive the opto-coupled inputs directly. You can check by connect the dir input manually to 5V / 0V and see if the direction changes. Can you post a schematic / sketch showing how you wired everything? Did you check the settings of the motor? Looks like it has different control modes which can be set by software...
    Hi Luni,

    Thanks for your reply !

    This just seems like Chinese to me.

    What I have came up with is connection-schema in annex.

    (trying to find out how I connect an attachment to this thread ... hold on a minute - or two) .....

    I assume also some electrical issue. I.e. trying to "reverse polarity" or do something crazy just doesn't seem to work.

    What I have tried so far:
    1. Dip switches to "automatic"
    2. Dip switches to on-on-of-of .... and multiple variations of this one.
    3. Reverse polarity (positive to negative .... as seen in the stargate movie ....)

    I can "change" the direction when setting dip-switch 5 to on or off.

    Hope You can see what might be wrong here ...

    Have to prepare now for the next concert. Might not be able to respond immediately ... (The conductor won't be please if would be on the phone during the concert ....)

    thanx !

    Kris
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	20211130_192957.jpg 
Views:	23 
Size:	39.7 KB 
ID:	26732  
    Attached Files Attached Files

  5. #5
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,815
    It is quite difficult to help you remotely on this. Might be a very good idea to find a local guy with some electronics background to help you wiring it.

    Anyway, lets give it a try: Looks like the Teensy breakout board is capable to drive those motor inputs. And, since the motor spins, the pulse signal arrives at the motor. Do you know why the DIR signal is wired with common 5V while the pulse signal is wired with common GND? It should work in both ways just curious why it is not wired in the same way for both signals. Do you think you can get a schematic of or at least more information about the breakout board?

    I can "change" the direction when setting dip-switch 5 to on or off.
    This is good.

    Can you measure the voltage between GND and the orange wire connected to SW2 while your program runs? The voltage should change every second. Let us know what you see. If you don't have a meter, remove the orange wire from SW2 on the breakout board and connect it to GND / 5V (switch everything off before doing this). The direction should change depending on the voltage on this wire. If it doesn't, check if you have a good connection between SW2 and the motor, check for a broken cable etc.
    Last edited by luni; 11-30-2021 at 07:03 PM.

  6. #6
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,815
    I had a closer look at the drawing of that breakout board. Of course this is only wild guesswork, but from the parts on the board it looks like the DIR and PUL outputs are switched by some transistor (Q3 / Q3) the SW1/SW2 outputs might be connected to the Teensy pins directly? Anyway, if the above doesn't work you could try to connect the PUL+/- and DIR +/- of one motor directly to the PUL+/- DIR+/- terminals of the breakout board. In your sketch you'd have to change the Stepper constructor to
    Code:
    Stepper motor (3,2);
    Of course this would only work for one motor but could exclude issues with the SW1/SW2 terminals.

  7. #7
    Junior Member
    Join Date
    Nov 2021
    Posts
    11
    Thanx Luni !

    Anyway, lets give it a try:
    I'll give it a try today and come back to it.

    The cables should be fine. (all brand new cables).
    Attached a complete view of the setup.

    Click image for larger version. 

Name:	20211130_192716.jpg 
Views:	21 
Size:	86.7 KB 
ID:	26737
    Last edited by krbek; 12-01-2021 at 05:27 AM.

  8. #8
    Junior Member
    Join Date
    Nov 2021
    Posts
    11
    Hi Luni.
    Just tested this one:
    Can you measure the voltage between GND and the orange wire connected to SW2 while your program runs?
    See attacheed image.
    Voltage reed 5v.
    No change when idle and no change when running.Click image for larger version. 

Name:	Voltage.png 
Views:	14 
Size:	165.3 KB 
ID:	26739

  9. #9
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,815
    Quote Originally Posted by krbek View Post
    Hi Luni.
    No change when idle and no change when running
    Which explains why the direction doesn't change. Can you do a simple sketch just toggling pin15 every second and check with your meter if that appears on SW2? (don't forget to set the pinmode to output). I'd also check SW1, maybe the pin association was swapped in your drawing? If you don't see changes on SW2/SW1 if you toggle pin14/15 I'd call the manufacturer of the breakout board and ask for advice.

    Edit: additionally measure directly on the Teensy pins 14/15.

  10. #10
    Junior Member
    Join Date
    Nov 2021
    Posts
    11
    I'll try.

    Something like this should achieve the toggling on pin15 ?

    Code:
    void setup() {
      // put your setup code here, to run once:
      pinMode(15, OUTPUT);                            // Must not forget this one.
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
    
        digitalWrite(15, HIGH);     
        delay(1000);                     // wait for a second
        
        digitalWrite(15, LOW);        
        delay(1000);                     // wait for a second
    
    }
    After setting the pin 15 or 14 to output (what I did not do the first time ) I have some sequential voltage readings
    0 - 2 - 5 - 0 - 3 - 5 .....

    On both pin 14 and pin 15 (not at the same time though).

    A little thought of mine: could it be that powering the teensy board using the usb cable connected to the computer does not provide enough voltage to power the board and give the pulses needed ?
    Last edited by krbek; 12-01-2021 at 12:24 PM. Reason: added result

  11. #11
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,815
    And what happens if you use the first example sketch you posted? If you set the target positions to 60000 it should move for about 1 second in each direction. You should be able to see that on the meter as well.

    A little thought of mine: could it be that powering the teensy board using the usb cable connected to the computer does not provide enough voltage to power the board and give the pulses needed ?
    I assume that you power the board with via its power connector right?

    Click image for larger version. 

Name:	Screenshot 2021-12-01 144327.png 
Views:	15 
Size:	82.9 KB 
ID:	26744

  12. #12
    Junior Member
    Join Date
    Nov 2021
    Posts
    11
    Hallo Luni.

    I assume that you power the board with via its power connector right?
    No. (not yet). I was powering it over USB to upload the program from the computer.
    Yesterday I also contacted the vendor who is also very helpful. (and very patient with me !)

    The board should be powered via its power connector.
    And the GND from the motor(s) should be attached to the GND on the board.
    I should have known this as the board is intended as a standalone board.

    I'll give that a try and give some feedback afterwards.

    Click image for larger version. 

Name:	Power_Suply.png 
Views:	18 
Size:	50.6 KB 
ID:	26756

  13. #13
    Junior Member
    Join Date
    Nov 2021
    Posts
    11
    @Luni

    Code:
    for (int i = 0; i < 10; i++)
    {
          serial.println ("Please don't blame me for I was wrong. :-)");
          
         for (int j = 0; j < 1000; j++)
          {
              serial.println.InCapitals("Thank you");
          }
    }
    Connecting the power to a correct power suply (and not powering the board through the USB) lets me spin the motor forward, backwards and every direction it should.

    I can get it to spin up to 85.000 (checked with the rotator.getCurrentSpeed()).

    forward and .... backward.


    ps. quick question: should the motor not be able to run twice that speed according to the specs?

  14. #14
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,815
    Connecting the power to a correct power suply (and not powering the board through the USB) lets me spin the motor forward, backwards and every direction it should.
    He, he, the good old 'forgot to plug the power cord in' :-))

    I can get it to spin up to 85.000 (checked with the rotator.getCurrentSpeed()).
    forward and .... backward.
    ps. quick question: should the motor not be able to run twice that speed according to the specs?
    Hm, what does 85.000 mean? 85 RPM? 85,000 steps per second? Fullsteps? Microsteps? How many steps per rev? ...

    I didn't read the manual very thoroughly but the servos you are using are highly configurable. There also is some software to parameterize the driver. I'm afraid you'll need to read into the manual to get the best performance out of your servos. Or just ask the vendor for help. He probably knows his servos well and can tell you what you can expect and if/what optimizing of the settings will improve the performance.

  15. #15
    Junior Member
    Join Date
    Nov 2021
    Posts
    11
    Hi Luni


    The 85.000 is the measurement I get back when calling the rotator.getCurrentSpeed();

    Calculating it as follows:
    Code:
    const int rpm = 1500;
    const int spindlePPR = 3200;                                             // Hardware settings pulse per revolution (dip switches)
    const int spindleSPR = 200;                                             // steps per revolution (360/1.8)
    const int spindleAccel = 75000;                                         // spindle acceleration
    constexpr signed spindleSpeed = (rpm * spindlePPR) / 60;                // steps per second
    Apparently it has to do with the max of 150 khz the teensyboard can go.
    My guess now is that lowering the "spindlePPR" to 800 instead of 3.200 will give lesser khz for a higher maximum speed.

    (Although 1.600 rpm is fine since there will be a gear mounted on to it with a ratio of 1:1.9 (approx.) so the motor spins at 1.500 rpm and the grinding part spins at 2.850 rpm - which I hope will be sufficient)

    The machine will look something like this ...
    Click image for larger version. 

Name:	usage_final.png 
Views:	16 
Size:	61.6 KB 
ID:	26767

  16. #16
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,815
    Apparently it has to do with the max of 150 khz the teensyboard can go.
    The T3.6 runs at 150MHz not kHz and TeensyStep is good for about 300kHz step rate. So, I doubt that the limitation comes from the Teensy side. If you have a scope you could try to measure the pulse signal and see if you find something strange at above 85kHz. If it is important to you I can do some measurements checking if there is something wrong with the library at >85kHz later today.

    The issue might also be related to the circuitry on the break out board (unlikely). As I mentioned, If you really want/need to you improve the performance of your servos, you need to dig into the manual to optimize the settings for your motor. All this parametrization stuff is there for a reason...

    I like that kind of machines. Would love to see some video showing it in action :-)

  17. #17
    Junior Member
    Join Date
    Nov 2021
    Posts
    11
    I like that kind of machines. Would love to see some video showing it in action :-)
    Hopefully it will be finished in January. (purpose of it is to highly increase the accuracy of the grinded reed increasing sound quality etc.)
    I'll certainly will post a video of it working.

    The T3.6
    The board is equipped with a Teensy 3.2

    If you have a scope you could try to measure the pulse signal and see if you find something strange at above 85kHz
    No other machines then a simple voltage meter and screwdriver.

    I'll also give it a try to set the dip switches to 800 instead of 3.200 pulses per revolution.
    With a RPM of 1.500 this will give (1500*800)/60 = 20.000 (pulses I guess, hence the kHz. Learned something new today)
    With a RPM of 3.000 this will give (3000*800)/60 = 40.000

  18. #18
    Junior Member
    Join Date
    Nov 2021
    Posts
    11
    Hi Luni

    Just gave it a try with the 800 pulses per revolution.
    The motor spins up fine up to 3.000, 4.500 rpm (with the above formula);
    (Don't know if the pulses correlates to 3.000 or 4.500 rpm but there is a distinct audible difference when spinning at 1.000, 1.500 or 3.000 rpm).

    When the machine is ready I'll post a video of it.
    In the mean time some more testing to do with connecting the second motor and a push-button to start the process.

    I'll try not to forget to plug in the power chord

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •