How to send multible g-code comands via pySerial without time-delay - python

I have a python script that creates a serial connection to my Arduino-Mega (ramps1. 4). I am using the pyserial library, with which I send G-Code commands via the COM. There "Marlin 2.0x" reads the input and acts on any G-Code.
So far everything works. I can write any G-Code via serial.write() and Marlin understands it. But unfortunately I had to add a time delay if I want to act on multiple commands.
Is there a nice way of circumventing that?
Here is an example code of Extruding 1mm of Filament twice.
import serial
import time
ser1 = serial.Serial('COM3', 250000)
time.sleep(1)
ser1.write(('G92 E1\n').encode())
time.sleep(1)
ser1.write(('G92 E1\n').encode())
Ideally it'd look like this without the delays:
import serial
import time
ser1 = serial.Serial('COM3', 250000)
ser1.write(('G92 E1\n').encode())
ser1.write(('G92 E1\n').encode())
But then commands get skipped.

Related

What did I do wrong when building receiver with pyserial?

I am using XBee modem to make mutual remote communication system.
Initially I tried using Arduino, however, I figured out that using two single board computer with python would be much more convenient. I am using pyserial right now.
This is the code which I made. It is really simple, and I don't see there would be something cause error.
Transmitter
import serial
import time
Xserial=serial.Serial('COM4',9600)
for i in range(10):
print(i)
Xserial.write(b"Test2")
time.sleep(3)
Xserial.close()
Receiver
import serial
import time
XSerial=serial.Serial('COM10',9600)
while (True):
line=XSerial.read(1)
print(line)
XSerial.close()
I think transmitter is working, however, receiver does not seem to receive what I send.
I am sure that it was working yesterday, but it is not working today. I checked XCTU and the connection is fine. I can communicate with each other by XCTU.

How to send one gcode command over USB?

I am trying to write a simple python script that sends a gcode command to my wanhao D9 motherboard printer, running Marlin. I am running the python script on a raspberry pi that is connected to the printer via USB.
import serial
ser = serial.Serial("/dev/ttyUSB0", 115200)
ser.write("G28\n")
I have read over 20 forum pages with simular problems and tried their answers such as changing the baud rate to 250000 and the following changes to the write function parameter:
ser.write("G28\r\n")
ser.write(b'G28\r\n')
ser.write(b'G28\n')
ser.write(b'G28')
ser.write("G28")
I have tried all these combinations, and I have also added:
time.sleep(5)
along with the relevant import statement for the time module at the top of my file. I added this line of code between my ser declaration and my ser.write function call.
I have also tried adding:
ser.close()
to see if that would make a difference but it has not, as I know this is best practice anyway.
No matter what combination of this code I used, when I run my python script my printer seems to restart (the screen changes from the home page to the opening wanhao logo and back to the home page)
I look forward to any help anyone can give me in regards to my code and what I may be doing wrong.
Adding an extra sleep period after my command fixed my issue. I can also now read back the initial set up feedback from the printer.
My final code without this is:
import serial
import time
ser = serial.Serial('/dev/ttyUSB0', 115200)
time.sleep(2)
ser.write("G28\r\n")
time.sleep(1)
ser.close()
Thank you, to the users in this post for guiding me in the right direction Full examples of using pySerial package
This code works for me, I hope someone else finds it useful in the future too.

Upload code to ESP32/Arduino while pySerial is running

I'm working on a project that an ESP32 module needs to read some value from a sensor and send it to a python code using pySerial. My code in constantly reading from the serial, as I can send data to it at any time. The problem is that the python program cannot be stopped because it's a server, but i still want to upload code whenever I want to the ESP32 module. Also, I'm sending data via serial on the void setup() function, so I need the python code to be running when the code is uploaded to the board, that is, when the setup() function runs.
I know I can't upload my code to the board while the serial port is being used by pySerial, but is there any way around? Like closing the connection while I'm uploading the code or when there is no data to be sent?
Here is the code that I'm using:
import serial
import json
ser = serial.Serial("COM6", 115200)
while(1):
if(ser.in_waiting > 0):
leitura = ser.read_until(b'}').decode('ascii')
data = json.loads(leitura)
handleRequest(data)

Importing and calling a list of different commands as functions

Currently I am trying to understand how a controlling software communicates with a modem/DCE through a serial port. I am using PySerial in Python for this purpose. I managed to passively listen to the communication of the two and do have a list of byte-strings (e.g. b'\x1d\x10\xff') the software sends while performing several single actions.
To fully understand the command-structure and the responses I want use a trial-and-error approach and mimic the controlling software with my own PC by extending my 'listen only'-script by sending commands and listen afterwards for the response. Right now I defined these commands as functions, for example:
def Testcommand1():
if serial.isOpen() == True:
serial.write(b'\x1d\x10\xff')
print('Testcommand1 to do some specific stuff sent, awaiting response.')
else:
print('ERROR: Serial port is closed')
In the end I will have 20-30 different commands. I plan to define them in a different file and call them from there. As I understand in order to call them I need to import each function individually, like
from commandfile import Testcommand1()
from commandfile import Testcommand2()
from commandfile import Testcommand3()
...
That's the point where I'm starting to doubt my approach (because I would have 20-30 lines before I start my actual 'listen'-program): is this really the best way? Or is there something slender and smarter as def function() to define my commands I want to send?
from commandfile import Testcommand1() won't work.
from commandfile import Testcommand1 will.
You could also import them all doing
from commandfile import *

Python: how to host a websocket and interact with a serial port without blocking?

I am busy developing a Python system that uses web-sockets to send/received data from a serial port.
For this to work I need to react to data from the serial port as it is received. Problem is to detect incoming data the serial port needs to queried continuously looking for incoming data. Most likely a continuous loop. From previous experiences(Slow disk access + heavy traffic) using Flask this sounds like it could cause the web-sockets to be blocked. Will this be the case or is there a work around?
I have looked at how NodeJS interact with serial ports and it seems much nicer. It raises an event when there is incoming data instead of querying it all the time. Is this an option in Python?
Extra Details:
For now it will only be run on Linux.(Raspbian)
Flask was my first selection but I am open to other Python Frameworks.
pyserial for serial connection.(Is the only option I know of)
Python provides the select module in the stdlib which can do what you want. It DOES depend on what operating system you are using though. So since you haven't provided that information I can't be that helpful. However a simple example under Linux would be:
import select
epoll = select.epoll()
# Do stuff to create serial connection and websocket connection
epoll.register(websocket_file_descriptor, select.EPOLLIN)
epoll.register(serial_file_descriptor, select.EPOLLIN)
while True:
events = epoll.poll(1)
# Do stuff with the event,
for fileno, event in events:
if fileno == serial_file_descriptor:
data = os.read(serial_file_descriptor)
os.write(websocket_file_descriptor, data)
elif fileno == websocket_file_descriptor:
data = os.read(websocket_file_descriptor)
# Do something with the incoming data
That's a basic, incomplete, example. But it should give you an idea of the general process of using a system like epoll.
Simply start a subprocess that listens to the serial socket and raises an event when it has a message. Have a separate sub-process for each web port that does the same.

Categories

Resources