Moon Gaze

Moon Gaze

A wearable interactive partner finder. A project by Yiyi Shao and Finlay Braithwaite for DIGF6037, Creation and Computation, Digital Futures, OCAD University.

人有悲欢离合,月有阴晴圆缺,此事古难全。但愿人长久,千里共婵娟 — 苏轼 《水调歌头》

Translation: The moon does wax, the moon does wane, and so men meet and say goodbye. May we all be blessed with longevity though far apart, we are still able to share the beauty of the moon together.

Our idea inspired from an old well-known Chinese poem Shui Diao Ge Tou by Shi Su (also known as Tungpo Su, 1037 – 1101). This poem describes the poet himself travelling long distances and missing his family. The moon is a comfort for him, because no matter how far people are separated, they are still watching and sharing the beauty of the same moon. Chinese people still carry on this traditions as part of the Mid Autumn Festival.

Moon gaze is a contemporary take on this desire for long distance connectedness through facing one another. With Moon Gaze, one can find, face, and connect with their partner irregardless of physical distance.

Moon Gaze creators Yiyi Shao and Finlay Braithwaite facing one another at a short distance.
Moon Gaze creators Finlay Braithwaite and Yiyi Shao face one another at a short distance.

User Experience

With a concept taking shape, we began thinking about how we could create a meaningful experience for users. A primary consideration was making the experience as natural as possible, requiring little to no input from users.
We focused on the experience of two partners facing one another, albeit at a great distance. One output of our system would allow a user to determine if they were facing one another. Interacting with this output would also allow the user to hone in on their partner’s bearing. We also saw meaningful interaction in knowing if your partner was facing you. This feedback would be simpler, only revealing if your partner was facing towards you or not.

With Moon Gaze’s summary objective of partners facing one another, we resolved that the interaction should be connected to the users’ body. The interaction would not be with a screen or input device, rather the interaction would respond to the users’ movements. With this in mind, we proceeded to develop Moon Gaze as a wearable interactive technology.

In making this determination, we also investigated Moon gaze as an object detached from the body. We thought it could be nice to have small arrow that pointed towards your partner. We also flirted with the idea of implementing Moon Gaze in a chair; a middle ground between object and wearable.

Proceeding as a wearable, we weighed our options for physical notification. We went back and forth between using a vibration motor or an LED. We felt a vibration motor would be discrete to the user and create an intimate haptic physical connection between partners. However, we felt that an LED would make for a stronger presentation of our first iteration and we felt confident in our ability to implement and finesse the behaviour of LEDs.

Moving forward with LEDs, we concluded that the blink rate of LEDs in the wearable would help orient partners to face one another. The faster the blinking, the closer the match. While we felt it could be interesting to know which direction, right or left, you needed to turn in order to find your partner, the math in determining left and right in a 360 degree bearing system was beyond the scope of the first iteration.

A second set of LEDs would turn on and off whether your partner is facing you or not.



Design Sketches

To match our concept, we attempted to get as close as possible to the theme of the moon. In deciding to make wearables, we faced a lot of options. There are so many possibilities for wearables; it could be a hat, a t-shirt, a jumper, a pair of trousers. Which one is better? Which kind of material would be the best to play with? What colour should we choose? Where should we put our LED moon? Where should we put our hardware? Imagining, designing, and creating our wearables was a significant portion of the overall project.

Sweaters on the rack at Uniqlo.

We choose to hack knit sweaters for our project, as they allow us to weave a string of LEDs into the knit itself. We went to Uniqlo to find suitable sweaters. In the men’s clothing section we found dark grey knits that perfectly mimic the dark night sky, a perfect backdrop for our moons.

LED string woven into sweater.
LED string woven into sweater.

We began to embed and sew the LED from the sweaters’ insides. However, it wasn’t a good look with only bare LEDs on the outside of the sweater. The light from the LEDs also appeared harsh without diffusion. Ruminating on this for quite some time, we designed a fabric cover for the LEDs but it still didn’t have the look we wanted. We found a bag of feathers in the Digital Futures studio space and they immediately found a home in our design. After playing around with feathers for a while, it seemed to be a perfect material to diffuse the light!

LED feather covering.
LED feather covering.

Tip: Adding a fabric backing helped cover the wires, making the sweater more comfortable to wear. Also, the LED string won’t be snagged when the user removes the sweater.

LED protective backing.
LED protective backing.
Moon Gaze wearables ready for presentation.
Moon Gaze wearables ready for presentation.

We wanted the LEDs to be highly visible and felt that individual LEDs would be difficult to implement. At this point, we weren’t up for the challenge of working with Neo Pixels, although they are the natural progression for our next iteration. We went a trip to Michaels and found a fancy LED string which is used to decorate Christmas trees. We checked the voltage of the LED string (4.5V) and found it should be fine to work with Feather M0 board if we connect to the USB pin to get the 5V power. We cut off the built-in battery pack from the LED string to gain access to the string’s positive and negative leads. As we were using 5V from the USB pin, we had to switch the LEDs using transistors connected to a digital output pin on the Feather.


Code on GitHub

The main coding challenge we faced was determining a vector between two locations on earth. In investigating geographic calculations, we determined that we needed to resolve a rhumb line bearing between the two coordinates. A rhumb line bearing is a single bearing that will take you to a destination on Earth. On a flat map, a rhumb line appears as a straight line. However, the earth is not flat like a map. As such a rhumb line is not the shortest distance to a destination. If you consider the earth as a sphere, the shortest distance between two points is a ‘great circle’ route. The haversine formula allows you to calculate the route between two points on a sphere, allowing the calculation of a great circle route on Earth. Despite the benefits of following the shorter great circle route, it cannot be described as a single bearing. If following a great circle route, your polar bearing changes over the course of the route. Sailors often used rhumb lines for that very reason. With a rhumb line you can maintain a constant compass bearing for the entire voyage (‘Keep north on your left and sail till dawn!’). We resolved to use the rhumb line to calculate a single bearing between our Moon Gaze partners.

The math for calculating a rhumb line bearing is the stuff of geographical math textbooks and fairly easy to find on the internet if you know what you’re looking for. We found a goldmine in Chris Veness’ ‘Movable Type’ site Calculate distance, bearing and more between Latitude/Longitude points. This is a live portfolio piece demonstrating his capacity for interpreting complex systems and creating interactive online tools to study them. The material on this site is free to use as long as his copyright is cited in any resulting works.

In addition to having an interface to calculate rhumb line bearings, Veness breaks down both the math and Javascript code.

Rhumb line bearing calculations from 'Movable Type Scripts'
Rhumb line bearing calculations from ‘Movable Type Scripts’ © 2002-2017 Chris Veness

While all freely available, it was a formidable challenge as relatively inexperienced coders to make sense of the math, evaluate the code, and translate it for the Arduino IDE’s C/C++ compiler. Here’s our translation:

double rhumbDIFF = log(abs(tan(rLAT2 / 2 + M_PI / 4) / tan(rLAT1 / 2 + M_PI / 4)));
 double rhumbBRNGrad = atan2(deltaLONG, rhumbDIFF);
 double rhumbBRNGdeg = rhumbBRNGrad * 180.0 / M_PI;
 headingToPartner = fmod((rhumbBRNGdeg + 360), 360);

Our favourite part of this code is the final modulus function that corrects for a negative bearing. It was an effective introduction into the power of modulus to place a value within a range.

Not knowing what our GPS data would look like, we also created functions to convert between degrees.minutes.seconds, decimal degrees, and radians (required for the rhumb bearing calculation). This math is less specific and available from a number of sources. Our source was Steven Dutch’s site Converting UTM to Latitude and Longitude (Or Vice Versa).

With the rhumb line bearing calculation in hand, we created functions to compare the local heading to the bearing pointing towards the remote partner. We wanted to determine the absolute difference in these values. The lower the difference, the faster the LED blink rate. The main challenge here is the 360 degree system of headings and bearings. 360 degrees equals 0 degrees. With this in mind, a heading of 10 degrees and a bearing of 350 degrees are only 20 degrees apart, yet with simple math they are 330 degrees apart. Both statements are true, but if you’re moving from 10 degrees to 350 by rotating 330, you’re going the long way around the circle. With this logic in mind, we created a correction if the absolute difference between heading and bearing is greater that 180 degrees (the long way around the circle).

double blinkCalc = abs(bearingToPartner - localHeadingDegrees);
 if (blinkCalc > 180){blinkCalc = -blinkCalc + 360;}

The next challenge was connecting our paired devices to one another on the internet. For this we employed PubNub ( to publish live data from each device. PubNub’s history function was crucial for allowing interaction even if both devices were not online as it stores the last published messages for each channel in a buffer.

For our interaction, each device publishes its local GPS coordinates as well as a local match status boolean that describes if a user is facing the other. The publishing was fairly straightforward using PubNub’s Arduino API code as massaged by our professors Nick Puckett and Kate Hartman.

Appreciating that a local user might not have a GPS fix during a session, we created a ‘self read’ function that pulls back the last known GPS coordinates of the device for use in the bearing calculations. If a GPS fix is achieved, the current data is published and used in updated bearing calculations.

A key challenge was the ‘blocking’ element of the Arduino PubNub code. While reading data from a subscribed PubNub channel, everything else in loop function temporarily stops. This includes sensing magnetometer data and our blinking LEDs. This behaviour is so irksome that we are looking into other data publishing solutions for our second iteration, including using the Particle Photon instead of the Adafruit Feather M0.

Another requirement of our coding was integrating the Adafruit GPS and SparkFun Magnetometer (compass) sensors. However, both companies provide expansive documentation with example code, making the integration of these devices fairly straightforward.

Privacy and Safety

It is reckless to publish one’s GPS coordinates if unsure about the identity and motives of that data’s audience. For future versions of this project, all bearing calculations would happen server-side, negating the need to share coordinates between users.


Moon Gaze provided an exciting opportunity to explore GPS and Magnetometer sensors which neither of us had used before.

Moon Gaze electronics overview.
Moon Gaze electronics overview.
Adafruit Ultimate GPS Featherwing

The Featherwing made for easy integration with our Adafruit Feather M0 micro controller. The featherwing is designed to stack on-top of the feather easily connecting the default connection pins.

The GPS unit connects via a serial connection and the example code makes it easy to pull a GPS coordinate from the device. However, we struggled most with getting a GPS fix in the Toronto downtown core and, as mentioned, adapted our code to operate without a GPS fix by pulling the last known address from PubNub on boot.

Link: Adafruit Ultimate GPS Featherwing

SparkFun HMC5883L Magnetometer

This little sensor board provides the local compass heading required to determine if you are indeed facing your partner. This device connects via I2C and the provided documentation and examples made this fairly straightforward to integrate.

Link: SparkFun HMC5883L Magnetometer

Future Developments

We see a lot of potential for future iterations of this project.

As a two-week crash project, we’re incredibly happy with our results, but are already planning next steps based on our team’s observations as well as feedback from our colleagues.

The first refinements would come in developing the physical wearable further. Scaling the electronics down and housing them in a wearable enclosure would make Moon Gaze a more natural experience. We are open to exploring different types of wearable notifications for Moon Gaze. We are interested in testing haptic feedback such as vibration motors for a future iteration.

Unhappy with problems inherent with PubNub’s Arduino implementation, we are looking at other data publish/subscribe options. Adafruit IO is top of the list as it could be more tightly integrated with the Feather M0. Another alternative would be to move to the Particle Photon which features built in networked functions for device-to-device variable sharing.

Moon Gaze could be further developed by adding a web component that displays connections for each relationship. On a meta level, this could be an aesthetic data visualizations of all the connections on Earth. As our cohort mentioned during our presentation, it can also be a useful product for people to find their friends in large event or activities such as a music festival. We do put into concern about our users’ privacy, so we will be very careful for this aspect for any future developments.

Video Demo


Leave a Reply