gnea / grbl

An open source, embedded, high performance g-code-parser and CNC milling controller written in optimized C that will run on a straight Arduino
https://github.com/gnea/grbl/wiki
Other
4.09k stars 1.61k forks source link

Control grbl through python3 #899

Open SHAO-1120 opened 4 years ago

SHAO-1120 commented 4 years ago

Hello everyone,

I was doing a small project, which needed using python3 to control the project. Most situations I had found on the Internet and Issues were controlled by software, for instance, Grbl controller. There was a controlling code named "stream.py". I am not familiar with Python. Therefore I was not sure if it could be used to control motor through G-code. The problem was that there were two files called "gcode_file" and "device_file". About gcode_file, I considered it as a file including G-code order. But I did not know the format of it. The other file was device_file, which seemed to related the COM port of the arduino uno. I changed the code in the stream.py by deleting line 66,

parser.add_argument('device_file',

    help='serial device path')

and changed line 88 into

s = serial.Serial('COM4', 9600)

But then I got a TypeError in line 173.

s.write(l_block + '\n') # Send g-code block to grbl

It showed that unicode strings are not supported, please encode to bytes: '%\n'.

I wondered if it was caused because I changed the device_file.

details:

  1. arduino uno
  2. A4988*2
  3. 2 phase stepper*2

I am a very beginner of python and this kind of controlling program. I really need everyone's help. Thank you for spending on reading this Issues.

statist32 commented 4 years ago

I am using this script to send files to the arduino. Maybe check out my comments and I hope it helps


import serial
import time
import argparse

BAUD_RATE = 115200

def remove_comment(string):
    if (string.find(';') == -1):
        return string
    else:
        return string[:string.index(';')]

def remove_eol_chars(string):
    # removed \n or traling spaces
    return string.strip()

def send_wake_up(ser):
    # Wake up
    # Hit enter a few times to wake the Printrbot
    ser.write(str.encode("\r\n\r\n"))
    time.sleep(2)   # Wait for Printrbot to initialize
    ser.flushInput()  # Flush startup text in serial input

def stream_gcode():
    # with contect opens file/connection and closes it if function(with) scope is left
    with open(args.file, "r") as file, serial.Serial(args.port, BAUD_RATE) as ser:
        send_wake_up(ser)
        for line in file:
            # cleaning up gcode from file
            gcode = remove_eol_chars(remove_comment(line))
            if gcode:  # checks if string is empty
                print(f"Sending gcode: {gcode}")
                # converts string to byte encoded string and append newline
                command = str.encode(line + '\n')
                ser.write(command)  # Send g-code
                grbl_out = ser.readline()  # Wait for response with carriage return
                print(f" : {grbl_out.strip().decode('utf-8')}")
                time.sleep(1)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description='This is a basic gcode sender. http://crcibernetica.com')
    parser.add_argument('-p', '--port', help='Input USB port', required=True)
    parser.add_argument('-f', '--file', help='Gcode file name', required=True)
    args = parser.parse_args()
    ## show values ##
    print("USB Port: %s" % args.port)
    print("Gcode file: %s" % args.file)
    stream_gcode()
SHAO-1120 commented 4 years ago

@statist32 Thank you very much for helping me. I am still trying figuring it out right now. May I ask you about the main code you used? Dose it relate to the definition of args.port and args.file? Pardon me to ask another question, what kinds of software you used to generate G-code from picture or space diagram?

statist32 commented 4 years ago

@SHAO-1120 if __name__ == "__main__"is basically like a main function. It will be executes if you call the file directly. If you import this file/module in another file this part won't be executed. Maybe have a look over here. This main part is basically unrelated to the argparser. The argparser just manages the correct call to be sure the args are available. But the args.port/args.file is related to the argparser of course. You could delete the whole parser part if you hardcode the filename and the serial port you are using.

I do not generate gcode now. I am currently working on a python interface to send gcode for an assignment. At a later point I have to generate gcode but you can just google for such a software there are many. GL :)