文档章节

呼吸灯的深入研究

BetaYuan
 BetaYuan
发布于 2016/10/31 12:58
字数 1030
阅读 16
收藏 0
点赞 0
评论 0

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

Re-creating the "breathing" LED

呼吸灯的逆向工程

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.

也许呼吸灯这东西没什么大不了的,然而苹果有一个专利关于用于指示电脑处于睡眠模式下LED亮灭的模式。

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.

最近有个个人项目,我想看看是不是能复制这个效果。事实上并不是我一个人这么做。Ladyada试着逆向工程这个几年前专利里提及的模式。不幸的是,她没有提供任何更进一步的东西,例如代码,那种慵懒的Arduino玩家可以用来创造这种效果的。这也是本教程的目的所在。

Digging Into the Math

挖掘数学根基

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.

苹果的专利声称呼吸模式只是简单的类正弦函数,但是据观察一个人(深)呼吸的模式比这个略复杂。也许一个正弦波对苹果是足够的,但是无法满足我的要求。在我呼吸的过程中,我趋向于不自在的快速吸气,然后突然停下来在#@%×(@#×(&%(@#%(。。。同时,从吸气到呼气之间的时间长度显得比呼气到下一次吸气之间的短。这不是简单的正弦,就如来自Ladyada(一个技术大姐)的示波器波形所揭示的。

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:

一个在Ladyada博客上一则评论认为这种闪烁模式能更精确的用 f(x) = esin(x)所建模。下图是该方程的图像:

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 →

© 著作权归作者所有

共有 人打赏支持
BetaYuan
粉丝 0
博文 47
码字总数 11273
作品 0
松江
程序员
iOS使用[核心动画]和[定时器]两种方式实现【呼吸灯动画】(仿蘑菇街价格标签)

最近公司需求做个类似小红书的标签呼吸灯动画,经过一段时间研究使用两种方式实现了该效果… 第一种方式使用定时器加 UIView动画,核心方法如下

秦无炎 ⋅ 2016/10/14 ⋅ 0

LED strip driver在pcDuino上完美运行

想在室内营造一点小氛围不,话说工程师工作繁忙也得自己造些情调不是。这我是在pcDuino上做的,接一个灯带驱动模块LED strip driver,链接文章里用的Arduino,附有程序代码,在pcDuino上点亮...

pc朵拉 ⋅ 2013/07/02 ⋅ 0

iOS 呼吸灯效果--RCLighting

RCLighting 可在任意view里添加呼吸灯效果,所谓呼吸灯效果,就是颜色和亮度慢慢若隐若现。 支持CocoaPods,pod 'RCLighting'。

红薯 ⋅ 2014/07/14 ⋅ 0

PIC16F883和TLC5615(DA)数模转化实验,呼吸灯

今天上课做了数模转换的实验。感觉很好玩,在这里写下。 器材:PIC16F883控制芯片、TLC5615、LED灯一个、电阻一个(1K)、PICkit2下载器 实验说明,本实验采用I/O模拟方法实现数模转换,转换...

0101 ⋅ 2012/07/06 ⋅ 0

OPPO在Find 7的5.5英寸屏幕上贴了防爆膜

OPPO在Find 7的5.5英寸屏幕上贴了防爆膜。 Android开发入门 372858684消息,防爆膜可以有效的防止屏幕碎裂的时候玻璃不会迸溅,但是防爆膜比较容易划伤,算是一把双刃剑吧。OPPO将呼吸灯做在...

净水居 ⋅ 2014/07/14 ⋅ 0

Qt 动画框架 按钮显示效果

怎么使用Qt 动画框架做一个 类似 呼吸灯 那样的 按钮,指点一下!

孔乙己式 ⋅ 2015/06/09 ⋅ 1

SYD8821 PWM模块使用说明

SYD8821是具有全球领先低功耗(RX 2.4mA @-94.5dBm灵敏度,TX 4.3mA @0dBm输出功率)的蓝牙低功耗SOC芯片,在极低电流下实现了优异的射频性能,搭配176kB SRAM,512kB flash,非常适合中高阶可...

chengdong1314 ⋅ 03/23 ⋅ 0

说说 Android 中的通知(Notification)

当应用程序不在前台运行,这时就可以借助通知( Notification )向用户发送一些提示消息。 发出通知后,手机最上方的状态栏中就会显示一个通知图标,下拉状态栏就会看到通知的详情。 1 基本用...

deniro ⋅ 05/20 ⋅ 0

pcDuino带动LED灯带

在节日里面,人们总喜欢张灯结彩来庆祝一番。 这时候,自然少不了彩灯带了。 感谢LED技术的发展, 现在有了LED灯条。 高电流的LED灯条一般的单片机是不能直接驱动的,所以需要一个LED strip...

pc朵拉 ⋅ 2013/11/30 ⋅ 1

NodeMCU学习笔记之初始化工作

NodeMCU学习笔记之初始化工作 丛林听雨2016-11-04132 阅读 工作初始化 NodeMCU是一个开源的可以运行脚本的微控制器,直接支持WiFi链接和GPIO,而且成本低廉。是物联网开发的不二之选。板子是...

丛林听雨 ⋅ 2016/11/04 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

JavaScript零基础入门——(八)JavaScript的数组

JavaScript零基础入门——(八)JavaScript的数组 欢迎大家回到我们的JavaScript零基础入门,上一节课我们讲了有关JavaScript正则表达式的相关知识点,便于大家更好的对字符串进行处理。这一...

JandenMa ⋅ 今天 ⋅ 0

sbt网络问题解决方案

转自:http://dblab.xmu.edu.cn/blog/maven-network-problem/ cd ~/.sbt/launchers/0.13.9unzip -q ./sbt-launch.jar 修改 vi sbt/sbt.boot.properties 增加一个oschina库地址: [reposit......

狐狸老侠 ⋅ 今天 ⋅ 0

大数据,必须掌握的10项顶级安全技术

我们看到越来越多的数据泄漏事故、勒索软件和其他类型的网络攻击,这使得安全成为一个热门话题。 去年,企业IT面临的威胁仍然处于非常高的水平,每天都会看到媒体报道大量数据泄漏事故和攻击...

p柯西 ⋅ 今天 ⋅ 0

Linux下安装配置Hadoop2.7.6

前提 安装jdk 下载 wget http://mirrors.hust.edu.cn/apache/hadoop/common/hadoop-2.7.6/hadoop-2.7.6.tar.gz 解压 配置 vim /etc/profile # 配置java环境变量 export JAVA_HOME=/opt/jdk1......

晨猫 ⋅ 今天 ⋅ 0

crontab工具介绍

crontab crontab 是一个用于设置周期性被执行的任务工具。 周期性执行的任务列表称为Cron Table crontab(选项)(参数) -e:编辑该用户的计时器设置; -l:列出该用户的计时器设置; -r:删除该...

Linux学习笔记 ⋅ 今天 ⋅ 0

深入Java多线程——Java内存模型深入(2)

5. final域的内存语义 5.1 final域的重排序规则 1.对于final域,编译器和处理器要遵守两个重排序规则: (1)在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用...

江左煤郎 ⋅ 今天 ⋅ 0

面试-正向代理和反向代理

面试-正向代理和反向代理 Nginx 是一个高性能的反向代理服务器,但同时也支持正向代理方式的配置。

秋日芒草 ⋅ 今天 ⋅ 0

Spring 依赖注入(DI)

1、Setter方法注入: 通过设置方法注入依赖。这种方法既简单又常用。 类中定义set()方法: public class HelloWorldOutput{ HelloWorld helloWorld; public void setHelloWorld...

霍淇滨 ⋅ 昨天 ⋅ 0

马氏距离与欧氏距离

马氏距离 马氏距离也可以定义为两个服从同一分布并且其协方差矩阵为Σ的随机变量之间的差异程度。 如果协方差矩阵为单位矩阵,那么马氏距离就简化为欧氏距离,如果协方差矩阵为对角阵,则其也...

漫步当下 ⋅ 昨天 ⋅ 0

聊聊spring cloud的RequestRateLimiterGatewayFilter

序 本文主要研究一下spring cloud的RequestRateLimiterGatewayFilter GatewayAutoConfiguration @Configuration@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMi......

go4it ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部