4桁の7seg LEDをラズパイにGPIO経由で接続して、時刻(mm:ss)を表示させてみた。
1桁の7segを表示する場合、ドットを含めて8個のGPIOを使う。
なので、単純に4桁の7segを表示するには、4*8=32個のGPIOが必要になるが、
ダイナミック点灯方式なるものを使えば、4+8=12個のGPIOで済むのでこれを採用。
実際には1桁ずつしか同時には点灯していないが、高速で順番に4桁を点灯させていくので
人の目には4桁が同時に点灯しているように見えるということらしい。
プログラム的には上記の仕組みをそのまま実装すれば実現できた。
ただ、シェルスクリプトの実装(echo)だと処理が遅すぎてあからさまにチカチカしてしまうので、
Luaのio.openなどを使用して書き直したらまぁまぁスムーズになったのでよしとする。
以下はLuaのコード(print_date.lua)
1 #!/usr/bin/lua
2
3 local keta={}
4 keta[4]='/sys/class/gpio/gpio2/value'
5 keta[3]='/sys/class/gpio/gpio3/value'
6 keta[2]='/sys/class/gpio/gpio7/value'
7 keta[1]='/sys/class/gpio/gpio8/value'
8
9 local leds={}
10 leds['a']='/sys/class/gpio/gpio11/value'
11 leds['b']='/sys/class/gpio/gpio10/value'
12 leds['c']='/sys/class/gpio/gpio24/value'
13 leds['d']='/sys/class/gpio/gpio27/value'
14 leds['e']='/sys/class/gpio/gpio22/value'
15 leds['f']='/sys/class/gpio/gpio9/value'
16 leds['g']='/sys/class/gpio/gpio23/value'
17 leds['p']='/sys/class/gpio/gpio25/value'
18
19 local f={}
20
21 local LED_ON=0
22 local LED_OFF=1
23
24 function setup_gpio(path)
25 local gpio_num = string.match(path, '%d+')
26 os.execute('echo '..gpio_num..' > /sys/class/gpio/export')
27 os.execute('echo out > /sys/class/gpio/gpio'..gpio_num..'/direction')
28 end
29
30 function close_gpio(path)
31 local gpio_num = string.match(path, '%d+')
32 os.execute('echo '..gpio_num..' > /sys/class/gpio/unexport')
33 end
34
35 function clear_all_leds()
36 f['a']:write(LED_OFF); f['b']:write(LED_OFF); f['c']:write(LED_OFF); f['d']:write(LED_OFF);
37 f['a']:flush(); f['b']:flush(); f['c']:flush(); f['d']:flush();
38 f['e']:write(LED_OFF); f['f']:write(LED_OFF); f['g']:write(LED_OFF); f['p']:write(LED_OFF);
39 f['e']:flush(); f['f']:flush(); f['g']:flush(); f['p']:flush();
40 end
41
42 function print_number(num)
43 if num == 0 then
44 f['a']:write(LED_ON); f['b']:write(LED_ON); f['c']:write(LED_ON); f['d']:write(LED_ON); f['e']:write(LED_ON); f['f']:write(LED_ON);
45 f['a']:flush(); f['b']:flush(); f['c']:flush(); f['d']:flush(); f['e']:flush(); f['f']:flush();
46 elseif num == 1 then
47 f['b']:write(LED_ON); f['c']:write(LED_ON);
48 f['b']:flush(); f['c']:flush();
49 elseif num == 2 then
50 f['a']:write(LED_ON); f['b']:write(LED_ON); f['d']:write(LED_ON); f['e']:write(LED_ON); f['g']:write(LED_ON);
51 f['a']:flush(); f['b']:flush(); f['d']:flush(); f['e']:flush(); f['g']:flush();
52 elseif num == 3 then
53 f['a']:write(LED_ON); f['b']:write(LED_ON); f['c']:write(LED_ON); f['d']:write(LED_ON); f['g']:write(LED_ON);
54 f['a']:flush(); f['b']:flush(); f['c']:flush(); f['d']:flush(); f['g']:flush();
55 elseif num == 4 then
56 f['b']:write(LED_ON); f['c']:write(LED_ON); f['f']:write(LED_ON); f['g']:write(LED_ON);
57 f['b']:flush(); f['c']:flush(); f['f']:flush(); f['g']:flush();
58 elseif num == 5 then
59 f['a']:write(LED_ON); f['c']:write(LED_ON); f['d']:write(LED_ON); f['f']:write(LED_ON); f['g']:write(LED_ON);
60 f['a']:flush(); f['c']:flush(); f['d']:flush(); f['f']:flush(); f['g']:flush();
61 elseif num == 6 then
62 f['a']:write(LED_ON); f['c']:write(LED_ON); f['d']:write(LED_ON); f['e']:write(LED_ON); f['f']:write(LED_ON); f['g']:write(LED_ON);
63 f['a']:flush(); f['c']:flush(); f['d']:flush(); f['e']:flush(); f['f']:flush(); f['g']:flush();
64 elseif num == 7 then
65 f['a']:write(LED_ON); f['b']:write(LED_ON); f['c']:write(LED_ON); f['f']:write(LED_ON);
66 f['a']:flush(); f['b']:flush(); f['c']:flush(); f['f']:flush();
67 elseif num == 8 then
68 f['a']:write(LED_ON); f['b']:write(LED_ON); f['c']:write(LED_ON); f['d']:write(LED_ON); f['e']:write(LED_ON); f['f']:write(LED_ON); f['g']:write(LED_ON);
69 f['a']:flush(); f['b']:flush(); f['c']:flush(); f['d']:flush(); f['e']:flush(); f['f']:flush(); f['g']:flush();
70 elseif num == 9 then
71 f['a']:write(LED_ON); f['b']:write(LED_ON); f['c']:write(LED_ON); f['d']:write(LED_ON); f['f']:write(LED_ON); f['g']:write(LED_ON);
72 f['a']:flush(); f['b']:flush(); f['c']:flush(); f['d']:flush(); f['f']:flush(); f['g']:flush();
73 end
74 end
75
76 function get_time()
77 time = os.date("%T")
78 local min={}
79 local sec={}
80 min[1] = tonumber(string.sub(time, 4, 4))
81 min[2] = tonumber(string.sub(time, 5, 5))
82 sec[1] = tonumber(string.sub(time, 7, 7))
83 sec[2] = tonumber(string.sub(time, 8, 8))
84 return min, sec
85 end
86
87 for i,v in pairs(leds) do setup_gpio(v); f[i] = io.open(v, 'w') end
88 for i,v in pairs(keta) do setup_gpio(v) end
89
90 local f1 = io.open(keta[1], 'w')
91 local f2 = io.open(keta[2], 'w')
92 local f3 = io.open(keta[3], 'w')
93 local f4 = io.open(keta[4], 'w')
94
95 clear_all_leds()
96
97 -- while true do
98 for i=1,10000 do
99 local min, sec = get_time()
100
101 f1:write(1)
102 f1:flush()
103 print_number(min[1])
104 -- os.execute('sleep 0.001')
105 clear_all_leds()
106 f1:write(0)
107 f1:flush()
108
109 f2:write(1)
110 f2:flush()
111 print_number(min[2])
112 f['p']:write(LED_ON)
113 f['p']:flush()
114 -- os.execute('sleep 0.001')
115 clear_all_leds()
116 f2:write(0)
117 f2:flush()
118
119 f3:write(1)
120 f3:flush()
121 print_number(sec[1])
122 -- os.execute('sleep 0.001')
123 clear_all_leds()
124 f3:write(0)
125 f3:flush()
126
127 f4:write(1)
128 f4:flush()
129 print_number(sec[2])
130 -- os.execute('sleep 0.001')
131 clear_all_leds()
132 f4:write(0)
133 f4:flush()
134 end
135
136 for i,v in pairs(leds) do close_gpio(v); f[i]:close() end
137 for i,v in pairs(keta) do close_gpio(v) end
138
139 f1:close()
140 f2:close()
141 f3:close()
142 f4:close()
最終更新:2015年12月03日 23:31