Create a device that gently notifies you of notifications from the system with Raspberry Pi. The goal is like this.
I bought the RaspberryPi from Amazon.
Distributor | Product name | price | quantity |
---|---|---|---|
TechShare | Raspberry Pi2 Model B board & case set(Standard, Clear) | ¥6,300 | 1 |
Amazon.com Int'l Sales, Inc. | Transcend microSDHC card 16GB Class10 TS16GUSDHC10E | ¥980 | 1 |
The attached special case has an opening in the GPIO socket part and is suitable for connecting to the base outside the case.
The configuration of the notification lamp is as follows.
In this article, I will write about the hardware part of "Color LED" and the "Led Driver" part that operates it.
item | Contents | comment |
---|---|---|
OS | Raspbian | Linux raspberrypi 3.18.7-v7+ #755 |
development language | Python | Ver. 2.7.3,Included in Raspbian |
GPIO operation | RPi.GPIO | Included in Raspbian |
Make the hardware of the "notification lamp". The mechanism of operating the LED from Raspberry Pi is almost the same as ["L Chika" written by many people](http://qiita.com/search?utf8= ✓ & sort = rel & q = L Chika + raspberry Pi & sort = rel) is.
There are various types of color LEDs, and there are various methods for controlling brightness and color, but here, we will design based on the following.
Power LED drive with transistor array The GPIO output of the Raspberry Pi is amplified by a transistor (array) so that sufficient current can flow through the Power LED.
Color control by software PWM (Puls Width Moduration) In order to be able to freely control the brightness of the three color LEDs with software, we will make a circuit that can independently turn on / off each RGB color by operating GPIO.
You can change the GPIO port to use. In that case, change the definition of the program described later.
The parts were purchased at Akizuki Denshi Tsusho (mail order).
Product number | Contents | price | quantity |
---|---|---|---|
P-03231 | Double-sided through-hole glass composite universal substrate C type plating finish 72x47 mm made in Japan | ¥100 | 1 |
C-07607 | USB cable A male-micro B male 1.5 m A-microB | ¥120 | 1 |
R-07799 | Carbonresistance(carbonfilmresistance)1/2W47Ω(100pieces) | ¥100 | 1 |
C-02485 | Connectingpinsocket2x20(40P) | ¥110 | 1 |
I-01587 | Transistorarray(7chDarlingtonsinkdriver)TD62003APG(2pieces) | ¥100 | 1 |
I-07233 | 1W high power full color RGB LED OSTCWBTHC1S with heat dissipation board | ¥250 | 1 |
The following tools and consumables are recommended for production.
Product name | Note |
---|---|
Soldering iron+Soldering iron stand | For electronic work of about 30W |
Solder | Diameter 0.Thin thing of about 6 mm |
Nippers+Needle-nose pliers+tweezers | |
tester | Convenient for continuity check etc. |
The appearance of the produced board is as follows.
On the back of the right end, there is a 40-pin pin socket for connecting to the Raspberry Pi. This pin socket has a long pin, but if you solder it at the tip without cutting it, you can connect it just so that the base rests on the case. In the photo, the gray part in the upper center of the board is the "push switch", but it is not used in this explanation, so please ignore it. The base of the Power LED is aluminum, so be careful not to let the wiring touch the edges. Although not visible in the photo, three 47Ω resistors are located under the LED.
Led Driver The module that controls the color and blinking of the LED is called "Led Driver" here. By configuring the "notification lamp" as a child process of the calling process, it is possible to operate asynchronously with the upper module.
The functionality of the Led Driver is simple. If you specify "Color" and "Blinking cycle (seconds)", the LED will continue to blink as it is. If you change the specification during the blinking process, it will be reflected within 1 second.
The module configuration is as follows.
IPC queues are used to communicate with Deamon. LedDeamon will change to the default Down state display if the lighting mode setting (set_mode) is not executed for 80 seconds. This is a function for detecting down of the upper program.
For details, see the source code below.
I'm new to Python, so I'm looking forward to your warmth!
Test execution method:
python
$ sudo ./led.py
led.py
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO
import time
class Led(object):
# Define your GPIO Ports
RED_PORT = 13
GREEN_PORT = 26
BLUE_PORT = 5
# Controll resolution Params
# You don't have to change following 3 Params usually
FREQUENCY = 200 # PWM Frequency
RESOLUTION = 50.0 # Brightness control per span
SPAN = 1.0 # Drive time in second at one call
# Brightness
MAX_BRIGHTNESS = 1.0 # Master Brightness parameter 0.1 - 1.0
# Color Table
# You can append your own colors
COLORS = {
"Red": [1.0, 0.0, 0.0],
"Pink": [1.0, 0.3, 0.3],
"Green": [0.0, 1.0, 0.0],
"LightGreen": [0.2, 1.0, 0.2],
"Blue": [0.0, 0.0, 1.0],
"LightBlue": [0.3, 0.3, 1.0],
"Yellow": [1.0, 1.0, 0.0],
"Orange": [1.0, 0.3, 0.0],
"Cyan": [0.0, 1.0, 1.0],
"Lime": [0.0, 1.0, 0.3],
"Magenta": [1.0, 0.0, 1.0],
"Violet": [0.3, 0.0, 1.0],
"White": [1.0, 1.0, 1.0],
"Black": [0.0, 0.0, 0.0]
}
# Color index for Color Table
RED = 0
GREEN = 1
BLUE = 2
def color_names(self):
return Led.COLORS.keys()
def __init__(self):
self.phase = 0.0
self.color = Led.COLORS["Black"]
GPIO.setmode(GPIO.BCM)
# set GPIO port as output
GPIO.setup(Led.RED_PORT, GPIO.OUT)
GPIO.setup(Led.GREEN_PORT, GPIO.OUT)
GPIO.setup(Led.BLUE_PORT, GPIO.OUT)
# set port as software PWM with f Hz
self.red = GPIO.PWM(Led.RED_PORT, Led.FREQUENCY)
self.green = GPIO.PWM(Led.GREEN_PORT, Led.FREQUENCY)
self.blue = GPIO.PWM(Led.BLUE_PORT, Led.FREQUENCY)
# start software PWM with 0.0%
self.red.start(0.0)
self.green.start(0.0)
self.blue.start(0.0)
return
def _set_brightness(self, brightness):
percent = Led.MAX_BRIGHTNESS * (brightness ** 2) * 100.0
# set duty cycle
self.red.ChangeDutyCycle(min(100.0, percent * self.color[Led.RED]))
self.green.ChangeDutyCycle(min(100.0, percent * self.color[Led.GREEN]))
self.blue.ChangeDutyCycle(min(100.0, percent * self.color[Led.BLUE]))
def set(self, color, interval):
# Color name to RGB value
self.color = Led.COLORS[color]
# interval in second
self.interval = float(interval)
# control resolution parameter
if self.interval > 0.0:
self.pitch = 1.0 / (Led.RESOLUTION * self.interval)
# Reset phase
self.phase = 0.0
def run(self):
if self.interval == 0.0:
# No Blink
self._set_brightness(0.5)
time.sleep(Led.SPAN)
else:
for i in range(int(Led.RESOLUTION * Led.SPAN)):
self.phase += self.pitch
if self.phase >= 1.0:
self.phase = 0.0
if self.phase < 0.5:
br = self.phase * 2.0
else:
br = 1.0 - ((self.phase - 0.5) * 2.0)
# keep a little light
br += 0.0001
self._set_brightness(br)
time.sleep(1.0 / Led.RESOLUTION)
def destroy(self):
self.red.stop()
self.green.stop()
self.blue.stop()
GPIO.cleanup()
if __name__ == ("__main__"):
l = Led()
l.set("Blue", 0.5)
l.run()
l.set("Black", 0)
l.run()
for interval in [0, 0.5, 1.0]:
print("- Inrerval = %2.1f" % interval )
for c in l.color_names():
if c == "Black":
continue
print(c)
l.set(c, interval)
for i in range(max(1, int(interval * 2.0))):
l.run()
l.destroy()
Test execution method:
python
$ sudo ./led_deamon.py
led_deamon.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
import multiprocessing
import Queue
from led import Led
class LedDeamon(object):
DOWN = {"color": "Magenta", "interval": 0}
def __init__(self):
self.queue = multiprocessing.Queue()
self.lighting_mode = None
def start(self):
p = multiprocessing.Process(target=self._led_control, args=(self.queue, ))
# Set deamon flug to kill process when parent process died
p.daemon = True
p.start()
def set_mode(self, lightning_mode):
self.queue.put(lightning_mode)
# Child loop
def _led_control(self, queue):
count = 0
lighting_mode = LedDeamon.DOWN
self.led = Led()
while True:
# get mode from queue
try:
lighting_mode = self.queue.get(False)
count = 0
# print("lighting_mode = %s" % lighting_mode)
except Queue.Empty:
count += 1
# parent seems dead
if count > 80:
lighting_mode = LedDeamon.DOWN
self._drive(lighting_mode) # Drive for about 1 sec.
def _drive(self, lighting_mode):
if self.lighting_mode != lighting_mode:
self.lighting_mode = lighting_mode
self.led.set(lighting_mode["color"], lighting_mode["interval"])
# print("lighting_mode = %s" % lighting_mode)
self.led.run()
if __name__ == '__main__':
mode_map = {
"DOWN": {"color": "Magenta", "interval": 0},
"ERR_UNACKED": {"color": "Red", "interval": 0.5},
"WARN_UNACKED": {"color": "Yellow", "interval": 2},
"ERR_ACKED": {"color": "Green", "interval": 4},
"WARN_ACKED": {"color": "Green", "interval": 8},
"NORMAL": {"color": "Blue", "interval": 8}}
# Create and start LED Driver
ld = LedDeamon()
ld.set_mode(mode_map["NORMAL"])
ld.start()
time.sleep(8)
ld.set_mode(mode_map["ERR_UNACKED"])
time.sleep(8)
ld.set_mode(mode_map["WARN_UNACKED"])
time.sleep(8)
ld.set_mode(mode_map["ERR_ACKED"])
time.sleep(8)
ld.set_mode(mode_map["WARN_ACKED"])
time.sleep(8)
ld.set_mode(mode_map["DOWN"])
time.sleep(8)
This is how it shines when an important problem occurs. When combined with a suitable chime, you can create a sense of urgency. (I don't want to see it too much ...)
The dome-shaped cover that covers the LED is a diversion of the LED light cover that was sold at Daiso. Actually, the hardest part of hardware production was finding this cover. (Lol)
Next time, I will write about the module Detector that controls notifications.
Recommended Posts