Drive Wheelchair Brake Knob

The bent-steel brake levers on our Drive Blue Streak wheelchair present themselves edge-on to the rider:

Drive Wheelchair Brake
Drive Wheelchair Brake

There are good mechanical reasons for shaping and orienting the steel like that, but the handle concentrates the considerable force required to push the brake tab into the rubberoid tire on your (well, my) palms. After a couple of weeks, I decided I didn’t need two more sore spots and conjured a palm-filling knob from the vasty digital deep:

Wheelchair Brake Knob - installed
Wheelchair Brake Knob – installed

Bonus part: the little octagon near the wheel prevents the leg rest (seen in the first picture) from smashing into the end of the brake tab and chipping the lovely blue powder coat. The brown fuzzy felt foot seemed like a good idea at the time, but isn’t strictly necessary.

A cylindrical handle on Thingiverse apparently fits on the bare steel underneath the rubberish “cushion”, but cutting a perfectly good, albeit uncomfortable, cushion off seemed like a step in the wrong direction. My knob thus descends from a doodle of the OEM dimensions:

Drive Wheelchair Brake Handle - dimensions
Drive Wheelchair Brake Handle – dimensions

The knob builds in two halves adjoining the bonus octagon, which stands on edge to eliminate support inside its slot:

Wheelchair Brake Mods - solid model - build layout
Wheelchair Brake Mods – solid model – build layout

You (probably) need two of all those shapes, a job your slicer is ready to perform. At three hours for each knob, I just printed the same G-Code twice.

You can customize the knob width to fit your palm, with the other two dimensions fitting themselves around the cushion. Mary and I settled on a knob size that fits both our hands reasonably well, so it’s probably not critical.

I tried building the knob halves without support for the first prototype, but the sloped upper surface produced awful bridging:

Wheelchair Brake Knob - unsupported interior
Wheelchair Brake Knob – unsupported interior

It’s easy enough to design a customized support structure:

Wheelchair Brake Mods - cross section
Wheelchair Brake Mods – cross section

I oriented the knob to put the split on the narrow sides of the brake handle in order to not have a seam facing my palm:

Wheelchair Brake Knob - rear half installed
Wheelchair Brake Knob – rear half installed

The quartet of M3×20 mm socket-head cap screws thread into brass inserts epoxied into the rear half. I recessed their heads deeply into the front half and avoided thinking too hard about plugs matching the surface curvature:

Wheelchair Brake Knob - front view
Wheelchair Brake Knob – front view

The low-vertex-count polygonal shape is a stylin’ thing and produces a nice feel during a firm shove, at least to my paws. Although I’d rather not need a wheelchair at all, setting the brakes now seems authoritative instead of annoying.

The OpenSCAD source code as a GitHub gist:

// Pride wheelchair brake lever mods
// Ed Nisley KE4ZNU 2020-11
/* [Layout options] */
Layout = "Build"; // [Build, Show, Fit, TabCap, Handle, Knob, Support]
// Hold up the knob's inside
Support = true;
/* [Extrusion parameters] */
/* [Hidden] */
ThreadThick = 0.25;
ThreadWidth = 0.40;
HoleWindage = 0.2;
function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
function IntegerLessMultiple(Size,Unit) = Unit * floor(Size / Unit);
Protrusion = 0.1; // make holes end cleanly
inch = 25.4;
ID = 0;
OD = 1;
LENGTH = 2;
//----------------------
// Useful routines
module PolyCyl(Dia,Height,ForceSides=0) { // based on nophead's polyholes
Sides = (ForceSides != 0) ? ForceSides : (ceil(Dia) + 2);
FixDia = Dia / cos(180/Sides);
cylinder(r=(FixDia + HoleWindage)/2,h=Height,$fn=Sides);
}
//* [Basic dimensions] */
WallThick = 4.0; // min wall thickness
Screw = [3.0,5.5,20.0]; // thread, head, length under head
Insert = [3.0,4.1,8.0]; // thread, knurl, length
//----------------------
// Brake tab cap
BrakeTab = [15,21,3.1]; // length to wheel, width, thickness
BrakeTabSagitta = 8.0; // height of curved endcap
CapOAL = [BrakeTab.y + 2*WallThick,BrakeTab.y + 2*WallThick,BrakeTab.z + 2*WallThick];
module TabCap() {
difference() {
rotate(180/8)
cylinder(d=CapOAL.y,h=CapOAL.z,center=true,$fn=8);
translate([BrakeTab.x/2,0,0])
cube(BrakeTab,center=true);
rotate(180/8)
cylinder(d=BrakeTab.y/cos(180/8),h=BrakeTab.z,center=true,$fn=8);
}
}
//----------------------
// Brake lever handle
// Soft covering with rounded sides that we square off for simplicity
HandleRibs = [15,34,14]; // ignoring slight taper from end
HandleCore = [50.0,24.0,12.0]; // straight section of lever to top of ribs
HandleTipWidth = 30.0; // ignoring actual sector height
module Handle() {
union() {
hull() {
rotate(180/8)
cylinder(d=HandleTipWidth/cos(180/8),h=HandleCore.z,center=true,$fn=8);
translate([-HandleCore.x/2,0,0])
cube(HandleCore,center=true);
}
translate([-(3*HandleCore.x/2 - Protrusion),0,0]) // extend base for ball trimming
cube(HandleCore,center=true);
translate([-HandleRibs.x/2,0,0])
cube(HandleRibs,center=true);
}
}
//----------------------
// Support structure for handle cavity inside knob
// Totally ad-hoc tweakage
// Remember it's lying on its side to match the handle
NumRibs = 2 + 1; // must be odd
RibSpace = floor(HandleCore.z/(NumRibs + 1));
module KnobSupport() {
color("Yellow") { // support overlaps in the middle
render(convexity=3)
intersection() {
for (k=[-1,1])
translate([0,k*ThreadThick,0]) // shrink inward to break adhesion
Handle();
translate([(HandleCore.x - HandleRibs.x)/2 - HandleCore.x - Protrusion,0,0])
cube([HandleCore.x - HandleRibs.x,HandleRibs.y,HandleCore.z],center=true);
union()
for (k=[-floor(NumRibs/2):floor(NumRibs/2)])
translate([0,0,k* RibSpace])
cube([2*HandleCore.x,HandleRibs.y,2*ThreadWidth],center=true);
}
translate([(HandleCore.x - HandleRibs.x)/2 - HandleCore.x,0,0])
cube([HandleCore.x - HandleRibs.x,4*ThreadWidth,NumRibs*RibSpace],center=true);
}
}
//----------------------
// Brake handle knob
// Largely built with magic numbers
// Includes support because it's not really optional
KnobOD = 55.0;
KnobOffset = HandleRibs.x/1;
KnobSides = 2*4*3;
module Knob() {
difference() {
hull() {
resize([0,HandleRibs.y + 4*WallThick,HandleCore.x + HandleTipWidth/2 + WallThick])
sphere(d=KnobOD,$fn=KnobSides);
}
translate([0,0,KnobOffset])
rotate([0,-90,0])
Handle();
for (i=[-1,1],k=[-1,1])
translate([i*KnobOD/4,0,k*KnobOD/4]) {
rotate([90,0,0])
PolyCyl(Insert[OD],1.5*Insert[LENGTH],6);
translate([0,-Screw[LENGTH]/2,0])
rotate([-90,0,0])
PolyCyl(Screw[ID],KnobOD,6);
translate([0,Screw[LENGTH] - Insert[LENGTH],0])
rotate([-90,0,0])
PolyCyl(Screw[OD],KnobOD,6);
}
}
if (Support)
translate([0,0,KnobOffset])
rotate([0,-90,0])
KnobSupport();
}
//----------------------
// Lash it together
if (Layout == "TabCap") {
TabCap();
}
if (Layout == "Handle") {
Handle();
}
if (Layout == "Support") {
KnobSupport();
}
if (Layout == "Knob") {
Knob();
}
if (Layout == "Show") {
translate([60,0,0])
TabCap();
Knob();
}
if (Layout == "Fit") {
translate([60,0,0])
difference() {
TabCap();
translate([0,0,CapOAL.z/2])
cube(CapOAL,center=true);
}
difference() {
Knob();
translate([KnobOD + KnobOD/4,0*KnobOD,0])
cube(2*KnobOD,center=true);
translate([-KnobOD,-KnobOD,0])
cube(2*KnobOD,center=true);
}
}
if (Layout == "Build") {
translate([KnobOD/2,0,(CapOAL.y*cos(180/8))/2])
rotate([0,-90,90])
TabCap();
for (j=[-1,1])
translate([0,-j*0.75*HandleCore.x,0])
difference() {
rotate([j*90,0,0])
Knob();
translate([0,0,-KnobOD])
cube(2*KnobOD,center=true);
}
}

A doodle with dimensions of other parts:

Drive Wheelchair - brake footrest tab dimensions
Drive Wheelchair – brake footrest tab dimensions

The angled tab on the middle left is for the leg rest release latch, but I decided not to silk-purse-ize the thing.