Ride Notes for Cool Breeze 2015

Today I completed the Cool Breeze Century in Ventura, CA, which was organized by the Channel Islands Bicycle Club (CIBC). This century ride was billed by the CIBC as: "102 miles with about 4000 feet of climb - moderately challenging, [and] excellent for 1st time centurions." This was my fourth century ride within the past nine months, and despite its advertised status as an excellent ride for "first-time century riders," I think it was one of the more-difficult long distance rides that I have done.

I participated in this century ride with my good friend Kevin, who lives in the Los Angeles area. Kevin told me a few weeks ago that he had signed up for this ride, and at the last minute I invited myself along. Since I live in Arizona, however, this meant that I had to endure a ten-hour drive through the desert to LA on the day before the ride. Nevertheless I met up with Kevin in Ventura on the night before the ride, and we put together our plans for the next day.

We both got up early as planned, and I drove the two of us to the starting point near the Ventura Unified School District offices, where we arrived around 6:15am. (We were one of the last cars to get a great spot in the main parking lot.) We quickly pulled into a parking space, and then Kevin and I put together the last of our things for the day's ride. After a few minutes of deciding what to bring and what to leave, we headed off toward the starting line around 6:30am. In keeping with the spirit of this ride as a "non-race event," there was very little fanfare at the starting line - we simply rode past a set of banners with dozens of other cyclists and we were off.

Prepping the last of our gear for the day.
Last-minute selfie before heading out.
Approaching the starting line.

I should point out before I go any further that I immediately appreciated how well-marked the route was throughout the day; there were route signs everywhere for the duration of the ride. (This was a great improvement over some other rides where you periodically wondered if you had accidentally left the route.) All of the route signs were emblazoned with color-coded arrows that matched the cue sheet that cyclists were given when they registered, so as long as cyclists followed the correctly-colored arrows throughout the day, they were going the right way. One discrepancy that Kevin and I noticed was that the cue sheet that we had been given only listed 97 miles for the length, which was five miles shorter than the 102 miles that was advertised for the ride. I told Kevin not to worry - I had my Garmin GPS with me, and we could use it to verify the ride length when the time came.

One of the many color-coded route signs
which were scattered throughout the route.

For the first 2.5 miles our route ran south along highway 33 in Ventura, but soon after that we were riding west along the beach trail by the ocean, which was great; this section of the course was what I thought a ride through California should be.

Panorama of the ocean as we rode along the beach.
(Note Rincon Island in the background.)

We were nine miles into the ride and cruising nicely along the beach when I suddenly heard a "Klank! Klank! Klank!" from immediately behind me. My initial thought was that something had fallen off my bicycle, but then I realized that the sound was coming from my rear wheel. I pulled to a stop, and after a quick examination I determined that my bike had broken a spoke. I have no idea how it happened; I didn't ride over anything like a branch that could get tangled up in my spokes - apparently it just snapped. It took me a few minutes of wrangling to bend the broken spoke into a position that would allow me to extricate it from my wheel, but I eventually managed to wrench it out and we quickly got back on the road. (Although I could hear the spoke nipple rattling around inside my rim for the rest of the ride.)

Kevin and I passing a photographer at 7:30am.
(Note that this single photo represents the only
time that we saw photographer during the ride.)

We were a little over an hour and 15 miles into the ride when we reached our first stop of the day, which was at Rincon Beach Park. After a quick ten-minute break to refill our water bottles, Kevin and I got back on the road.

Kevin posing behind my bike.
Displaying my usual "hang ten" pose.

Our route took us north and inland as we left Rincon Beach Park, which kept us away from the water for the next eight miles or so. Over the next mile or so we faced our first climbs of the day, which were relatively short and nothing too difficult to worry about. After a few climbs and descents, we were mostly riding downhill as we rode to the west for the next few miles.

That being said, before the ride I studied the profile on the Ride with GPS website, which the ride organizers were kind enough to share online. With that in mind, I knew that we were rapidly approaching the most-difficult climbs for the day. Apparently I was not the only cyclist to have studied the course in advance, because shortly after we passed the 25-mile mark we faced the first serious climb and several cyclists loudly remarked, "Oh - this is the hill."

Route Map and Elevation Profile for the Century Ride.

I'll be honest - this climb was moderately difficult, and thankfully it only lasted for a couple of miles or so. At one point or other, both Kevin's and my bicycles threw their chains when shifting from the large chain ring to the small chain ring, which was exceedingly frustrating. Thankfully each of us was wearing black shorts for the ride, because black shorts always afford a great place to wipe off all the bicycle grease from your hands once you have reseated your chain. (See #14 and #8 and  in The Rules.) I should mention that one of the times when Kevin's bike threw its chain during a climb, Kevin did a masterful job of avoiding having to fall down with the bike. Many other people (including me) probably wouldn't have been able to prevent the fall, and several nearby riders remarked, "Nice save!"

After we had reached the summit for this set of climbs, we were treated to three miles or so of downhill riding, which was a great change of pace. Unfortunately, I knew that these few moments of physical respite would be brief; having studied the ride profile, I knew that the next part of the course was going to be the most-difficult segment of the ride.

One we had descended back to sea level and rode west along the ocean for a half-mile or so, we turned inland again and began a one-mile climb to the north and our second stop of the day at the 31-mile point around 9:00am in Manning Park. This stop is actually situated during the difficult part of the ride, so it's well-located for cyclists because it gives them a moment to rest up before tackling the really challenging climbs ahead.

Scores of cyclists in Manning Park.
Resting my bike near the park fence.
Refueling and bicycle maintenance stations.

While Kevin and I were taking a break, we both refilled our water bottles, and I quickly ate a half a banana (for the potassium), a half-sandwich (for the carbs and protein), and a cookie (for the sugar). After a little over a half hour, we were sufficiently rested and refueled, so we climbed back on our bicycles and rode off to the north and into the toughest part of the course.

For the next two miles we faced steep climbs that ascended several hundred feet into the hills above Santa Barbara, where we slogged our way through neighborhoods filled with luxurious mansions overlooking the city. I will freely admit, the climbs were often steep, and they seemed to keep going on forever. We turned west as we continued to climb, and for the next eight miles it seemed that whenever we thought that we were finally beginning our descent we would round a corner and discover another climb was waiting for us.

This future site of somebody's mansion
will have an awesome view.
Posing for a useless photo.
Dozens of narrow, hairpin turns during the climbs.

I wear a heart rate monitor while I ride that is paired with my Garmin GPS, and occasionally it beeps at me when my heart rate is too high; e.g. over 170bpm. Usually I ignore it, because it's generally just a momentary spike in my pulse during a difficult moment or two, so eventually the beeping will go away on its own. But during this part of the ride it began beeping at me, and it wouldn't stop. After a few minutes I decided that it was best not to ignore it, so I told Kevin that I needed to pull over for a couple of minutes. As we pulled to the side of the road, my GPS showed that my hear rate was a little over 170bpm, but after five minutes' rest it came back down to 140bpm and we got back on the road. One other thing, I found it a little difficult to breathe during a few of the climbs, which I attributed to a lack of proper time to acclimate before starting this ride. (I had only arrived the day before, and I'm used to riding at an altitude that is 3,000 feet higher. When I rode in the Seattle to Portland ride a few weeks ago, I had a week to acclimate and enough time to get in a training ride.)

There is an old adage that states, "All Good Things Must Come to an End," and thankfully the same can be said about bad things. With that in mind, somewhere before we hit the 40-mile mark we had finally made it through the truly-difficult sections of the ride and we began our descent into Goleta. We encountered small climbs here and there over the next ten miles or so, but nothing as difficult as the major climbs that we had just completed. As we passed the 50-mile point of the ride, both Kevin and I had to suffer through some lower leg cramps, but nothing unbearable.

We pulled into our next stop at Stow Grove Park around 11:30am, which represented the mid-way point for the ride at 51-miles. Kevin and I refilled our water bottles, then we headed over to the dining area to grab some lunch. Once again I had a half-sandwich (for carbs and protein), a half a banana (for potassium), and few cookies (for sugar).

Resting my bike against a railing.
Picking up lunch.
Simple fare for simple minds.
Cookies and fruit!!!
More cookies!!!

During lunch Kevin and I were seated across a table from three ladies, and I made several jokes with everyone about classic songs that I had been rewriting in my head during the day's ride:

  • Sung to the tune of "Safety Dance":
    "We can pass if you want to,
    We can leave your friends behind.
    'Cause your friends can't climb, and if they can't climb -
    Well they're no friends of mine."
  • Sung to the tune of "Hotel California":
    "Welcome to the Cool Breeze California,
    Such a tiring race, such a grueling pace.
    You'll question your mind at the Cool Breeze California:
    I'm no competitor; why'd I register?"
  • Sung to the tune of "Margaritaville":
    "Climbing the hills again in California,
    Wondering why I'm still here at all.
    Some people say that there's a friend I can blame,
    But I know - it's my own dang fault."

My re-written version of "Margaritaville" drew an especially large chuckle from everyone, because I followed that up by mentioning how the pain of endurance riding passes over time, and then next thing you know you're inviting people along with you for your next excursion by saying things like, "Hey - you should sign up for this century ride with me; it's going to be lots of fun." At which point two of the ladies quickly turned and pointed at the other member of their party, who responded, "Yup - I'm the guilty one in our group."

After a 50-minute break Kevin and I headed back to our bicycles. As we prepped our gear for the next half of the ride, I met a cyclist who was wearing a jersey from the Paris-Brest-Paris (PBP) randonneuring ride, which is a 1200-kilometer (≈745-mile) endurance ride in France. (Which - by way of coincidence - was starting this same weekend.) The two of us chatted for a couple of minutes, and he admitted that he had ridden the PBP four times, but he was now too old to survive riding 250 miles a day for three days (with only four hours of sleep per day). I admitted that I was probably never young enough to have survived the ride.

As we left Stow Grove Park, our route had us backtrack to the east for three miles or so before zig-zagging for the next few miles in a mostly-southern direction through Hope Ranch towards the ocean.

The view of the ocean from the southern end of Hope Ranch.

For the next three or four miles we rode eastward and parallel to the beach, although much of that riding was through residential areas so we only saw the water occasionally. (That being said, a lot of the mansions that we were riding past were pretty amazing; it must be nice to be that rich, but couldn't that opulent wealth be better spent? [Deep sigh.])

As we rode into downtown Santa Barbara, we turned toward the ocean again, and we cycled along the water past a series of beaches, parks, and marinas. As we passed the entrance to Santa Barbara Harbor, Kevin suddenly had a flat. The two of us worked on the flat, and we managed to get it sorted out in a few minutes. (I was obviously taking photos at the time, but I actually helped Kevin fix his flat. Seriously. I really did. I promise.)

Santa Barbara Harbor was pretty nice.
Fixing a flat. No fun.
The beach near Santa Barbara Harbor and Stearns Wharf.

After we got back on the road, we passed the ladies with whom we had met during lunch earlier in the day. As we pulled up to a stoplight, I mentioned that we had stopped to fix a flat, and I asked why they hadn't stopped to help us out; to which one of them replied humorously that it was every man and woman for themselves. As we approached another stoplight a short time later, some @#$% motorist unnecessarily blocked the bicycle lane even though the light was green, thereby causing all of us cyclists to quickly pull to a stop in order to avoid an accident. One of the ladies issued an appropriate expletive at the clueless driver, and I remarked that I completely agreed with her assessment of the situation. She replied by asking if I had a song in mind that expressed that sentiment, and I said that I could put anything to music - even that.

We rode east along the water for another three miles before turning inland to the north. After another two miles of riding and a short climb we arrived back at Manning Park around 2:30pm. This park had been our second stop of the day, and I thought that it was pretty ingenious that the ride's organizers had managed to arrange the ride in order as to recycle some of the stops. (Great logistics.) We refilled our water bottles and ate a few snacks, and then Kevin took advantage of the bicycle repair facilities to make sure that his tube repair was sufficient for continuing the ride. (The guy was able to discover a couple of places where the bead for Kevin's tire had not been seated completely, and he was able to fix that.)

Back at Manning Park.
Pausing to refuel for the next segment of the ride.
Kevin having his bike checked out.
(That's just good sense.)

We got back on the road after the bike technician had signed off on Kevin's bike, where we continued to ride east and parallel to the beach for several miles. We started our final climb somewhere around the 80-mile mark, but to be honest it wasn't much of a climb. That being said, my bicycle decided to throw it's @#$% chain again, so we had to stop for me to fix it again.

The accumulated filth on my fingers.
(And this was after wiping them off on my shorts.)

Nevertheless, my chain was an easy fix, and we were quickly back on the road. After a couple of miles we ran into a brief moment of confusion with a small gaggle of cyclists about whether our route really meant to take us onto the highway, which it did. Once we had ridden a few hundred meters, we had arrived back at Rincon Beach Park around 3:50pm, which was our final stop for the day at mile 82. (You may recall that Rincon Beach Park had been our first stop of the day, so once again the ride's organizers had managed to recycle one of the stops.)

The view from Rincon Beach Park.
Good to know.

The main claim to fame for riders who make it to the final stop at Rincon Beach Park is - popsicles. I had heard about this feature before we started the ride, and I must admit - an ice-cold popsicle tastes pretty good after a long day of cycling.

Popsicle Power!
Posing with our popsicles.

After a 25-minute stop to rest and recharge, Kevin and I climbed back on our bicycles for the last segment of the ride. The next 12 miles had us riding along the beach again, which was great. At some point about ten miles from the end of the ride I changed cycling techniques so that I was only pulling up on the pedals. I do this occasionally in order to allow some of the muscles in my lower legs a brief respite from my normal riding, but on this occasion my change in technique was met with a sudden and sharp cramp in my inner right thigh. This was painful enough for me to loudly and angrily remark, "Oh crap!", and I drifted off to the right side of the bike lane as I desperately tried to stretch out the affected muscles while still riding. Kevin overhead my exclamation and asked if everything was okay, and I responded that I would be fine in a moment or two. I eventually managed to work my way through the pain, but still... that really hurt.

Shortly after we hit the 94-mile point we turned northward into Ventura as we retraced the 2.5-mile route that had started the day's ride. As we approached the Ventura Unified School District offices where the finish line was located, a cycling couple quickly pulled off the bike path several hundred meters from the end of the route. As Kevin and I rode past I remarked, "You can't quit now!" However, after Kevin and I had ridden few hundred meters further, my Garmin GPS showed that we were going to reach the finish line after having ridden only 97 miles, so I told Kevin that we needed to pull to the side.

I mentioned that if we crossed the finish line, we weren't going to make 100 miles; however, we both wanted to officially claim this as a "Century Ride,", which meant that we needed to add three miles to the length. I proposed that we create a quick loop through Ventura and Kevin agreed, so we bypassed the finish line and headed off into areas of Ventura that weren't on the scheduled route. After a little over a mile we merged back onto the official course, and as we headed toward the finish line I remarked that we were still going to be short by a little less than half a mile, so we bypassed the finish line and rode off in a different direction. As we approached the point where I wanted us to turn around, we bumped into the cycling couple that we had seen earlier, and I remarked to them, "Oh - now I get it; you two wanted your official century ride, too!" They both laughed and said that yes - that's why they had bypassed the finish line, too.

As Kevin and I rode back toward the finish line, I could see that we were just going to make it, and as we pulled to a stop past the finish line my GPS showed that we had just crossed the century mark.

One hundred miles!

Once we had crossed the finish line, we rode over to my car, where we loaded all of our combined gear into the back and locked up our bikes on the bike carrier.

Post-ride selfie before heading home.

After we had all of our things stowed in the car, Kevin and I dropped by the registration area to take advantage of the dinner that was provided, then the two of us hopped in the car and drove back to Kevin's house for the night.

Ride Stats:

  • Primary Statistics:
    • Start Time: 6:35am
    • Distance: 100 miles
    • Duration: 7:09:34
    • Calories Burned: 3,892 kcal
    • Altitude Gain: 4,724 feet
  • Speed:
    • Average Speed: 14.0 mph
    • Peak Speed: 30.3 mph
    • Average Cadence: 80.0 rpm
  • Temperature:
    • Average: 73.6 F
    • Minimum: 55.4 F
    • Maximum: 104.0 F
      (This is according to my GPS, but I find that hard to believe.)
  • Heart Rate:
    • Average: 148 bpm
    • Maximum: 181 bpm

Epilogue and Miscellaneous Parting Thoughts

As I had done for my Seattle to Portland ride notes, I had jotted several things down that didn't necessarily apply to any part of the ride, so I thought that I would add a special section to this blog in order to share them.

  • Based on advertising, I thought this ride was going to be peaceful cruise along the water with the cool breeze at our backs, but it was seldom like that. I realized from looking at the ride profile that the climbs were going to take us inland for several miles so I expected that, but what was unexpected (and somewhat disappointing) was that we sometimes rode parallel to the ocean for several miles without actually being able to see the water.
  • We rode through Santa Barbara for quite a while, yet I never saw Gus or Shawn. But then again, I guess that they live in San Francisco now. (Inside joke.)
  • It was rather warm during parts of the ride; as a result, several of the locals and some others complained, but the temperature was not bad for me.
  • We completed this ride at a considerably slower pace than my normal rides, and somewhat slower than my previous century rides. But Kevin and I had agreed to take this ride at a comfortable pace; I specifically did not want to feel like I was racing a clock (which I normally do), and as a result the ride was more enjoyable [sic] than normal.
  • Despite the advertised length of 102 miles with 4,000 feet of climb, the Ride with GPS website lists the length of this ride at 97 miles with a little over 5,000 feet of climb. That being said, my GPS agreed that the length of the ride was 97 miles, although my GPS said that the final altitude gain was closer to 4,700 feet. In either case, I think the CIBC guys were pretty far off.
  • The fact that almost all of the difficult climbs were relegated to one segment of the course was a mixed blessing; it was nice to ride for dozens of miles over long, flat stretches of road, but the hours of actual climbing were exceptionally arduous since the bulk of the elevation gains were all in one small segment.
  • As I mentioned in the notes, my bike threw its chain a few times during this ride. However, I managed to catch it quickly each time, so I avoided wiping out. After some experimentation, I determined that the problem seems to be when I am shifting chain rings at a high RPM; when I consciously slowed my cadence I was able to avoid throwing my chain. (But still - my bicycle should not be throwing the chain like that.)
  • I had overlooked one unfortunate side effect of driving ten hours on the day before the ride: I had predominately used my right arm while driving cross country, and it was hurting by the time that I arrived in Ventura. Even though I took some Advil and tried to relax my arm during the night before the ride, I could still feel my right arm hurting during the ride as a direct result of the previous day's drive.
  • I purchased a new saddle a couple of weeks before this ride, and I had not completely broken it in; so my derriere was understandably a little sore by the end of the ride. It was fine by the next day as I drove home, but still - I can honestly say that this ride was literally a pain in the... butt.

Ride Notes for July 22nd, 2015

Today was a fun day of mountain biking with family members, at least for a little while. Here's the scoop: my wife's relatives were hosting a family reunion at the Tanque Verde Ranch at the base of the Rincon Mountains, (which is an awesome place), and one of the activities available to guests was an hour of Mountain Biking.

2015-07-22

There were four of us who decided to go mountain biking today: my brother-in-law, Mike, and I are both road cyclists, so mountain biking sounded like it would be a little different from our usual routines; one of my nephews, Nate, likes to go mountain biking when he's back home in Washington state; and my son-in-law, Curt, is a fan of myriad outdoor activities (namely surfing).

We showed up at the cycling office at the ranch around 6:45am and met with Chuck, who was to be our guide for the day. After some basic fitting of cyclists to full-suspension mountain bike frames, we took off around 7:00am. Chuck took us through some easy trails at first to get everyone acclimated to their bicycles, then he navigated the group to a small track which the ranch has created on its property. The track is a small oval with lots of bumps and high-berm corners. Chuck had each of us make several passes around the track to get used to working with the full-suspension systems on the bicycles, and then we headed off into the desert.

Our route primarily consisted of extremely narrow paths between rows of cacti and other pointy plants, which kept everyone on their toes. At one point I had to mention to Curt that he shouldn't brush up against the cholla cactus, because they have a tendency to break off and painfully attach themselves to people. We also traversed a lot of small hills, and Chuck took us to one particular hill where everyone could jump off and get a little air under their bicycle.

After riding around for a while Chuck asked if we'd like to go on the harder trails, and everyone agreed; sometime around that decision the injuries started to happen:

The first mishap was when Curt flipped his bike trying to cross a small wash. (Note: Curt was wearing his GoPro camera at the time and managed to get that on video.)

The later mishap occurred when we were climbing a hill over some rocks, and my left leg slipped off the pedal. Since I was pushing hard with my legs to climb the hill and over the rocks, this meant that I had nothing to slow the speed of my right leg as it pushed down hard on the remaining pedal, which spun the empty pedal around and smashed broad-faced into my left shin at full force. This hurt more than you can possibly imagine; I went from a 0 to 10 on the pain scale instantaneously, and I immediately formed two golf-ball-sized welts on my shin where the pedal collided with the bone. I quickly pulled to a halt, exclaimed something a little more dire than "Oh Crap," and it took me a couple of minutes to get myself together.

I walked my bike to where the rest of group was waiting and announced, "I'm done for the day." I explained what had happened, and by now the contusions on my leg were so large that everyone else thought that I had broken my leg, and the swollen areas were the bone jutting out. I assured everyone that my leg wasn't broken because I could put weight on it, but I didn't want to risk injuring it again, so my day of cycling was over.

We walked our bikes toward the ranch for a little bit, which was out of courtesy for me, but I informed everyone that it would be easier for me to ride than to walk. With that in mind, we boarded our bicycles and headed back to the shop at the ranch. Once we arrived, Chuck brought me a bag of ice and a crash kit, and I started to ice the swelling on my leg.

The following photo shows my injuries (on the left) and Curt's injuries (on the right); unfortunately the photo is from the front of my leg, so you can't see how high the swelling was at this point - all you can see are light shadows.

WP_20150722_08_34_45_Pro.edited.cropped

Once we had returned our bikes to the shop, we met the rest of the family for breakfast, where my wife - the nurse - took one look at me and asked something like, "So, where did you hurt yourself this time?" After breakfast I headed back to our room, and after a couple hours of icing my injuries the swelling had disappeared; all that remained was a nagging pain in my left leg when I walked.

All that being said, despite the injuries it was a fun time. And my injury serves to illustrate why riders should clip in when mountain biking.

Ride Stats:

  • Primary Statistics:
    • Start Time: 7:00am
    • Distance: 7.8 miles
    • Duration: 1:03:57
    • Calories Burned: 490 kcal
    • Altitude Gain: 182 feet
  • Speed:
    • Average Speed: 7.3 mph
    • Peak Speed: 19.7 mph
  • Temperature:
    • Average: 85.4 F
    • Minimum: 78.8 F
    • Maximum: 87.8 F
  • Heart Rate:
    • Average: 133 bpm
    • Maximum: 163 bpm

Ride Notes for Seattle to Portland 2015

This past weekend I completed the two-day, 206-mile Seattle to Portland (STP) ride with my brother-in-law, Mike. This event is hosted annually by the Cascade Bicycle Club (CBC), and despite its daunting length, the ride sells out with 10,000 registered riders. Just to clarify, you read that correctly: every year ten thousand cyclists are willing to endure almost two-dozen hours of self-inflicted physical abuse for little more than bragging rights.

And this year, I was one of those masochists.

Prologue

I do not recall whether it was Mike or me who first suggested participating in this year's STP ride, but I am pretty sure that it quickly evolved into one of those "I'll do it if you'll do it" kind of conversations that guys often find themselves in. (And once the gauntlet has been thrown, you have to accept the challenge.) In any event, at some point back in 2014 we decided that riding in the STP seemed like a good [sic] idea, so I did some preliminary research about the ride on the CBC website. Once I had put together some rough details about the event, (e.g. when to register, where to stay, etc.), I sent everything to Mike. I let him know that the STP sells out quickly, so we both set calendar reminders to register on the day that registration opened.

When the starting day for STP registration arrived, Mike and I were both able to register for the event. Although in keeping with tradition, the STP was quickly sold out at 10,000 cyclists.

I received my official packet in the mail a few weeks before the ride, which brought a sense of reality the whole affair. My bib number for the ride was 8564, which was easy to remember, but it wasn't one of the numbers that I'd like to have. (e.g. I'd prefer to have something like 1024, 2112, 2600, 4096, 6502, 8088, etc. And no - I will not explain any of those numbers to you.)

My STP Packet! Bib Number 8564!

Once all of the event registration details were in place, I booked a hotel in Seattle for my stay before the ride, and Mike booked us a hotel in Centralia for the mid-point of the ride. After that, all that was left to do was buy a travel case for my bicycle, fly to Seattle to meet with Mike and his wife, Tesa, and prep our gear for the big day.

Packing my gear into our car for the ride to the airport.
Prepping my gear in my hotel room on the night before the ride.

Day One - Saturday

Mike and Tesa picked me up from my hotel shortly before 5:00am, and we headed across the 520 bridge in Seattle to the University of Washington where the ride was scheduled to begin. As we neared the parking lot for Husky Stadium, we could see that there was a long line to get to the drop-off location, so I suggested that we pull into the parking lot across the street in University Village; this turned out to be the best idea and saved us lots of time. Mike and I got the last of our things ready for the ride, said our goodbyes to Tesa, and we rode to the start line.

We dropped off our bags with one of the trucks that was headed to Centralia, and then we got in line for the next wave of cyclists. Note: In order to keep the hordes of cyclists from bunching up at the start, the event organizers combine riders into large groups and release them every few minutes; it was a very organized and efficient system. (One-day riders were allowed to start 30 minutes before two-day riders; this was also a great idea, because at a 16 mph pace that means that you could be eight miles away from the first wave two-day riders.) As we waited in the chilly morning air for our wave to start, Mike grabbed a quick cup of coffee, and we chatted for a few minutes until they announced that our group was ready to go.

Queuing at the Start Line.
Mike's last cup of coffee before the ride.

When they pulled back the tape around 6:00am, I made sure to start both my Garmin GPS and the GPS app that I had written for my Windows Phone that allows family members to track our progress, and then we took off amidst a sea of exuberant riders.

Waiting to start.

The first leg of our journey took us through a series of neighborhoods and parks that line the western shore of Lake Washington. The day was overcast, so we couldn't see any volcanoes, but it made the day cooler overall. There were a few small hills here and there as we started out, but nothing of significant difficulty.

Mike and I riding along Lake Washington.

Mike and I had set our goal for the morning to ride straight through to the 40-mile stop in Puyallup, so we quickly bypassed the first official stop at Seward Park around the 10-mile mark. (Actually, I couldn't believe that anyone was bothering to stop there; we were barely a half-hour into the ride.) I should mention that I pushed Mike's and my pace pretty hard at the beginning of the day for the first hour or so; I wanted to get past several groups of slow-moving cyclists, and that way we would be riding with more of the serious cyclists who would keep a better pace.

Route map for the first half of Day 1.

Shortly after we passed the 24-mile stop in Kent, Mike and I pulled up to a stoplight with a hundred or so riders. I unclipped my left foot so I could stand on it while waiting for the light to change. But as I came to a stop, I suddenly lost my balance to the right, and I couldn't unclip my right foot before I fell over. (Thankfully I was wearing a helmet when I hit the ground.) There were a half-dozen or so concerned cyclists surrounding me and asking if I was okay, but I chose to reply by jumping up and addressing the entire crowd of cyclists by exclaiming, "Nothing wounded but my pride, folks! Did anyone get that on video? I'd like to post it online later." This had the desired effect of assuring everyone that I was all right while allowing everyone the opportunity to laugh along with me at my own expense. However, this little mishap left a lovely, little series of gashes on the back of my left leg, and I got lots of comments about it for the rest of the day. (e.g. "Nice tattoo!", "Blood and grease make great lubricants!", etc.)

My first War Wound of the day.

A couple of hours into the ride we had passed the one-third point for the day, and I tried something kind of stupid: I pulled out my camera and held it backwards over my shoulder in order to snap a few photos of Mike. All of the photos came out pretty well, but just the same - I resolved not to try that again.

Mike looks pretty good after two hours of riding.

We arrived at the 40-mile stop in Puyallup around 8:30am, and it was nice to get off the bike for a few minutes and walk around. Mike and I refilled our water bottles, ate some chocolate cookies that were for sale, and we split a banana. (Bananas are a good source of potassium, which helps cut down on muscle cramps.) After a quick 10-minute break, we hopped back on our bikes and headed south towards Portland.

Taking a quick break in Puyallup.
Back on the road.

I knew from looking at the elevation profile before the ride that the largest hill climbs of the day were immediately ahead of us, and we hit the base of the first hill somewhere around the 44-mile point. As Mike and I made our way up the hill, Mike found a great opening amidst the mass of cyclists and attacked the hill with some serious gusto. Unfortunately for me, however, I managed to get myself boxed in by a group slow-moving cyclists. By the time that I managed to maneuver my way past them around the mid-point of the first hill it was too late; I had lost all of my initial momentum to launch a proper attack, so I was forced to slog my way up the first hill. I was still passing scores of cyclists, but I should have been moving a lot faster. (Darn. Darn. Darn.)

Once Mike and I were past the big hills for the day, (which comprised about four miles of the day's riding), it was fairly easy cycling for the next ten miles to the 57-mile stop at Joint Base Lewis McChord (JBLM), where lunch awaited us. (Note: There were some serious winds as we rode around the base's airfield; that was no fun.) We arrived around 10:00am, and we were pleased to discover that there was a fairly decent spread of food at this stop; I had a turkey sandwich, a Rice Krispy Treat, some fruit, another cookie, etc. But to be perfectly honest, by this point I was so ravenously hungry I could have eaten just about anything. After resting for 20 minutes, Mike and I refilled our water bottles and we got back on the road.

Hundreds of cyclists taking a lunch beak on JBLM.
Mike and I taking a quick photo before heading out.

As we weaved our way through the base housing, that brought back memories of being raised as a kid on various military bases, and also of my own years serving in the military and living on base. (Note: Those nostalgic reminiscences weren't necessarily happy memories for me, because base housing usually leaves a lot to be desired.) Anyway, many of the cyclists were giving high-fives to the MPs and other military personnel who were directing traffic for us. They were all enlisted personnel, so I'm sure that most of them were ordered to guard the roads for the cyclists, but nevertheless their efforts were greatly appreciated by all of the riders.

Route map for the second half of Day 1.

The route took us through some of the back woods on the base, and eventually we exited the base near the town of Roy, WA. Mike and I pressed on to McKenna, which was the next official stop at mile 72 for the day. We arrived around 11:40am, and we took a break to rest our weary legs for about 20 minutes. After we refilled our water bottles, it was time to head out.

Stopping briefly in McKenna

Shortly after we left the stop at McKenna, we faced a steep hill climb. Mike was ahead of me, so he didn't notice the following incident: I attempted to shift from my top chain ring to my small chain ring in order to climb a little easier, but my bicycle threw its chain off the small chain ring. I tried to backpedal out of the situation, but my chain became completely lodged and it wouldn't move. This predicament caused me to quickly lose all of my forward momentum in the middle of the hill, and in one of those moments that seems like an eternity at the time (but was really just milliseconds) I weighed my options. There was obviously nothing that I could do to dislodge my chain, but if I unclipped my left foot (which I always unclip) I would be leaning (or falling) into traffic. This risk was unacceptable, so with no other options available to me, I threw all of my weight to the right side of the road, where my bicycle and I tumbled over the concrete curb and into the grass and dirt that lined the road. This undoubtedly looked much worse than it felt; several approaching cyclists called out to me to see if I was okay. I assured everyone that I was fine, (although my fall had bruised my right arm and torn up my right knee a little). I explained that my bicycle had simply thrown its chain, and I encouraged everyone to continue pedaling uphill. After that, I spent the next 10 to 15 minutes attempting to untangle my bicycle chain. This proved to be a very difficult task; my chain was stuck fast, but I eventually succeeded - although my hands were filthy by the end. (It's a good thing that I had packed hand wipes with me.) Mike eventually noticed that I was nowhere to be seen, so he pulled off the road into an unofficial stop at mile 81 and sent me a text message to let me know that he was waiting for me. When I caught up with Mike, I explained what had happened, then we quickly got back on the road.

My second War Wound of the day.

The next segment of the ride Mike and I both agreed was the best part of the day's ride; we rode along the well-paved Yelm-Tenino Trail for 14 miles or so. First and foremost - there were no cars on the trail, which was a pleasant change. In addition, the trail was wide enough for Mike and I to ride together, and yet there was still enough room for other cyclists room to pass when necessary. This trail was also the smoothest part of the day's ride, which was greatly appreciated.

Riding along the Yelm-Tenino Trail.

Note: As we were riding along the trail, Mike and I saw the aftermath of a female cyclist who had suffered some sort of major catastrophe; medical personnel were treating her myriad injuries, and I make no exaggeration by stating that she was covered in blood.

Mike and I stopped in Tenino at the 89-mile point around 1:25pm, which was the last official stop before our destination for the day in Centralia. Our decision to stop in Tenino was mainly due to my earlier accident; I wanted to have some bicycle repair technicians check out my bike to see if they could determine why it threw its chain. The technician ran my bike through all of its gears but couldn't reproduce the problem, so he commented that it must have been a fluke. His diagnosis put my mind at ease, although that later proved untrue. (But I'm getting ahead of myself.)

Taking a break at the Tenino stop.

When Mike and I left Tenino, we had only 14 miles to go for the day, and the miles passed pretty quickly as we rode for the next hour or so. (To be perfectly honest, I can't recall anything of importance from that hour's worth of riding.)

Finishing up the day's ride.

We crossed the Day 1 finish line at Centralia College shortly before 3:00pm, so we made pretty good time for the day. My wife, Kathleen, had been tracking our progress throughout the day via the GPS app that I had written, and she sent me a text message to congratulate Mike and me for completing the first day's ride.

Mike crossing the Day 1 finish line.

As various cyclists made their way across the finish line, an announcer was having fun calling out the various jerseys and costumes worn by the participants. Mike and I pushed our bicycles out of the way to allow arriving cyclists more room to exit the course, and as we did we were met by volunteers who were handing out orange-flavored popsicles. Mike and I both gladly accepted the proffered popsicles, although at that point the volunteers could have frozen just about anything and I would have eaten it. (e.g. "Here's your frozen kale!", "Get your frozen lutefisk here!")

Mike enjoying some well-earned reclination.

After a little rest and relaxation, we decided that we should either find something to eat for dinner, or we should depart for our hotel. We looked at our dining choices, and we chose to order a pizza at the hotel later. Our next step was to retrieve our backpacks, and it took us a few minutes to discover where the pickup point was located. (This was due to a misunderstanding of what the announcer said.) Once we found the right place, it was well-organized and we quickly found our things.

Our hotel was a little less than two miles from the college, and once we got settled into our room we both took long showers to wash off the grime from the day's activities. We ordered a pizza to be delivered to our hotel room - which was fantastic. We ate most of the pizza, but we set aside two pieces for breakfast the following morning. (For some people, cold pizza in the morning is the breakfast of champions.)

After dinner we put together our riding plan for the next day, and I wrote up a cheat sheet with the distances for all of the stops. The pickup up time for our backpacks at Centralia College wasn't until 6:00am the following morning, so we both set our alarms for 5:00am, and we headed off to sleep by 8:00pm.

Putting together my cheat sheet for the next day.

We had averaged a little over 15 mph for the day, which wasn't bad. Here are some quick stats for the first day's ride:

  • Total Distance: 102.1 miles
  • Riding Time: 6 hours, 39 minutes
  • Total Time: 9 hours, 4 minutes
  • Elevation Gain: 3,290 feet
  • Average Speed: 15.4 mph
  • Calories Burned: 3,444 kcal

Day Two - Sunday

Mike and I both woke up shortly before our alarms, and since neither of us could sleep, we got up and started to put our things together for the day. We pulled the pizza out of the mini-fridge from the night before, although by now neither of us wanted to touch it. (It's funny how appetites can change overnight.)

Mike and I preparing to start our Day 2 ride.

We got on the road by 5:40am, which was close to our goal. As we pulled up to a stoplight near the hotel, I pulled my bicycle onto the sidewalk in order to push the button to change the traffic signal. Unfortunately I decelerated too quickly and - surprise, surprise - I lost my balance and fell over. Seriously - one minute into the day's ride and I had already fallen over. Who DOES that? (Apparently I do. And just to clarify, my count for falling over during this trip was now at three. Darn.)

Route map for the first half of Day 2.

Mike and I arrived at Centralia College within ten minutes of leaving our hotel, and we quickly dropped off our backpacks. Once that task was taken care of, we got on the road shortly before 6:00am. Even though my muscles were a little sore when we got up and headed out from our hotel, much of that soreness quickly passed as we started the actual ride.

Dropping our backpacks off at Centralia College.

We skipped the first stop in Chehalis at the 7-mile point, but as we rode through town we realized why some of the more experienced STP riders push on to Chehalis or some other town during the first day; it diminishes the length that you need to ride on the second day, and it probably helps psychologically to know that your ride will be shorter. You would miss out on all the half-way point festivities in Centralia, of course, although you could hang out there for a half-hour or so before riding on to your ultimate destination.

Riding through Chehalis in the early morning.

Our plan for the day was to ride a little slower than the previous day and to hit all of the stops. We had made good time the day before, but we didn't want to kill ourselves during the second day's ride. With that in mind, Mike and I started off together, and the road was wide enough for us to carry on a conversation as we rode. Sometime later I started to break away on the hill climbs, and at the next stop Mike suggested that I ride at my own pace and simply wait for him at each successive stop. With that in mind, I routinely sped off after each stop, but I only arrived at each stop about two or three minutes before Mike, so he was riding at pretty much the same level as me. What's more, Mike passed me during a couple of the hill climbs and I somehow didn't notice, so I was perplexed when I found myself passing him later. ("Hey, how did you get here?") Once I discovered to my amusement that Mike was waiting at the next stop for me, and I queried when he had managed to pass me; Mike replied that he had passed me following a climb, and he had arrived at the stop just 30 seconds before me.

At one point I was passing a bunch of cyclists and I kept hollering "On your left" to announce my intention to pass each cyclist. I started hearing a woman behind me announcing the same as we passed several cyclists, so I thought she was drafting behind me. But as I was passing another cyclist the woman behind me exclaimed, "I'm not kidding; ON YOUR LEFT!" This meant that she wanted me to get out of her way, but I need to point out that there was no shoulder on the right, so the cyclist to my right had nowhere to go. I was in the middle of our lane passing that cyclist with only inches to spare between our bicycles, whereas the woman behind me had the rest of our lane and the entire oncoming traffic lane (with no traffic visible for at least a mile) with which to pass me. As I couldn't get out of the way without pushing the cyclist to my right off the road, I ignored the woman behind me. When she eventually pulled alongside I remarked, "In case it wasn't obvious, I was passing someone, too. Just a thought." (I got no reply as she sped off.)

I knew from studying the ride profile the day before that we had a big hill awaiting us near the start of the day, and sure enough we hit the base of the hill around the 14-mile point. However, this hill was a little different than the big hill on the previous day, because it was more like a series of hills that seemed to go on and on for five or six miles, and for a little while it became kind of annoying. (Well, it was annoying for me, anyway.) But I was really glad that I train on the Pistol Hill Loop back in Tucson, which has a long, uphill climb for seven miles or so. As I was riding I kept thinking about Rule #10 from The Rules: "It never gets easier, you just go faster." (Of course, Rule #5 always applies, too.)

That being said, as I attempted to shift my bike onto the smaller chain ring, my bike threw its chain again. But since I had a sneaky suspicion that it might do so, I chose a time to shift when few people were near me, and when my chain was thrown I was able to quickly pull to a stop and get off the road in a controlled manner. A few of the passing cyclists asked if everything was okay, and I replied, "Yup - I just threw my chain." They just nodded sympathetically and rode on. It took me about five minutes to fix my chain, and once I had done so I wondered what to do with all the oil on my hands. I decided that my cycling shorts were black for a reason, and I just wiped my hands off on them.

Rejoining a hill climb in the middle is tricky; you have to find a good gear to get started, and you have to find a good interval between cyclists to get back on the road. Nevertheless, I managed to get back on the road pretty quickly.

As we neared the summit of a really tough climb, I loudly asked everyone around me, "Why are we doing this? Is ANYONE having fun?" Most people just laughed, but the woman riding next to me said this was the best thing that had happened to her all year. I replied, "Really? This climb is the best thing that's happened to you this year?" She responded, "Yeah, I've had a really awful year." (I said I was so sorry for her; and I really meant it.)

Our first official stop of the day was in Winlock around 7:15am. Mike and I both bought a small cup of coffee, and we split a simple breakfast sandwich. (Which at the time tasted better than filet mignon.) As we arrived, medical personnel were loading an injured cyclist into an ambulance, which was yet another reminder that I was fortunate that my previous day's injuries had been pretty minor.

Arriving in Winlock.
Thankfully the ambulances were not there for us.
This may not have been the breakfast
of champions, but it was fantastic.
Mike insisted on this photo. I kind of regret it now.

The next official stop was in Vader (no relation to Darth) at 8:20am, but Mike and I were both feeling pretty strong so we decided to bypass this stop and we hopped back on the road in order to push on to the next stop.

Bypassing the mini-stop in Vader.

The sun broke out, which made it much warmer, and I finally had a need for my sunglasses. Some of the cyclists complained about the heat, but it was cooler than my usual riding temperatures in Arizona so I didn't mind. (Although I did increase my water intake.) Unfortunately, since the first day had been overcast, Mike had packed his nice sunglasses for this trip, so he only had his normal glasses with him. (Even though his normal glasses automatically tint in sunlight, it's just not the same.)

We pulled into Castle Rock around 9:00am, which was the 38-mile stop for Day 2. I think Mike may have refilled his water bottles, but I was doing fine for supplies so I just stretched my legs for a few minutes before we got back on the road.

The stop at Castle Rock.
Mike expressing his elation upon our arrival.
My bike leaning against a rock in Castle Rock.
It might have been the actual "Castle Rock," but I couldn't be sure.
(Note: That was meant as a joke, of course.)

The next stop was in Lexington at the 45-mile point, which was the first major food stop of the day. We arrived at 10:00am, so we were a little behind a timeline that I would have liked. But we had kept our pace pretty well; we had simply been following our plan to hit more of the stops along the way, which slowed us down a little. However, this approach was arguably worth the sacrifice from a psychological perspective; it was nice to know that our next stop was never more than 10 to 15 miles away, even if we decided to skip it. In any event, Mike and I ate a leisurely lunch in Lexington and we relaxed for a while before getting back on the road.

The Lexington stop had a much larger crowd
than normal, but that was to be expected.
Mike enjoying lunch.

Unfortunately we discovered as we got ready to leave the Lexington stop that there was a really long line to refill our water bottles, so that set our departure time back a little. Apparently there was a problem with the water pressure, so they only had a single tap working for hundreds of cyclists. (If we had known that fact a little sooner, we could have got in line when we arrived. But in the grand scheme of things it wasn't that much of an imposition; and we were glad to have enough water to depart safely.)

Sorting through the food that I picked up and choosing what
comes with me on the road and what gets eaten immediately.

Mike and I got on the road around 11:00am, and about a half-hour later I arrived at the Lewis and Clark Bridge over the Columbia River, which signified the border with Oregon. The ride organizers and police were corralling cyclists onto a frontage road while allowing southbound road traffic to continue over the bridge unabated, with the intention of stopping traffic at some point and allowing the mass of cyclists to make their way across the bridge. Mike arrived about ten minutes after me, so he was further back in the mob of bicyclists than me. About ten minutes after Mike arrived the police finally blocked off the traffic and allowed the cyclists to cross the bridge; this action was greeted by a number of cheers from the assembled throng of cyclists.

The hundred or so riders who had
arrived at the bridge before me.

As we approached the bridge, several of the ride organizers called out to the crowd to say that the descent on the opposite side of the bridge was going to be very bumpy. With this in mind, they were recommending that everyone should make sure that all of their gear was securely fastened to their bikes, and to watch out for lost gear as they descended. I reached down and made sure that my water bottles were snugly fastened into their cages, and I made my way up the bridge climb.

I have to admit, when I first saw the bridge from a distance, I thought that the climb would be exceptionally terrible. But as it turns out, the climb wasn't that bad. However, what was bad was that there was a large number of cyclists who were riding very slowly, but we had been grouped into such a thick horde of cyclists that it was difficult to maneuver around the slow-moving riders. Meanwhile, we had fast-moving traffic approaching in the opposite direction. As a result, the ride across the bridge was often terrifying - just for fear of accidents. (PS - some people simply gave up and walked their bikes across the bridge.)

The Lewis and Clark Bridge from a distance.

As I approached the mid-point of the bridge, the crowd around me had thinned out considerably. A group of cyclists (including me) had broken away from the main group, and as a result I had enough of a buffer behind me that I felt comfortable enough to pull out my camera and snap a couple of photos before starting my descent. As I coasted down the far side of the bridge, I put on a lot of speed due to the steep decline, so I was braking constantly as I hit the series of bumps about which we had been warned. True to the predictions, there were somewhere between 50 and 100 water bottles lying beside the road. I guess some people failed to heed the warnings. Once we were past the bridge, we were back to road riding - only now we were in Oregon.

Entering Oregon!

Sometime later my bike threw its chain again, and this happened a few more times. However, each time I was able to catch the problem before I wiped out, and I pulled to the side to fix the problem. (I waved Mike on whenever this happened.) But I decided that I no longer trusted my bicycle to shift to the small chain ring, so I chose to ride for the rest of the day on my small chain ring in order to avoid throwing my chain again. (This is, of course, unacceptable for a bicycle, so I resolved to have to have that looked at when I got home.) However, this also meant that I forfeited my highest gears, and therefore I lost my top speeds.

After a while I had so much oil and grease on my fingers due to resetting my chain that it was kind of gross to eat. That being said, there simply wasn't a place to properly wash off all of the fifth, so I was forced to make do. (In my military days I called this condition "perma-grime," and I learned to live with it or starve.)

Route map for the second half of Day 2.

At some point during the day I started to ride with a group of women with Skull/Butterfly gear. We rode together for quite awhile because we seemed to ride at the same pace for the flat sections; I would climb hills faster than them, but they were willing to take the downhills faster than me. I can't remember when we started riding together, and I can't remember when we stopped. It was probably at one of the stops, but I don't recall.

Mike and I stopped in Goble at the 62-mile point around 12:30pm, although we didn't stay long. We refilled our water bottles, and I had a couple snacks that I had saved from an earlier stop that day. After 10 minutes or so we were back on the road.

Stopping for water in Goble.

The next big stop of the day was in St. Helens, which was shortly before the 75-mile point. We arrived around 1:50pm, and we found a good place to ground our bikes while we wandered off in search of food. The sandwiches and snacks were largely the same as other stops, except that they had watermelon, which was fantastic. They also had a water mister operating, and it was fun to see people walk through it again and again.

Mike pulling into St. Helens.
Navigating through the sea of
cyclists to find our lunch.

Mike needed to pick up something from the medical tent, and one of the volunteers asked if I wanted her to wrap my knee from the previous day's accident. I replied, "No, I earned that." (She laughed and walked away.) After an hour's rest, we packed our things and got back on the road.

Visiting the medical tent.
Mike leaning back, kicking his shoes off, catching some shade...

Somewhere after we left St. Helens, I realized that I had not been pulling up on my legs during the climbs; I had just been pushing down. So I decided to change pedaling techniques, and I discovered that I had so much power in reserve that I found myself climbing a few of the difficult hills at 18 to 20 mph. That being said, I realized that this was going to be a short-lived discovery; after a few hills I recognized that I was quickly burning up that reserve, and all of it was gone by the time I hit the uphill climb to St. John's bridge an hour or so later.

Our last stop of the day was in Scappoose at mile 87, and we arrived around 3:30pm. This stop was pretty small; it was really just the last chance to fill up on water before starting the final 17-mile stretch to Portland. Kathleen sent me a text message that the GPS app that I had written had stopped uploading data at Goble, so I quickly reset it and it started transmitting again. (If Kathleen hadn't sent me that message I would never have known, and Kathleen would have thought that something had gone wrong in Goble.) After Mike and I topped off our water bottles, we got back on the road.

My bike was helping to point the way to water.
Taking stock of my snacks for the final push.

Mike later remarked that he started to listen to music through his iPhone about three or four hours from the end of the ride, although I didn't turn on my music until the last hour or so before the St. John's bridge. (Then I turned off my music for the ride through Portland.)

Mike and I had agreed to meet up at St. John's bridge, which crossed the Willamette River into Portland, in order to finish the ride together. The distance from Scappoose to the finish line was roughly 16 miles, and the bridge was about midway between the two locations, so from a psychological perspective it helped to subdivide the last of the ride into two shorter segments. (At this point in the ride, it's all about the mind games.)

I arrived at the bridge less than a minute before Mike, who pulled along side as I took a photo of the bridge. We had to wait for a stoplight to change, and then we made our way across the bridge with a small group of cyclists.

Crossing the St. John's bridge into Portland.

The ride through Portland was predominantly a nice respite from all of the up and down hill riding over the past several days, except that there was one small hill near the finish line that was a brief moment of difficulty, for which I loudly remarked, "Okay, who added THIS hill to the ride?" That being said, we were forced to stop for a large number of stoplights as we rode through Portland, which probably added at least a half-hour to our ride time.

Nevertheless, before we realized it, Mike and I were crossing the finish line at Holladay Park, and our second century ride of the STP was over. (Note: I should have taken off my sunglasses as I crossed the finish line, because you probably can't see my face in official ride photos. But perhaps that's a good thing.) Mike and I were handed our "STP Finisher" patches, and then we pulled our bikes off to the side to allow room for arriving cyclists who were completing the ride.

Approaching the last few meters to the finish line!
Mike's opinion of what it feels like to finish.
Proudly displaying my hard-earned "Finisher" patch!

We walked our bikes through the crowds, and we found a tree off to the side of the park on which to lean them. Mike watched our bikes while I picked up our backpacks.

My bike finally earned its own rest.

Shortly thereafter we were met by Tesa and her sister, Mary, who showed up to congratulate us. After a few minutes of visiting with Mary and Tesa, Mike and I ventured off in search of something to replace the thousands of calories that we had just burned.

We decided on Greek Gyros, (which were amazing), and we picked up some free souvenir STP cups from the Cascade Bicycle Club. After that, Mike and I ordered our 2015 STP jerseys. (Note: I don't pre-buy my jersey before a ride, which is kind of like a minor superstition for me; I don't want to jinx the ride by buying the jersey and then failing to complete the ride.)

What this year's jersey looks like.

We were informed that we won't receive our jerseys until October, which was unfortunate, but what choice did we have? Once we were done eating and buying our jerseys, we packed up our bikes and headed off to spend the evening with family.

Mike and I had averaged just under 15 mph for the day, which once again was pretty good. Here are some quick stats for the second day's ride:

  • Total Distance: 106.2 miles
  • Riding Time: 7 hours, 8 minutes
  • Total Time: 11 hours, 39 minutes
  • Elevation Gain: 3,809 feet
  • Average Speed: 14.9 mph
  • Calories Burned: 3,954 kcal

Epilogue and Random Thoughts

I had jotted several things down in my notes that didn't apply to either day in particular, so I thought that I would add a special section to this blog in order to share them.

  • Ford Prefect described Earth as "Mostly Harmless." If I was following his lead, I would label STP Day 1 as "Mostly Flat," and STP Day 2 as "Mostly Hills."
  • Mike and I saw several bad accidents during the ride, with several people being whisked away in ambulances. So in the grand scheme of things, my minor injuries were nothing. (Although it should be noted that Mike had no injuries; only I did.)
  • Throughout the ride, most cyclists did their best to thank the volunteer staff and police officers who provided food, drinks, directed traffic, etc.
  • Two words: Honey Buckets. Enough said.
  • On Day 1, Mike and I both wore our El Tour de Tucson jerseys, and Mike got lots of comments about his jersey. It was from the 2012 El Tour, and I have to admit, that year had my favorite artwork; it appears that everyone else agrees with me.
  • On Day, 2 Mike wore a plain jersey while I wore a Microsoft jersey. At some point another cyclist from Microsoft noticed my jersey, and we started a small conversation as we rode. The guy asked me if I work on Visual Studio, since that logo was on my jersey, and I replied, "More or less." (I work in the division that creates Visual Studio, and I designed the development web server that ships with Visual Studio.) I asked where he works, and he replied, "I work on HoloLens." I said, "Dude, you work on the cool stuff." To which he responded, "Yeah, and I use your stuff to make my stuff."
  • I had several groups of cyclists touch on one of my pet peeves: they failed to queue properly at a stoplight. In several specific instances, a group of cyclists was already queued at a stoplight, when an approaching group of cyclists would glide past the whole queue in order to take the best position for when the light changes. This was especially frustrating to me when it was a group of cyclists that I had already passed, which meant that I would have to pass them again! (If I recall correctly, I politely chastised a couple of groups of cyclists for failure to queue properly. After all, we were in it together, right? Weren't we supposed to cooperate? Sheesh.)
  • Unlike the El Tour de Tucson, which has thousands of people cheering cyclists on, most of the Seattle to Portland course was devoid of anyone other than angry motorists who appeared to hate the inconvenience of cyclists taking up their precious roadways.
  • Some groups of fast-moving cyclists speed up on your left side unannounced and it scares the poop out of you. (I did my best to announce all of my passes.)
  • We saw some interesting bicycles on this ride. For example, one group of cyclists riding for charity were doing the entire ride on vintage, single-speed bicycles. (That's either gutsy or foolish - but either way I admired their bravery.) I saw two cyclists on commuter bikes that resemble Brompton Folding Bikes, which was even more insane than riding a single speed bike. There were also a few recumbent bikes completing the ride, several tandem bicycles, a Penny-farthing, and one hand-pedaled cyclist who was making pretty good time.
  • At most of the stops (full and mini) they had water, Clif bars, and sometimes fruit, while at the full stops they also had sandwiches a greater selection of snack foods. The full stops also had lots of vendors selling their wares or offering free samples.
  • I over-packed for my supplies, but that's actually a good thing; I would rather have something with me and not need it than to need something and not have it.
  • There is an old adage that says, "If you ain't the lead dog, the view never changes." This applies to cyclists as well.
  • I made good time for a lot of the ride; I was able to keep a pretty good pace even climbing the moderate hills, and I found myself climbing with a good deal of power. (I was nowhere near competitive, of course, but I was really glad that I always train with hills.)
  • After the ride was over I did the math, and I could have done the ride in a single day if I started at 4:45am with the rest of the single-day riders. Now I am not suggesting that I wouldn't have been in a great deal of pain after the ride, and during the ride I would have been psychologically punishing myself for being stupid enough to attempt a 206-mile ride in one day, but the math definitely proved to me that it could be done by me. (I should point out that I am not suggesting that I ever intend to do such a thing, but it is possible.)
  • Throughout the ride I tried to joke around with other cyclists; I complimented people on their jerseys, silly things they attached to their bicycles or helmets, funny costumes, etc. I tried anything to take people's minds off the immediate suffering that we were all experiencing. I used to do the same thing in my Army days; I am not trying to be a "comedian" and make people laugh - I am just trying to spread a little joy and alleviate a little pain when it's needed most.
  • Mike later made fun of me for a few of my verbalizations to other cyclists during the ride. For example, I chastised one guy for tossing a plastic wrapper to the ground: "Dude, you should pack out your own garbage." (Note: I always do.) And I chastised someone else for cutting me off with an abrupt lane change: "A little warning next time would be great. Thanks."
  • I alluded to this earlier, but several of The Rules applied during this ride; I mentioned Rules #5 and #10 earlier, but the more you ride, you start to realize how many of those rules are apropos for any big riding event.

At the end of the event, Mike and I averaged just over 15 mph for the entire ride, which was better than I had anticipated during our planning. Here are some quick stats from both days:

  • Total Calories Burned: 7,398 kcal
  • Total Elevation Gained: 7,099 feet
  • Final Average Speed: 15.1 mph
  • Total Cycling Time: 13 hours, 48 minutes
  • Total Participation Time: 20 hours, 43 minutes

The day after the ride was over I told Mike that 7,400 calories seemed too low, and he agreed: "That seemed a lot more like 10,000 calories."

As a parting thought, there are five stages to dealing with grief - Denial, Anger, Bargaining, Depression, and Acceptance - and I've learned that it's much like that for distance rides:

  • Denial: "Hey, this 206-mile ride won't be that bad..."
  • Anger: "Why am I doing this ride? I am such an idiot!"
  • Bargaining: "Dear God, if you help me to survive this ride, I promise that I will be nicer to all of humanity."
  • Depression: "Oh my gosh, I still have another 20 miles to go. I could just die right now."
  • Acceptance: "Well, that ride is over. I will never do that again."

The problem is, within a few weeks the vicious cycle will begin again. Immediately after a long ride like the STP is over you think, "I will never ride my bicycle again, so I'm going to sell it and take up an indoor hobby." On the day after the ride you think, "Well, maybe I'll keep my bicycle as a souvenir." One month later you start to think, "Hmm. I might ride the STP again." After another month passes you think, "Hey, I wonder when I can register for next year's STP?" And then in another month or so you find yourself telling your friends, "Hey! Do you guys want to ride the STP with me? It's LOTS of fun!" When that happens, denial has set in, and that's pretty much how it starts.

More 511th History: Happy 4th of July

Here's a 4th of July story for you from our days in the 511th...

Anyone who remembers Steve Meyers will recall that he had no fear - although sometimes he had no common sense, either. Steve backpacked across Europe with no cash as a teenager, wandered off in Turkey without knowing the language or telling anyone where he was going, and managed to pull off a two-week vacation using his MAC flight privileges to visit Athens, Jerusalem, and Cairo and still made it back in time for duty. Steve was an amazing guy who simply went where no one else would think to go.

But what some of you who joined the 511th after the Fall Of The Wall may not know is that our unit used to work with members of the British RAF before they rotated back to the UK. We deployed to the border with them several times, and a few of us were sent to work with the RAF somewhere further north (in locations about which we cannot speak). ;-)

Anyway, during one of those deployments along the border, we were having coffee with a few of the Brits, when Steve turned to them out-of-the-blue and asked, "So, how do you guys feel about when you lost the Revolutionary War? Are you guys still upset about that?"

For a flash of a second you probably could have heard a pin drop all the way across the border, then one of the Brits - without looking up from his coffee - replied in his best British accent, "Lost? I think not. We simply left it to you. Have you been home lately? Ah, what a piece-o-crap."

This comment was followed by a well-deserved round of laughter, and all was well in the world. :-D

Happy 4th of July everyone!


UPDATE: I found the following image, which seems apropos for this topic:

Happy-Treason-Day

Ride Notes for June 27th, 2015

Despite having ridden in temperatures over 100 degrees (Fahrenheit) in the past, I appear to have failed in learning the important lesson that riding in extreme temperatures really takes a lot out of you. That was abundantly evident during today's 60-mile ride; even though I started early to avoid the hotter temperatures, as the day wore on I found myself suffering through the worst temps of the day, as evidenced by the following photo of my GPS when I approached the 50-mile mark of the ride:

Way-Too-Hot

When I'm riding during the hotter times of year, I tend to arrange my rides in something like a cloverleaf pattern, where I am always trying to get back to the entrance of Saguaro National Park (SNP) in order to refill my water bottles. (I try to do that every 15 to 20 miles.) During this ride, however, I was still several miles away from SNP when I realized that I wasn't going to have enough water to get back.

With that in mind, I called Kathleen, and the following conversation transpired:

  • Kathleen: Hello? Where are you?
  • Me: [Panting.] I'm not sure; somewhere way out on east Tanque Verde.
  • Kathleen: Are you okay?
  • Me: I've just realized that I don't have enough water to make it back to my refill location.
  • Kathleen: Okay, I'll come get you.
  • Me: Oh no, I don't want to quit - I just need you to bring me some more water.
  • Kathleen: You realize that you're nuts, right?
  • Me: Yup.

And my darling spouse, being the wonderful person that she is, drove out to meet me and brought me several bottles of water so I could refill and continue my ride for another 10 miles.

Ride Stats:

  • Primary Statistics:
    • Start Time: 9:25am
    • Distance: 60.1 miles
    • Duration: 4:32:22
    • Calories Burned: 2526 kcal
    • Altitude Gain: 2681 feet
  • Speed:
    • Average Speed: 13.4 mph
    • Peak Speed: 33.3 mph
    • Average Cadence: 71.0 rpm
  • Temperature:
    • Average: 99.6 F
    • Minimum: 78.8 F
    • Maximum: 111.2 F
  • Heart Rate:
    • Average: 152 bpm
    • Maximum: 182 bpm

Still More Examples of Bad Technical Support

Here is another entry in my on-going list of examples for both good and bad technical support experiences. For this situation, I will show an example of bad technical support as provided by the Microsoft Outlook Support Team.

Here is the scenario: about two months ago one of my Hotmail accounts stopped working with Windows Live Mail. When I attempted to sync that particular email account, I received an error message that was similar to the following example:

Bear in mind, however, that I made no changes to my Windows Live Mail settings, and I have several other Hotmail accounts which are working perfectly with the same settings on the same computer.

So I started a support issue with the the Microsoft Outlook Support Team, and over the next several weeks I went back and forth with several people on that team who were clearly uninterested in working on this issue. (In fact, at one point they simply closed the case without notifying me!) As of today the issue is still not resolved, and I have not heard from anyone at Microsoft within the past month.

As I said before, this is an example of really bad technical support.

With that in mind, listed below is the full thread from my support case in order of the events. Note that I have substituted the following variables where necessary to hide my actual account name, email address, and support number:

  • %ACCOUNT_NAME% is my Hotmail account name
  • %EMAIL_ACCOUNT% is my email address for my Hotmail account
  • %TICKET_NUMBER% is my ticket number for my Microsoft support case (e.g. SRX12345678ID)

So without further narrative, here are all of the notes from the support case.

04/18/2015 15:14

Service: General Issue

What type of problem do you have?

  • Selected Product
    • Outlook
  • Selected Issue
    • Your account has been temporarily blocked

Enter a short description of your issue: Cannot Sync Email from Windows Live Mail

Enter the email address (Microsoft account) affected by this issue: %EMAIL_ACCOUNT%

Enter your contact email address: %EMAIL_ACCOUNT%

Enter a detailed description of your issue:

I was able to sync my %EMAIL_ACCOUNT% account in Windows Live Mail until a week or so ago, and now I receive the following error message:

Unable to send or receive messages for the Hotmail (%ACCOUNT_NAME%) account.
Server Error: 3219
Server: 'https://mail.services.live.com/DeltaSync_v2.0.0/Sync.aspx'
Windows Live Mail Error ID: 0x8DE00005


For reasons that are completely unrelated to this issue, I completely reinstalled Windows 7 Ultimate on this computer, and yet after reinstalling Windows and Windows Live Mail on this computer I still see the same error. In addition, I have a couple of other Hotmail accounts that I use with Windows Live Mail on the same computer and they work without any errors.

With that in mind, the problem should not be caused by any settings on my computer. However, I did not make any changes to my account settings at Hotmail before I started seeing this problem.

There is one thing that I have noticed, though - when I log into the Hotmail.com website, when I use one of my other Hotmail accounts the title bar says Outlook.com, whereas the title bar for my %EMAIL_ACCOUNT% account says Outlook Mail (Preview).

04/18/2015 15:18

From: Microsoft Support

We are writing to let you know that we have received your request for support and will reply within 24 hours.

If you don't see a message from us within 24 hours, check to see if email from @css.one.microsoft.com is in your junk mail folder. You can check the status of your request on the Microsoft Support site.

https://support.microsoft.com/oas/default.aspx?tp=il&tenant=WOL&sd=winlive&incno=%TICKET_NUMBER%

Thank you,
The Microsoft Support team

04/19/2015 22:51

Subject: %TICKET_NUMBER%
From: Escalation Agent

Hi,

Thank you for contacting Outlook.com support.

My name is Therese and I'm glad you have reached us today. I have read your description and I understand that you are getting an error message when syncing your account at Windows Live Mail. Let me see what I can do for you.

To start off, we appreciate your efforts in isolating the case by uninstalling and reinstalling your Operating System and Windows Live Mail on your computer. You also mentioned that other Microsoft accounts are working fine on Windows Live Mail which tells us that this is not an issue with the mail client but can be an account-related issue.

With that, I would like you to know that I have escalated this case to our Support Specialist for further evaluation. We will get back to you as soon as we have a resolution or if we need more information.

Your patience is highly appreciated.

Regards,
Therese

04/21/2015 11:12

Subject: RE: %TICKET_NUMBER%
From: %ACCOUNT_NAME%

Has there been any progress on this issue?

FWIW - I have included a screen shot of the error message in Windows Live Mail.

Thanks.
--------------------
Attachments:
0x8DE00005.png

04/21/2015 13:17

Subject: %TICKET_NUMBER%
From: Escalation Agent

Hello,

Good to hear from you again. This is John from Outlook.com support.

We appreciate the screenshot that you have provided us. I have checked your service request and found out that your issue is still being handled by our Support specialists and the investigation is still ongoing. Once we got any developments or if there is anything that our Support specialist would need from you, we'll inform you right away.

Thank you for your cooperation and patience on this matter.

Regards,
John

PS: Please do not delete the first email notification from us. If you did not receive another notification in 24 hours, please check the link on the first email notification to see the case progress.

04/25/2015 12:33

Subject: %TICKET_NUMBER% (Reopen)
From: %ACCOUNT_NAME%

It has been a week since I first opened this support case, and from what I could tell - nothing was ever done. So imagine my surprise when I logged in today and I discovered that this support case had been closed without a single notification from Microsoft. This is terrible customer service, and I AM A VERY DISSATISFIED CUSTOMER!!!

At this point I expect three things:

1. I demand that this issue be escalated to someone who can actually work on the issue and resolve it; I no longer want to suffer through working with incompetent 1st-tier support people.

2. I expect to hear from someone within the next 24 hours with an actual update on this issue; I do not want to hear another blasé response which says "the investigation is still ongoing," because it very clearly was not being investigated.

3. I expect to hear from a manager within the next 48 hours as to why this issue was never worked, never resolved, and closed without contacting me.

If I do not hear from anyone within the times that I have put forth, I will escalate this issue through appropriate channels on my own, which will reflect even more poorly on those who have been doing a terrible job thus far.

04/25/2015 16:52

Subject: %TICKET_NUMBER%
From: Escalation Agent

Hi %ACCOUNT_NAME%,

Thank you for your response and for sharing your feelings with us. I'm Froilan, at your service.

We apologize for taking your valuable time in trying to resolve your issue with the error message when syncing your account in Windows Live mail. I fully understand how you feel about the inconvenience this has brought you. Please be informed that I will get back to our Support Specialist to get update about the status of your case. We understand the urgency of this issue; however, we cannot provide you with the time when a reply will be available. Rest assured that this post is being tracked and we will inform you immediately once we get any updates from them.

We appreciate your continued patience in going through this issue.

IMPORTANT REMINDERS:

Please save and keep the first email notification you received after submitting this request. That notification contains the link for this service request. If you did not receive another notification in 24 hours after your reply, you can check the status of this case and view our response by clicking the link on the first notification.

Best regards.

05/01/2015 09:54

Subject: %TICKET_NUMBER%
From: Escalation Agent

Hello %ACCOUNT_NAME%,

How is it going? We received an update coming from our Escalations Engineer and based from what we've observed, it seems the issue is encountered when the server settings for IMAP is not selected.

What you need to do is to make sure that you've selected and followed the Manual Server Settings for IMAP. This should allow the syncing of your accounts.

For more information about this setting, please refer to the IMAP setting that can be found in the link below.

http://windows.microsoft.com/en-US/windows/outlook/send-receive-from-app

Kindly share us the outcome afterwards.

Regards,
Microsoft Support Team

05/03/2015 22:22

Subject: RE: %TICKET_NUMBER%
From: %ACCOUNT_NAME%

This simply does not make sense; I have several other Hotmail accounts which I simply add them to Windows Live Mail and they automatically work. In the Properties dialog for each of my other accounts, the Server Information tab lists "My mail server is an HTTP server" with the following URL:

https://mail.services.live.com/DeltaSync_v2.0.0/sync.aspx

These are the EXACT same settings as the %EMAIL_ACCOUNT% email account. So why would this one account require custom IMAP settings?

Also, this account was working fine until a few weeks ago when I started seeing the errors. I made no changes to my settings, so it would seem that Microsoft has changed something about this specific Hotmail account. As I pointed out before, the web page banner when I am using this account reads "Outlook Mail (Preview)", which leads me to believe that this account was only partially migrated to the new Outlook Mail servers. With that in mind, I would theorize that the problem is due to a failed attempt on Microsoft's behalf when trying migrate my account from the old Hotmail.com servers to the new Outlook.com servers.

05/03/2015 22:23

Subject: %TICKET_NUMBER%
From: %ACCOUNT_NAME%

By the way, while I sincerely appreciate the assistance of the escalation engineer, I still have not heard back from a manager with an answer as to why my support case was closed by the initial support engineer after no work was completed and no attempts were made to contact me.

05/03/2015 23:56

Subject: %TICKET_NUMBER%
From: Escalation Agent

Hi %ACCOUNT_NAME%,

Thank you for providing us additional details. I'm Hyver from Outlook.com Support and I have reviewed the exchange of responses that you had with my colleagues. I'm truly sorry if the issue still persists after a week of communicating with us. I understand the displeasure that you've expressed for the support that you experienced. We're still here to help you on your issue.

I really apologize for the inconvenience that you've faced. I know you're expecting an email from a manager explaining why the support ticket was closed without someone trying to attempt to contact you. I'd like to let you k now that we are actively monitoring cases that are being reviewed by the Escalations Team and we do not close cases with open escalations. So we would like to ask for a copy of the email notification that indicates that the case was closed. I will include this to my reports as this could be an honest mistake or a system glitch,

I totally recognize that you deserve a valid explanation about what happened and we are not letting our customers to be upset at any point of our investigation. We don't like to see our customers upset and inconvenienced and we always strive to create a positive customer experience. With that being said, this should be reviewed again by our Escalations Team and should be taken care with utmost urgency. Please do not lost faith in us as we are doing our best to resolve this issue the soonest possible time.

As we speak, this support request is in our Escalations Team queue and should be treated with immediate attention. We appreciate your cooperation and understanding.

Should you have other questions or clarifications, please do not hesitate to contact us back.

Sincerely,
Hyver

05/05/2015 18:04

Subject: RE: %TICKET_NUMBER%
From: %ACCOUNT_NAME%

Hello Hyver,

There was never an email when the case was closed, which was part of my complaint. If you look at the case notes, you will see that I had to reopen the case on 04/25/2105 when I discovered that the case had been closed when I logged into this support website to check on the status.

05/05/2015 19:47

Subject: %TICKET_NUMBER%
From: Escalation Agent

Hello,

Thank you for letting us know that there was no email with regard to this case that was closed. We will report this to our higher support team and we'll get back to you immediately once we have the latest update from them.

Again, your patience and understanding are much appreciated.

Kindest regards,
Glenda

05/12/2015 22:46

Subject: %TICKET_NUMBER%
From: %ACCOUNT_NAME%

Another week has passed by, and yet I still have not heard anything, which leads me to believe that no one at Microsoft is actually doing nothing with this case. From my perspective, it seems that the "Escalation Agents" with whom I am working are simply stalling for time and hoping that either the problem will go away or I will quit trying and give up.

With that in mind, I will keep everyone up-to-date: the problem is still there - which should be expected since no one at Microsoft appears to be doing anything to fix the problem.

So let me recap the past week or so: I have heard nothing from Microsoft since the last time that I requested an update, my issue is not resolved, and I never heard from a manager at Microsoft with an explanation as to why the front-line engineers closed the case without contacting me or to discuss a plan of action to resolve this issue.

All of this reflects very poorly on the support engineers with whom I am working. As such, I want to work with someone else. Someone who knows what they're doing. Someone who can actually resolve an issue.

05/13/2015 03:37

Subject: %TICKET_NUMBER%
From: Escalation Agent

Note: To check the status of your request, kindly refrain from deleting our email notification. If you haven't received another notification in 24 hours, you can view the agent's response on URL link provided on the notification email.

Hi,

This is Audrey and we apologizer if this case has been going on for so long without any results. Upon checking your concern is still under investigation by our support specialist. We will be making a follow up regarding this and once we have received a word from them it will be immediately relayed to you.

Rest assured that we are exhausting our resources to resolve this matter as soon as possible.

Thank you,
Outlook.com Support Team

05/19/2015 13:36

Subject: %TICKET_NUMBER%
From: Escalation Agent

Hello %ACCOUNT_NAME%,

Sorry for the wait. We received an update coming from our Escalations Team and there's a possibility that your account's server settings were changed. With this, configuring your account to Windows Live Mail using this server "Windows Live Hotmail" will not work.

We are still working on your issue but what you can do is to use IMAP as your server type if you want to sync your emails.

Thank you for consideration and cooperation.

Regards,
Microsoft Support Team

05/29/2015 13:19

Subject: RE: %TICKET_NUMBER%
From: %ACCOUNT_NAME%

I do not wish to use IMAP; I have used that before and it has presented me with a separate series of issues. I will continue to wait for you to fix the problem with the server settings.


To be honest, at this point I have little faith that the Microsoft Outlook Support Team will do anything to resolve this issue. It is abundantly clear to me that the support team is ignoring my support case and simply waiting for me to close it, which I refuse to do since my problem is not resolved.

So once again I reiterate the obvious - this is a perfect example of truly awful technical support, and it demonstrates why many people eventually give up on Hotmail and switch to Gmail.

Simple Java Wrapper Class for raspistill on the Raspberry Pi 2

Like many self-proclaimed geeks, I can't resist a change to play with new technology. So when the Raspberry Pi 2 was released a short time ago, I didn't hesitate buying one. My first impressions was: for $35, that's a lot of computer power in a very small package. And because I really am a geek, I will admit that the first thing I tried to do with it was to install DOSBOX and run Microsoft Flight Simulator 4.

Once I got that out of my system, I started experimenting with some simple Java programming and the Raspberry Pi camera module. (It's great that Java is built-into Raspian Wheezy; in the past you had to install it.)

That being said, there isn't any direct I/O control of the camera via Java, although that's pretty much expected. When considering ways to control the camera I came across the Pi4J library, which provides Java-based APIs to control the Raspberry Pi's I/O. This looks like it will be great for me eventually, but for the moment the best idea that I could come up with was to write a simple Java-based wrapper class for the raspistill command line executable.

With that in mind, here's a sample class that you can use to take photos from Java on a Raspberry Pi. I added lots of code comments to explain how everything works, and I'll provide a little more detail after the code sample.

// This class is a very simple Java wrapper for the raspistill executable,
// which makes it easier to take photos from a Java application. Note that
// there are considerably more parameters available for raspistill which
// could be added to this class. (e.g. Shutter Speed, ISO, AWB, etc.) 

public class RaspiStill
{
   // Define the path to the raspistill executable.
   private final String _raspistillPath = "/opt/vc/bin/raspistill";
   // Define the amount of time that the camera will use to take a photo.
   private final int _picTimeout = 5000;
   // Define the image quality.
   private final int _picQuality = 100;

   // Specify a default image width.
   private int _picWidth = 1024;
   // Specify a default image height.
   private int _picHeight = 768;
   // Specify a default image name.
   private String _picName = "example.jpg";
   // Specify a default image encoding.
   private String _picType = "jpg";

   // Default class constructor.
   public void RaspiStill()
   {
      // Do anything else here. For example, you could create another
      // constructor which accepts an alternate path to raspistill,
      // or defines global parameters like the image quality.
   }

   // Default method to take a photo using the private values for name/width/height.
   // Note: See the overloaded methods to override the private values.
   public void TakePicture()
   {
      try
      {
         // Determine the image type based on the file extension (or use the default).
         if (_picName.indexOf('.')!=-1) _picType = _picName.substring(_picName.lastIndexOf('.')+1);

         // Create a new string builder with the path to raspistill.
         StringBuilder sb = new StringBuilder(_raspistillPath);

         // Add parameters for no preview and burst mode.
         sb.append(" -n -bm");
         // Configure the camera timeout.
         sb.append(" -t " + _picTimeout);
         // Configure the picture width.
         sb.append(" -w " + _picWidth);
         // Configure the picture height.
         sb.append(" -h " + _picHeight);
         // Configure the picture quality.
         sb.append(" -q " + _picQuality);
         // Specify the image type.
         sb.append(" -e " + _picType);
         // Specify the name of the image.
         sb.append(" -o " + _picName);

         // Invoke raspistill to take the photo.
         Runtime.getRuntime().exec(sb.toString());
         // Pause to allow the camera time to take the photo.
         Thread.sleep(_picTimeout);
      }
      catch (Exception e)
      {
         // Exit the application with the exception's hash code.
         System.exit(e.hashCode());
      }
   }

   // Overloaded method to take a photo using specific values for the name/width/height.
   public void TakePicture(String name, int width, int height)
   {
      _picName = name;
      _picWidth = width;
      _picHeight = height;
      TakePicture();
   }

   // Overloaded method to take a photo using a specific value for the image name.
   public void TakePicture(String name)
   {
      TakePicture(name, _picWidth, _picHeight);
   }

   // Overloaded method to take a photo using specific values for width/height.
   public void TakePicture(int width, int height)
   {
      TakePicture(_picName, width, height);
   }
}

The wrapper class should be pretty self-explanatory: calling the TakePicture() method with no parameters will use the application defaults, and calling the overloaded methods will allow you to specify the output filename and the width/height for the image. You specify the image type based on the file extension; (e.g. ".jpg", ".png", ".gif"). There are a bunch of additional raspistill options which you can easily add to the application; see the Raspberry Pi camera module page for more information.

Here's a simple application to test it out:

public class CameraTest
{
  // Define the number of photos to take.
  private static final long _numberOfImages = 5;
  // Define the interval between photos.
  private static final int _delayInterval = 5000;

  public static void main(String[] args)
  {
    try
    {
      // Create a new RaspiStill object.
      RaspiStill camera = new RaspiStill();
      // Loop through the number of images to take.
      for (long i = 0; i < _numberOfImages; ++i)
      {
        // Capture the image.
        camera.TakePicture("image" + i + ".jpg",800,600);
        // Pause after each photo.
        Thread.sleep(_delayInterval);
      }
    }
    catch (Exception e)
    {
      // Exit the application with the exception's hash code.
      System.exit(e.hashCode());
    }
  }
}

Now that I've shared this odd little sample, I'll wander back to my dungeon so I can keep playing with my Raspberry Pi.


Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/

Sunset On This Evening's Ride

Sunset during this evening's 52-mile bicycle ride...

WP_20150606_19_33_07_Pro
Sunset Over the Desert

Which reminds me, I should point out that there are both good and bad things about heading out for a long ride in the evening; one of the good things is getting to see sunsets like this. However, one of the bad things is when you realize that you're seeing a sunset like this while you're still 15 miles away from your house, which means that in a few minutes you will be plunged into a darkness that will surround you like an encroaching evil, where you are never more than one menacing pothole away from certain death.

Did I mention that the light on my bicycle failed five minutes after I turned it on? It's a good thing that I was once a Boy Scout and I had a backup light; it was better than nothing, but it barely offered enough light to see the road.

WP_20150606_19_42_40_Pro
Just Before Darkness Fell,
(And I still needed to ride half-way to the far horizon)

That being said, I can see that I have digressed from my original thought... it really was a nice sunset.

Ride Stats:

  • Primary Statistics:
    • Start Time: 5:14pm
    • Distance: 52.5 miles
    • Duration: 3:29:01
    • Calories Burned: 1656 kcal
    • Altitude Gain: 2181 feet
  • Speed:
    • Average Speed: 14.8 mph
    • Peak Speed: 30.8 mph
    • Average Cadence: 76.0 rpm
  • Temperature:
    • Average: 83.7 F
    • Minimum: 78.8 F
    • Maximum: 89.6 F
  • Heart Rate:
    • Average: 144 bpm
    • Maximum: 175 bpm

Follow Up: Converting Text Files to Audio Files

A couple of days ago I posted a blog which I titled Creating an HTML Application to Convert Text Files to Audio Files, in which I showed how to create an HTML Application that will convert a text file to an audio file. I thought that I would follow up that article with a quick demonstration which compares some of the built-in text-to-speech voices that ship with Windows 7 and Windows 8.

For the text in this demonstration I will use Edgar Allan Poe's famous poem titled The Raven, which is one of my personal favorites. (I used to have the poem memorized as a teenager... that might have been when I was going through a Fahrenheit 451 phase.)

Click the above image
to download the text file.

Microsoft Anna (Windows 7)

For the first demo we will take a look at the poem as read by the Microsoft Anna text-to-speech voice, which ships with Windows 7. This voice is acceptable, and certainly better than the text-to-speech voices which shipped before Windows 7 was released. But still, it has a few odd quirks to it, and as a result this voice typically sounds unnatural to me.

Click the above image
to download the MP3 file.

Microsoft David (Windows 8)

For the second demo we will take a look at the poem as read by the Microsoft David text-to-speech voice, which ships with Windows 8. This voice is considerably more acceptable that Microsoft Anna, and it sounds very natural to me. It is obviously a male voice, and several people with whom I have discussed this subject seem to prefer the Microsoft David voice over all the others.

Click the above image
to download the MP3 file.

Microsoft Hazel (Windows 8)

For the third demo we will take a look at the poem as read by the Microsoft Hazel text-to-speech voice, which also ships with Windows 8. This also much better than the text-to-speech voices which shipped before Windows 7, and it has an English accent which makes it fun for converting literary works.

Click the above image
to download the MP3 file.

Microsoft Zira (Windows 8)

For the fourth and final demo we will take a look at the poem as read by the Microsoft Zira text-to-speech voice, which also ships with Windows 8. This voice is my personal favorite, as I find it the most-natural sounding of all the text-to-speech voices which ship with Windows 7; this is the voice that I used for all of my textbook reading assignments.

Click the above image
to download the MP3 file.

In Closing

As a parting thought, the text-to-speech voices which ship with Windows 8 are extremely good in my opinion; they sound very natural, and they are very easy to understand. As a result, I have a tendency to speed up the playback a little when I am using the script which I shared in my previous blog. That being said, I hope these samples help to demonstrate the various text-to-speech voices that are available in the recent versions of Windows.


Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/

Creating an HTML Application to Convert Text Files to Audio Files

I'd like to take a brief departure from my normal collage of web-related and server-management examples and share a rather eclectic code sample.

Here's the scenario: I am presently working on another college degree, and I was recently taking a class which required a great deal of reading.  These assignments were all in digital form: I was using PDF or Kindle-based versions of the textbooks, and the remaining reading consisted of online articles. However, I am also an avid bicyclist, and the voluminous amount of reading was preventing me from going on some of my normal weekly rides. This gave me an idea: if I could convert the digital text to audio, I could bring my assignments with me on my longer rides and have my MP3 player read my assignments to me as I pedaled my way around the Arizona deserts.

I had experimented with Microsoft's built-in text-to-speech features some years ago, so I thought that this would be the perfect opportunity to revisit some of those APIs and write a full application to do the conversions for me. That being said, I could have written this application by using C# (which is my preferred language), but I decided to create an HTML Application for two reasons: 1) it is easier for me to share HTMLA applications in a blog, and 2) I keep this application in my OneDrive, so it's easier for me to modify the source code on systems where I don't have Visual Studio installed.

With that in mind, here is the resulting script which will convert a Text File to a Wave (*.WAV) File.

Using the HTML Application

As with most of my HTML Applications, the user interface is pretty simple to use; when you double click the HTA file, it will present you with the following user interface:

Clicking the Browse button will obviously allow you to browse to a text file, clicking the Close button will close the application, and clicking the Write File button will create a Wave file that is in the same path as the source text file. For example, if you have a text file at "C:\Text\Test.txt", the script will create a Wave file at "C:\Text\Test.txt.wav".

That being said, there are a few options which you can set:

  • Depending on your version of Windows and which languages you have installed, you will be presented with a list of available voices in the first drop-down menu; the following example is from a Windows 8 computer:
  • The second drop-down menu allows you to vary the playback speed; sometimes I prefer the playback speed to be slighter faster than normal:
  • The third drop-down menu allows you to alter the volume of the resulting Wave file:

Note: You can modify the script to alter the values that are used in the playback speed and volume drop-down menus, but the list of voices is obtained dynamically from your operating system.

Creating the HTML Application

To create this HTML Application, save the following HTMLA code as "Text to Wave File.hta" to your computer, and then double-click its icon to run the application. (Note that in a few places I added code comments which contain the MSDN URL for the APIs that I am using for this sample.)

<html>
<head>
<title>Text-to-Speech Writer</title>
<HTA:APPLICATION
  APPLICATIONNAME="Text-to-Speech Writer"
  ID="TextToSpeech"
  VERSION="1.0"
  BORDER="dialog"
  BORDERSTYLE="static"
  INNERBORDER="no"
  CAPTION="yes"
  SYSMENU="no"
  MAXIMIZEBUTTON="no"
  MINIMIZEBUTTON="no"
  SCROLL="no"
  SCROLLFLAT="yes"
  SINGLEINSTANCE="yes"
  CONTEXTMENU="no"
  SELECTION="no"/>
</head>

<script language="VBScript">

Option Explicit

Dim blnCancelBubble

' ----------------------------------------
' 
' OnLoad event handler for the application.
' 
' ----------------------------------------

Sub Window_OnLoad
  blnCancelBubble = False
  ' Set up the UI dimensions.
  Const intDialogWidth = 550
  Const intDialogHeight = 125
  ' Specify the window position and size.
  Self.resizeTo intDialogWidth,intDialogHeight
  Self.moveTo (Screen.AvailWidth - intDialogWidth) / 2,_
    (Screen.AvailHeight - intDialogHeight) / 2
  ' Load the list of text-to-speech voices into the drop-down menu.
  ' See the notes in WriteFile() for more information.
  Dim objSAPI, objVoice, objSelect, objOption
  Set objSAPI = CreateObject("SAPI.SpVoice")
  For Each objVoice In objSAPI.GetVoices("","")
    Set objSelect = Document.getElementById("optVoices")
    Set objOption = Document.createElement("option")
    objOption.text = objVoice.GetDescription() 
    objSelect.Add objOption
  Next
End Sub

' ----------------------------------------
' 
' Click handler for the Write button.
' 
' ----------------------------------------

Sub btnWrite_OnClick()
  ' Test for a file name.
  If Len(txtFile.Value) > 0 Then
    ' Test if we need to cancel bubbling of events.
    If blnCancelBubble = False Then
        ' Write the input file.
        Call WriteFile(txtFile.Value)
      End If
    End If
    ' Specify whether to bubble events.
    blnCancelBubble = IIf(blnCancelBubble=True,False,True)
End Sub

' ----------------------------------------
' 
' Change handler for the input box.
' 
' ----------------------------------------

Sub txtFile_OnChange()
  ' Enable the Write button.
  btnWrite.Disabled = False
  ' Enable event bubbling.
  blnCancelBubble = False
End Sub

' ----------------------------------------
' 
' Click handler for the Close button.
' 
' ----------------------------------------

Sub btnClose_OnClick()
  ' Test if we need to cancel bubbling of events.
  If blnCancelBubble = False Then
    ' Prompt the user to exit.
    If MsgBox("Are you sure you wish to exit?", _
      vbYesNo+vbDefaultButton2+vbQuestion+vbSystemModal, _
      TextToSpeech.applicationName)=vbYes Then
      ' Enable event bubbling.
      blnCancelBubble = True
      ' Close the application.
      Window.close
    End If
  End If
  ' Specify whether to bubble events.
     blnCancelBubble = IIf(blnCancelBubble=True,False,True)
End Sub

' ----------------------------------------
' 
' This is an ultra-lame workaround for the lack
' of a DoEvents() feature in HTA applications.
' 
' ----------------------------------------

Sub DoEvents()
  On Error Resume Next
  ' Create a shell object.
  Dim objShell : Set objShell = CreateObject("Wscript.Shell")
  ' Call out to the shell and essentially do nothing.
  objShell.Run "ver", 0, True
End Sub

' ----------------------------------------
' 
' This is an ultra-lame workaround for the lack
' of an IIf() function in vbscript applications.
' 
' ----------------------------------------

Function IIf(tx,ty,tz)
  If (tx) Then IIf = ty Else IIf = tz
End Function

' ----------------------------------------
' 
' Main text-to-speech function
' 
' ----------------------------------------

Sub WriteFile(strInputFileName)
  On Error Resume Next
  Dim objFSO
  Dim objFile
  Dim objSAPI
  Dim objFileStream
  Dim strOldTitle
  Dim strOutputFilename
  Const strProcessing = "Creating WAV file... "
  
  ' Define the audio format as 44.1kHz / 16-bit audio.
  ' See http://msdn.microsoft.com/en-us/library/ms720595.aspx
  Const SAFT44kHz16BitStereo = 35
  ' Allow text to be read as well as written.
  ' See http://msdn.microsoft.com/en-us/library/ms720858.aspx
  Const SSFMCreateForWrite = 3
  
  ' Define the output WAV filename.
  strOutputFilename = strInputFileName & ".wav"

  ' Create a file system object and open the input file.
  Set objFSO = CreateObject("Scripting.FileSystemObject")
  Set objFile = objFSO.OpenTextFile(strInputFileName, 1)
  
  ' Disable the form fields.
  optVoices.Disabled = True
  optRate.Disabled = True
  optVolume.Disabled = True
  txtFile.Disabled = True
  btnWrite.Disabled = True
  btnClose.Value = "Cancel"

  ' Test for an error.
  If Err.Number <> 0 Then
      MsgBox "Error: " & Err.Number & vbCrLf & Err.Description
  Else
    ' Store the original dialog title.
    strOldTitle = Document.title
    ' Display a status message.
    Document.title = strProcessing & Time()
    ' Pause briefly to let the screen refresh and capture events.
    Call DoEvents()
    ' Create a text-to-speech object.
    ' See http://msdn.microsoft.com/en-us/library/ms720149.aspx
    Set objSAPI = CreateObject("SAPI.SpVoice")
    ' Create a SAPI file stream object.
    ' See http://msdn.microsoft.com/en-us/library/ms722561.aspx
    Set objFileStream = CreateObject("SAPI.SpFileStream")
    ' Specify the stream format.
    ' See http://msdn.microsoft.com/en-us/library/ms720998.aspx
    objFileStream.Format.Type = SAFT44kHz16BitStereo
    ' Open the output file stream.
    objFileStream.Open strOutputFilename, SSFMCreateForWrite
    ' Specify the output file stream.
    ' See http://msdn.microsoft.com/en-us/library/ms723597.aspx
    Set objSAPI.AudioOutputStream = objFileStream
    
    ' Specify the speaking rate.
    ' See http://msdn.microsoft.com/en-us/library/ms723606.aspx
    objSAPI.Rate = optRate.Options(optRate.SelectedIndex).Value
    ' Specify the speaking volume.
    ' See http://msdn.microsoft.com/en-us/library/ms723615.aspx
    objSAPI.Volume = optVolume.Options(optVolume.SelectedIndex).Value
    ' Specify the voice to use.
    ' See http://msdn.microsoft.com/en-us/library/ms723601.aspx
    ' See http://msdn.microsoft.com/en-us/library/ms723614.aspx
    Set objSAPI.Voice = objSAPI.GetVoices("","").Item(optVoices.SelectedIndex)
    
    ' Loop through the lines in the input file.
    Do While Not objFile.AtEndOfStream
      ' Test if we need to cancel bubbling of events.
      If blnCancelBubble = True Then
        Exit Do
      Else
        ' Display a status message.
        Document.title = strProcessing & Time()
        ' Pause briefly to let the screen refresh and capture events.
        Call DoEvents()
        ' Speak one line from the input file.
        ' See http://msdn.microsoft.com/en-us/library/ms723609.aspx
        objSAPI.Speak objFile.ReadLine
      End If
    Loop
    ' Close the output file stream.
    objFileStream.Close
  End If

  ' Close the input file.
  objFile.Close

  ' Destroy all objects.
  Set objFileStream = Nothing
  Set objSAPI = Nothing
  Set objFile = Nothing
  Set objFSO = Nothing
  
  ' Reset the original dialog title.
  Document.title = strOldTitle

  ' Notify the user that the file has been written.
  MsgBox "Finished!", vbInformation, strOldTitle
  
  ' Re-enable the form fields.
  btnClose.Value = "Close"
  optVoices.Disabled = False
  optRate.Disabled = False
  optVolume.Disabled = False
  txtFile.Disabled = False
  btnWrite.Disabled = False

End Sub

</script>

<body bgcolor="white" id="HtmlBody">
<div id="FormControls">
  <table>
    <tr>
      <td align="left">
        <input type="file"
        style="width:250px;height:22px"
        name="txtFile"
        id="txtFile"
        onchange="txtFile_OnChange">
      </td>
      <td align="left">
        <input type="button"
        style="width:125px;height:22px"
        name="btnWrite"
        id="btnWrite"
        value="Write File"
        disabled
        onclick="btnWrite_OnClick">
      </td>
      <td align="right">
        <input type="button"
        style="width:125px;height:22px"
        name="btnClose"
        id="btnClose"
        value="Close"
        onclick="btnClose_OnClick">
      </td>
    </tr>
    <tr>
      <td align="left">
        <select name="optVoices"
          style="width:250px;height:22px">
        </select>
      </td>
      <td align="left">
        <select name="optRate"
          style="width:125px;height:22px">
          <option value="-2">Slowest</option>
          <option value="-1">Slower</option>
          <option value="0" selected>Normal Speed</option>
          <option value="1">Faster</option>
          <option value="2">Fastest</option>
        </select>
      </td>
      <td align="right">
        <select name="optVolume"
          style="width:125px;height:22px">
          <option value="25">25% Volume</option>
          <option value="50">50% Volume</option>
          <option value="75">75% Volume</option>
          <option value="100" selected>Full Volume</option>
        </select>
      </td>
    </tr>
  </table>
</div>
</body>
</html>

Note that I intentionally chose to have this HTML Application convert the text to audio one line at a time; this slows the down the conversion process, but it allows the conversion to be cancelled if necessary. (My original version of this script would convert an entire text file at one time; since there was no way to cancel the operation, the script appeared to hang when converting larger text files.)

Additional Notes

Once you have created a Wave (*.WAV) file, you can optionally convert it to an MP3 file for use in an MP3 player or mobile phone. (Most devices should playback Wave files, but MP3 files are considerably smaller and more portable.) There are a variety of Wave-to-MP3 converters out there, but I prefer to use the LAME encoder, which is an open-source code project that is available on SourceForge. Once you have the LAME encoder project compiled, (or you have located and downloaded a pre-compiled version), you can use LAME.EXE from a command prompt to convert your Wave files into MP3 files.

That being said, I prefer to automate as much as possible, so I have written a batch file which converts all of the Wave files in a directory to MP3 files and renames the source Wave files with a "*.old" filename extension:

@echo off

for /f "usebackq delims=|" %%a in (`dir /b *.wav`) do (
  for %%b in (^"%%a^") do (
    if not exist "%%~db%%~pb%%~nb.mp3" (
      lame.exe -b 128 -m j "%%a" "%%~nb.mp3"
    )
    if exist "%%~db%%~pb%%~nb.mp3" (
      move "%%a" "%%a.old"
    )
  )
)

Note that the above batch file was written for text-to-speech use, and as such it defines a bit rate of 128kbps, which would be pretty low for music files. If you want to repurpose this batch file for higher bitrates, modify the value of the "-b" parameter for the LAME.EXE command.

That wraps it up for today's post.


Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/