Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Just for info: easily read/write from/to Smart Stepper by raspberry pi/bash #54

Open
vmario89 opened this issue Mar 19, 2020 · 1 comment

Comments

@vmario89
Copy link

Hi,

just wired up some bash stuff to operate Smart Steppers with scripts utilizing screen

apt install screen
#!/bin/bash
SCREEN_NAME="screen_smart_stepper"
LOG_FILE="/opt/${SCREEN_NAME}.log"

# remove old log file if existent
rm "${LOG_FILE}" > /dev/null 2>&1

# send "smart stepper command + enter (^M) keystroke" to first window (-p 0 could be applied) in a new named screen by stuffing (https://www.gnu.org/software/screen/manual/html_node/Command-Summary.html) the string into input; log the output to file
screen -d -m -L ${LOG_FILE} -S ${SCREEN_NAME} /dev/ttyUSB-SMARTSTEPPER 115200

declare -a cmdArray=("getcal" "microsteps" "readpos" "encoderdiag" "spid" "vpid" "ppid" "dirpin" "enablepinmode" "errorlimit" "ctrlmode" "maxcurrent" "holdcurrent" "homecurrent" "motorwiring" "stepsperrotation" "velocity" "looptime" "eepromerror" "eepromloc" "geterror" "getsteps" "torque")
for val in ${cmdArray[@]}; do
        screen -S ${SCREEN_NAME} -X stuff "${val}^M"
done

sleep 1
screen -S ${SCREEN_NAME} -X quit

# clean up the log with ^M symbols
sed -i 's/\r//g' ${LOG_FILE}

it looks easy but it was torture to find out how to communicate best without bugging the complete USB buffer or change stty settings. Maybe someone has smarter solution. That one works and might be a starting point.

same script can be used as basis to send commands or to build up some cyclic things.

i am using it for Hangprinter project to read encoder data without I2C/Two Wire interface, because there's no Duet support yet. And i dont want to mess around with firmware mods.

cheers, Mario

@vmario89
Copy link
Author

vmario89 commented May 3, 2020

Some weeks later: i made a stable Python 3.7 script using PySerial library for polling out data. The following example code grabs ctrlmode and cuts out the mode number of the read line.

This script can be used to do things like sending values into an InfluxDB or whatever. It's stable enough to survive removed USB device, powered off Smart Stepper and other errors. I also configured it to set USB port to exclusive so no other connection can mess with the established one.

import serial
import time
import termios # workaround for IOError on resetting input/output buffers
import re

# note that when defining serial.Serial will automatically open the port!
ser=None
def createSerial():
        global ser
        time.sleep(1) # always wait one second before re-opening. This prevents hiccups
        try:
                #print("trying to open serial connection")
                ser=serial.Serial(
                        port="/dev/ttyUSB-SMART-A-AXIS",
                        baudrate=115200,
                        bytesize=serial.EIGHTBITS,
                        parity=serial.PARITY_NONE,
                        stopbits=serial.STOPBITS_ONE,
                        timeout=1,
                        xonxoff=False,
                        rtscts=False,
                        write_timeout=1,
                        dsrdtr=False,
                        inter_byte_timeout=None,
                        exclusive=True) # force to get behaviour "Cannot open line '/dev/ttyUSB-SMART-A-AXIS' for R/W: open() blocked, aborted." or "Error: read failed: device reports readiness to read but returned no data (device disconnected or multiple access on port?)"

        except IOError as e: # the serial creation may fail if device not connected or not ready
                print("Error:", e)
                pass
while True:
        if ser == None:
                #print("serial is set to None. Creating new serial connection")
                createSerial()
        else:
                try:
                        ser.reset_input_buffer()
                        ser.reset_output_buffer()
                        ser.write("ctrlmode".encode() + b'\r')
                        #time.sleep(0.05)
                        while ser.inWaiting() > 0:
                                line=ser.readline().decode()
                                #print(line)
                                p=re.compile(r'^controller\s.*\(\d\)$', re.M)
                                m=p.search(line)
                                if m:
                                        print("ctrlmode =",m.group(0)[-2]) #extract the number from "controller <modeString> (<number>)"
                except (IOError, termios.error) as e: # in case the USB device was removed or buffer reset fails try to close and re-open serial port
                        print("Error:", e)
                        ser.close()
                        ser = None #unset
                        createSerial()
                        pass

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant