Skip to content

Commit

Permalink
light-up boat: initial post
Browse files Browse the repository at this point in the history
  • Loading branch information
igor47 committed Dec 24, 2023
1 parent 07937bb commit 0c11cac
Show file tree
Hide file tree
Showing 9 changed files with 141 additions and 0 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"react-bootstrap-icons": "^1.10.3",
"react-dom": "18.2.0",
"rehype-format": "^5.0.0",
"rehype-raw": "^7.0.0",
"rehype-slug": "^6.0.0",
"rehype-stringify": "^10.0.0",
"remark-parse": "^11.0.0",
Expand Down
102 changes: 102 additions & 0 deletions posts/light-up-boat-parade.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
title: Light Up Boat Parade 2023
date: 2023-12-18
slug: light-up-boats
description: |
We decorated a boat for the Sausalito light-up boat parade!
image: /images/lights.png
---

In October, I completed [ASA104](https://asa.com/certifications/asa-104-bareboat-cruising/) with [Modern Sailing](https://www.modernsailing.com/content/bareboat-cruising-asa-104).
I wanted to take out some of their larger crusing boats, but due to the [wind patterns in the San Francisco Bay](https://boardsportscalifornia.com/understanding-san-francisco-bay-area-weather-the-wind-beneath-our-wings/), there's no wind in the winter.
Sailboats are for sailing, and I am not a big fan of recreation which consists of sitting around while an engine burns diesel.
My excuse came in the form of the [Sausalito light-up boat parade](https://www.winterfestsausalito.com/).
I could get on the water in a big boat, and not feel **too** bad about motoring around all day.
Plus, I had never been in a parade before!

## Decoration

Modern Sailing rentals are a 24-hour period starting at 9am.
Our plan was to get the boat first thing in the morning and spend the day decorating.
The parade was at 6pm or so.
We would sleep on the boat after the "Captains Afterparty", then wake up early to take the lights down.

Here's our final result:

<p>
<video controls muted loop disablepictureinpicture>
<source src="/videos/lightupboat.webm" type="video/webm" />
Download the <a href="/videos/lightupboat.webm">WEBM</a>.
</video>
</p>

## Rigging The Mainsail

A friend had a giant cache of [twinkly strings](https://twinkly.com/en-us/products/strings-multicolor).
Our plan was to hang them up in the mainsail triangle, and display some cool mapped patterns in 2D.
Here's our rigging plan:

![Rigging Plan](/images/light-up-boat-rigging.svg)

I was really worried about losing the main halyard, so we use a serious line with some extra-redundant knots to secure it at the mainsail clip and on the deck.
For the rigging, we used paracord with some alpine butterflies tied into it:

![Alpine Butterfly](/images/alpine-butterfly.jpg)

The first few twinkly strings, by the mast, used the entire length of the string.
For the later strings, we could start at the top, go back down to the boom, then go back up to the top again.
This required hosting the rigging, figuring out where the string would end up, and securing it on the rigging that ran along the boom.
Then we could lower the whole rigging, and secure the other end of the string in the loop that ran along the topping lift.

This was a huge plain.
It took us until the last two strings to figure out that we could just put paracord through the loops, and use paracord to hoist one string at a time.
If we do it again, we'll just install paracord for every LED string from the very beginning.

We ended up using 2 strings of 400 lights, and 1 string of 600 lights -- 1400 LEDs total on the mainsail triangle.

## Mapping

Our whole plan was to use the Twinkly app to map the lights to a 2D image.
This **absolutely** did not work.
First, the mast is really tall -- it was difficult just to get the whole set of lights in the frame.
To do that, we had to stand pretty far back, which made each LED hard to distinguish in the picture.
Finally, the strings swayed in the wind, and the whole boat rocked in the water -- no way to get a still image.

Thankfully, with just the default unmapped patterns, the Twinkly lights look pretty good.
However, I am now kind of obsessed with the idea of mapping the lights to a 2D image.
I think using a hybrid automatic-manual approach should work well.
I should be able to take a single photo as the base of the scene.
Then, I should be able to turn on sections of the lights, and then indicate their position in the base image.
It doesn't have to be perfect -- just good enough to get the general shape of the boat.

I would like to try writing some software for this in time for next year's parade.

## Other Lights

I bought some of [these lights](https://amzn.to/3RSKvv1) to put on the lifelines.
My plan was to control them with [WLED](https://kno.wled.ge/).
But I discovered that, though they are individually addressable, they have some bug in the implementation of the protocol that causes them to flicker unpredictably.

I did bring some of [these strings](https://amzn.to/3NI0LfP).
Unlike the previous lights, these don't explicitly advertise WS2812.
However, they do work well with WLED.
Their implementation of WS2812 is kind of [odd](https://todbot.com/blog/2021/01/01/ws2812-compatible-fairy-light-leds-that-know-their-address/).
Rather than shifting out the bits for the next light, they allow the controller to wiggle the entire common data line, and each LED knows its own address.
This means you cannot link multiple strands together serially -- the second string will just mirror the first.

I didn't have time to do anything fancy with these lights.
We used them with their default controllers using some built-in patterns.

## Future Work

For next time, I would dispense with the fancy Twinkly lights (which, wow, are pretty expensive!).
Instead, I would use the cheap strings off Amazon and write my own software to control them over WS2812.
Let me know if you have ideas for how to create a 2D mapping UI for this!

## The Parade

Oh yeah, there was a parade!
That part was super-fun.
We got to see all the other boats up-close, and listening to the marine radio chatter with the stressed-out parade organizers trying to keep everything going was pretty entertaining.
Next time I would like some other crew to feel confident driving -- turns out operating a 40' boat in close quarters with a bunch of other boats, in the dark, in a shallow marina, is stressful!
We didn't win any prizes, but we had a great time.
Binary file added public/images/alpine-butterfly.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions public/images/light-up-boat-rigging.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/lights.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/videos/lightupboat.webm
Binary file not shown.
3 changes: 3 additions & 0 deletions src/pages/posts/[slug].tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Head from 'next/head'

import rehypeRaw from 'rehype-raw'
import rehypePrism from '@mapbox/rehype-prism'
import rehypeFormat from 'rehype-format'
import rehypeSlug from 'rehype-slug'
Expand Down Expand Up @@ -98,6 +99,8 @@ export async function getStaticProps({ params }: { params: { slug: string } }) {
const body = await unified()
.use(remarkParse)
.use(remarkRehype, { allowDangerousHtml: true })
// raw html support
.use(rehypeRaw)
// @ts-ignore -- this has some kind of typing issue
.use(rehypePrism, { ignoreMissing: true })
.use(rehypeFormat)
Expand Down
5 changes: 5 additions & 0 deletions src/styles/default.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ main p > img {
@extend .ms-4;
}

main p > video {
max-width: 80%;
@extend .ms-4;
}

main blockquote {
background: #f9f9f9;
border-left: 10px solid #ccc;
Expand Down
9 changes: 9 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4407,6 +4407,15 @@ rehype-minify-whitespace@^6.0.0:
hast-util-whitespace "^3.0.0"
unist-util-is "^6.0.0"

rehype-raw@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/rehype-raw/-/rehype-raw-7.0.0.tgz#59d7348fd5dbef3807bbaa1d443efd2dd85ecee4"
integrity sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==
dependencies:
"@types/hast" "^3.0.0"
hast-util-raw "^9.0.0"
vfile "^6.0.0"

rehype-slug@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/rehype-slug/-/rehype-slug-6.0.0.tgz#1d21cf7fc8a83ef874d873c15e6adaee6344eaf1"
Expand Down

0 comments on commit 0c11cac

Please sign in to comment.