diff --git a/Software/TMC2130.py b/Software/TMC2130.py new file mode 100644 index 0000000..3afc313 --- /dev/null +++ b/Software/TMC2130.py @@ -0,0 +1,228 @@ +from machine import Pin, PWM, SPI +import time +import utime +from config import * +from led import * +from sTimer import sTimer_Start, sTimer_Stop +import sys + +EN = Pin(13, Pin.OUT) +DIR = Pin(14, Pin.OUT) +STEP = Pin(15, Pin.OUT) +ENDSTOP = Pin(8, Pin.IN, Pin.PULL_UP) +DC_EN = Pin(11, Pin.OUT) +DC_IN = Pin(10, Pin.OUT) +DC_OUT = Pin(12, Pin.IN) +SPI_MODE = Pin(20, Pin.OUT) +spi_cs = Pin(17, Pin.OUT) + +spi = SPI(0, baudrate=100000, polarity=1, phase=1, bits=8, firstbit=SPI.MSB, sck=Pin(18, Pin.OUT), mosi=Pin(19, Pin.OUT), miso=Pin(16, Pin.IN)) + +DC_EN(0) +DC_IN(0) +spi_cs(1) +EN(1) #0 = enabled +DIR(0) +STEP(0) + +MM_PER_STEP = SCREW_PITCH / (MOTOR_STEPS * MICROSTEPPING) +FREQ_PER_STEP_INCREASE = (((MOTOR_STEPS * MICROSTEPPING) / SCREW_PITCH) * ACCELERATION) / 60 + +REG_GCONF = 0x00 +REG_GSTAT = 0x01 +REG_IHOLD_IRUN = 0x10 +REG_CHOPCONF = 0x6C +REG_COOLCONF = 0x6D +REG_DCCTRL = 0x6E +REG_DRVSTATUS = 0x6F + +step_cntr = 0 +target_steps = 0 +target_frequency = 0 +current_frequency = 0 +def step(): + global STEP, step_cntr, current_frequency, target_frequency, target_steps, FREQ_PER_STEP_INCREASE + STEP.value(not STEP.value()) + STEP.value(not STEP.value()) + LED_ERR.value(not LED_ERR.value()) + + step_cntr += 1 + if(current_frequency < target_frequency): + current_frequency += FREQ_PER_STEP_INCREASE + if(target_steps >= step_cntr): + pass + +def rotate_motor(steps, feedrate): + global current_frequency, step_cntr, target_steps, target_frequency + step_cntr = 0 + target_steps = steps + target_frequency = ((feedrate / SCREW_PITCH) * MOTOR_STEPS * MICROSTEPPING) / 60 #steps/s = rpm * steps_per_rotation / 60 + print(target_frequency) + print(FREQ_PER_STEP_INCREASE) + current_frequency = FREQ_PER_STEP_INCREASE + +def timer_callback(counter): + if (counter % 1) == 0: + step() + +def get_stats(): + global STEP, step_cntr, current_frequency, target_frequency, target_steps, FREQ_PER_STEP_INCREASE + print(step_cntr, current_frequency, target_frequency, FREQ_PER_STEP_INCREASE) + +def rotate_motor_test(): + rotate_motor(32*200, 5) + sTimer_Start() + time.sleep(2) + sTimer_Stop() + +def prepare_spi_msg(addr, d0, d1, d2, d3, rw): + msg = bytearray() + if rw == 'r': + msg.append(addr) + else: + msg.append(0x80 + addr) + msg.append(d0) + msg.append(d1) + msg.append(d2) + msg.append(d3) + + return msg + +def send_spi_msg(msg): + spi_cs(0) + rxdata = bytearray(5) + spi.write_readinto(msg, rxdata) + #print(rxdata.hex()) + spi_cs(1) + time.sleep(0.01) + +def TMC2130_Rotate(dir, steps, speed): #speed in rpm + #1rmp = 200steps/min=3.333steps/s~150ms@50%duty + wait = (((1 / ((MOTOR_STEPS * MICROSTEPPING) / 60)) / 2) / speed) * 1000 * 1000 + freq = 1 / ((wait / 1000000) * 2) + + if AXIS_REVERSE: + if dir == 0: + dir = 1 + else: + dir = 0 + + DIR(dir) + LED_DIR(dir) + + STEP = PWM(Pin(15), freq=int(freq), duty_u16=32768) + time.sleep((1 / freq) * steps) + STEP.deinit() + +homing = False +def TMC2130_Home(): + global homing + + dir = HOME_DIR + STEP = Pin(15, Pin.OUT) + + steps_mm = (MOTOR_STEPS * MICROSTEPPING) / SCREW_PITCH + rpm = HOME_SPEED / SCREW_PITCH + wait = (((1 / ((MOTOR_STEPS * MICROSTEPPING) / 60)) / 2) / rpm) * 1000 * 1000 + freq = 1 / ((wait / 1000000) * 2) + + if AXIS_REVERSE: + if dir == 0: + dir = 1 + else: + dir = 0 + + DIR(dir) + LED_DIR(dir) + + sys.stdout.write('homing\r\n') + homing = True + STEP = PWM(Pin(15), freq=int(freq), duty_u16=32768) + while homing: + pass + STEP.deinit() + + if HOME_DEBOUNCE == True: + sys.stdout.write('debouncing\r\n') + if dir == 0: + dir = 1 + else: + dir = 0 + + DIR(dir) + LED_DIR(dir) + + steps = steps_mm * abs(HOME_DEBOUNCE_DISTANCE) + + TMC2130_Rotate(dir, steps, HOME_DEBOUNCE_SPEED) + + rpm = HOME_DEBOUNCE_SPEED / SCREW_PITCH + wait = (((1 / ((MOTOR_STEPS * MICROSTEPPING) / 60)) / 2) / rpm) * 1000 * 1000 + freq = 1 / ((wait / 1000000) * 2) + + if dir == 0: + dir = 1 + else: + dir = 0 + + DIR(dir) + LED_DIR(dir) + + homing = True + STEP = PWM(Pin(15), freq=int(freq), duty_u16=32768) + while homing: + pass + STEP.deinit() + +def TMC2130_Disable(): + EN.value(1) + +def TMC2130_Enable(): + EN.value(0) + +def endstop_callback(endstop): + global homing + + homing = False + +def TMC2130_Init(): + SPI_MODE(1) + # setup coolstep + microstep = 0 + if MICROSTEPPING == 128: + microstep = 1 + elif MICROSTEPPING == 64: + microstep = 2 + elif MICROSTEPPING == 32: + microstep = 3 + elif MICROSTEPPING == 16: + microstep = 4 + elif MICROSTEPPING == 8: + microstep = 5 + elif MICROSTEPPING == 4: + microstep = 6 + elif MICROSTEPPING == 2: + microstep = 7 + elif MICROSTEPPING == 1: + microstep = 8 + else: + microstep = 0 + + msg = prepare_spi_msg(REG_CHOPCONF, 0x00+microstep, 0x01, 0x00, 0xC3, 'w') + send_spi_msg(msg) + msg = prepare_spi_msg(REG_IHOLD_IRUN, 0x00, 0x06, I_RUN, I_HOLD, 'w') + send_spi_msg(msg) + msg = prepare_spi_msg(0x11, 0x00, 0x00, 0x00, 0x0A, 'w') + send_spi_msg(msg) + msg = prepare_spi_msg(REG_GCONF, 0x00, 0x00, 0x00, 0x04, 'w') + send_spi_msg(msg) + msg = prepare_spi_msg(0x13, 0x00, 0x00, 0x01, 0xF4, 'w') + send_spi_msg(msg) + msg = prepare_spi_msg(0x70, 0x00, 0x04, 0x01, 0xC8, 'w') + send_spi_msg(msg) + msg = prepare_spi_msg(REG_COOLCONF, 0x00, 0x00, 0x03, 0x01, 'w') + send_spi_msg(msg) + + TMC2130_Enable() + + ENDSTOP.irq(trigger=Pin.IRQ_FALLING, handler=endstop_callback) \ No newline at end of file diff --git a/Software/comms.py b/Software/comms.py new file mode 100644 index 0000000..fb9d2d5 --- /dev/null +++ b/Software/comms.py @@ -0,0 +1,66 @@ +import sys +import select +from config import * +from motion import Motion_Move +from TMC2130 import TMC2130_Home +import machine + +poll_obj = '' + +def Comms_Init(): + global poll_obj + + poll_obj = select.poll() + poll_obj.register(sys.stdin, select.POLLIN) + +def Comms_Hello(): + hello_str = 'Stepper motor driver\r\n' + hello_str += 'Software: v0.3\r\n' + hello_str += 'Hardware: v1.0\r\n' + hello_str += 'Author: Angoosh\r\n' + sys.stdout.write(hello_str) + +def Comms_Reset(): + machine.reset() + +def Comms_GetInfo(info): + if info == 0: + sys.stdout.write(AXIS_ID+'\r\n') + +def Comms_Read(): + global poll_obj + + poll_results = poll_obj.poll(1) + + if poll_results: + rw = sys.stdin.readline().strip() + rw = rw.upper() + + if 'G0' in rw: + if AXIS_ID in rw: + data = rw.split(' ') + for i in data: + if AXIS_ID in i: + motorics = i.split(':') + Motion_Move(int(motorics[1]), int(motorics[2])) + sys.stdout.write('OK\r\n') + elif 'G1' in rw: + if AXIS_ID in rw: + data = rw.split(' ') + for i in data: + if AXIS_ID in i: + motorics = i.split(':') + Motion_Move(int(motorics[1]), int(motorics[2])) + sys.stdout.write('OK\r\n') + elif 'G28' in rw: + TMC2130_Home() + elif 'RESET' in rw: + sys.stdout.write('OK\r\n') + Comms_Reset() + elif 'INFO' in rw: + data = rw.split(' ') + Comms_GetInfo(int(data[1])) + elif rw == '': + pass + else: + sys.stdout.write('INVALID 1\r\n') \ No newline at end of file diff --git a/Software/config.py b/Software/config.py new file mode 100644 index 0000000..3f08e34 --- /dev/null +++ b/Software/config.py @@ -0,0 +1,17 @@ +MOTOR_STEPS = 200 +MICROSTEPPING = 16 +I_HOLD = 10 #hold current (1-31) +I_RUN = 10 #run current (1-31) + +SCREW_PITCH = 5 #in mm/rotation +AXIS_LENGTH = 1000 #mm +AXIS_ID = 'X' #id of axis (X,Y,U,V) +AXIS_REVERSE = False + +HOME_DIR = 0 +HOME_SPEED = 600 #in mm/s +HOME_DEBOUNCE = True +HOME_DEBOUNCE_DISTANCE = 5 #in mm +HOME_DEBOUNCE_SPEED = 200 + +ACCELERATION = 1 \ No newline at end of file diff --git a/Software/led.py b/Software/led.py new file mode 100644 index 0000000..a7a835b --- /dev/null +++ b/Software/led.py @@ -0,0 +1,6 @@ +from machine import Pin + +LED_ERR = Pin(25, Pin.OUT) +LED_DIR = Pin(3, Pin.OUT) +LED_STOP = Pin(6, Pin.OUT) +LED_OK = Pin(7, Pin.OUT) \ No newline at end of file diff --git a/Software/main.py b/Software/main.py new file mode 100644 index 0000000..fb57f93 --- /dev/null +++ b/Software/main.py @@ -0,0 +1,29 @@ +# Example using PWM to fade an LED. +import time +from machine import Pin, PWM, Timer, SPI +from config import * +from led import * +from TMC2130 import TMC2130_Rotate, TMC2130_Init, rotate_motor_test +from motion import Motion_Init, Motion_Move +from comms import * + +LED_OK.value(0) +LED_ERR.value(1) +time.sleep(0.5) +LED_ERR.value(0) +LED_DIR.value(1) +time.sleep(0.5) +LED_DIR.value(0) +LED_STOP.value(1) +time.sleep(0.5) +LED_STOP.value(0) +LED_OK.value(1) +time.sleep(0.5) + +TMC2130_Init() +Motion_Init() +Comms_Init() + +Comms_Hello() +while True: + Comms_Read() \ No newline at end of file diff --git a/Software/motion.py b/Software/motion.py new file mode 100644 index 0000000..36afa5d --- /dev/null +++ b/Software/motion.py @@ -0,0 +1,30 @@ +from TMC2130 import TMC2130_Rotate +from config import * + +steps_mm = 0 + +def Motion_Init(): + global steps_mm + + steps_mm = (MOTOR_STEPS * MICROSTEPPING) / SCREW_PITCH + +def Motion_Move(distance, speed): #distance in mm, speed in mm/min + global steps_mm + + steps = steps_mm * abs(distance) + + direction = 0 + if distance < 0: + if AXIS_REVERSE == False: + direction = 0 + else: + direction = 1 + else: + if AXIS_REVERSE == False: + direction = 1 + else: + direction = 0 + + rpm = speed / SCREW_PITCH + + TMC2130_Rotate(direction, steps, rpm) \ No newline at end of file diff --git a/motor_driver/motor_driver-backups/motor_driver-2024-03-22_143644.zip b/motor_driver/motor_driver-backups/motor_driver-2024-03-22_143644.zip deleted file mode 100644 index 0330f86..0000000 Binary files a/motor_driver/motor_driver-backups/motor_driver-2024-03-22_143644.zip and /dev/null differ diff --git a/motor_driver/motor_driver-backups/motor_driver-2024-03-22_144650.zip b/motor_driver/motor_driver-backups/motor_driver-2024-03-22_144650.zip deleted file mode 100644 index 5d119b1..0000000 Binary files a/motor_driver/motor_driver-backups/motor_driver-2024-03-22_144650.zip and /dev/null differ diff --git a/motor_driver/motor_driver-backups/motor_driver-2024-03-22_145414.zip b/motor_driver/motor_driver-backups/motor_driver-2024-03-22_145414.zip deleted file mode 100644 index d67a90b..0000000 Binary files a/motor_driver/motor_driver-backups/motor_driver-2024-03-22_145414.zip and /dev/null differ diff --git a/motor_driver/motor_driver-backups/motor_driver-2024-03-22_190606.zip b/motor_driver/motor_driver-backups/motor_driver-2024-03-22_190606.zip new file mode 100644 index 0000000..9456339 Binary files /dev/null and b/motor_driver/motor_driver-backups/motor_driver-2024-03-22_190606.zip differ diff --git a/motor_driver/motor_driver-backups/motor_driver-2024-03-22_193314.zip b/motor_driver/motor_driver-backups/motor_driver-2024-03-22_193314.zip new file mode 100644 index 0000000..9456339 Binary files /dev/null and b/motor_driver/motor_driver-backups/motor_driver-2024-03-22_193314.zip differ diff --git a/motor_driver/motor_driver-backups/motor_driver-2024-04-10_152917.zip b/motor_driver/motor_driver-backups/motor_driver-2024-04-10_152917.zip new file mode 100644 index 0000000..9456339 Binary files /dev/null and b/motor_driver/motor_driver-backups/motor_driver-2024-04-10_152917.zip differ diff --git a/motor_driver/motor_driver-backups/motor_driver-2024-05-19_095207.zip b/motor_driver/motor_driver-backups/motor_driver-2024-05-19_095207.zip new file mode 100644 index 0000000..9456339 Binary files /dev/null and b/motor_driver/motor_driver-backups/motor_driver-2024-05-19_095207.zip differ diff --git a/motor_driver/motor_driver-backups/motor_driver-2024-06-06_220859.zip b/motor_driver/motor_driver-backups/motor_driver-2024-06-06_220859.zip new file mode 100644 index 0000000..9456339 Binary files /dev/null and b/motor_driver/motor_driver-backups/motor_driver-2024-06-06_220859.zip differ diff --git a/motor_driver/~motor_driver.kicad_pcb.lck b/motor_driver/~motor_driver.kicad_pcb.lck new file mode 100644 index 0000000..61c7f2b --- /dev/null +++ b/motor_driver/~motor_driver.kicad_pcb.lck @@ -0,0 +1 @@ +{"hostname":"Oneill","username":"angoosh"} \ No newline at end of file