Make a Breathing Visualizer With an Arduino Stretch Sensor and P5.js

by mark1290 in Circuits > Arduino

910 Views, 1 Favorites, 0 Comments

Make a Breathing Visualizer With an Arduino Stretch Sensor and P5.js

Life With Every Breath: An Arduino and p5.js Project by Mark Lim

This project is created as a course assignment at the California State University, Long Beach; taught by Behnaz Farahi: DESN 586 Human Experience and Embodied Interactions Studio.

Project Description

In recent years, digital technologies have become layered into the background of everyday life. At the same time, mental health awareness is becoming equally ubiquitous: news articles regularly reinforce the idea that the US is facing a mental health crisis. However, people are interested not only in healing mental illness, but seeing life—encompassing work, play and relationships--through a lens of mental wellness.

For this project, I was inspired by the popularity of mental wellness activities to design a new experience to help with that goal. That led to thinking about one of the basic things we learn to calm ourselves down: taking deep breaths. Recently, wellness communities have gone farther, embracing "breathwork," which includes both ancient and newer techniques using conscious control of breathing to influence mental and physical states.

One of the challenges doing breathwork is difficulty knowing, outside of a literal gut feel, how your lungs are doing. So to augment breathwork with data, I found biofeedback, which includes a variety of experiences but generally involves a sensor on the body whose real-time data can give a person greater awareness--and control--of their physiology. A simple way to measure breathing is using a stretch sensor around the torso to measure expansion. A key idea in many breathing practices is to breath more with your lower belly, since shallow, chest-level breathing can signal danger to the body and cause unnecessary stress. Therefore, the sensor is intended to be placed around the belly.

As for how this data is visualized, I worked on a simple and artistic experience that aims to be meditative, rather than raw data or a graph. This is supported by the emerging field of neuroesthetics, which not only demonstrates that art relieves mental disorders, but is working to describe how exactly it does so.

So with the help of an Arduino Uno, I connected the sensor to an artistic breath visualization made with p5.js. The result is a uniquely mesmerizing way to practice deep breathing.

Note that it works best when you're sitting down in a chair with your back upright. Unfortunately, sitting back makes the cord less sensitive, and sitting cross-legged on the ground makes your abs throw off the sensor.

Project Context

The rest of the introduction describes my design process and trial-and-error experience. For straightforward instructions, skip down to Supplies.

I started the project wanting to create a way for people to feel more aware of their body through an artistic biofeedback experience. To do this, I did research on various options for breath sensing, and also meditative visuals.

Breath sensors

There are many sensors to measure breath, including the sensitive accelerometer in an Apple Watch. However, not all of them measure it with the fine detail that is important in breathwork, like how deep and expanded the lungs are. I reviewed various DIY options and have some case studies of related works below:

Simplest Breath Sensor for a MIDI Wind Instrument EVER - From a plastic water bottle. 

I am also interested in musical expression, so this seemed like a fun idea--it could measure the breath and encourage deep breathing by being in the form of a wind instrument. However, it strays from the original idea, and breathing in through a straw may not be appealing. The nail in the coffin was, in the COVID era that it would not be possible for avoid contamination issues with people breathing in and out of the same sensor chamber (even with different straws).

What is nose airflow sensor | Respiratory sensor for breathing and respiration

This fascinating sensor is placed in the nostrils to track thermal differences caused by breathing. But while it has medical value, it doesn't seem as appealing for an everyday person as a simple band around the chest.

DIY Breath Sensor With Arduino (Conductive Knitted Stretch Sensor)

This is a very similar breath sensor to what I ended up making. It uses conductive yarn to measure the expansion of the torso. However, I don't knit, and wanted something ready-made.

Can You Train People to Breathe Better?

This is the breath sensor I based my project on. I made some modifications because I wanted the belt to carry the Arduino Uno for wearable convenience. If I were to do it again, I would follow this tutorial but make the breathing monitor out of an old fanny pack. It saves buying the strap on Amazon, and has a built-in pouch for the Arduino.

Meditative Visuals

Aten Reign [art installation]

This was a massive art installation that turned the whole Guggenheim Museum into an immersive experience of gradients of color. By James Turrell, the most famous member of the Light and Space art movement, the work caused me to reflect on the psychology of colors, and all the shades they come in. One of the otherworldly qualities of his work is its ability to induce visual hallucinations, known as the Ganzfeld effect, through an immersive and uniform blanket of color. While the overall impacts of color are cultural and personal, the UX field has settled on guidelines for how colors tend to evoke emotion in digital experiences, such as how, "greens and blues symbolize nature and tend to make people feel serene, peaceful, and relaxed," while, "deep blue and greens can come off strong, powerful, energetic, and even evoke awe." Moreover, the crossover of neuroscience and aesthetics ("neuroesthetics") has a lot to say as well, with one expert noting that, regardless of color, "pinker hues tend to have a more calming and soothing effect on us".

Compound [art gallery]

I visited Compound, a local gallery, a few months before I started this project, and it had several pieces that I recalled when seeking inspiration. In its "Chaos to Cosmos" Exhibit, many sculptures played with sublime colors in circular form. Also, Chromasonic Field Study, an art installation there, caused me to reflect on the impact of ambient sounds and colors. The unique thing about this experience is that the sounds are carefully synchronized to match the rhythm of flickering LED lights to create a feeling of synesthesia; you are "hearing lights" or "seeing sounds." I appreciated this gallery for how it evokes a feeling of awe for a surreal sensory environment.

Tennis Backdrop [Band Concert]

Once I started thinking about surreal circles, I saw them everywhere. One example was this visual backdrop from a concert for the band, "Tennis." I liked the pink shades, and how the multiple sizes of rings increased visual interest.

Aurora Borealis [p5.js sketch]

Often, artificial designs can do best by mimicking what nature has already shown us; one such example is the awe one may experience on seeing the Northern Lights. Therefore, I looked for p5.js examples, and I was interested in how a few simple lines of code could make this interactive light display. The graph-like appearance also seemed like a natural match for breathing data. I pondered some quotes and striking visuals from this article about sublime spatial design:

Why would we want to inflict any sense of threat in a space that is supposed to generate a positive, spiritual emotion? Safe threat makes for a crucial distinction between the sublime and the beautiful [...] an essential character of the sublime is that it has the power to hurt yet does not care to hurt.
If the contact with awe has a rhythm, it is a pause. If it has a sound, it is silence.

Sounds like seeing the Northern Lights to me.

Polar Perlin Noise Loop [p5.js sketch]

Perlin noise is a common technique for adding organic randomness to CGI artwork, including 3D terrain landscapes and image textures. In this case, it is used to make a circle seem to come alive with ever-changing fluctuations. I liked this as a way of holding someone's attention.

Prototyping Process

Creating the Sensor

Building the sensor, I initially stuck very close to the Science Buddies instructions. First, I built the circuit using the same large number of wires. Since I wanted my experience to focus on only one sensor instead of two, I skipped the chest sensor and all the wires that came with that. I also didn't need the LEDs, so I left those out too. My initial design is in these TinkerCAD diagram and photos, and includes power and ground, two potentiometers and the belly sensor.

Next was putting together the belly strap with the rubber cord stretch sensor. It seemed to be a big challenge to get the hole just large enough--I spent a good while expanding the holes with scissors. Then, when I lit the strap to get rid of the loose threads, the holes became so large it was clear I overdid it.

I noticed during testing that the standard wires from my Elegoo kit weren't very long, so the Arduino and breadboard were sitting precariously on my knee. The solution was to attach a pouch to the strap. Another observation was that having the cord pulling pulling from both the top and bottom of the strap seemed to reduce the elasticity and make it less comfortable to breathe in. Therefore, I tried having just one line of cord between the straps, and I even tried removing the strap entirely and just having a cord around the belly. However, both of these options were less sensitive to expansion and also more likely to slip, so I kept the design.

Finally, I realized that I didn't need the potentiometers at all. They were used in the Science Buddies breathing system to set minimum and maximum reading parameters in order to calculate how many LEDs would light up. However, since I didn't have LEDs and was using p5.js, I could easily add any parameters there. With this, I experimented with minimalistic design. I tried removing the breadboard and simply soldering the resistor in place between the wires. However, with all the pulling forces happening with this being a wearable system, the solder soon broke. I could have re-done it more securely, but with the pouch sewn into the side of the strap, I ended up simply putting the breadboard and arduino together inside. To make it more secure, I used pliers to bend each jumper cable's connector 90 degrees so that they fit perpendicular into the pins. Then, I could easily tape the Arduino and breadboard together, back to back, and fit them in the pouch.

Box Breathing

My original concept was to make a literal visualization of the box breathing technique, a popular relaxation method that involves a cycle of inhaling, holding an inhale, exhaling, and holding the exhale for four seconds each. To do this, the breath sensor would measure the amount of time spent on each of the four parts of breathing. Meanwhile, the p5.js sketch would draw a line in a square, changing direction for each part of the breath cycle. It would look like this video, except imperfect to show the actual breathing of the person.

However, while it was technically possible to create, there were many issues that made it less rewarding. When testing it out, I immediately noticed that the data didn't look like a smooth sin curve as I was expecting. Instead, there were two peaks, one for the inhale, followed by a drop while air is held in the lungs, then another for the exhale. Because of this, I couldn't simply have a threshold for determining each breathing state, instead using a crude cyclic switch function. However, this often cycled too fast because the stretch sensor is unfortunately unable to tell the difference between muscle movement and actual breathing, so it was often inaccurate, either reacting to subtle movements or not reacting to breathing. Finally, I noticed that it turned the experience into one of 'gaming the system' to get a perfect square, rather than focusing on deepening your breath and feeling a state of ease.

Aurora Borealis [Prototype video]

My next idea was to admit the superior sublimity of nature, and attempt to mimic a literal visual of the aurora borealis. Following the p5.js sketch, I set it up to use the breath sensor reading to determine the height of the aurora, while keeping some random noise. To help provide guidance for the breathing, I thought of adding a looping background video that showed a wave on the beach going in and out. This looked okay, but I was limited by my coding skills from making the leap to something truly sublime. Therefore, I tried to go in a direction that prized simplicity, hence turning my attention to Light and Space art, and circles.

Making a Circle [Prototype video]

It was simple to get the sensor data to expand and contract the circle, so what could I do next? I was interested in biophilic design and biomimicry, which take inspiration from nature but blend it with other elements--perhaps the Aurora Borealis was too literal. I thought about the expansion and contraction, and circles, and recalled the tiny balloon-like air sacs in our lungs, called alveoli. These tiny structures do so much for us, so perhaps my experience could help us see them in a new way. To do so, I wanted the circles to look more organic and alive, so I found a Coding Train tutorial on perlin noise, which is a popular way to add randomness to CGI art. I loved how the circle now seemed to grow and shrink in a more natural way, almost like a balloon.

Adding Color and Form [Prototype video]

Next I thought about heightening the sense of biofeedback with the art, for a deeper sense of connection. I thought this could be done by also changing the shape in other ways. One obvious thing was color. I recalled the psychological research on the soothing effect of pink hues, and also the striking effect of pink circles in James Turrell's Aten Reign. Deep blue was also a candidate color since it also has calming effects and is associated with nature. Luckily, pink also seems like an organic and human color, whereas blue seems environmental, so I chose to make the circle pink. The complementary aspects of pink representing gathering lifeforce, and blue of releasing it is also a visual metaphor for our bodies in another way. With literally each in-breath, the sympathetic nervous system is activated and we are energized. With each outbreath, the parasympathetic nervous system is activated and we release some of that energy. I thought the artwork could help visualize this aspect of how people are truly re-becoming in each moment, as mindfulness allows us to experience.

Another way to bring in biomimicry would be to make the piece consist of a number of circles bunched in the shape of lungs, all expanding and contracting like alveoli. This would be a challenge, but I was able to find an example of a simple recursive tree, that expanded and contracted like lungs.

Finally, I wanted to have a softer edge around the circle, like those from the Compound gallery. I achieved this by using an easy glow effect from YouTube. I found the soft edges became even more interesting when I turned down the opacity, but ultimately decided that this washed out the image, and made it hard to consistently see the changes in size [Low opacity prototype video]

Bringing it all together [Prototype video]

I slowly brought the various p5.js sketches together in Dreamweaver, making extensive use of map(). Even having all the pieces, this project was very stressful (the irony!) for being new to coding. In the prototype video, the reason that the lungs are so jittery is only partly the code's fault. It's also because I'm screaming from excitement and relief!

To do this project, I got a lot of help from professors Behnaz Farahi and Steve Boyer, friends, the Arduino and p5.js communities, and--last but not least--ChatGPT. While I had never used it extensively before this, the platform was absolutely invaluable for translating prompts into code, blending code together, learning how it worked, and lots and lots of debugging its own code. I would likely have chosen a simpler project without the instantaneous feedback from ChatGPT.

Finally, after relishing that the lungs were now moving, I noticed that the movements of the lungs were jerky and erratic. One thing that really helped was switching the Arduino data from an Integer to Float, for capturing more minute movements. Also, a key data smoothing technique I used was applying a Low Pass Filter.

For future directions, one critique I received was that it did not seem to have a goal. I am interested in seeing if the background can adjust more slowly as a form of goal-oriented feedback to reward deep breathing. Specifically, the background would turn from pink to blue over a period of minutes, as the user's breath rate slows down and becomes more regular. The first step for this is to find variables that adapt to the user and are achieveable. I think it could do even more, and am open to ideas.

That's all. Hope you found this interesting!

Supplies

  • 1 Arduino Uno R3
  • 1 USB 2.0 Cable Type A/B (I used a printer cable)
  • 1 laptop to run Arduino IDE and p5.js
  • 1 Conductive rubber cord
  • 2 Alligator clip leads (comes with cord)
  • 1 1/4W 5k1Ω resistor
  • 2 Male-male flexible jumper wires
  • 1 Solid jumper wire kit
  • 1 Full-sized breadboard
  • 1 old fanny pack OR
  • 1 Adjustable nylon buckle strap kit
  • 1 small cloth pouch
  • 1 spool of thread w/needle
  • 1 lighter
  • 1 gorilla glue
  • 1 pair of sharp-ended scissors (or a hobby knife)
  • 1 pair of pliers (optional)
  • Repair tape (optional)

Cut the Belly Strap and Add Buckles

buckle-straps-installed.jpg

Adult supervision recommended

To make the belly strap, I advise using an old fanny pack with an adjustable strap. If one is not available, you can order the strap kit from Amazon, and sew a small cloth pouch to it to hold your Arduino.

If starting from the kit:

  1. Cut a piece of strap about 5 feet long. You can decide to cut it shorter later if desired.
  2. Outdoors or somewhere with good ventilation, use a lighter to melt ("heat seal") the cut ends. This should take just a second or two, so you shouldn't have much smoke. It prevents the threads from fraying.
  3. Install the buckles and adjustment clips on each end of the strap so it looks like the image (Source: Science Buddies)
  4. Buckle the strap, then put it on over your belly. The buckle should sit on your belly button. Tighten until there isn't much slack around the back but you can still breathe comfortably.
  5. Find where the strap is about at your 10 'o'clock (45 degrees to your left). Move the adjustment clip towards the buckle if it's in the way.
  6. Take off the strap and use scissors to cut it at that spot.

Add the Conductive Rubber Cord

IMG_4232.JPG
IMG_4241.JPG
IMG_4247.JPG
IMG_4246.JPG
  1. Heat seal both ends of the cut strap.
  2. Use a scissors or a hobby knife to poke two holes in one end of the cut strap, 1 inch from the cut and .25 inches from each edge (image 1). When the hole feels large enough, even if it looks too small, use the lighter to heat seal it. This will burn the loose threads and expand the hole to what it feels like (image 2)
  3. Fold each end of the buckle strap back and use a few drops of gorilla glue at the cut edges to seal them in place (see image 3). For the side with holes, make sure the holes are facing the new edge. They should now be small loops with enough room for the rubber cord to pass through.
  4. Thread the conductive rubber cord through the loop on the non-hole side.
  5. On the other side, pull each end of the cord through the holes and the loop on each end.
  6. Tie a knot in each end of the rubber cord, as close to the strap as possible. This is to keep the cord from falling through. There should be just an inch or two gap between the strap ends.
  7. Cut the cord on each side, making sure to leave about 1 inch of cord past each knot (see image 4).
  8. Pull on the strap ends to check that the cord doesn't come through. If needed, tie bigger knots.

Sew on the Pouch

IMG_4437.JPG

If you're using the strap kit, find your small pouch. Using a thread and needle, sew it onto the strap just to the left of the cord (about 3 'o'clock or directly on your left). As a novice sewer, I suggest using a simple whip stitch or similar. I simply re-stitched the same spot about 10 times for good measure. Then I pulled the thread in between the materials and the stitches twice and cut it.

Build the Arduino Circuit

IMG_4431.JPG
Schematic.png
IMG_4444.JPG
IMG_4445.JPG
  1. Use pliers to bend the metal ends of each jumper cable 90 degrees. This is so that they lie flat on the Arduino and breadboard and can be taped to them.
  2. Assemble the circuit on your breadboard and Arduino according to the schematic and photo.
  3. I recommend using ~3-4" jumper cables for the 5V and A5 wires, and ~8" jumper cables for the ground and resistor-to-sensor cables. I did not have these so I added a male-female cable to extend mine and more comfortably reach from the Arduino to the sensor.
  4. For the rubber cord, poke the jumper cable tips through each alligator clip and bend it on the other side to secure it. Then, use the teeth on each clip to clamp on the extra 1" of rubber cord hanging on each side of the strap.
  5. Optionally, use repair tape to tape the breadboard and Arduino together back-to-back, making sure that all the pins are covered.
  6. Connect the printer cable to the Arduino. Place the Arduino and breadboard in your pouch.
  7. Connect the printer cable to your computer. You're ready to test!

Upload Arduino Code

  1. Download and save the Arduino code attached, LowPassFilter.ino
  2. Read the commenting to understand how the low pass filter and other aspects work.
  3. Make sure the USB serial port is set to the appropriate one.
  4. Upload the code to your Arduino IDE.
  5. Open the serial monitor to test. You should see a series of readings that say "A5: 434" or some other number. It should fluctuate with your breathing, following a regular range.
  6. Use CoolTerm if you'd like to graph your data in Excel. Note that there will be two peaks for each breath cycle, once when you inhale and once when you exhale (I'm not sure why this happens).

Downloads

Create the P5.js Visual

  1. Download and save the p5.js folder here: Instructable.zip
  2. Extract the files.
  3. Optionally, examine the code with an IDE, located in /public and titled LungsBreathing2
  4. Turn off the Arduino IDE if it is on.
  5. Open the Terminal on your computer
  6. Change the directory to the Instructable folder which contains serialserver.js by typing the command: cd "[File Path]"
  7. For example: C:\Users\You> cd "C:\Users\You\[...]\Instructable\public"
  8. Type the command: node serialserver.js COM9
  9. The COM# will depend on your computer, check the Arduino IDE to confirm
  10. This should start the A5 data streaming in the Terminal instead of Arduino IDE. Open a web browser and type in the address bar: localhost:3000
  11. Click on the screen to activate the visual. It should start with a blank light blue screen, playing a voice with instructions. The visual starts after 1 minute.
  12. Remember that it works best when you're sitting down in a chair with your back upright.
  13. Enjoy!

*And if none of the above steps work, fake it.