Final Project - Nudge
BOM
Qty | Part | Des | Cost | Total | Link |
---|---|---|---|---|---|
1 | Raspberry Pi Pico 2 W Board | Main Board for device | €8.27 | €8.27 | Link |
3 | RIC11-31S15D7-GSMT | SMD rotart encoder - User Input | €2.52 | €7.56 | Link |
3 | SLIDE POT 10KOHM 0.125W TOP 20MM | Slid Pot - User input | €1.37 | €4.11 | Link |
1 | Board of FR1 | Copper board for milling | €2.90 | €2.90 | Link |
1 | OLED | Oled Display for setting sencivitity | €3.08 | €3.08 | Link |
1 | Oak Board | Top plate material | €0.00 | €0.00 | Offcut from wood shop |
1 | Jesmonite | Material for base | €20.00 | €20.00 | Link |
1 | PLA | Knobs and oled Shroud | €20.00 | €20.00 | Link |
€65.92 |
Weeklies:
Week 5 - 3D printing and scanning
Week 13 - Moulding and Casting
Week 14 - Interface and Applications
Week 16 - Wild Card Week(Carry Case)
System Integration:
Legal and Copyright:
All programming was assisted by ChatGPT, I have included the full chat logs in the files download below. Much of my development was done on boards designed by Adrian Torres
Concept development
At the beginning for Fabacademy I was not sure what to do for my final project so put together the list below. My strengths are design and Fabrication, my weaknesses are all things electronic and programing related. A key goal for me in this project is to address this weakness
- Input device for computer, something like space mouse for CAD - Inspired by over-engineered keyboards
- Drone / RC car or boat
- something big, like a pavilion or something with lighting or weather monitoring
- Basic but nice lamp
- Basic but nice printed shoe
- Basic but nice headphones
- Medical wearable (cast with sensors?)
- Automation for Print farm
Research
- Orbion 3D Space Mouse
- Mighty Mouse
- Space Mouse With Arduino
- Ahmsville Dial v2
- OS3M
- Space Mushroom
- DIY Space Mouse Magnets
- Custom Keyboards SubRedit
- Official 3D Connexion Spacemouse
Idea 1:
The idea for this is to make a space mouse style interface for CAD software that is inspired by opensource designs and fancy over-engineered keyboards using premium materials like the ones on the Custom Keyboards SubRedit
Idea 2:
This would be a custom cast that is 3D printed and custom fit using a scan. This would be incorporated with sensors that will inform the user if they are imparting to much force on there healing bones. Also could check that limb is being elevated at the correct angle
I used the the weekly assignment where possible to test out my ideas, such as week 2 where I used different cad software to explore the cast and the space mouse idea
While these are very conceptual they helped me move forward and get a better picture of relative complexity of each product.
In week 3 I kept things conceptual and used the brief to create a lasercut interpretation of the cast idea. While I knew I was not going to use this process going forward it this was my first week where I had a physical thing to hold and in this case ware.
Week 4 was the first week where I was basically a complete beginner. getting a very basic simulation up and running of the joystick gave me confidence that I could make this project work and I started to drift towards this being my final project.
Week 5 was a big one for me in this process. In the process of sketching, using the 3D connection cad mouse and talking to my instructor my project idea really solidified.
Mixer inspired CAD interface
The core idea for my project is the 6 axis CAD peripherals are very difficult to learn and use precisely. So my idea is to make a peripheral that splits each of the axes into its own input. This could be a dial, a slider, a toggle with a jog wheel. I’m not sure yet, but the basic concept is there.
With this decided I have been gathering more reference images
And sketching around this idea to develop my forms.
And also visiting my local music shop to have a play around with things.
This lead me into the project for week 5 where I had the opportunity to create a print in place model and an animation to further refine some of the ideas that have been in my head.
I have started to jump back into Wokwi to help plan and program some of my components
In recent development sketches I have removed the large wheel as its may be redundant, I only need 6 inputs for 6 axis of motion.
Chat with a ChatBot
can you help me create a BOM for this project, I will be milling a board to mount all the parts out of FR1 coper clad board and I can cnc, laser cut and machine the parts for the case, I just need the BOM for the electrical components
ChatGPT said: Memory updated Here’s a Bill of Materials (BOM) for your CAD macro pad:
🔌 Core Components
🧠 Microcontroller
- Raspberry Pi Pico 2W (RP2350) Link
⚡️ Power
- LiPo Battery (3.7V, ~1000mAh or more)
- LiPo Charging Module (TP4056 or similar)
- 3.3V Regulator (if needed, e.g., MIC5225-3.3V for stable power)
🎛 Input Devices
- Rotary Encoders (3x) – EC11 or similar (for rotational control) Link
- Linear Potentiometers (3x) – 10kΩ slide potentiometers (for linear motion control) Link
- Mode Selector (1x) – Rotary switch (4 positions) or 10kΩ potentiometer (if using an ADC-based selector) Link
- Hotkeys (6x) – Momentary push buttons Link
📺 Display & Feedback
- Display – 0.96” or 1.3” OLED (I2C, SSD1306 or SH1106) OR small TFT screen (SPI) Link
- LED Indicators (Optional) – RGB LEDs or status LEDs (for mode indication)
- Buzzer (Optional) – Small piezo buzzer for audio feedback
🔌 Connectors & Miscellaneous
- Headers & Sockets – 2.54mm pin headers or JST connectors (for modularity)
- Wires & Solder – 30AWG wire for signal connections, thicker for power
- Copper-Clad FR1 Board – For custom PCB milling
- Resistors – 10kΩ pull-ups for encoders/buttons if needed
- Capacitors – 100nF decoupling capacitors (for power stability)
Disclaimer: Im aware that this BOM what created by a Chatbot and will be reviewed by a human before finalizing.
Spiral Development:
- V1 - Just Dials and Linear Potentiometers using relative positions for inputs
- V2 - Add Hotkeys
- V3 - Add toggle for encoder being in absolute or relative mode
- V4 - Add a display to give user information about the current mode.
- V5 - Add Bluetooth support for wireless connectivity but keep power over usb.
- V6 - Full wireless use using a rechargeable lithium-ion battery
- V7- Infinity tune and make the dials feel sweeeeeet to use. 🤙
Prototyping
Test from week 10
Prototype of the housing
Prototype of the user inputs
Final project development
The aesthetic of the design was further refined in week 15.
And the materials nailed down.
Giving it a name
All products need a name and this is the one I landed on!
Helping nudge your models to the right angle
Final - CAD design
The design for the final product was done in Fusion 360.
The steps we as follows:
- Extrude the overall shape
- Fillet the side corners
- Chamfer the bottom edge
- Shell the piece removing the top edge
- Add the corner standoffs and add a big chamfer
- Add the mounting holes
- Extend the standoffs to carry the top as a new body and patern for all the corners.
- Bool combine all th bodies.
- Fillet all edges
I tried to make is so the design would work well for both a printed version and a cast version.
The core proportions of the design are sized around the board that was also designed in Fusion.
Using the board above meant I needed to adjust my proportions a bit from the render
For the knobs, printed them in increments of 0.1mm so I could achieve a slip fit on the inputs.
For the top plate, I printed each revision only 0.2mm tall, this meant I could confirm the positions of the holes and slots without wasting material
When I had a working model I tried to print it as early as possible to refine out errors before the moulding process.
Using the board above meant I needed to adjust my proportions a bit from the render
For the knobs, printed them in increments of 0.1mm so I could achieve a slip fit on the inputs.
For the top plate, I printed each revision only 0.2mm tall, this meant I could confirm the positions of the holes and slots without wasting material
I then moved the screen so as not to cover it with your hand.
The laser cut wood will hopefully be replaced with oak for the final.
The knobs and top details were made in a similar style
Final - Electronic Design and Production
I downloaded a Pico V2 footprint from the link above
Downloaded the symbols and footprint for my encoders from Digikey
And imported my OLED screen and linear pot symbols from previous weeks
Pushed the design to the board design workspace
rearranged the parts until autoroute completed successfully
And tweaked the layout until I was happy with how everything looked and used export->image
to get my files ready from CAM.
The sittings I used were:
[x] monochrome images
1000 dpi
*.png file format
Area: Full
There were some elements that were included in some of my downloaded footprint’s that I could not hide with layers
in Fusion 360 so I used GIMP to clean it up.
Pushed the file to a 3D pcb. You can see it hear in a temporarily case I use for Week 14
Handled my CAM in mods, I am still finding the 60 deg vbit is working for me.
And the final PNG’s:
Traces - 60deg v bit
Holes drilling - 0.8mm endmill
Outline - 0.8mm endmill
And got to cutting!
The traces were cut using a 60deg bit
The outline was cut using a 0.8mm endmill
And the components were hand soldered using lead free solder
Final - Moulding and Casting
This video takes you through a full walk though of the CAD process for the moulds.
For more detail see screens below
To make the master mould I started in CAD with my final design
I then created a block around the design and started to use boolean’s and splits to create my master
This is the negative of the bottom of the master mould for the bottom half of the part
And the final positive is then booleaned one more time.
And the same process for the top.
Here we can see more detail with the part that will be rubber in a clear material
As the parts are going to get printed on a resin printer I wanted to shell them to save as much material as possible.
The last step was to add a small mould for making the insert for the port on the side of the part.
The parts were sliced in Preform, Formlabs slicer
The masters for the two mould halves were printed on the Form 3L
I used draft resin as it has a higher print speed than the other printers.
The orientation of the parts was adjusted to minimise any supports on the area that will become the mould surface.
The parts were washed and cured, to get for mould prep.
Both sides of the moulds were wet sanded up to 800 grit to help achieve a good surface finish and minmimise the need for clean up of the finished model.
Diarmuid had these left over prints from his mould making week and they were perfect for my print to create some pour spouts.
One half complete.
I did not have great draft angle on the other half of the mould so I had to break it out.
Started experimenting with some Jesmonite, this initial cast took a few attempts to fully fill the mould, but that meant I had my qtys going forward.
After this experimenting I knew I needed aprox 700g of Jesmonite to fill the mould.
Then it was time to demould the first test.
The part ended up failing due to the mould not filling properly, I think this was due to the multiple pours. So for the next version I made sure I had enough material to do in one single pour.
Still with some super glue, it gave a nice effect.
The second pour was just black and the mould filled much better.
There was some trapped air on the bottom of the part but as this is an unseen surface I was not too concerned.
This was my cleanest mould to date, just needed some cleanup at the seam.
This was trimmed back and wet sanded to 800 grit.
Final - Programming
My board uses Circuit Python’s HID library for its functionality
The programming was greatly assisted by ChatGPT. There was a very long back and forth over chat that can be downloaded in my project files.
All the testing was done in Thonny IDE
# Carl McAteer 16/6/25
#
# This work may be reproduced, modified, distributed,
# performed, and displayed for any purpose, but must
# acknowledge this project. Copyright is retained and
# must be preserved. The work is provided as is; no
# warranty is provided, and users accept all liability.
#
import time
import board
import digitalio
import rotaryio
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
from adafruit_hid.mouse import Mouse
# HID interfaces
keyboard = Keyboard(usb_hid.devices)
mouse = Mouse(usb_hid.devices)
# === Button Setup ===
buttons = [
{'pin': board.GP0, 'key': Keycode.KEYPAD_THREE, 'name': 'Left Button'},
{'pin': board.GP3, 'key': Keycode.KEYPAD_ONE, 'name': 'Middle Button'},
{'pin': board.GP6, 'key': Keycode.KEYPAD_SEVEN, 'name': 'Right Button'}
]
for b in buttons:
b['io'] = digitalio.DigitalInOut(b['pin'])
b['io'].switch_to_input(pull=digitalio.Pull.UP)
b['prev'] = True
b['last_time'] = time.monotonic()
debounce_s = 0.02
# === Rotary Encoder Setup ===
encoder_left = rotaryio.IncrementalEncoder(board.GP1, board.GP2)
encoder_middle = rotaryio.IncrementalEncoder(board.GP4, board.GP5)
encoder_right = rotaryio.IncrementalEncoder(board.GP7, board.GP8)
last_pos_left = encoder_left.position
last_pos_middle = encoder_middle.position
last_pos_right = encoder_right.position
# Speed multiplier
speed_multiplier = 5 # Initial value
middle_mouse_down = False
mouse_idle_counter = 0
mouse_idle_timeout = 0.5 # seconds
def press_middle_mouse():
global middle_mouse_down
if not middle_mouse_down:
mouse.press(Mouse.MIDDLE_BUTTON)
middle_mouse_down = True
def release_middle_mouse():
global middle_mouse_down
if middle_mouse_down:
mouse.release(Mouse.MIDDLE_BUTTON)
middle_mouse_down = False
def handle_buttons():
now = time.monotonic()
for b in buttons:
curr = b['io'].value
if curr != b['prev'] and (now - b['last_time']) > debounce_s:
if not curr:
keyboard.press(b['key'])
keyboard.release(b['key'])
b['last_time'] = now
b['prev'] = curr
def handle_encoders():
global last_pos_left, last_pos_middle, last_pos_right
global speed_multiplier, mouse_idle_counter
# Left encoder adjusts speed
new_pos_left = encoder_left.position
delta_left = new_pos_left - last_pos_left
if delta_left != 0:
speed_multiplier += delta_left
speed_multiplier = max(1, min(speed_multiplier, 20)) # Clamp speed
last_pos_left = new_pos_left
print("Speed multiplier:", speed_multiplier)
# Middle and right control mouse
dx = encoder_middle.position - last_pos_middle
dy = encoder_right.position - last_pos_right
if dx != 0 or dy != 0:
press_middle_mouse()
mouse.move(x=dx * speed_multiplier, y=dy * speed_multiplier)
last_pos_middle = encoder_middle.position
last_pos_right = encoder_right.position
mouse_idle_counter = time.monotonic()
elif middle_mouse_down and (time.monotonic() - mouse_idle_counter) > mouse_idle_timeout:
release_middle_mouse()
while True:
handle_buttons()
handle_encoders()
time.sleep(0.01)
Final - CNC
The top plate was programed in Fusion 360 manufacturing
I used a the following toolpaths to get to the final shape:
- 2D Adaptive with a 6mm bit to rough the majority of the material, I left 0.5mm stock on my part.
- 2D pocket with a 6mm bit to rough window for the OLED
-
2D pocket with a 6mm bit to finish the floor of my part
-
2D pocket with a 3mm bit to rough the slots and the holes
-
2D pocket with a 3mm bit to finish the slots and the holes
-
2D contour with a 6mm compression bit to cut the outline of the part, 0.5mm left on the part with a tab on each side
- 2D contour with a 6mm compression bit to finish the outline of the part
Note that I always climb mill for roughing passes and conventional for finishing.
The unfinished assembly, note how the sanding has dulled the bottom of the part.
Final - Finishing and assembly
To finish the wood and the Jesmonite I tried out a few finishes, Osmo Oil, Furniture polish and a brush on wax.
I took some time at this point to make the final top plate.
This was just on our shopbot CNC out of solid Oak using a mix of 3 and 6mm bits
I tested the wax on one of the wood offcuts just to make sure I was happy with the finish.
And the finished piece, The wax was applied thick with a rag and then buffed off.
And the same procedure for the housing.
And we are ready for final assembly.
I had a last minute problem where the switch on the left encoder would not work because it did not have enough room to travel.
This was solved by placing a small piece of scrap PLA in the button to raise it up.
This process has involved a lot of iterations …
Final - Video and documentation
For my video I needed to get some top down shots of using the Nudge
And the final video was shot on my iphone, had some 3D elements produced in Blender and the whole thing was edited in Blender
Thats That
Its been a wild ride.