RPi to RAMBo Serial Communication - RAMBo Restarting?

Hello! I’ve been running into problems recently trying to get serial communication up and running between my Raspberry Pi 3B and my RAMBo 1.4. I’m trying to use a Python program to send Gcode instructions to the RAMBo. I’ve looked through about 100 pages of stack overflow and the like at this point confirming that I have the right baud rate; the serial port is opening; my Python code gives no error and should work. I’ve also confirmed that the RAMBo works properly when Gcode is sent via a computer with Repetier.

Here’s my python code:

import serial
import time

ser = serial.Serial(’/dev/serial/by-path/platform-3f980000.usb-usb-0:1.4:1.0’, 115200)

time.sleep(2)
ser.write(str.encode(“G0 X20\r\n”))
time.sleep(1)

Any ideas as to why this is causing the RAMBo to restart when I run it? To clarify, it doesn’t actually move X20 either even after it restarts.

The marlin we put on Rambos is 250k baud. That firmware is at MarlinBuilder releases. It might be worth trying to eliminate some issues.

I often connect to boards with miniterm.py:

miniterm.py /dev/ttyUSB0 250000 (or ttyACM0 or whatever, from dmesg).

I send M115<enter> and get a response.

It is possible that the rambo serial chip is resetting the board on connect or disconnect… Maybe?

Thank you! I’m a newbie to commands like dmesg and didn’t know what information could give. Looks like for whatever reason even though python was able to open the /dev/serial/…usb-0:1.4:1.0 path, it decided it wouldn’t work unless it was given /dev/ttyACM0. So I guess, one problem down, one to go? The RAMBo is still restarting when I run the code unfortunately, but at least the CNC is moving as expected once the restart is complete.

Can you give some more explanation into your last suggestion? Not sure how I would fix it if the serial chip is resetting the board. Thanks again for your help!

Independent point of information, OctoPrint via V1Pi resets my RAMPS (not RAMbO) 3D printer board each time it connects.

If the act of opening the ttyACM0 is enough to reset the board, then IDK if you can avoid it.

You can only make sure to open the serial port and leave it open until you are done.

I know this is now kinda getting outside of the “mostly printed cnc” territory and into more of the technical side of programming…but any idea how to do that in python on raspberry pi? I need to run a block of code multiple times in a row rather than just passing a gcode file when I run the program once, and I have no idea how to leave the serial port open and defined after I run it once.

Thanks for all your help though!

You can put the send in a while or for loop. You need to be careful not to send too many commands at once. You should see an ‘ok’ whenever a command is accepted. Don’t send the next one until you receive the ok.

It isn’t trivial. It will take some time to learn and some trial and error if you haven’t tried this kind of thing already.

You can do it.

#!/usr/bin/python
import time
import serial

# Globals
ser = serial.Serial(
    port = '/dev/ttyUSB0',\
    baudrate = 25000,\
    parity = serial.PARITY_NONE,\
    stopbits = serial.STOPBITS_ONE,\
    bytesize = serial.EIGHTBITS,\
        timeout = 0)

def sendGcode(codeLine):
    codeLine = codeLine+"\r\n"
    ser.write(codeLine)
    done = 0
    while done == 0:
        status = ser.read()
        if status.upper() == "OK":
            done = 1
        time.sleep(0.5)

# Main Function
sendGcode("G28")
sendGcode("G0 Z3")
sendGcode("G0 X100 Y100")
sendGcode("G0 X5 Y5")
sendGcode("G0 Z0")
#And so on...
ser.close()

As far as I know, Marlin resets when you connect to the serial port. It will happen if I (for example) start Octoprint while printing something from the LCD SD card, so as a result, I either start Octoprint first to get a serial log, or I don’t start it at all. Well, now I don’t use it at all, since I no lionger use Marlin. I don’t know if that’s Marlin’s behaviour or the board, but I think it’s Marlin, since it doesn’t reboot the board, it just interrupts the SD card job. It does not power off the motors, or (I think) lose it’s current machine coordinates.

Edit: I would personally not use ser.read() – I prefer to go character by character when reading files or the serial device, but it should work for a case like this, and my usual coding practice may be a bit paranoid. I don’t know if you get the newline/carriage return characters on the string though, so it might need tweaking…

Well, thanks guys! I figured I could just loop it if I really needed to…it would just make my life easier if I could just leave the port open even between different .py files running. But I guess not…this works regardless! I’ll leave this open until I can test just looping the function tomorrow, and if it doesn’t restart Marlin I’ll mark as answered.