呼吸燈的深刻研究

http://sean.voisen.org/blog/2011/10/breathing-led-with-arduino/

Re-creating the "breathing" LED

呼吸燈的逆向工程html

October 31, 2011

Perhaps it’s not surprising, but Apple has a patent on the iconic "breathing" pattern used for the sleep indicator LED on all their computers.web

也許呼吸燈這東西沒什麼大不了的,然而蘋果有一個專利關於用於指示電腦處於睡眠模式下LED亮滅的模式。app

Recently — for a personal project — I wanted to see if I could replicate this effect. It turns out that I wasn’t alone. Ladyada tried to reverse engineer the pattern a few years ago. Unfortunately, she stopped short of providing anything — like code — that the lazy web surfing Arduino hacker might use to recreate the effect. That’s the purpose of this short tutorial.ide

最近有個我的項目,我想看看是否是能複製這個效果。事實上並非我一我的這麼作。Ladyada試着逆向工程這個幾年前專利裏說起的模式。不幸的是,她沒有提供任何更進一步的東西,例如代碼,那種慵懶的Arduino玩家能夠用來創造這種效果的。這也是本教程的目的所在。函數

Digging Into the Math

挖掘數學根基oop

The Apple patent claims that the breathing pattern is a simple sinusoid, but observation of one’s own (heavy) breathing will show that the pattern is a little more complicated than that. Maybe a sine wave works for Apple, but it doesn’t look quite right to me. In my own breathing, I tend to ease in to a fast inhale, and stop suddenly before easing out to a fast exhale. Also, the period between inhalation and exhalation happens to be shorter than the period between exhalation and the next inhalation. This is not a simple sinusoid, as the oscilloscope plot from Ladyada’s own investigations will attest.post

蘋果的專利聲稱呼吸模式只是簡單的類正弦函數,可是據觀察一我的(深)呼吸的模式比這個略複雜。也許一個正弦波對蘋果是足夠的,可是沒法知足個人要求。在我呼吸的過程當中,我趨向於不自在的快速吸氣,而後忽然停下來在#@%×(@#×(&%(@#%(。。。同時,從吸氣到呼氣之間的時間長度顯得比呼氣到下一次吸氣之間的短。這不是簡單的正弦,就如來自Ladyada(一個技術大姐)的示波器波形所揭示的。ui

A commenter on Ladyada’s blog suggested that the pattern is probably more accurately modeled by f(x) = esin(x). Plotting this equation gives the following:this

一個在Ladyada博客上一則評論認爲這種閃爍模式能更精確的用 f(x) = esin(x)所建模。下圖是該方程的圖像:spa

Plot of exp(sin(x))

Compare the curvature characteristics of this plot with the simple sinusoid below:

對比這條曲線和正弦曲線的差別:

Plot of sin(x)

The plot of f(x) = esin(x) has wider "troughs" (periods between inhale and exhale) and narrower "peaks" (periods between exhale and inhale), more accurately matching natural breathing patterns. As a simple experiment, try breathing "sinusoidally" and you’ll see how unnatural it feels.

 

Turning it Into Code

For my own experimentation, I used the ubiquitous Arduino. The Arduino supports analog output using pulse-width modulation (PWM) mapped to integer values from 0 to 255. To recreate the breathing LED, this means manipulating the original equation f(x) = esin(x) such that the amplitude fits within the PWM range.

I took enough math in school to know that the minima and maxima of any equation occur at critical points in the equation, where the derivative of that equation is either 0 or its not differentiable. Beyond that, I left it to Wolfram Alpha to do the hard work. It turns out that the minimum of the wave is 1/e, and the maximum is e. Using this information to adjust the amplitude of the equation such that it fits within the 0 to 255 range gives the following:

The final equation

Swap x for the number of seconds that have elapsed, and map the above equation to PWM output on any supported Arduino pin, and you have the beginnings of a breathing pattern. The problem is that the frequency may be too high or low (depending on your preference), and so the breathing will appear fast or slow. Easy enough: Multiply x by any value to adjust the frequency. I like π/2.

Finally, 1 - e, and 255/(e - 1/e) are constants, and can be pre-calcuated to reduce overhead. The final Arduino sketch is as follows (with the LED connected to pin 11, a suitable resistor in series, yadda, yadda …):

#include <math.h>

void setup()
{
  pinMode(11, OUTPUT);
}

void loop()
{
  float val = (exp(sin(millis()/2000.0*PI)) - 0.36787944)*108.0;
  analogWrite(11, val);
}

Gratuitous Video

And, in case you don’t have an Arduino handy, here’s a short video of the final effect:

 

Conclusion

You might be asking: Is it really that big of a difference? Wouldn’t a simple sinusoid suffice? To answer the latter question: yes. To answer the former: the difference is noticeable, but only slightly. Steve Jobs was a notorious perfectionist. I like to think that he would’ve cared about such things.

More posts in the archives →

相關文章
相關標籤/搜索