[Tutor] Pen plotter data format
Dennis Lee Bieber
wlfraed at ix.netcom.com
Sat Apr 1 02:20:09 EDT 2023
On Sat, 1 Apr 2023 13:54:23 +1000, Phil <phillor9 at gmail.com> declaimed the
following:
>The original plan was to build a plotter with at least a 100mm x 100mm
>drawing surface. However, due to the parts that I have on hand plus some
>parts that are in the mail somewhere that area has been reduced so I
>will now only need to pass a two digit coordinate byte.
What is the resolution of the stepper motors themselves -- I'd hope an
attempt at a pen plotter has finer resolution than 1mm steps.
Also, are you trying to pass binary data or (ASCII) text strings? I
suspect things will be easier if you follow something like the HP-GL style
of text. Among other things, it may make it much easier in the future to
add commands for "plotting" text (wherein the font and actual coordinate
generation of letter forms is performed totally in the controller [R-Pi]).
>After the micro-controller has received a byte and moved the motor it
>send an acknowledgement back to the laptop signalling that it's ready
>for the next byte.
>
HP-GL assumes a simple serial port -- if one has RTS/CTS (or
X-on/X-off) protocols on the serial port that alone should stop the sender
while the controller processes each command in sequence (and technically,
the R-Pi is not a "microcontroller" -- a microcontroller would be an
Arduino, Adafruit Metro M4*, and things of that ilk; they don't run an
operating system [though I think FreeRTOS has been ported to the ARM-based
Arduinos, probably not to the 8-bit AVR versions]; the R-Pi is, at worst,
an embedded microcomputer though some are using them as replacement desktop
computers).
Granted, with the rarity of serial ports these days, that could mean
having a USB<>serial adapter on both the host and R-Pi, with a null-modem
adapter between them <G>
>
>I'm building a plotter from scratch using Lego parts and I'm not using
>the Lego software. It's just a project to keep me out of mischief and I
>doubt the plotter will ever serve a useful function. I'll be pleased if
>it produces a reasonable plot.
Either find the source code for a g-code 3-D printer controller (should
be lots, since a lot of such printers use R-Pi boards as the controller)
and hack it to isolate just the 2-D operations (hijacking the commands used
to start/stop the plastic thread feeder for pen-up/-down) and then conform
your host side to send in whatever protocol that software requires... Or,
as you are no doubt getting tired of reading, send an ASCII text stream and
write a parser for that on the R-Pi side. A parser for HP-GL (based on the
little I've seen in those links) would look something like (and I'm
assuming some sequences may be all in one "line" using ";" delimiters...
Also this is pseudo-code, not executable Python -- the real code should
have a lot of try/except blocks, especially when handling the parameters of
each command)
def penUp(parameters):
try:
x, y = parameters.split(",")
except <pick the appropriate exception for too many/few parameters>:
return "Incorrect number of parameters provided; expected 2"
try:
int_x = int(x)
int_y = int(y)
except <pick exception for invalid integer conversion attempt>:
return "Invalid integer data"
if (MIN_X > int_x > MAX_X)
or (MIN_Y > int_y > MAX_Y):
return "Coordinate out-of-range"
#issue servo command to raise pen
#issue stepper motor controls to move pen to (int_x, int_y)
command_table = { "SP" : selectPen,
"PU" : penUp,
"PD" : penDown }
while True:
command_string = serial.readline() #block for EOL
commands = command_string.split(";") #split into each command
for command in commands: #process each command
cmd, parameters = command[:2], command[2:]
#call the handler function matching "cmd"
#all handlers have the same signature!
result = command_table[cmd.upper()](parameters)
if not result:
serial.write("%s : %s\n" % (command, result))
Adding a command just requires adding a new "def cmd_handler()" and an
entry in the command_table.
If you change the signature from (parameters) to (cmd, parameters) you
could maybe save some duplication in code. Instead of penUp() and penDown()
you would have both commands invoke penMove(cmd, parameters) and have a
test for
if cmd == "PU":
#issue servo command to raise pen
else:
#issue servo command to lower pen
the stepper motor logic being the same for both, as is the parameter
parsing.
* The (Arduino Uno/Due style) Adafruit Metro M4 Express
https://learn.adafruit.com/adafruit-metro-m4-express-featuring-atsamd51/overview
(along with a lot of Adafruit microcontroller boards) natively runs
CircuitPython -- a variant of Python optimized for small boards (lots of
control over the GPIO, etc.) and running without an OS. Instead, one writes
a CircuitPython program on the host, connects the board via USB -- it will
create a (on Windows at least) "drive". You drag the program file to the
drive; the boot firmware on the board detects the new file, and will start
running it (and it gets run anytime the board is reset or power-cycled). If
you overwrite the firmware with an Arduino boot-loader, you can write
Arduino [C/C++] style (setup()/loop() functions) instead. You'd have to
restore the CircuitPython firmware to return to "native" mode. If you can't
fit your controller program into its 2MB QSPI flash, the larger (Arduino
Mega style) Grand Central
https://learn.adafruit.com/adafruit-grand-central/overview has 8MB
One potential glitch -- I've found that while the "drive" is active,
the firmware looking for changed files interrupts (actually -- restarts)
the program. "Ejecting" the drive but leaving the board connected via USB
seems to allow the program to run without interruptions. I did not check if
the USB /serial/ monitor could still read the program output. Just reset
the board to get it to remount as a drive.
More information about the Tutor
mailing list