Temperature to Morse Code

Atommann

  - . -- .--. ..--- -- --- .-. ... .


缘由

做这种温度计的想法由来已久,但直到近两天才把它做来了。夏天来了,我家里那位总是说空调的温度显示不正确,比如空调上显示的是 27 度,她认为可能是 24 度左右,我则说空调的温度正负一度很正常,但不会偏差这么大,她不信我,我决定尽快做个温度计出来说服她(另一个原因是我从未制作过电池供电的嵌入式设备,因此决定尝试一下)。


设计构想

因为想设计成用电池供电,显示设备最初考虑使用 LCD 而不是数码管,因为数码管比较耗电。我正好有 2x8 的字符型 LCD 模块(每行可显示 8 个字符,两行),其资料上显示工作电流典型值是 1.5mA,背光 LED 典型工作电流 15mA,最大 25mA,可见 LCD 的背光是比较耗电的,如果用电池供电,这不是一个好事情。

此外,LCD 还需要占用更多的 IO 口,LCD 体积也较大,而我想设计一个小温度计。还有一点:在夜晚如果不开背光,LCD 上的显示是不可读的。当然我可以不用 LCD 的背光而自己加一个 LED 来照亮 LCD,那既然可以加一个 LED,为何不就用这个 LED 来做显示呢?

用 1 只 LED 来做显示器,听上去有点疯狂,但这是完全可行的,而且这个技术在 170 多年前已经解决了:使用 Morse 码。国际 Morse 码的数字非常有规律,极易读取,如下:

1 .----
2 ..---
3 ...--
4 ....-
5 .....
6 -....
7 --...
8 ---..
9 ----.
0 -----

用 LED 做显示时,点(.)表示 LED 短亮,划(-)表示 LED 长亮,划的长度是点的 3 倍。让 Morse 码显示得慢一些,并且只显示两位整数,这样更好读值。


硬件设计


MCU

由于显示器只用一只 LED,只占用 mcu 一个 IO,这样可以使用只有 8 个脚的 AVR,这个项目使用了 ATTiny85V,其实 ATTiny45/ATTiny13 也是可以的。

MCU 工作在 1MHz,我想让它工作在内部 128KHz 以进一步省电,但是在读 DS18B20 的时候有问题。


供电

采用两节 AA 电池,3V.


LED

为了省电,在 LED 上串联了一只 1k 欧的电阻,假设红色 LED 的压降是 1.7V,根据欧姆定律,LED 工作时的电流为:

(3V-1.7V)/1000 Ohm = 0.0013A = 1.3mA


温度传感器

有多种温度传感器可供选择,比如 NTC, LM35, TMP36 等等。这里采用 DS18B20 单总线数字温度传感器,误差是正负 0.5 度,数据手册上说它的工作电压是 3.0V 到 5.5V,电池的电压正好是 3V,网上有人报告说在 2.5V 时 DS18B20 都可以工作。

DS18B20 的 VCC 使用 tiny85 的一个引脚供电,这样在 tiny85 休眠的时候可以关闭 DS18B20 的电源以节省电池能量。

其实在 tiny85 内部有一个内置温度传感器,但不是很准确(即使做校正也不太准)。


按键

ATTiny85 的 INT0 通过一个按钮 S1 接地,中断采用低电平触发。


功耗

采用 Power-down 休眠模式,用万用表测得休眠电流 1 uA;工作时 10mA 左右。

软件

平时 mcu 处于休眠状态,用户按按键时触发中断唤醒 mcu,在 INT0 中断服务程序中设置一个标志位,然后测量温度并以 Morse 码的形式显示,显示完成后又进入休眠模式。

DS18B20 采用从 Martin Thomas 网站上下载的一个库,对于这个应用可以进一步裁剪以减少代码大小。如果使用 ATTiny13 可能要用汇编语言写 DS18B20 的操作代码才能把代码放进 ROM 里。

关于外壳

最初想把这个温度计和两节 AA 电池放在一个透明的外壳中,但是这个外壳体积有点大,电池也不好固定。

其次尝试了把它放进一个常见的 AA 电池盒里,花了一翻功夫,比较麻烦,没能完成。

这时想到前两周在柴火玩冷光管时的升压电池盒,它上面正好有一个按键,而且放升压电路的地方正好可以用来安装温度计的电路,并且装电池的地方也有了,就决定使用这个外壳。

对这个升压器作了如下修改:

一些想法