八兆天空 发表于 2017-2-8 16:39:05

转载----用指针式电压表制作超 · 极客时钟!《无线电》杂志 公众号

本帖最后由 八兆天空 于 2017-2-8 16:41 编辑

转载于 《无线电》公众号
无线电杂志微信号 radiomagazine




看到标题,可能很多朋友已经按捺不住自己了!没错!就是这种非常硬核的极客风格,今天来学习一下如何使用指针式的电压表来作为指针,显示当前的时间和温度吧!


实际上,这个设计原理非常好懂:单片机使用PWM并通过电阻分压来得到0~2V的电压值,而这个电压则是表头的满偏电压,而将其分成60份后,就可以用来指示60分钟或60秒的示数了。时间采用实时时钟DC1307来保存,而温度则通过读写单线温度传感器DS18B20得到。整个设计的主控单片机使用Picaxe 14M2单片机。不过说实话,这个单片机使用什么都无所谓,只要能够有三路PWM输出(或软或硬)即可。


原理非常简单,可能最难的地方在于如何分出适当的电压值。将2V分成60份,每份电压值为0.033V,因此表盘的设计和电压的输出就全都要参照这个电压值来设计。每增加一个分度,PWM都要相应地增加0.033V的电压值,而这又要考虑到PWM的精度和外部的低通滤波电路。因此这个设计还需要一定的思考才行!


其他的诸如操作DC1307和DS18B20的程序我想大家已经非常熟悉了,此处不再赘述。如果想要借鉴源程序的话欢迎在公众号的对话中回复“电压表时钟”以取得源程序哦!

本文为 无线电杂志 微信公众平台原创文章。详细内容及高清大图请查阅《无线电》杂志。版权所有,欢迎个人转发至朋友圈。公众号、报刊等转载请给本公众号后台留言获得授权。
…………………………………………………




无线电杂志
微信号:radiomagazine长按识别二维码关注我们


八兆天空 发表于 2017-2-8 16:39:42

电压表时钟 · 源程序
2017-01-16 WTH 无线电杂志

电压表时钟的正文,请看一楼


;源程序由WTH编写,运行于PicAxe

14M2上,阅读程序可以让你了解思

路。
;    Project Name: 3 Panel Meter Clock
; REV: FIN (everything works fine with

clock and temp)
;
;    Start Date:Feb 12, 2012
;   
;    Program Rev History/Ideas:
; - to set clock push M or H button
; - push main button to display temp

F, C, and K
; - Routine to drive 3 meters to full

scale when main button AND (M OR

H)
; is pressed.This is to allow

adjustment of trimmers to full scale.
; Adjustment to zero scale should be

done first with power off.
;
; *******************************
;    PICAXE PE Rev: MacAXEPad 1.3.2
;
#picaxe14m2
'define memory locations as symbols
symbol hour_meter = c.0 'LEG 7
symbol minute_meter = c.2 'LEG 5
symbol second_meter = b.2 ' LEG 11
symbol temp_switch = pinc.4 ' LEG3
symbol temp_sensor = b.5 'LEG8
symbol hour_set = pinc.3 'LEG3
symbol minute_set = pinc.1 'LEG6
symbol CthermoValue = b10
symbol FthermoValue = b11
symbol KthermoValue = w6 'b12 and

b13
symbol seconds = b0
symbol minutes = b1
symbol hours = b2
symbol day = b3
symbol date = b4
symbol month = b5
symbol year = b6
symbol blinky = b7
symbol Tens_Digi = b8   ;Used to get

the Tens Digit from the $HEX RTC

value
symbol Ones_Digi = b9 ;Used to get

the Ones Digit from the $HEX RTC

value
' w7 (b14 and b15) is used to control

the PCM to the meters
' Set the time on the DS1307 RTC
i2cslave %11010000, i2cslow, i2cbyte ;

set PICAXE as master and DS1307

slave address
pause 50
'Set all meters to full scale with 100%

duty cycle
pwmout hour_meter,99,400      
pwmout minute_meter,99,400   
pwmout second_meter,99,400   
'\/ \/ \/ \/ Un_REM THESE LINES

(BELOW) IF SETTING UP A NEW RTC\/

\/ \/ \/
#rem
' Set the RTC chip time
;write time and date e.g. to 11:59:00

on Thurs 25/12/03
'; would be "writei2c 0,($00, $59, $11,

$03, $25, $12, $03, 010000)"
' readi2c 0, (b0,b1,b2,b3,b4,b5,b6,b7)

reads back the data
let seconds = $00 ; 00-59 Note all

BCD format
let minutes = $00   ; 00-59 Note all

BCD format   
let hours = $01 ; 01-12 Note all BCD

format
let day = $03   ; program does not

use date, date, month, year
let date = $22      
let month = $03
let year = $12      
let blinky = 000000 ; 010000 would

Enable output at 1Hz blink rate.

000000 is no blink
writei2c 0,(seconds, minutes, hours,

day, date, month, year, blinky)
pause 50
#endrem
'/\ /\ /\ /\ Un_REM THESE LINES

(ABOVE) IF SETTING UP A NEW RTC/\

/\ /\ /\
; POWER ON SELF TEST.Send all three

meters to FULL Scale and back to 0
'NOTE:pwmduty hour_meter, w7

---->> w7 ranges from 0 to 400 to

move meter from 0VDC to 2VDC
for w7 = 400 to 0 step -1' pwmduty

needs a (W)ord var, not a (B)yte var
pwmduty hour_meter, w7 'adjust

PWM Duty from 100% to 0%
pwmduty minute_meter, w7
pwmduty second_meter, w7
next w7
main:
if temp_switch = 1 then
do ' while hour_set = 1 or minute_set

= 1 then 'if main buttom and H or M

set button pushed then
pwmduty hour_meter, 400 ' move all

meters to full scale to allow trimmer

adjust.Do 0 meter adjust1st with

power off.
pwmduty minute_meter, 400
pwmduty second_meter, 400
loop while hour_set = 1 or minute_set

= 1
end if ' temp_switch = 1
if temp_switch = 1 and hour_set = 0

and minute_set = 0 then
do 'while temp_switch is pressed
gosub DisplayTemp
loop while temp_switch = 1 and

hour_set = 0 and minute_set = 0
end if
'read the RTC and display the time
readi2c 0, (seconds, minutes, hours,

day, date, month, year, blinky)
pause 10
'\/ \/ \/ \/ \/ SECONDS SECONDS

SECONDS \/ \/ \/ \/ \/
;Convert the Seconds from the RTC to

Base10 and update the meter
if temp_switch = 0 and minute_set =

1 and hour_set = 1 then 'all pressed.

Seconds to $00
gosub Seconds_set
end if
Ones_digi = seconds & 0x0F   ' zero

out the top four bits
Tens_Digi = seconds & 0xF0   ' zero

out the lower four bits
Tens_Digi = Tens_Digi / 2 ' each

divide by 2 shifts the
Tens_Digi = Tens_Digi / 2 ' bits LEFT.

Four shift get
Tens_Digi = Tens_Digi / 2 ' them all to

the lower four bits
Tens_Digi = Tens_Digi / 2
Tens_Digi = Tens_Digi * 10 'Now shift

the Base10 value to Tens place
seconds = Tens_Digi + Ones_Digi

'complete. Now $ss is ss (in Base10)
' Update the seconds meter with a

w9 value of 0 to 400
w7 =seconds * 677 / 100;

(400/59=6.77) scale 0-59 seconds to

0-400 for PWM
pwmduty second_meter, w7
'/\ /\ /\ /\ SECONDS END /\ /\ /\ /\

/\ /\ /\
'\/ \/ \/ \/ MINUTES MINUTES

MINUTES \/ \/ \/ \/ \/
if temp_switch = 0 and minute_set =

1 and hour_set = 0 then 'if

temp_switch and M is pressed then

add on minute
gosub Minutes_set
end if
;Convert the Minutes from the RTC to

Base10 and update the meter
Ones_digi = minutes & 0x0F   ' zero

out the top four bits
Tens_digi = minutes & 0xF0   ' zero

out the lower four bits
Tens_Digi = Tens_Digi / 2 ' each

divide by 2 shifts the
Tens_Digi = Tens_Digi / 2 ' bits LEFT.

Four shift get
Tens_Digi = Tens_Digi / 2 ' them all to

the lower four bits
Tens_Digi = Tens_Digi / 2
Tens_Digi = Tens_Digi * 10 'Now shift

the Base10 value to Tens place
minutes = Tens_Digi + Ones_Digi

'complete. Now $mm is mm (in

Base10)
'Update the minutes meter with a w9

value of 0 to 400
If minute_set = 0 then 'dont update if

we are setting the minutes.Should

correct this in Minutes_set routine
w7 = minutes * 677 / 100 ;

(400/59=6.77) scale 0-59 minutes to

0-400 for PWM
pwmduty minute_meter, w7
end if
'/\ /\ /\ /\ /\ MINUTES END /\ /\ /\ /\

/\
'\/ \/ \/ \/ \/ HOURS HOURS HOURS

\/ \/ \/ \/
if temp_switch = 0 and minute_set =

0 and hour_set = 1 then 'if

temp_switch and M is pressed then

add on minute
gosub Hours_set
end if
;Convert the Hours from the RTC to

Base10 and update the meter
Ones_digi = hours & 0x0F   ' zero out

the top four bits
Tens_digi = hours & 0xF0   ' zero out

the lower four bits
Tens_Digi = Tens_Digi / 2 ' each

divide by 2 shifts the
Tens_Digi = Tens_Digi / 2 ' bits LEFT.

Four shift get
Tens_Digi = Tens_Digi / 2 ' them all to

the lower four bits
Tens_Digi = Tens_Digi / 2
Tens_Digi = Tens_Digi * 10 'Now shift

the Base10 value to Tens place
hours = Tens_Digi + Ones_Digi

'complete. Now $hh is hh (in Base10)
if hours > 12 then
hours = hours - 12
end if
if hours = 0 then
hours = 12
end if
' Update the hours meter with a w9

value of 0 to 400
w7 = hours * 3636; (400/11 = 36.36)

scale 1 to 12 hours to 0-400 for PWM
w7 = w7 - 3636 'subtracty interceot

to start PCM at 0 to 1 o'clock.
w7 = w7 / 100 'scale 1 to 12 hours to

0-400 for PWM
pwmduty hour_meter, w7
'/\ /\ /\ /\ /\ HOURS END /\ /\ /\ /\

/\
goto main
DisplayTemp:
readtemp temp_sensor,

CthermoValue
w7 = CthermoValue * 677 / 100

'(400/59=6.77) scale C to 0-400 for

PWM
pwmduty minute_meter, w7 'C (raw)

in the minutes meter)
'Convert C to F
FthermoValue = 9 * CthermoValue / 5

+ 32
w7 = FthermoValue * 364; (400/11 =

36.36)scale 10 to 120Fto 0-400 for

PWM
w7 = w7 - 3636 'subtracty interceot

to start PCM at 0 to 10F
w7 = w7 / 100 'scale 0-400 for PWM
pwmduty hour_meter, w7 '(F (x10) on

the hours meter
'Convert C to K
KthermoValue = CthermoValue + 273
w7 = KthermoValue / 10
w7 = w7 * 677 / 100
pwmduty second_meter, w7 'Kelvin

*100 on the seconds meter
return 'DisplayTemp
Seconds_Set:
seconds = $00
writei2c 0,(seconds, minutes, hours,

day, date, month, year, blinky)
pause 50
w7 =seconds * 677 / 100;

(400/59=6.77) scale 0-59 seconds to

0-400 for PWM
pwmduty second_meter, w7
return 'Seconds_set
Minutes_Set:
readi2c 0, (seconds, minutes, hours,

day, date, month, year, blinky)
;Convert the Minutes from the RTC to

Base10 and update the meter
Ones_digi = minutes & 0x0F   ' zero

out the top four bits
Tens_digi = minutes & 0xF0   ' zero

out the lower four bits
Tens_Digi = Tens_Digi / 2 ' each

divide by 2 shifts the
Tens_Digi = Tens_Digi / 2 ' bits LEFT.

Four shift get
Tens_Digi = Tens_Digi / 2 ' them all to

the lower four bits
Tens_Digi = Tens_Digi / 2
Tens_Digi = Tens_Digi * 10 'Now shift

the Base10 value to Tens place
minutes = Tens_Digi + Ones_Digi

'complete. Now $mm is mm (in

Base10)
minutes = minutes + 1
if minutes > 59 then
minutes = 0
end if
'convert base10 minutes to BCD here

then write new minute value to RTC
Ones_Digi = minutes // 10
Tens_Digi = minutes - Ones_Digi
Tens_Digi = Tens_Digi / 10
Tens_Digi = Tens_Digi * 2' shift the

lower right bits
Tens_Digi = Tens_Digi * 2' to the

upper left.
Tens_Digi = Tens_Digi * 2
Tens_Digi = Tens_Digi * 2
Tens_Digi = Tens_Digi OR Ones_Digi

'OR function on the two values to get

8 bit BDC
'Now Ten_digi = minutes in packed

BCD.Just using Tens_Digi as a temp

var
writei2c 0,(seconds, Tens_Digi, hours,

day, date, month, year, blinky)
pause 50
'Update the minutes meter with a w9

value of 0 to 400
w7 = minutes * 677 / 100 ;

(400/59=6.77) scale 0-59 minutes to

0-400 for PWM
pwmduty minute_meter, w7
pause 500
return ' Minutes_Set
Hours_Set: 'HOURS SET WORKS

PERFECT
readi2c 0, (seconds, minutes, hours,

day, date, month, year, blinky)
;Convert the Hours from the RTC to

Base10 and update the meter
Ones_digi = hours & 0x0F   ' zero out

the top four bits
Tens_digi = hours & 0xF0   ' zero out

the lower four bits
Tens_Digi = Tens_Digi / 2 ' each

divide by 2 shifts the
Tens_Digi = Tens_Digi / 2 ' bits LEFT.

Four shift get
Tens_Digi = Tens_Digi / 2 ' them all to

the lower four bits
Tens_Digi = Tens_Digi / 2
Tens_Digi = Tens_Digi * 10 'Now shift

the Base10 value to Tens place
hours = Tens_Digi + Ones_Digi

'complete. Now $hh is hh (in Base10)
hours = hours + 1
if hours > 12 then
hours = hours - 12
end if
if hours = 0 then
hours = 12
end if
if hours > 9 then
if hours = 10 then
hours = $10
end if
if hours = 11 then
hours = $11
end if
if hours = 12 then
hours = $12
end if
end if
writei2c 0,(seconds, minutes, hours,

day, date, month, year, blinky)
pause 50
;Convert the Hours from the RTC to

Base10 and update the meter
Ones_digi = hours & 0x0F   ' zero out

the top four bits
Tens_digi = hours & 0xF0   ' zero out

the lower four bits
Tens_Digi = Tens_Digi / 2 ' each

divide by 2 shifts the
Tens_Digi = Tens_Digi / 2 ' bits LEFT.

Four shift get
Tens_Digi = Tens_Digi / 2 ' them all to

the lower four bits
Tens_Digi = Tens_Digi / 2
Tens_Digi = Tens_Digi * 10 'Now shift

the Base10 value to Tens place
hours = Tens_Digi + Ones_Digi

'complete. Now $hh is hh (in Base10)
' Update the hours meter with a w9

value of 0 to 400
w7 = hours * 3636; (400/11 = 36.36)

scale 1 to 12 hours to 0-400 for PWM
w7 = w7 - 3636 'subtracty interceot

to start PCM at 0 to 1 o'clock.
w7 = w7 / 100 'scale 1 to 12 hours to

0-400 for PWM
pwmduty hour_meter, w7
pause 1000

return ' Hours_Set

眉间尺 发表于 2017-2-8 17:17:53

好思路.
用4个或者5个表头, 每个表头只要能显示0-9这几个数值, 就可以让指针万用表具备与4位或者5位数码管显示的万用表相同的分辨率了.

yxlin000 发表于 2017-2-15 21:51:20

作者 大才小用 能有这样的技术 我就去 做表头 和家用定时器不过作者可能是都会 了才做些与众不同的东西:lol

hlw2957 发表于 2017-2-19 22:49:37

52jsj 发表于 2017-3-16 17:41:43

这是就是炫一下,没有什么实际效用,首先就是读数不明显

老柳 发表于 2017-3-22 13:33:51

眉间尺 发表于 2017-2-8 17:17
好思路.
用4个或者5个表头, 每个表头只要能显示0-9这几个数值, 就可以让指针万用表具备与4位或者5位数码 ...

每个表盘100刻度,视觉可直读两位数。两个表盘四位数,最大是9999,比三位半还强。
不过看完第一表盘,记住读数,再看第二表盘的读数,合拢起来才是结果,会很不方便,怪怪的,拿来玩可以。

w6955 发表于 2017-3-22 14:33:51

没有数码管的时代,就是用这个办法显示数字电路的输出的,按数字电路的权值取电阻就可以显示一位数字信息。

眉间尺 发表于 2017-3-22 17:01:56

老柳 发表于 2017-3-22 13:33
每个表盘100刻度,视觉可直读两位数。两个表盘四位数,最大是9999,比三位半还强。
不过看完第一表盘, ...

看数码管如果看了个位忘了十位或者百位也不行啊.:lol

DIYYER 发表于 2017-3-22 20:48:55

学习看看听很高级

爱你矿坛 发表于 2017-3-22 20:49:16

不错的作品!
单片机,不懂。想学,老了,太迟了。

壹法拉 发表于 2017-3-26 13:38:03

不知道源程序是用什么语言写的。

ZJHFY 发表于 2017-3-30 19:49:04

独特风格 学习一下

snb 发表于 2017-4-5 07:45:36

换三个猫头表加黄色背光更赞

岑蓉络阳 发表于 2017-4-5 09:44:22

页: [1] 2 3 4
查看完整版本: 转载----用指针式电压表制作超 · 极客时钟!《无线电》杂志 公众号