Tracking Time

Early in the pandemic my employer had us working from home. For the most part this was not an issue. But not having a dedicated office, I found it too easy to lose track of time, and spend too much (in my opinion) time working. With my computer set up in our lounge, it was too easy to check an email, or quickly test something else. It was right there.

There was also no separation that came from cycling/taking the train to or from work. Wake up in the morning, sit down at the desk with breakfast/coffee, start working. Without planned events in the evening, continuing to work was easy.

I have not worked enough (4+ hours). First LED is a status.

In an effort to limit this I once again repurposed my Particle Internet Button to do some time tracking. I’d used Toggl in the past to do some time tracking, but liked the idea of having a visual display available to me, without having to pull out my phone, or install additional applications on my work laptop.

My basic idea was to use the Particle Internet Button as a switch and display mechanism for interfacing with the Toggl API. The main issue I encountered with this approach was that Toggl was enforcing https for their API calls (and rightly so), but there were complications around the available Particle https libraries at the time.

I have worked too much (9+ hours)

Not wanting to spend the time on figuring that out, I somehow convinced myself that I should just spin up my own “Toggl-like” service. Obviously just for me, and not requiring https :) Hopefully my employer doesn’t hack my Wi-Fi to intercept my network comms and make me think I’m working less than I actually am.

And so that’s what I did. I setup a database, and threw together some php scripts to interpret different requests as start and stop commands, also taking a date-time string as a parameter. I expanded it a bit, allowing for different work-id’s, if I want to track different topics, and protected it all behind a nice long ‘key’ to limit the risk of someone messing with my data.

I have worked an appropriate length of times (8+ hours)

The Internet Button itself is round, and has a bunch of RGB LEDs on it. Eleven LEDs lets me use one for a notification, one as a spacer, and the other nine as hours worked increments. The Internet Button does have buttons that can be used as inputs, but instead I chose to use the accelerometer to give me a more intuitive input, without the need for labels.

My beautiful web interface

I 3D printed an octagon-shaped holder for it, which allows me to rotate the internet button to five fixed locations, which are easily distinguished from each other by the accelerometer. If you’re in the central position, the timer stops. If you shift to one of the other four positions, you start the timer associated with that position. In practice I’m only using one, so the other’s are mostly untested for now.

If I don’t have the hardware with me at any time, there’s also a basic web-interface, that allows me to view the entire week’s hours worked, and each stop and start event. I can also add events if I forgot to start or stop at some time.

Page title includes hours worked, and auto-refreshes every 5 minutes

Here you can find a link to a GitHub repo with some associated code: link

Below you can see a video of it working, and interspersed in this article are a couple photos of different stages.

Nike+ Sportwatch Teardown

I bought this watch back in ~2013 and used it track my runs for several years. I recently got an Android watch which also had a built-in GPS, so gave the Nike+ SportWatch to my wife. After a few months of using it, she could no longer download her runs. I wrote about this previously.

With no real use for it, I decided I’d open it up and see what makes it tick.

While iFixit has some nice photo guides to disassemble and replace different components, and someone even replaced the entire USB cable, this video shows a complete teardown and takes a look at some of the components used inside the now defunct Nike+ SportWatch.

The teardown is pretty straightforward. There are 6 screws on the back of the watch, that once cleaned of accumulated dirt come off quite easily. The back then separates from the front, with a half of the strap attached to each.

The back half contains the battery, and the front half the rest of the components and USB cable. The USB cable is soldered to the PCBA, so has to be desoldered to continue the teardown. Another two screws hold the PCBA in place.

The LCD comes straight out, but its backlight is held in place by a melted support that must be cut, and has to be unhooked from the bluetooth antenna. The last thing to open up is the shield can, which has many small, tight tabs holding it in place.

Other info:

  • US design patent US D636,686
  • KCC registration: KCC-REM-NSW-GP132
    • I was hoping there’d be an FCC registration, as then all the testing documentation is available, but I could only find reference to the KCC.

Features:

  • GPS
  • Backlit LCD Screen
  • Tap sensor
  • Lithium Ion battery
  • Built-in USB cable/connector
  • Pairs with:
    • Polar Wearlink + Transmitter (heart rate monitor)
    • Shoepod Nike+ Sensor

Components Used:

  • TI MSP430
    • Main microcontroller
    • Marked as M430V317, unsure which exact spec component it is.
    • 7x7mm BGA, most likely includes the USB interface.
  • NRF 24L01+
    • Bluetooth connection
  • Lithium Ion Battery
    • B&K E332430 170mAh 3.7V 0.63Wh
    • E130910-DV33-11
  • Uknown
    • U4 looks like an IMU, and the watch did have a tap functionality
    • U3 is almost certainly 16Mb of Flash Memory, but unclear which manufacturer.
      • Marking of 2SP16 matches Micron, but the form factor doesn’t
    • The actual GPS circuitry is likely custom TomTom hardware, and not off the shelf components.
Diagram of Nike+ Sportwatch PCBA with main components labelled
Diagram of Nike+ Sportwatch PCBA – rear

Panelizng non-square PCBs in Altium

Note: this guide specifically shows how I panelized boards to manufacturer with JLCPCB, but the process can probably be applied/modified to fit any PCB fab’s requirements. Also, this is what worked for me in ~March 2020, processes may change, always check for the latest information from your PCB Manufacturer.

JLCPCB Panelizing notes: link (More under capabilities: link)
OSHPark Panelizing notes: link

A number of PCB manufacturers offer amazing introductory deals for PCB manufacturing. Often this will have a size restriction, in JLCPCB’s case, less than 100x100mm. If you’re making something considerably smaller than this though, you might be able to get multiple boards within that area. But the PCB fabs won’t do the hard work for you, without charging you extra. So why not do it yourself.


For boring rectangular boards, the standard way to do this is using v-grooves cut with a circular saw. Because a circular saw is used, it is only compatible with rectangularly shaped boards. The alternative for irregularly shaped boards is to route the outline of the board, but leave tabs supporting the PCB relative to a frame, or neighbouring PCBs.

One import thing to keep in mind when panelizing boards is how the board will broken apart, especially if your boards are going to be assembled beforehand. It requires putting stress on the boards, which can damage traces and soldered components. For more info on the practicalities of panelizing, read more here.

If you are using Altium Designer to design your board, below are the steps I followed to generate Gerber files that I submitted to JLCPCB. My aim was to get multiple of my boards within the 100x100mm for JLCPCB. I used Altium Designer 19.

  1. In a PCB file, layout your single board including the planned PCB outline.
First step is to layout a single board. The board I used here is roughly 20mm long and 14mm wide
  1. Create a new PCB file that will contain your panelized design
  2. Set the board shape to be the size of your final panelized design, in my case, 100mmx100mm.
  3. Insert your original PCB design.
    1. Place > Embedded Board Array/Panelize
  1. Push Tab to access the settings
    1. Select your original board under “PCB Document”
    2. Adjust the Column Count, Row Count, and spacing and margin values to get as many of the boards to fit in your limited area. Take into account minimum requirements from your manufacturer, as well as whether you want to have external and/or internal frames around and in between your boards.
As you update the count, spacing and margin values, Altium will update the layout on the board, so you can change these values interactively to find the best fit. You can additionally do some maths with your fab’s recommended specifications to optimize the number of boards you can place.

If you really want to cram boards in, you can experiment with different rotation of boards so that you don’t waste space. This requires importing the board more than once, with a different rotation specified. Additionally, joining boards to each other, instead of to a frame will also save space. In my case, I didn’t need or want hundreds of copies of this board, I just wanted ten or twenty.

  1. You should now see roughly how your boards will be situated.
  2. To allow for better visualization within Altium’s PCB view, we create a “Route Tool Path” layer to place our routing. User a different Layer Type will allow for correct Gerber generation, but not viewing with Altium’s PCB viewer.
  1. Now we want to create the router patterns to separate our PCBs.
    1. Design > Board Shape > Create Primitives From Board Shape
    2. Select the layer that you want the routing to go on: “Route Tool Path”
    3. For the width of the routing, reference the minimum width requirement specified by the PCB fab.
    4. Select “Route Tool Outline”
This step creates the routing paths around all the boards you’ve placed
  1. You should now have a visible routing path around all your individual PCBs. When you switch to PCB view, you’ll see these as empty spaces.
Left shows your panelized PCBs with routed paths. Right shows the generated routing paths in green.
  • Notes:
    • In my example I am separating boards with a frame, if you’re not planning on having a frame, there should be no PCB between each of your boards at this stage.
    • Because these edges are routed, internal angles can’t be perfectly machined, and will have a radius related to your router width
In left image, you can see how your original board outline has a sharp angle, but the generated routing path has a radius. In the right image you can see this curved routing path in the generated PCB view. If this will cause a fitment problem, you need to update your original standalone PCB layout to take the routing into account
  1. Now that we have the boards routed, we need to add in breakaway tabs, also known as mouse-bites. This is just a bit of bridging PCB, that has an edge perforated with little holes to make it easier to break off.
  2. To place these in your design, you need to either make a custom part, or create another PCB design that contains just the holes required for your tab. A custom part is better, but both will work.
    1. If you’re linking boards directly to other boards, you want two rows of holes, if you are linking boards to a frame, you only need one row of boards, inline with the edge of the board.
    2. In my example, I have two rows of holes, even though the boards are linked to a frame
    3. The width of the part/board should be the width of your routed edge.
    4. Hole size and spacing should be on your fab’s recommendations.
This image shows our mouse-bites placed, but still shows routing through the mouse-bite. We need to remove this portion of routing to create the bridging tab.
  1. Based on relative sizes and other factors, you must now decide how many tabs are required to join each of your of your boards, and where they should be located. You must also reference your fab’s recommendations.
    1. For my design I have just two tabs holding each board up.
  2. Once placed, we now have to ‘add’ the material back to support the boards. You can do this by just selecting the relevant part of the route ‘trace’, and either deleting or resizing it.
Comparing this image to the previous one we can see how the routing through the mouse-bite has been removed, creating a tab to support the individual PCB in its panel.
  1. Switch to PCB view and confirm the resultant tab looks correct.
PCB view of our mouse-bitten tab
  1. Now rinse and repeat for all tab locations.

Once you’ve got everything laid out, just make sure to add your entire board outline to your routing layer so they get exported on the same layer. Most fabs expect this. Then all you have to do is export your Gerber files and upload them.

When I actually had the boards manufactured, I only put 5 boards horizontally to a panel of a single row. I also placed the tabs on the sides. As such the below images won’t match what I demonstrated above.

Altium generated view of my panelized PCB

For JLCPCB, this is what my exported board outline layer looked like, as well as how JLCPCB displayed the boards in their Gerber viewer, and how they came out:

What my board outline layer looked like for JLCPCB (Altium Gerber viewer)
How JLCPCB showed my boards after importing
And what the final product looked like

At the same time I had the same boards manufactured with OSH Park. They ask for a slightly different layout. They want the outline of the milled area as opposed to a single trace for the mill. As such the board outline layer looked like this (along with how OSH Park displayed it and how they came out).

What my board outline layer looked like for OSH Park (Altium Gerber viewer)
How OSH Park showed my boards after importing
In the flesh?

OSH Park actually offer to do the tabs themselves. You just provide the milling outline around the entire board, and they’ll add the tabs. I don’t recall this being an option when I had the boards made (~March 2020), but it is on their website (Jan 2021).

Below is another design I had manufactured this year for my Touch Lamp. Here I joined boards directly to each other. Below you can see Altium’s PCB view as well as the final product. To achieve this, I had to import my nominal PCB twice, once for the upright orientation, and once for the upside down orientation. In this case, when I exported the Gerber’s, I did not include the rectangle that went around the entire board, as I didn’t want the little triangles included.

Altium representation of Touch Lamp PCBs
What the PCBs looked like after I had them made (two variants)

If you have any questions, or additional information you think others will find useful, please leave a comment below.


Whitney in Winter

It’s February 2020. You’re excited. You enter the lottery to get permits to hike Mt Whitney. It’s the highest mountain in the contiguous United States. You’ve never been that high before! In March you find out you’ve got a permit for May. There’s some pandemic thing happening, but that’ll totally be resolved by May. You book campsites at Whitney Portal; you book a few nights before at Onion Valley. You’ve got a team ready to go. Time to kick up the training a notch.

Multiple trips to the San Gabriels, culminating in a summit of San Gorgonio two weeks before you’re due to hike Whitney. You hear rumours of permits getting cancelled. You’re nervous, but optimistic. It’s the week before your hike. Your campsites have been cancelled, but oddly not your permit. It’s 5 days before your planned summit. Your permit is revoked. All permits for the rest of the year are already booked. No dice.

Endure 6 months of pandemic…

It’s early November 2020, you’re planning on camping up the 395 for the Thanksgiving week. Permit season has ended, but fire season has devastated the Sierras. Whitney’s still closed.

This image has nothing to do with Whitney, I just needed something to intersperse all the words. It’s taken at the Hot Creek Geological Site, just outside Mammoth Lakes, CA

It’s two weeks before your trip; Whitney is open; permits are being offered for the following week. Ooh. You wait patiently for the week to finish and the following week’s worth of permits to be released. They aren’t…

It’s Wednesday, your trip is planned to start on Sunday. Still no permits for the following week. You phone, they acknowledge its odd, but claim permits will be up the next day most likely. Next day, no permits. You phone Friday, this time they open a reservation spot just for you. You claim the reservation! You phone back minutes later to get them to email you your permit. They do! You have a permit for Monday.

It’s the Thanksgiving week. By some fortune there hasn’t been a snowfall in the Sierras for two weeks, and reports claim the initial season’s snowfall hasn’t been too heavy. You got this.

Parking lot is down there somewhere

Ideally you would have trained for this. You would have planned camping at altitude the few days prior to the summit attempt. You and your wife wouldn’t have to work on the Saturday to ensure work is done for when you get back from your trip. This is not an ideal attempt. But this is probably the only attempt you’re going to get.

Sunday we get a camping spot at Tuttle Creek Campground, just outside Lone Pine. We drive up to the trailhead and take a leisurely stroll. This is all we can do to try acclimatize.

It’s 4am on Monday morning. Time to get up. We met people the day before who had started hiking Whitney at midnight. We met them around 3pm on their way down. Tired but triumphant. We couldn’t imagine starting at midnight. Our bags are pre-packed. Prepared hot water is in the thermos. We top up our oats and eat as we drive up to Whitney Portal. It’s winter, and understandably dark.

While this sign was up at the trailhead, it was clearly old, from when the trails had initially been closed for fires. We had just been given a permit two days prior. When we finished the hike, the sign had been taken down.

04:56 marks our start time. It’s chilly but comfortable. We pick up our WAG bags, gloss over the outdated and yet to be removed “TRAIL CLOSED” sign and start up the trail. Headlights leading the way. Half an hour in we see another vehicle in the parking lot and we have a tail. Half an hour later and we’ve lost them. Concerning :/

To track our pace, and make sure we’d get up and down the mountain safely, I marked down whenever we took a break and how far we’d gone. I was somewhat successful with this on the way up. And on the way down had other things on my mind. Summary at the end of this post.

06:21 we enter the Whitney Zone, 06:48 we hit Outpost Camp. and at 07:25 we’ve done 8.0km of our 18km ascent (then there’s another 18km down). We’re feeling pretty good. We’ve climbed 800m of the planned 2000m.

It’s cold, earlier thoughts of removing base layers disappeared quickly as we ventured deeper into the valleys, and gained altitude. Running streams with hints of cold temperatures are followed by completely frozen lakes, and rock hopping surrounded by ice. But we’re prepared. Gloves stay on. Bandanas and masks that had previously been intended to limit covid transmissibility now do double duty keeping our faces warm. Ice starts to form within our water bottles.

Ice crystals forming

08:48 the sun is well up, but not hitting us. Headlamps are long since forgotten. We just arrived at Trail Camp. It’s empty. We met a couple making their way down half an hour earlier. They’d spent the night at Trail Camp. I do not envy them. Having survived the frigid night, and inspected conditions, they had elected to not summit, and instead head back down to the warmth. What do they know that we don’t?

It starts to snow on us. It’s very weird. The sky is mostly blue with some puffs of cloud. But those puffs of clouds are blessing us with the lightest snow I’ve ever experienced. Weather forecasts predicted clear conditions, and besides these wisps of clouds, the sky is otherwise barren. We forge on. We have switchbacks awaiting us.

It’s an itty bitty snowflake! Look at it!

We break at 10:03 (12.3km). There are a lot of switchbacks. The gradient is extremely steady, and very manageable, but it’s a long way up. A few snowy sections demand caution, but nothing overly dangerous.

At 11:15 we crest the ridge that divides Inyo National Forest from Sequoia National Park. The views down into Sequoia are astonishing. The landscape is incredibly barren, spotted with trees and the most amazing looking frozen lakes. We’ve done 14.3km. We’re at roughly 4200m. Only 5km left, and another 250m of altitude to gain, unfortunately first we have to drop down 100m.

As we’re getting ready to go a guy comes down. He was our tail from 6 hours ago. He’d done the mountaineers route. Enjoyed his time at the top and was on his way down. We’re jealous he made it to the top so fast. It would be nice to be heading down now.

View from the Ridgeline, looking down into Sequoia National Park

We’re both feeling pretty good at this stage. It’s taken us a long time to get here. But we’re not terribly behind schedule. We catch some sunlight here. It’s glorious. Weather forecasts predicted -20 C at the summit. I’ve experienced those temperatures for brief times while skiing, usually followed by some good time in front of the fire. There is no fire here. Even were it to be allowed, there is nothing to burn.

The biggest issue we’ve faced thus far is a slightly upset stomach, a headache, and our camelback nozzles freezing. Not the end of the world. But what do you do when your water freezes. Fortunately the liquid in our packs themselves remained mostly unfrozen. Somehow. Besides our times in the sun, I don’t think we’ve experienced temperatures above freezing the entire day.

But we could keep ourselves warm. Unfortunately we couldn’t control the altitude (I mean we could, but we wanted to get to the top…), and this is when it started to take its toll. The last 2 hours of hiking was some of the least pleasant time I’ve ever experienced. Fatigue. It just killed me.

It doesn’t look cold, but it was

I’ve climbed all the SoCal peaks, but they top out at 3,500m. That’s higher than the highest point in South Africa. For most of my childhood I never spent any time above 2,000m. With only two occasions that I’m aware of to hit 2,900m at the top of the Sani Pass. The highest I’ve ever been outside of an airplane is in the Rocky Mountains, where we got to 3,650m, and we drove to 3,550m, and had a light walk to the top. Now we’re trying to get to 4,400m, and my body is not playing ball.

But we’ve come this far. The weather is good, we’ve got food, we push on. The last two hours are gruelling. And the final few hundred meters have you making your way up a convex crest, never quite sure where the top is. We walk a short way, stop, catch our breaths, continue. We see the hut on the top. I’m too tired to be happy. We sit down in the hut. Relieved more than anything else. We’ve made it.

The sign inside the hut says that the hut will not provide protection from lightning

We force down some food. Drink some water, try to recover. But we’re just so tired. I wish I had felt better. I wish I’d given myself more time to train. I wish we’d spent more nights at altitude before trying to go straight up in one day. I wish for many things. We take some photos. We don’t look happy. I didn’t enjoy the top. I have some photos. The views look amazing. But I was in no state to appreciate it. I want to go back.

We spend only a short time at the top. We still have a long day/night ahead of us. It’s 13:30. We should make it down the sketchiest sections to Trail Camp long before it gets dark. Things to be grateful for. We start the descent.

Happy or pained?

Altitude is one hell of a drug. Going downhill is so much easier. Why couldn’t it all be downhill. We still have a long way to go. But at least I’m not having to stop every few minutes. I’m actually slightly hungry. I’m happy to be enjoying food as opposed to force feeding myself.

We’re down the switchbacks. Tarryn counted them. She got 98. It’s easy to see how someone could count differently. I mean, what really is a switchback. Short breaks to eat and drink, but we’re feeling much better. Struggling to remember how terrible we felt just hours before.

It gets dark and the headlamps are back on. We feel good, but this seems to be taking forever. This path is surprisingly easy to follow in the dark. Like astoundingly. Have to stop once or twice to make sure where the path goes next, but for the most part, just walk and follow the path. I’ve been on countless routes that are harder to follow in the middle of the day.

Surrounded by ice

How is this taking so long? Oh that’s right, it’s just really far.

Ooh someone is following us again. Headlamps are great for being able to spot a tail. The stranger’s light disappears as we go through a wooded section. Stop for another break and zoom! A runner comes flying by. His bright headlamp shining everywhere. Where did he come from? We can’t figure this out. Maybe he did the mountaineers route? He didn’t look kitted out for it, but where else would he have come from? We should have seen him earlier in the day. He checks we’re okay, but doesn’t stop, so there’s no chance to ask.

Rocks

Finally. Finally. Finally, we make the final turn dropping the last few meters to level up with the parking lot. We’re so close. It’s 20:15. It’s been over 15 hours since we left our car here. The “TRAIL CLOSED” sign is down. That’s reassuring. We hop in our car, eat a snack or two and make our way back to our campsite.

At the campsite, I walk to the restroom. I don’t remember this road being an uphill yesterday. Weird. We sleep well. Wake up the next morning and are relieved to be in relatively good condition.

Looking back on it, I’m very glad we took this opportunity to climb Mt. Whitney. Were conditions perfect? No, far from it. It was very cold, we didn’t have the time to prepare and acclimatize like I would have liked. Would I suggest other people do the same thing? Probably not. Often for hikes like these, you’re advised to just come back later. The mountain’s not going anyway. And it’s true. Whitney’s not going anywhere, but sadly we are. We’re most likely not going to have another opportunity to climb Whitney. So I’m glad we took it.

there’s just something about frozen lakes I’ll never get over

For everyone else though, you want to do it earlier in the year. It was at times unpleasantly cold. You want to take time to acclimatize. You don’t want to feel like I did on the summit. I was miserable, I didn’t appreciate it, I couldn’t. Camp at Whitney Portal a night or two before your hike. Hike to Trail Camp and spend a night there. Take your time and enjoy it.

I’ve added a table below with our average speed for different sections of the route. Besides the first section they’re all much slower than I feel I’ve ever hiked before. They obviously also include break times, so are slower than are actual moving averages, but still.