A Python interface to a large-format pen plotter

Connect to the Plotter

Line 113 – commented out – is how I connect to the physical plotter; note the Linux serial port location /dev/ttyUSB0 for the serial dongle. The nullPlotter class is discussed later. Once you're connected to a plotter, line 115 requests the paper size currently loaded.

Plot!

Calling the plot() function starts the plotting process, which is implemented as a separate function. Line 121 defines the default path where HPGL files are located. Because I normally use scp to copy the files onto the Pi, this is where they show up.

Lines 122-125 initialize y, selectedX, and selectedY, which indicate the current cursor position in the browser. Line 127 starts the file browser loop; once a file is selected, break is called to break out of the loop.

In each iteration of the loop the file display is completely recreated. I start by initializing two dictionaries, screenDirectories and screenFiles (lines 128-129). dirOffset and fileOffset (lines 131-132) are used to track paging when directories or files run off the screen. The screen is cleared on line 134, and the program is ready to draw the file list.

Line 136 sets up a loop with the output of os.walk, which walks a directory tree and provides a list of files and directories in the current path. Lines 137 and 138 reset y and x to draw at the upper left of the screen, then line 139 sets up a loop that traverses the range of dirOffset to dirOffset + <screen height>. This results in one screen of listings via slice notation.

Lines 140-143 draw that list to the screen. If this is the currently selected file, it is drawn highlighted (curses.A_REVERSE); otherwise, line 141 draws it in the same position but with regular text. Line 142 adds each entry to the screenDirectories dictionary using the screen coordinate's tuple as a key. Then, y is incremented so the next iteration will draw on the next line down (line 143).

Lines 145-157 repeat the process for files rather than directories, with a couple of minor differences. Line 149 checks for "hpgl" in the filename and skips the entry if it is not found. Lines 155-157 reset y and x for additional columns if they are required.

After the program loops over all of the directories and files in the current working directory, the screen is refreshed (line 159) to make sure the entire list is visible. A break occurs, and then os.walk traverses the directory tree up or down until it can't go any deeper or hits "/" depending on its direction. This is great to create an entire directory tree, but I don't want the index of the entire disk volume, so break stops it after the current directory.

On lines 162-183, fileBrowser runs its own loop to process keystrokes. Line 162 gets a key with getch(), then it gets processed.

Line 163 checks for return or newline. When one of these is detected, line 164 creates a tuple of the current screen position and checks to see whether it exists in screenFiles. Next, selectedY is incremented by 1 because the file list starts on line 1, not 0, and selectedX is multiplied by 30 because the file browser columns are 30 characters wide. If the index is found, then its corresponding value is returned.

If the coordinates weren't found in the file list, then the check is performed in screenDirectories (line 166). If it's found here, the path is updated (line 167) and cursor coordinates are reset to 1,1 (lines 168-169). The next iteration of the loop will reflect the files in the updated path. Each pair of lines from 170-177 work the same. They each check for an arrow key and then increment or decrement the appropriate value.

Line 178 checks for a u keypress; if it's found, then /.. is appended to the path (line 179). Because the directory was changed, selectedX and selectedY are reset to 1 (lines 180-181).

Line 182 started as a debug command to see the coordinates of the currently selected file but I liked it, so I left it in. Finally, line 183 refreshes the screen so that any redrawing that occurs is reflected on the screen.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Raspberry Pi Geek

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content