Maker.io main logo

Pathfinder Robot Companion

2020-08-25 | By Adafruit Industries

License: See Original Project

Courtesy of Adafruit

Guide by John Park

Overview

Pathfinder is a fan favorite character from the game Apex Legends. In this guide, we'll show you how to build your own interactive desktop Pathfinder desktop companion, complete with Adafruit PyPortal chest screen, voiceover lines from the game, and glowing LED robot eye!

 

robot_1

We'll build Pathfinder using 3D printed parts, Sugru moldable glue, and an array of electronics, all programmed on the PyPortal with CircuitPython.

This is an advanced project and a very involved build!

Parts

Tools

In addition to the parts above you'll need access to a 3D printer and PLA filament in a variety of colors to suit your Pathfinder build.

For the electronics, you'll want the following tools, or equivalent:

Fasteners

Most attachments will be made using Sugru, however, we'll use M4 hardware to fasten Pathfinder's torso halves together, as well as to secure the monitor frame.

Fasteners

Build the Pathfinder PyPortal Circuit

build_3

circuit_4

The Pathfinder Circuit

The circuit will enable the following systems/functions:

  • PyPortal as the central brain, display, and touch screen. This can be reprogrammed over the USB data port and can be reset with illuminated external momentary button.
  • Battery and PowerBoost converter for power and external USB port for charging. The power switch connects to the PowerBoost.
  • 3.7W amplifier and speaker with volume knob.
  • NeoPixel full-color LED for eyeball lighting.

The circuit diagram above shows how all of these parts are connected. Follow that diagram closely and build the circuit on the Perma-Proto board.

You'll see in the photos below that we'll use interconnect cables for some of the parts to make assembly into the 3D printed model easier. While it takes more work than simply soldering long wires directly to the proto board and the PyPortal, the added flexibility can be a lifesaver when trying to fit buttons and switches through their mounting holes!

Amplifier

Tie the power and ground rails of the PermaProto board together.

Mount the audio amplifier to the board as shown and then add the JST connector breakout board so the two center pins are connected to the L- and L+ of the amp board. To prevent shorting these to R- and SDWN you can cut the traces on the proto board the would join these and don't solder the outer pins of the breakout board to the proto board.

amplifier_5

amplifier_6

Power Rails

From the bottom of the proto board, jump the 5V and G columns where the PowerBoost will connect to the power rails.

Use a bare JST PH 2-pin connector to connect the toggle switch to the En and GND pins of the PowerBoost as shown. This will be used to turn Pathfinder on and off.

rails_7

rails_8

Power and Sound Connections

You can then plug in the USB power cable, the amplifier input from the PyPortal, the enable switch cable, the speaker, and the battery as shown here.

Note: Ignore the DIY USB plug soldered to the PowerBoost here, we'll simply plug one end into the PowerBoost USB-B and the other to the panel mount adapter later.

connections_9

PyPortal Connections

The PyPortal audio out runs to the L+ and L- inputs on the amplifier, you can see the small JST cable plugged in here.

Note: Ignore the DIY USB cable plugged into the PyPortal here -- we'll leave that port free for programming and run the power over JST instead.

pyportal_10

Reset Button

To access the reset button from the outside of the robot, solder two leads to the left two SMD pads of the programming connector as shown here. Polarity doesn't matter as this is used to short the reset pin to ground.

You can use a female socketed JST cable as shown here to make the connect to the button easier later when feeding it through Pathfinder's torso.

reset_11

reset_12

Knobs and Switches

Solder a two-conductor interconnect cable to the power enable switch and plug it into the JST socket that extends the PowerBoost En/GND pins.

Solder an interconnect cable to the potentiometer as shown in the circuit diagram, and in order to plug it between the speaker output of the PyPortal and the left channel input of the amplifier.

Connect the speaker to the screw terminals of the amplifier's left output channel as shown.

knobs_13

Final Wiring

Here we can see the final wiring and the circuit powered on (we'll still need to program it before testing).

Power runs from the PermaProto board rails to one of the three-pin JST connectors on the side of the PyPortal (this leaves the USB port free for programming).

The other three-pin JST port on the PyPortal is used to send power and data to Pathfinder's eyeball NeoPixel LED as seen here.

wiring_14

wiring_15

Next, we'll prep Pathfinder's PyPortal for coding!

Code Pathfinder

Setup

Prepare the PyPortal by following this setup guide to install the latest version of CircuitPython. This guide was created using version 5.3.0, so use that or later.

Install the libraries onto the PyPortal's /lib directory as instructed here.

Libraries

These are the libraries we'll have installed.

libraries_16

Media Files

Pathfinder has two sets of media files - .bmp images for his chest monitor "emotes", and sound files for his voice over (VO) lines.

Download the Project Zip .zip file from the link in the code embed below. Once it's been downloaded, unarchive the .zip file and then copy the two directories named /emotes and /vo onto the PyPortal's CIRCUITPY drive.

media_17

Text Editor

Adafruit recommends using the Mu editor for using your CircuitPython code to the PyPortal. You can get more info in this guide.

Alternatively, you can use any text editor that saves files.

text_18

Code.py

Copy the code below and paste it into Mu. Then, save it to your PyPortal as code.py.

Code

This version of the code play's Pathfinder's emotes screens and audio files as an automatically advancing slideshow. You can hold the touch screen to toggle the sound on and off.

Download: Project Zip or pathfinder_auto.py | View on Github

Copy Code
# Pathfinder Auto Mode
# automatically advances to new image/sound
# press and hold the touch screen to toggle sound on and off
# by John Park for Adafruit and Sugru
# MIT License
import time
import board
import displayio
import neopixel
from adafruit_pyportal import PyPortal

# ===========User Settings=============
sound_mode = 1 # 0 is silent, 1 is normal
eye_mode = 1 # 0 is always red, 1 changes per emote
slide_speed = 1.0 # number of seconds to pause, 0 will go as fast as it can
# =======end User Settings=============

i = 0 # emote image index
display = board.DISPLAY

pixel = neopixel.NeoPixel(board.D4, 1, brightness=0.2, auto_write=False)
PINK = (200, 0, 50)
RED = (255, 0, 0)
YELLOW = (255, 150, 0)
ORANGE = (255, 75, 0)
WHITE = (100, 100, 100)
CYAN = (0, 255, 255)
GREEN = (0, 235, 20)
BLUE = (0, 0, 255)
PURPLE = (180, 0, 255)
BLACK = (0, 0, 0)
GREY = (10, 10, 10)

if eye_mode is not 0:
colors = [PINK, RED, ORANGE, CYAN, YELLOW, GREEN, WHITE, RED, PURPLE, GREEN, GREY]
else:
colors = [RED, RED, RED, RED, RED, RED, RED, RED, RED, RED, RED]

pixel.fill(colors[0])
pixel.show()

emote_img = [
"/emotes/01_love.bmp",
"/emotes/02_anger.bmp",
"/emotes/03_KO.bmp",
"/emotes/04_sad.bmp",
"/emotes/05_happy.bmp",
"/emotes/06_bang.bmp",
"/emotes/07_sick.bmp",
"/emotes/08_thumbsup.bmp",
"/emotes/09_question.bmp",
"/emotes/10_glitch.bmp",
"/emotes/11_static.bmp",
]

vo_sound = [
"/vo/pathfnd_45.wav",
"/vo/pathfnd_46.wav",
"/vo/pathfnd_47.wav",
"/vo/pathfnd_48.wav",
"/vo/pathfnd_49.wav",
"/vo/pathfnd_51.wav",
"/vo/pathfnd_52.wav",
"/vo/pathfnd_53.wav",
"/vo/pathfnd_54.wav",
"/vo/pathfnd_55.wav",
"/vo/pathfnd_56.wav",
]

pyportal = PyPortal(status_neopixel=board.NEOPIXEL)

# Open the file
with open(emote_img[0], "rb") as bitmap_file:
# Setup the file as the bitmap data source
bitmap = displayio.OnDiskBitmap(bitmap_file)
# Create a TileGrid to hold the bitmap
tile_grid = displayio.TileGrid(bitmap, pixel_shader=displayio.ColorConverter())
# Create a Group to hold the TileGrid
group = displayio.Group()
# Add the TileGrid to the Group
group.append(tile_grid)
# Add the Group to the Display
display.show(group)
if sound_mode is not 0:
# play a sound file
pyportal.play_file(vo_sound[10])
else:
pyportal.play_file("/vo/pathfnd_silent.wav") # hack to deal w no mute method


# Loop forever so you can enjoy your image
while True:
if pyportal.touchscreen.touch_point:
if sound_mode == 0:
sound_mode = 1
else:
sound_mode = 0
i = (i + 1) % 11
pixel.fill(colors[i])
pixel.show()
time.sleep(1)
with open(emote_img[i], "rb") as bitmap_file:
bitmap = displayio.OnDiskBitmap(bitmap_file)
tile_grid = displayio.TileGrid(bitmap, pixel_shader=displayio.ColorConverter())
group = displayio.Group()
group.append(tile_grid)
display.show(group)
if sound_mode is not 0:
# play a sound file
pyportal.play_file(vo_sound[i])
else:
pyportal.play_file("/vo/pathfnd_silent.wav")
time.sleep(slide_speed)

This alternate version of the code will only advance the emote and VO line when the touchscreen is pressed. This is perfect for picking a mood and sticking with it!

Download: Project Zip or pathfinder_touch.py | View on Github

Copy Code
# Pathfinder Touch Screen
# press screen to advance to new image/sound
# by John Park for Adafruit and Sugru
# MIT License
import time
import board
import displayio
import neopixel
from adafruit_pyportal import PyPortal

# ===========User Settings=============
sound_mode = 1 # 0 is silent, 1 is normal
eye_mode = 0 # 0 is always red, 1 changes per emote
# =======end=User Settings=============

i = 0 # emote image index
display = board.DISPLAY

pixel = neopixel.NeoPixel(board.D4, 1, brightness=0.3, auto_write=False)
PINK = (200, 0, 50)
RED = (255, 0, 0)
YELLOW = (255, 150, 0)
ORANGE = (255, 75, 0)
WHITE = (100, 100, 100)
CYAN = (0, 255, 255)
GREEN = (0, 235, 20)
BLUE = (0, 0, 255)
PURPLE = (180, 0, 255)
BLACK = (0, 0, 0)
GREY = (10, 10, 10)

if eye_mode is not 0:
colors = [PINK, RED, ORANGE, CYAN, YELLOW, GREEN, WHITE, RED, PURPLE, GREEN, GREY]
else:
colors = [RED, RED, RED, RED, RED, RED, RED, RED, RED, RED, RED]

pixel.fill(colors[0])
pixel.show()

emote_img = [
"/emotes/01_love.bmp",
"/emotes/02_anger.bmp",
"/emotes/03_KO.bmp",
"/emotes/04_sad.bmp",
"/emotes/05_happy.bmp",
"/emotes/06_bang.bmp",
"/emotes/07_sick.bmp",
"/emotes/08_thumbsup.bmp",
"/emotes/09_question.bmp",
"/emotes/10_glitch.bmp",
"/emotes/11_static.bmp",
]

vo_sound = [
"/vo/pathfnd_45.wav",
"/vo/pathfnd_46.wav",
"/vo/pathfnd_47.wav",
"/vo/pathfnd_48.wav",
"/vo/pathfnd_49.wav",
"/vo/pathfnd_51.wav",
"/vo/pathfnd_52.wav",
"/vo/pathfnd_53.wav",
"/vo/pathfnd_54.wav",
"/vo/pathfnd_55.wav",
"/vo/pathfnd_56.wav",
]

pyportal = PyPortal(status_neopixel=board.NEOPIXEL)

# Open the file
with open(emote_img[0], "rb") as bitmap_file:
# Setup the file as the bitmap data source
bitmap = displayio.OnDiskBitmap(bitmap_file)
# Create a TileGrid to hold the bitmap
tile_grid = displayio.TileGrid(bitmap, pixel_shader=displayio.ColorConverter())
# Create a Group to hold the TileGrid
group = displayio.Group()
# Add the TileGrid to the Group
group.append(tile_grid)
# Add the Group to the Display
display.show(group)
if sound_mode is not 0:
# play a sound file
pyportal.play_file(vo_sound[10])
else:
pyportal.play_file("/vo/pathfnd_silent.wav") # hack to deal w no mute method

while True:
if pyportal.touchscreen.touch_point:
i = (i + 1) % 11
pixel.fill(colors[i])
pixel.show()
time.sleep(1)
with open(emote_img[i], "rb") as bitmap_file:
bitmap = displayio.OnDiskBitmap(bitmap_file)
tile_grid = displayio.TileGrid(
bitmap, pixel_shader=displayio.ColorConverter()
)
group = displayio.Group()
group.append(tile_grid)
display.show(group)
if sound_mode is not 0:
# play a sound file
pyportal.play_file(vo_sound[i])
else:
pyportal.play_file("/vo/pathfnd_silent.wav")

Once you've tested this code on your PyPortal and connected circuit, we'll build the Pathfinder robot himself.

Print and Assemble Pathfinder

3D Printing

Pathfinder will be made primarily of 3D printed parts, using PLA plastic filament in a variety of colors. You can get creative here and do your own color scheme for Pathfinder!

Sugru works very well to fasten PLA parts together as well as to form part extensions, and to smooth some surfaces. You may want to test Sugru bonding with alternate filament materials if not using PLA.

First, download the Pathfinder STL models from the .zip link button below, then get printing!

Note, any model file with a multiples suffix in the name, such as pathfinder_lens_protector_x2.stl need to be printed in those multiples.

Do not print the pathfinder_assembled.stl file, it is only provided as assembly reference.

printing_19

printing_20

printing_21

printing_22

printing_23

printing_24

printing_25

printing_26

printing_27

printing_28

Pathfinder_STLs.zip

parts_29

parts_30

parts_31

Once the parts are printed (whew!) it's time to begin assembly.

This rendered turnaround of the model will show you how the parts will all fit together.

 

Abdomen Section

The abdomen section goes together with two main parts -- the abdomen base and the roller on which the torso will later rest -- and two brackets.

There are also four cylindrical press-fit plugs that join the parts. Use a small bit of Sugru in the receiving holes of the abdomen and roller to hold these all in place as shown.

abdomen_32

abdomen_33

abdomen_34

abdomen_35

Canister Build

Some parts need to be created as sub-assemblies before adding to the full robot.

The canisters on Pathfinder's shoulders can be assembled with a bead of Sugru rolled out and then placed on the top and bottom of the main cylinder.

Then, press it onto the base and place the lid on top as shown here.

You can cut off any excess Sugru that overlaps when the base and lid are pressed into place.

Use a small dot of Sugru to attach the handle as well.

You will repeat all of these steps for the second canister.

Add the canister handles and nubs, building up the nubs with some red Sugru.

build_36

build_37

build_38

build_39

build_40

Canister Magnets

Using a bit of Sugru, embed a small magnet into the baseball of each canister.

Mark the north sides of two magnets so the opposite magnet can be flipped and embedded later into the canister attachment cups.

Magnets_41

Magnets_42

Shoulders

To secure the shoulder ball into the shoulder socket, roll out a bead strip of Sugru and add it inside the socket.

Push the ball through from the inside, then sculpt and smooth the Sugru to create a nice, seamless joint.

Shoulders_43

Shoulders_44

Shoulders_45

Shoulders_46

Shoulders_47

Monitor

Use your soldering iron to place M2.5 heat-set threaded inserts into the holes inside the monitor frame. You'll use these to secure the PyPortal acrylic frame and the PyPortal in place.

Align the PyPortal acrylic frame inside the printed monitor frame, then screw the PyPortal into place with the nylon M2.5 screws.

Monitor_48

Monitor_49

Monitor_50

Monitor_51

Monitor_52

Monitor_53

Sculpted Pouch Nubs

Pathfinder's three front pouches have red release nubs on them -- use red Sugru to sculpt these.

Nubs_54

Nubs_55

Nubs_56

Torso Threaded Inserts

Use a soldering iron to place two M4 heat-set threaded inserts into the left torso half.

These will be used later to screw in the right torso half using M4 x 50mm screws.

Inserts_57

Inserts_58

Inserts_59

Torso Electronics

Add the reset button, power switch, volume potentiometer, and USB power port extender to the left torso half as shown. Fasten them with their provided nuts. Then, reconnect their cable interconnects to the main proto board if necessary.

Use some Sugru to secure the speaker, battery, and electronics inside the torso. It will be a bit of a snug fit, so try dry fitting the halves together before allowing the Sugru time to cure in case things need to be adjusted.

Electronics_60

Electronics_61

Electronics_62

Electronics_63

Electronics_64

Electronics_65

Electronics_66

Electronics_67

Electronics_68

Torso_69

Close It Up

Add one M4 threaded insert to each torso half so the monitor can be screwed into it from the top using the M4 x 14mm screws.

Fasten the two torso halves together with the longer M4 x 50mm screws now.

Close_70

Close_71

Close_72

Close_73

Close_74

Close_75

Close_76

Close_77

Close_78

Testing

This is a good time to test all of the functions!

Testing_79

Testing_80

Head and Eye

Secure the lens to the inside of the head/eye socket with a thin bead of Sugru. You can use a shop towel or cloth when handling the lens to avoid fingerprints.

Secure the outer eye detail parts with Sugru as well.

Push the eye NeoPixel up through the neck and then secure it inside the head with Sugru. You can create a nice depth effect by adding a spacer between the NeoPixel and lens.

Head_81

Head_82

Head_83

Head_84

Head_85

Head_86

Shoulder Gaskets

To attach the shoulders to the torso, press fit them in place and then fill the connection with a gasket-like strip of black Sugru.

You can trim, sculpt, and smooth it with a tool or your finger to give it the appearance of a rubber gasket.

Gaskets_87

Gaskets_88

Gaskets_89

Gaskets_90

Gaskets_91

Gaskets_92

Neck Cowl

With the NeoPixel eye fed up through the neck tube and secured inside the head with Sugru, you can attach the neck and head to the torso.

Then, wrap the neck cowl form pieces around the neck and begin sculpting a Sugru cowl over the top of it. Pathfinder has a rubberized canvas cowl in the game, so this will emulate that look and have organic folds and curves in it.

Neck_93

Neck_94

Neck_95

Neck_96

Neck_97

Neck_98

Neck_99

Pouches and Mounting

Attach the mounting plate to the abdomen brackets and then affix the pouches to the mounting plate with Sugru.

You can place the torso on top of the abdomen roller and affix it with a dot of Sugru.

Pouches_100

Pouches_101

Collarbones and Canisters

You can now pop into place the collarbones and canisters using their magnets to hold them.

Collarbones_102

Collarbones_103

Collarbones_104

Collarbones_105

Collarbones_106

Collarbones_107

Bring Pathfinder to Life

You can now bring Pathfinder to life! Flip the on switch and he'll start playing his voice over audio and display emotes!

You can adjust his volume with the large volume knob, and if you're in touch screen mode, tap the screen to advance to the next emote.

pathfinder_108

One of the best things about Pathfinder and PyPortal is that he's fully customizable! You can swap out different graphics and sound files, or reprogram him for entirely different uses, such as a Bitcoin price display, art museum collection frame, weather station, Hue lighting controller, or Reddit stats trophy.

pathfinder_109

制造商零件编号 4116
PYPORTAL - CIRCUITPYTHON POWERED
Adafruit Industries LLC
制造商零件编号 4146
PYPORTAL DESKTOP STAND ENCLOSURE
Adafruit Industries LLC
制造商零件编号 2465
EVAL BOARD FOR TPS61090
Adafruit Industries LLC
制造商零件编号 987
EVAL BOARD FOR MAX98306
Adafruit Industries LLC
制造商零件编号 3968
SPEAKER 4OHM 3W TOP PORT
Adafruit Industries LLC
制造商零件编号 1609
BREADBOARD GENERAL PURPOSE PTH
Adafruit Industries LLC
制造商零件编号 3853
CONVEX GLASS LENS WITH EDGE - 40
Adafruit Industries LLC
制造商零件编号 592
CABLE A PLUG TO MCR B PLUG 3'
Adafruit Industries LLC
制造商零件编号 3562
CABLE JUMPER 11"
Adafruit Industries LLC
制造商零件编号 4109
DIY USB CABLE PARTS - STRAIGHT T
Adafruit Industries LLC
制造商零件编号 4105
DIY USB CABLE PARTS - RIGHT ANGL
Adafruit Industries LLC
制造商零件编号 1862
JST-PH 2-PIN R/A BREAKOUT BOARD
Adafruit Industries LLC
制造商零件编号 2056
KNOB KNURLED 0.236" METAL
Adafruit Industries LLC
制造商零件编号 1260
FLORA PLATFORM RGB NEOPXL V2 4PK
Adafruit Industries LLC
制造商零件编号 3893
JST PH 3PIN TO MALE HEADER CABLE
Adafruit Industries LLC
制造商零件编号 TLXURON420
420 ANGLED HEAD SHEAR
SRA Soldering Products
制造商零件编号 3434
STAINLESS STEEL SPUDGER - DOUBLE
Adafruit Industries LLC
制造商零件编号 3299
BLACK NYLON SCREW AND STAND-OFF
Adafruit Industries LLC
Add all DigiKey Parts to Cart
TechForum

Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.

Visit TechForum