MrYsLab / telemetrix

A user-extensible replacement for StandardFirmata. All without the complexity of Firmata!
GNU Affero General Public License v3.0
67 stars 26 forks source link

probably overflow of values above negative 2^15 (step values below -32768) #50

Closed flugenheimer closed 1 year ago

flugenheimer commented 1 year ago

After having homed and set current position to zero, i can move to the desired positions, but if the step value is below -32768 it is spinning in the wrong direction. if I choose step -32769 it will therefore spin in the wrong direction. This seems like an overflow issue, as the motor is likely going to some positive step value.

MrYsLab commented 1 year ago

Thanks for reporting the issue. Are you using an Arduino serially connected board or an ESP8266 with WiFi? Also, are you moving the motor with stepper_move or stepper_move_to? Thanks.

MrYsLab commented 1 year ago

Looking at the source code, I don't see anything obvious. Could you please also provide a simple Python script so I can recreate the issue here?

MrYsLab commented 1 year ago

I just checked to see if the correct values are being passed to the AccelStepper library, and they are. For example, if I use "stepper_move_to" with a value of -32769, that value is given to AccelStepeer. What motor and controller are you using? Also, please provide the Python telemetrix script you are using. Thanks.

flugenheimer commented 1 year ago

I used "stepper_move_to"

The controller is a CNC shield for arduino. Stepper motor is this: https://uk.rs-online.com/web/p/stepper-motors/5350401

I will upload some code to test it when I get back to the labtop again

MrYsLab commented 1 year ago

To make sure I understand the issue correctly, are you saying that if you use a position value of -32768, the motor moves in one direction, but if you change the value to -32769, the motor moves in the opposite direction?

My setup uses a TB6600 driver and this motor. I just ran a test using -32768 and then -32769 as position values, and the motor turns in the same direction for both values.

When you call _set_pin_modestepper, do you set the interface to a value of 1 for use with a stepper driver?

You may also try creating a native Arduino sketch that does not use telemetrix to determine if the behavior is the same with or without telemetrix.

MrYsLab commented 1 year ago

I am closing this issue because I am unable to reproduce your findings. I will be happy to reopen the issue if you can provide the code that will allow me to reproduce it.

flugenheimer commented 1 year ago

I just tried to test it just using your example code, If I for example use 10000 steps it moves in one direction, and if I use 50000 it moves in the other direction. `import sys import time

from telemetrix import telemetrix

""" Run a motor to a relative position. Motor used to test is a NEMA-17 size - 200 steps/rev, 12V 350mA. And the driver is a TB6600 4A 9-42V Nema 17 Stepper Motor Driver. The driver was connected as follows: VCC 12 VDC GND Power supply ground ENA- Not connected ENA+ Not connected DIR- ESP32 GND DIR+ GPIO Pin 23 ESP32 PUL- ESP32 GND PUL+ GPIO Pin 22 ESP32 A-, A+ Coil 1 stepper motor B-, B+ Coil 2 stepper motor """

GPIO Pins

PULSE_PIN = 2 DIRECTION_PIN = 5

flag to keep track of the number of times the callback

was called. When == 2, exit program

exit_flag = 0

def the_callback(data): global exit_flag

date = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(data[2]))
print(f'Motor {data[1]} relative  motion completed at: {date}.')
exit_flag += 1

def step_relative(the_board):

global exit_flag

# create an accelstepper instance for a TB6600 motor driver
# if you are using a micro stepper controller board:
# pin1 = pulse pin, pin2 = direction
motor = the_board.set_pin_mode_stepper(interface=2, pin1=PULSE_PIN,
                                             pin2=DIRECTION_PIN)

# if you are using a 28BYJ-48 Stepper Motor with ULN2003
# comment out the line above and uncomment out the line below.
# motor = the_board.set_pin_mode_stepper(interface=4, pin1=5, pin2=4, pin3=14,
# pin4=12)

# set the max speed and acceleration
the_board.stepper_set_max_speed(motor, 1000)
the_board.stepper_set_acceleration(motor, 1000)

# set the relative position in steps
the_board.stepper_move(motor, 50000)

print('Running Motor')
# run the motor
the_board.stepper_run(motor, completion_callback=the_callback)

# keep application running
while exit_flag == 0:
    try:
        time.sleep(.2)
    except KeyboardInterrupt:
        board.shutdown()
        sys.exit(0)

the_board.shutdown()
sys.exit(0)

instantiate telemetrix

board = telemetrix.Telemetrix()

try:

start the main function

step_relative(board)
board.shutdown()

except KeyboardInterrupt: board.shutdown() sys.exit(0)`

I have 1/4 steps set on the CNC shield. I also tried it with interface=1

MrYsLab commented 1 year ago

I ran the program below, and the motor turns in the same direction for both the call for 1000 and 50000 steps. I am unable to reproduce what you are seeing. You may wish to create an Arduino sketch using the AccelStepper library directly to check how your motor behaves.

"""
 Copyright (c) 2022 Alan Yorinks All rights reserved.

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
 Version 3 as published by the Free Software Foundation; either
 or (at your option) any later version.
 This library is distributed in the hope that it will be useful,f
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 General Public License for more details.

 You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
 along with this library; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

"""
import sys
import time

from telemetrix import telemetrix

"""
Run a motor to a relative position.

Motor used to test is a NEMA-17 size - 200 steps/rev, 12V 350mA.
And the driver is a TB6600 4A 9-42V Nema 17 Stepper Motor Driver.

The driver was connected as follows:
VCC 12 VDC
GND Power supply ground
ENA- Not connected
ENA+ Not connected
DIR- ESP32 GND
DIR+ GPIO Pin 23 ESP32
PUL- ESP32 GND
PUL+ GPIO Pin 22 ESP32
A-, A+ Coil 1 stepper motor
B-, B+ Coil 2 stepper motor
"""

# GPIO Pins
PULSE_PIN = 8
DIRECTION_PIN = 9

# flag to keep track of the number of times the callback
# was called. When == 2, exit program
exit_flag = 0

def the_callback(data):
    global exit_flag

    date = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(data[2]))
    print(f'Motor {data[1]} relative  motion completed at: {date}.')
    exit_flag += 1

def step_relative(the_board):

    global exit_flag

    # create an accelstepper instance for a TB6600 motor driver
    # if you are using a micro stepper controller board:
    # pin1 = pulse pin, pin2 = direction
    motor = the_board.set_pin_mode_stepper(interface=1, pin1=PULSE_PIN,
                                                 pin2=DIRECTION_PIN)

    # if you are using a 28BYJ-48 Stepper Motor with ULN2003
    # comment out the line above and uncomment out the line below.
    # motor = the_board.set_pin_mode_stepper(interface=4, pin1=5, pin2=4, pin3=14,
    # pin4=12)

    # set the max speed and acceleration
    the_board.stepper_set_max_speed(motor, 400)
    the_board.stepper_set_acceleration(motor, 800)

    # set the relative position in steps
    the_board.stepper_move(motor, 1000)

    print('Running Motor')
    # run the motor
    the_board.stepper_run(motor, completion_callback=the_callback)

    # keep application running
    while exit_flag == 0:
        try:
            time.sleep(.2)
        except KeyboardInterrupt:
            board.shutdown()
            sys.exit(0)

    print('Reversing Direction')
    the_board.stepper_move(motor, 50000)
    the_board.stepper_run(motor, completion_callback=the_callback)

    while exit_flag < 2:
        try:
            time.sleep(.2)
        except KeyboardInterrupt:
            board.shutdown()
            sys.exit(0)

    the_board.shutdown()
    sys.exit(0)

# instantiate telemetrix
board = telemetrix.Telemetrix()

try:
    # start the main function
    step_relative(board)
    board.shutdown()
except KeyboardInterrupt:
    board.shutdown()
    sys.exit(0)