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 2 - CAD

Week 5 - 3D printing and scanning

Week 9 - Inputs

Week 10 - Outputs

Week 11 - Networking

Week 13 - Moulding and Casting

Week 14 - Interface and Applications

Week 16 - Wild Card Week(Carry Case)

System Integration:


Week 15 - System Integration


Click for weekly

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

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.

8


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

Back to top

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

8

And sketching around this idea to develop my forms.

8

8

And also visiting my local music shop to have a play around with things.

8 8 8 8

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

Back to top

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

Back to top

Test from week 10

Prototype of the housing

Prototype of the user inputs




Final project development

Back to top

The aesthetic of the design was further refined in week 15.

And the materials nailed down.

Giving it a name

Back to top

All products need a name and this is the one I landed on!

Helping nudge your models to the right angle

Final - CAD design

Back to top

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

Back to top

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

Back to top

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

Back to top

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.

AI Chat Logs

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

Back to top

Its been a wild ride.




Final files

2D Files

3D Files

EDA File

Code

AI Chat Logs


End

Back to top