STS220 Motor driver and raspberry PI

Hi,
As part of a personal project I have to run a stepper motor with high precision on the steps, I bought 4 sts220pin drivers on pololu.

This driver has a specificity, it has 4 pins for assigning the step modes (from 1/1 to 1/256), but on these 4 pins it shares two as DIR and STEP pin.
To be able to control them and specify the type of step, you must use the standby pin of the driver, put it in LOW, then inject the resolution of the steps and release the standby mode.
After this manipulation, the DIR and STEP pins can be used normally.
Here is a official manufacturer’s note to use this driver:

BlockquoteFunctional description
The STSPIN220 is a stepper motor driver integrating a microstepping sequencer (up to
1/256th of a step), two PWM current controllers and a power stage composed of two fullyprotected full-bridges.
6.1 Standby and power-up
The device provides a low consumption mode forcing the STBY\RESET input below the
VSTBYL threshold.
When the device is in standby status, the power stage is disabled (outputs are in high
impedance) and the supply to the integrated control circuitry is cut off. When the device
exits the standby status, all of the control circuitry is reset to power-up condition.
6.2 Microstepping sequencer
The value of the MODEx inputs is latched at power-up and when the device exits the STBY
condition. After this, the input value is unimportant and the MODE3 and MODE4 inputs
start operating as step-clock and direction input.
The only exception is the MODE1 = MODE2 = LOW condition; in this case the system is
forced into full-step mode. The previous condition is restored as soon as the MODE1 and
MODE2 inputs switch to a different combination.
An example of mode selection is shown in Figure 5.
At each STCK rising edge, the sequencer of the device is increased (DIR input high) or
decreased (DIR input low) of a module selected through the MODEx inputs as listed in
Table 8.
The sequencer is a 10-bit counter that sets the reference value of the PWM current
controller and the direction of the current for both of the H bridges.

I can set the resolution, but as soon as I want to change the direction it also changes the resolution … without changing the direction. Like as the driver remained in STANDBY mode.

To use this driver I modified a WaveShare library to adapt it to the STS220PIN.

I rechecked everything, PINS connexions, my scripts but nothing helps, there is only one mode which works both in direction and in the resolution mode, and that is the fullstep mode (0, 0, 0, 0) weird … really weird

As soon as I modify something, it becomes completely random.

Here is my class which supports the driver:
DRVSTS220.py

# -*- coding: utf-8 -*-
#!/usr/bin/env python3
import RPi.GPIO as GPIO
import time

MotorDir = [
    'haut',
    'bas',
]



class DRVSTS220():
    def __init__(self, dir_pin, step_pin, standby_pin, mode_pins):
        self.dir_pin = dir_pin
        self.step_pin = step_pin        
        self.standby_pin = standby_pin
        self.mode_pins = mode_pins
        
        GPIO.setmode(GPIO.BCM)
        GPIO.setwarnings(False)
        GPIO.setup(self.dir_pin, GPIO.OUT)
        GPIO.setup(self.step_pin, GPIO.OUT)
        GPIO.setup(self.standby_pin, GPIO.OUT)
        GPIO.setup(self.mode_pins, GPIO.OUT)
        
               
    def digital_write(self, pin, value):
        GPIO.output(pin, value)
        
    def Stop(self):
        GPIO.cleanup()
        
    def Start(self):
        self.digital_write(self.standby_pin, 1)
        
    def SetMicroStep(self, stepformat):
        GPIO.output(21, 0)
        microstep = {'full': (0, 0, 0, 0), 
              'half': (1, 0, 1, 0),
              '1/4': (0, 1, 0, 1),
              '1/8': (1, 1, 1, 0),
              '1/16': (1, 1, 1, 1),
              '1/32': (0, 1, 0, 0),
              '1/64': (0, 1, 1, 1),
              '1/128': (1, 0, 0, 0),
              '1/256': (1, 1, 0, 0)
              }

        self.digital_write(self.mode_pins, microstep[stepformat])
        print("Mode avec STBY :", GPIO.input(26), GPIO.input(19), GPIO.input(20), GPIO.input(16)) #Affichage de l'Ă©tat des GPIO avec STANDBY Ă  LOW
        GPIO.output(21, 1)
        print("Mode sans STBY :", GPIO.input(26), GPIO.input(19), GPIO.input(20), GPIO.input(16)) #Affichage de l'Ă©tat des GPIO avec STANDBY Ă  LOW
        
    def TurnStep(self, Dir, steps, stepdelay=0.005):
        if (Dir == MotorDir[0]):
            self.digital_write(self.dir_pin, 1)
        elif (Dir == MotorDir[1]):
            self.digital_write(self.dir_pin, 0)
        else:
            self.digital_write(self.standby_pin, 1)
            return

        if (steps == 0):
            return
            
        
        for i in range(steps):
            self.digital_write(self.step_pin, True)
            time.sleep(stepdelay)
            self.digital_write(self.step_pin, False)
            time.sleep(stepdelay)

and the motor controller script

# -*- coding: utf-8 -*-
#!/usr/bin/env python3
import time
import pygame, sys
from pygame.locals import *
from DRVSTS220 import DRVSTS220
import RPi.GPIO as GPIO

#Block PYGAME et affichage des icĂ´nes
pygame.init()
pygame.joystick.init()

screen = pygame.display.set_mode ( ( 600 , 300 ),RESIZABLE )
pygame.display.set_caption("Mes test moteurs")

image_moteur1 = image_moteur1_rotated = pygame.image.load("//home/manuel/pathfinder/moteur1.png").convert_alpha()
image_moteur2 = image_moteur2_rotated = pygame.image.load("/home/manuel/pathfinder/moteur2.png").convert_alpha()

image_moteur1_rect = image_moteur1.get_rect() 
image_moteur2_rect = image_moteur2.get_rect() 

screen.blit(image_moteur1, (0, 0))
screen.blit(image_moteur2, (300,0))

pygame.display.flip()
clock = pygame.time.Clock()
pygame.key.set_repeat()

#Block DRVSTS220
moteur_1 = DRVSTS220(dir_pin=16, step_pin=20, standby_pin=21, mode_pins=(26,19,20,16)) #Déclaration des pins utilisés



def start_engine():
    while True:
        for event in pygame.event.get():    #Attente des Ă©venements clavier
            if event.type == QUIT:
                pygame.quit()
        Touche_clavier = pygame.key.get_pressed()
        if Touche_clavier[K_UP]:
            moteur_1.SetMicroStep('1/4'); # définitin de la résolution des pas
            moteur_1.TurnStep(Dir='haut', steps=4, stepdelay = 0.002); # définitin de la direction du nombre de pas par pression de la touche et delai entre chaque pas
        if Touche_clavier[K_DOWN]:
            moteur_1.SetMicroStep('1/4'); # définitin de la résolution des pas
            moteur_1.TurnStep(Dir='bas', steps=4, stepdelay = 0.002); # définitin de la direction du nombre de pas par pression de la touche et delai entre chaque pas
        if Touche_clavier[K_SPACE]:
            moteur_1.Stop()
            pygame.quit
            return 0
                    
    pygame.display.flip()
    clock.tick(30)


start_engine()

I use Pygame to control motor (direction, steps, resolution), it’s work fine with other drivers, like DRV8825 but with STS220 it’s became totally random.

Did i miss something, or i do something wrong ?
If you are some tips to give me it’s will be great, cause now i start to lost motivation.

And excuse for my english…

Many thanks

Hello.

Can you post some pictures that show your board and all of your connections?

It seems like there is a lot going on in your code, so I suggest setting this program aside for now and just writing the simplest program you can (i.e. without using a custom classes or a user control interface) to test the driver. For example, you could write a quick program that sets a microstepping mode, steps in one direction for a while, then steps the motor in the other direction for a while. If you have the same problem with that program, can you use an oscilloscope to confirm whether or not your program is sending the control signals you expect?

- Patrick

Thank you Patrick for your good tip, the issue was in one of my Pygame function. i corrected my mistake and now it’s work perfectly.
For owners of STS220 here a python script to test driver with all steps modes (from full to 1/256), directions and steps delays.
Have a good day

STS220_testmode.py

# -*- coding: utf-8 -*-
#!/usr/bin/env python3
from time import sleep
import RPi.GPIO as GPIO

#Variable block
mode_pins = (26,19,20,16) # Modes pins, be careful at the sequence, see driver manual
standby_pin = 21	# Standby motor pin
step_pin = 20       # Step motor pin
dir_pin = 16        # Direction motor pin


microstep = {'full': (0,0,0,0),
              'half': (1,0,1,0),
              '1/4': (0,1,0,1),
              '1/8': (1,1,1,0),
              '1/16': (1,1,1,1),
              '1/32': (0,1,0,0),
              '1/64': (0,1,1,1),
              '1/128': (1,0,0,0),
              '1/256': (1,1,0,0)
              }

#GPIO setup block
GPIO.setmode(GPIO.BCM) # Declare using BCM notation
GPIO.setwarnings(False) # Warning messages at true or true as you want
GPIO.setup(standby_pin, GPIO.OUT) # Setup standby pin as output
GPIO.setup(26, GPIO.OUT)   
GPIO.setup(19, GPIO.OUT)
GPIO.setup(20, GPIO.OUT)
GPIO.setup(16, GPIO.OUT)


# Change resolution function
def change_resolution(resolution):
    GPIO.output(standby_pin,0)   # Standby on
    i = 0
    for i in range(4):
        GPIO.setup(mode_pins [i], GPIO.OUT)
        GPIO.output(mode_pins [i], microstep[resolution][i]) # Push stepmode to the driver
    GPIO.output(standby_pin,1) # Standby off

def test_mode(resolution, steps, step_sleep_delay):
    i = 0
    print ("Mode_1 status = ", GPIO.input(26))
    print ("Mode_2 status = ", GPIO.input(19))
    print ("Mode_3 \ step status = ", GPIO.input(20))
    print ("Mode_4 \ dir status ", GPIO.input(16),'\n')
    print("Mode:",resolution,"  ", "Clockwise steps:",steps / 2,"Anticlockwise steps:",steps / 2,)
    change_resolution(resolution)
    if GPIO.output(16, 0)  != 0 :
        GPIO.output(16, 0)
        
    while i <= steps:
        if i <= steps / 2 :
            GPIO.output(20, GPIO.HIGH)
            sleep(step_sleep_delay)
            GPIO.output(20, GPIO.LOW)
        elif i >= steps / 2 :
            GPIO.output(16, 1)
            GPIO.output(20, GPIO.HIGH)
            sleep(step_sleep_delay)
            GPIO.output(20, GPIO.LOW)
        i = i+1
        
test_mode("1/32",500, 0.005) #setting step mode ; number of steps ; and delay between steps (less = more smoothly)


1 Like

I am glad to hear you were able to get your driver working! Thanks for letting us know and for sharing your test program!

- Patrick