DIY docs rev6, firmware tweaks, software tweaks

This commit is contained in:
Will Toohey
2018-01-25 14:28:52 +10:00
parent 33a69dcf9a
commit d7a756be80
40 changed files with 31635 additions and 73 deletions
+20 -42
View File
@@ -3,61 +3,39 @@
Run through this guide once before building, ensuring you have all the parts required. You'll also need a soldering iron and solder.
## LEDs
First up, the LEDs.
## Acrylic
**STOP NOW!** I *know* it's tempting, but don't peel off the protective backing from all the acrylic yet.
Once it's off, the pieces attract dust, which can make the rear look messy.
![leds](img/2_leds.jpg)
**WARNING:** The top 2 plates (those with encoder holes) are fragile and easily snap if dropped. Take care when assembling. Once assembled, they are protected by the rest of the controller and should not break.
Take note, each LED point on the board has labelled connections for R, G and B. The long leg on the LEDs goes into the unmarked (ground) hole.
Take off the protective backing from the top clear acrylic.
Take your top clear plate and top black plate and place them over the LEDs. Take note of the clear plate - it has engraved edges for optimal lighting. It can be installed with the edges up or down, but they look best when facing up.
![topRing](img/2_top.jpg)
![topRing](img/3_top_engrave.jpg)
![ledLegs](img/3_ledLegs.jpg)
Insert the LEDs roughly to the red line, then bend them over:
![ledBend](img/4_ledBend.jpg)
![ledBendComplete](img/5_ledBendComplete.jpg)
Work on a slightly raised surface and place the board face down to solder, with the MACRO switch off the edge. This ensures all the LEDs are flush with the board surface.
![ledSandwich](img/6_ledSandwich.jpg)
I recommend soldering one leg of each LED to keep it in place, then cutting off all the leads. This makes soldering the rest of the connections much easier.
The bend doesn't have to be perfect - the acrylic will diffuse the light.
![ledSolder](img/7_ledSolder.jpg)
## Encoders
You can solder the encoders now or after you install the switches, but I prefer to do them sooner. Solder one of the small pins to keep it in place then pump lots of solder into the big connecting lugs. These need to take your abuse, so make it a good joint!
![encoders](img/8_encoders.jpg)
Use the 1.5mm Allen key provided to screw the board together.
Insert the top 8 bolts and 8 long nuts into the holes provided.
![nutsNbolts](img/4_top_stack.jpg)
## Switches
**STOP NOW!** Have you finished soldering your LEDs? Have you tested them?
Once you have soldered the switches you cannot fix anything without desoldering
them again.
**WARNING:** The top 2 plates (those with encoder holes) are fragile and easily snap if dropped. Take care when assembling. Once assembled, they are protected by the rest of the controller and are much stronger.
Take your top clear plate and top black plate and place them over the LEDs. Take note of the clear plate - it has engraved edges for optimal lighting. It can be installed with the edges up or down, but they look best when facing up.
![topRing](img/9_topRing.jpg)
Insert all your switches, and make sure they are seated properly. They are meant to be a tight fit into the PCB and should be completely flush with the surface.
![switches](img/10_switches.jpg)
![switches](img_old/10_switches.jpg)
Solder the switches. I solder with the back plate on, with its protective backing. This prevents flux from splashing over your board.
![protec](img/5_presolder.jpg)
## Nuts and bolts
Use the 1.5mm Allen key provided to screw the board together.
Insert the top 8 bolts and 8 long nuts into the holes provided. Take note, there are 3 holes in the PCB that are unused. These nuts can sometimes be a tight fit - you may need to push them into the case with a hard surface.
![nutsNbolts](img/11_nutsNbolts.jpg)
Stack the bottom 2 plates and insert the remaining 8 bolts. Take care to align the cutout over the USB port. The bolts are a fraction too short, you may need to back off the top bolts by about 2 turns to get the nut close enough.
![acrylicDone](img/12_acrylicDone.jpg)
## Rubber feet
Stack the bottom 2 plates after removing their protective backing and insert the remaining 8 bolts.
Take care to align the cutout over the USB port.
Attach your 6 adhesive rubber feet. You can place these anywhere, but here is where I put them:
![feet](img/13_feet.jpg)
![acrylicDone](img/6_rear.jpg)
# Final touches
Using the Allen key provided, attach the knobs. The encoder shaft is shaped like a D - ensure you tighten the grub screw on the flat part of the D.
*Optional:* Add 7 o-rings to your keycaps.
*Optional:* Add 7 o-rings to your keycaps to make them quieter.
Install keycaps by simply pushing them onto the switches.
![done](img/14_done.jpg)
![done](/ProductShot.jpg)
+63
View File
@@ -0,0 +1,63 @@
# Assembly
![parts](img_old/1_parts.jpg)
Run through this guide once before building, ensuring you have all the parts required. You'll also need a soldering iron and solder.
## LEDs
First up, the LEDs.
![leds](img_old/2_leds.jpg)
Take note, each LED point on the board has labelled connections for R, G and B. The long leg on the LEDs goes into the unmarked (ground) hole.
![ledLegs](img_old/3_ledLegs.jpg)
Insert the LEDs roughly to the red line, then bend them over:
![ledBend](img_old/4_ledBend.jpg)
![ledBendComplete](img_old/5_ledBendComplete.jpg)
Work on a slightly raised surface and place the board face down to solder, with the MACRO switch off the edge. This ensures all the LEDs are flush with the board surface.
![ledSandwich](img_old/6_ledSandwich.jpg)
I recommend soldering one leg of each LED to keep it in place, then cutting off all the leads. This makes soldering the rest of the connections much easier.
The bend doesn't have to be perfect - the acrylic will diffuse the light.
![ledSolder](img_old/7_ledSolder.jpg)
## Encoders
You can solder the encoders now or after you install the switches, but I prefer to do them sooner. Solder one of the small pins to keep it in place then pump lots of solder into the big connecting lugs. These need to take your abuse, so make it a good joint!
![encoders](img_old/8_encoders.jpg)
## Switches
**STOP NOW!** Have you finished soldering your LEDs? Have you tested them?
Once you have soldered the switches you cannot fix anything without desoldering
them again.
**WARNING:** The top 2 plates (those with encoder holes) are fragile and easily snap if dropped. Take care when assembling. Once assembled, they are protected by the rest of the controller and are much stronger.
Take your top clear plate and top black plate and place them over the LEDs. Take note of the clear plate - it has engraved edges for optimal lighting. It can be installed with the edges up or down, but they look best when facing up.
![topRing](img_old/9_topRing.jpg)
Insert all your switches, and make sure they are seated properly. They are meant to be a tight fit into the PCB and should be completely flush with the surface.
![switches](img_old/10_switches.jpg)
## Nuts and bolts
Use the 1.5mm Allen key provided to screw the board together.
Insert the top 8 bolts and 8 long nuts into the holes provided. Take note, there are 3 holes in the PCB that are unused. These nuts can sometimes be a tight fit - you may need to push them into the case with a hard surface.
![nutsNbolts](img_old/11_nutsNbolts.jpg)
Stack the bottom 2 plates and insert the remaining 8 bolts. Take care to align the cutout over the USB port. The bolts are a fraction too short, you may need to back off the top bolts by about 2 turns to get the nut close enough.
![acrylicDone](img_old/12_acrylicDone.jpg)
## Rubber feet
Attach your 6 adhesive rubber feet. You can place these anywhere, but here is where I put them:
![feet](img_old/13_feet.jpg)
# Final touches
Using the Allen key provided, attach the knobs. The encoder shaft is shaped like a D - ensure you tighten the grub screw on the flat part of the D.
*Optional:* Add 7 o-rings to your keycaps.
Install keycaps by simply pushing them onto the switches.
![done](img_old/14_done.jpg)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 KiB

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Before

Width:  |  Height:  |  Size: 190 KiB

After

Width:  |  Height:  |  Size: 190 KiB

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 140 KiB

Before

Width:  |  Height:  |  Size: 281 KiB

After

Width:  |  Height:  |  Size: 281 KiB

Before

Width:  |  Height:  |  Size: 173 KiB

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

Before

Width:  |  Height:  |  Size: 225 KiB

After

Width:  |  Height:  |  Size: 225 KiB

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 105 KiB

Before

Width:  |  Height:  |  Size: 468 KiB

After

Width:  |  Height:  |  Size: 468 KiB

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Before

Width:  |  Height:  |  Size: 175 KiB

After

Width:  |  Height:  |  Size: 175 KiB

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 92 KiB

@@ -63,9 +63,9 @@ def get_device_handle(context):
# because there is the pseudo-composite-parent we ignore
try:
voltex = dev.open()
print "Open success!"
print("Open success!")
except:
print "Open fail"
print("Open fail")
return voltex
def bootloader_boot(device):
@@ -93,13 +93,13 @@ def program_device(hex_data, device_info):
# page sized chunks
for addr in range(0, hex_data.maxaddr(), device_info['page_size']):
# Compute the address range of the current page in the device
current_page_range = range(addr, addr+device_info['page_size'])
current_page_range = list(range(addr, addr+device_info['page_size']))
# Extract the data from the hex file at the specified start page
# address and convert it to a regular list of bytes
page_data = [hex_data[i] for i in current_page_range]
print("Writing address 0x%04X-0x%04X" % (current_page_range[0], current_page_range[-1]))
print(("Writing address 0x%04X-0x%04X" % (current_page_range[0], current_page_range[-1])))
# Devices with more than 64KB of flash should shift down the page
# address so that it is 16-bit (page size is guaranteed to be
Binary file not shown.
+2 -2
View File
@@ -14,8 +14,8 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM LEDReport[] =
// Globals
HID_RI_REPORT_COUNT(8, LED_TOTAL_COUNT),
HID_RI_REPORT_SIZE(8, 8),
HID_RI_LOGICAL_MINIMUM(8, 0),
HID_RI_LOGICAL_MAXIMUM(8, BRIGHTNESS_MAX),
HID_RI_LOGICAL_MINIMUM(16, 0),
HID_RI_LOGICAL_MAXIMUM(16, BRIGHTNESS_MAX),
HID_RI_USAGE_PAGE(8, 0x0A), // Ordinals
// Locals
+9 -1
View File
@@ -46,6 +46,10 @@ test: all
cat TestingApp.hex | grep -v '^:00000001FF' > TestFull.hex
cat DFU/BootloaderUSB.hex >> TestFull.hex
$(TARGET)_WithBoot.hex: $(TARGET).hex
cat $(TARGET).hex | grep -v '^:00000001FF' > $(TARGET)_WithBoot.hex
cat DFU/BootloaderUSB.hex >> $(TARGET)_WithBoot.hex
debug: CC_FLAGS += -DDEBUG
debug: clean flash
@@ -55,7 +59,8 @@ rev4: clean all
initboot: erase wfuse flashboot
initboot_rev4: erase wfuse flashboot_rev4
init: initboot flash
init: $(TARGET)_WithBoot.hex
$(AVRDUDE) -U lfuse:w:0xde:m -U hfuse:w:0xda:m -U efuse:w:0xfe:m -U flash:w:$(TARGET)_WithBoot.hex:i
init_rev4: initboot_rev4 disablereset flash
erase:
@@ -80,6 +85,9 @@ flashboot:
flash: all
cd DFU && python control_bootloader.py atmega16u2 ../$(TARGET).hex
flash_with_boot: $(TARGET)_WithBoot.hex
$(AVRDUDE) -U flash:w:$(TARGET)_WithBoot.hex:i
testflash: test wfuse
$(AVRDUDE) -U flash:w:TestFull.hex:i
+8
View File
@@ -0,0 +1,8 @@
@echo off
:loop
make init
IF %ERRORLEVEL% EQU 0 (
echo Success!
ping -n 5 127.0.0.1 >nul
)
goto loop
+11 -1
View File
@@ -64,4 +64,14 @@ Extensions->Modify Path->Flatten Beziers (flatness 0.1)
Save as -> Desktop cutting plotter dxf
Use LWPOLYLINE
Base unit mm
Visible layers only
Visible layers only
Finally, once it's inside RDWorks - Select all, Handle->Curve auto close, "Force to close"
Otherwise, you will get rendering errors on some letters
Best engraving - very thin circles - cut, 150mm/s, 14%
- POCKET VOLTEX and MACRO text - engrave, 240mm/s, 17%
- rest - engrave, 240mm/s, 15%
- cutting - 14mm/s, 70%
Don't forget 0.05mm interval for engrave
+1
View File
@@ -88,6 +88,7 @@ module render() {
bottom_padding();
color([0.3,0.3,0.3,0.9])
translate([0, 0, 150]) // raise it up to see the board
translate([0, 0, 25.5])
linear_extrude(padding_thickness)
padding();
+28 -7
View File
@@ -2,7 +2,7 @@ use <imports/cherry_mx.scad>
include <imports/mx_keycap.scad>
key_profile_index = 11;
$fn = 64;
$fn = 512;
black = [0.1,0.1,0.1];
blue = [0,0.6,1];
@@ -55,7 +55,7 @@ wallOverlap = 1;
boltDiam = 2;
boltFudge = 0.1;
boltSize = boltDiam + boltFudge;
spacerSize = boltSize + 1 + fudge; // extra wiggle
spacerSize = boltSize + 1.7 + fudge; // extra wiggle
boltExpand = boltDiam;
@@ -94,6 +94,7 @@ module switch(holetype){
square([holesize+2*cutoutwidth,holesize-2]);
}
} else {
offset(delta = 0.5) // so plate clips can latch
square([holesize,holesize]);
}
}
@@ -152,13 +153,33 @@ module bolts_expansion() {
bolt_spacers();
}
module encoders() {
for(enc = encoders) {
translate([enc[0], enc[1]])
circle(r=encoderRadius, center = true);
module enc_smooth() {
translate([-10, -9.777])
difference() {
rotate(-54)
translate([-2,0.19])
square([4, 2], center=true);
circle(d=2);
}
}
module enc_single() {
translate([encoders[0][0], encoders[0][1]]) {
circle(r=encoderRadius, center = true);
// smooth harsh edges
enc_smooth();
mirror([0,1])
enc_smooth();
}
}
module encoders() {
enc_single();
mirror([1,0])
enc_single();
}
module encoder_holes() {
for(enc = encoders) {
translate([enc[0], enc[1]]) {
@@ -440,7 +461,7 @@ module fiducials() {
}
}
// override in commandline
build = "render";
build = "bottom_spacer";
enable_fiducials = 0;
if(build == "render") {
full_stack();
+31398
View File
File diff suppressed because it is too large Load Diff
+20
View File
@@ -37,6 +37,26 @@ body, html {
font-size: 40pt;
}
.board {
cursor: pointer;
max-width: 50%;
}
#boardSelector {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#boardSelector.hidden {
display: none;
}
.big {
font-family: sans-serif;
font-size: 30pt;
}
.configOptions {
display: flex;
flex-wrap: wrap;
+14 -3
View File
@@ -1,5 +1,16 @@
{
"version": 14,
"md5": "a07ab17b2ac21c9e0f165eac30f40e99",
"changelog" : "Add support for e-AMUSEMENT CLOUD native input"
"4" :
{
"version": 14,
"board" : 4,
"md5": "a07ab17b2ac21c9e0f165eac30f40e99",
"changelog" : "Add support for e-AMUSEMENT CLOUD native input"
},
"6" :
{
"version": 14,
"board" : 6,
"md5": "3fc03bf512c04e26a67825ba22a9eac2",
"changelog" : "Batch 2 shipping firmware"
}
}

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 144 KiB

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

+11 -3
View File
@@ -11,11 +11,16 @@
<script type="text/javascript" src="js/md5.min.js"></script>
<script type="text/javascript" src="js/jscolor.min.js"></script>
<script type="text/javascript">
// because I am bad
if (location.protocol != 'https:' && location.hostname != "localhost" && location.hostname != "127.0.0.1") {
location.href = 'https:' + window.location.href.substring(window.location.protocol.length);
}
window.addEventListener("load", function() {
UsbWrapper_init();
if(UsbWrapper.hasUSB) {
document.getElementById("compat-failure").classList.add("hidden");
document.getElementById("connectBtn").classList.remove("hidden");
document.getElementById("logview").classList.remove("hidden");
config = new Config();
@@ -35,8 +40,6 @@
}
});
</script>
<!-- Origin Trial Token, feature = WebUSB (For Chrome M57+), origin = https://mon.im, expires = 2017-07-17 -->
<meta http-equiv="origin-trial" data-feature="WebUSB (For Chrome M57+)" data-expires="2017-07-17" content="AtfCI+37VRHohPe+OASF7EuEDM1ZhH6Dr1W2je8iRI885ETbV5VT/RGnIyg06SGJiGUgNrl20HrAH47shlEyjwsAAABHeyJvcmlnaW4iOiJodHRwczovL21vbi5pbTo0NDMiLCJmZWF0dXJlIjoiV2ViVVNCMiIsImV4cGlyeSI6MTUwMDMwMjYwNn0=">
</head>
<body>
<div class="center">
@@ -44,12 +47,17 @@
This configurator requires Javascript, Windows 7+ (or OSX/Linux) and a WebUSB capable browser (Chrome 57+). If you lack these, harass mon for an exe config app.
</div>
<div>
<div id="logview"></div>
<div id="logview" class="hidden"></div>
<!--<div id="configBox" class="configBox hidden disabled">
</div>-->
<div id="connect" class="connect">
<button id="connectBtn" class="hidden" onclick="config.connectNew()">Connect</button>
</div>
<div id="boardSelector" class="hidden">
<div class="big">Select your board:</div>
<img class="board" src="img/r6-topdown-small.png" onclick="config.selectBoard(6);">
<img class="board" src="img/r4-topdown-small.png" onclick="config.selectBoard(4);">
</div>
<div id="configOptions" class="configOptions">
</div>
</div>
+32 -7
View File
@@ -40,7 +40,7 @@ var configDisplay = [
{id: 'knobR', name: 'VOL-R colour'},
]},
{id: 'lightPattern', name: 'Lights pattern',
options : [{name: 'None', val : 1},
options : [{name: 'None', val: 1},
{name: 'Solid', val: 2},
{name: 'Breathe', val: 4},
{name: 'Follower', val: 3}]},
@@ -216,7 +216,11 @@ class Config {
})
.then(() => {
if(device.deviceVersionSubminor == 2) { // bootloader
return this.loadFirmware();
if(this.board) {
return this.loadFirmware();
} else {
document.getElementById('boardSelector').classList.remove('hidden');
}
} else if(device.deviceVersionSubminor == 3) { // main program
return this.loadConfig();
} else {
@@ -231,9 +235,22 @@ class Config {
});
}
selectBoard(board) {
this.board = board;
document.getElementById('boardSelector').classList.add('hidden');
this.loadFirmware()
.catch(error => {
//alert(error);
visibleLog(error);
if(device && device.opened)
device.close();
});
}
loadFirmware() {
visibleLog("Downloading fimware...");
return getLatest()
return getLatest(this.board)
.then(downloadLatest)
.then(firmware => {
visibleLog("Flashing firmware...");
@@ -252,9 +269,10 @@ class Config {
return this.readVersion();
})
.then(version => {
this.version = version;
visibleLog("Found Pocket Voltex v" + version/10.0);
return getLatest();
this.version = version.fw;
this.board = version.board;
visibleLog("Found Pocket Voltex v" + this.version/10.0);
return getLatest(this.board);
})
.then(latestInfo => {
if(latestInfo.version > this.version) {
@@ -282,7 +300,13 @@ class Config {
console.log(result);
console.log("Got version response of len", result.data.buffer.byteLength);
// version int exists at offset 1
return result.data.getUint16(1, true);
let fwVersion = result.data.getUint16(1, true);
let boardRevision = result.data.getUint16(3, true);
if(boardRevision == 0xDEAD) {
boardRevision = 4;
}
console.log('ver:board', fwVersion, boardRevision);
return {fw: fwVersion, board: boardRevision};
})
}
@@ -350,6 +374,7 @@ class Config {
disableUI() {
visibleLog('Device disconnected');
document.getElementById('connect').classList.remove('hidden');
document.getElementById('boardSelector').classList.add('hidden');
this.optionsDiv.innerHTML = '';
}
};
+14 -3
View File
@@ -13,7 +13,7 @@ var WEBUSB_ID = 0x01;
var MS_OS_ID = 0x02;
var CONFIG_ID = 0x03;
function getLatest() {
function getLatest(version) {
return new Promise ((resolve, reject) => {
var req = new XMLHttpRequest();
req.open("GET", "firmwares/latest.json", true);
@@ -21,11 +21,19 @@ function getLatest() {
req.onload = function (oEvent) {
if (req.response) {
resolve(req.response);
let res = req.response[version];
if(res) {
resolve(req.response[version]);
} else {
reject('Could not find firmwares for board rev:' + version);
}
} else {
reject(Error(req.status + ": Could not fetch latest firmware information"));
}
};
req.onerror = function() {
reject(Error(req.status + ": Could not fetch latest firmware information"));
}
req.send();
});
@@ -34,7 +42,7 @@ function getLatest() {
function downloadLatest(versionInfo) {
return new Promise ((resolve, reject) => {
var req = new XMLHttpRequest();
req.open("GET", "firmwares/PocketVoltex_" + versionInfo.version + ".bin", true);
req.open("GET", "firmwares/PocketVoltex_" + versionInfo.board + "_" + versionInfo.version + ".bin", true);
req.responseType = "arraybuffer";
req.onload = function (oEvent) {
@@ -53,6 +61,9 @@ function downloadLatest(versionInfo) {
reject(Error(req.status + ": Could not fetch firmware version " + versionInfo.version));
}
};
req.onerror = function() {
reject(Error(req.status + ": Could not fetch firmware version " + versionInfo.version));
}
req.send();
})