센서들이 모여있는 Hat이다.
- 자이로 센서
- 가속도 센서
- 기압 센서
- 지자기 센서
- 온/습도 센서
컨트롤러와 디스플레이도 포함한다.
- 8x8 LED
- 8 방향 조이스틱
무려 우주정거장에 보내진 제품이라고 한다(!)
참고로 라즈베리파이의 위(?)에 결합시켜 사용할 수 있는 악세사리로 Add-on board라고도 한다. (라즈베리파이 종료하고, 케이블을 분리하고 연결할 것!!)
=> https://www.raspberrypi.com/products/
이번에는 센스햇에 달린 8x8 LED를 이용해 방향지시등을 만들어 보려고 한다. (실시간 방향에 따라 반영되는 거라 사실 방향"지시"등 보다는 방향"중계"등에 가깝다)
센스햇을 사용하기 위해 관련 라이브러리를 설치하고, 재시작한다.
sudo apt-get update
sudo apt-get install sense-hat
sudo reboot
샘플 코드를 작성하고 테스트해보자.
from sense_hat import SenseHat
sense = SenseHat()
sense.show_message("Hello world!")
더 많은 API는 센스햇 공식 document 참고
=> https://pythonhosted.org/sense-hat/api/
sensehat_thread.py
from sense_hat import SenseHat
import threading
import paho.mqtt.client as mqtt
import socket
class SenseHatThread(threading.Thread):
BROKER_ADDRESS = socket.gethostbyname(socket.gethostname())
WHITE = (255, 255, 255)
RED = (255, 0, 0)
YELLOW = (255, 255, 0)
FRONT = [
[0, 3], [0, 4],
[1, 2], [1, 3], [1, 4], [1, 5],
[2, 3], [2, 4],
[3, 3], [3, 4]
]
BACK = [
[4, 3], [4, 4],
[5, 3], [5, 4],
[6, 2], [6, 3], [6, 4], [6, 5],
[7, 3], [7, 4]
]
LEFT = [
[3, 4], [4, 4],
[3, 5], [4, 5],
[2, 6], [3, 6], [4, 6], [5, 6],
[3, 7], [4, 7]
]
RIGHT = [
[3, 0], [4, 0],
[2, 1], [3, 1], [4, 1], [5, 1],
[3, 2], [4, 2],
[3, 3], [4, 3]
]
FRONT_LEFT = [
[0, 7],
[0, 6], [1, 7],
[0, 5], [1, 6], [2, 7],
[2, 5],
[3, 4]
]
FRONT_RIGHT = [
[0, 0],
[0, 1], [1, 0],
[0, 2], [1, 1], [2, 0],
[2, 2],
[3, 3]
]
BACK_LEFT = [
[7, 7],
[6, 7], [7, 6],
[5, 7], [6, 6], [7, 5],
[5, 5],
[4, 4]
]
BACK_RIGHT = [
[7, 0],
[6, 0], [7, 1],
[5, 0], [6, 1], [7, 2],
[5, 2],
[4, 3]
]
IS_FRONT = False
IS_BACK = False
IS_LEFT = False
IS_RIGHT = False
def __init__(self):
super().__init__()
self.sense = SenseHat()
self.client = mqtt.Client("sensehat_sub")
self.client.connect(self.BROKER_ADDRESS)
self.client.subscribe("command")
self.client.on_message = self.on_command
def on_command(self, client, userdata, message):
cmd = str(message.payload.decode("utf-8"))
self.sense.clear()
if "go" == cmd:
if self.IS_LEFT:
self.on_dir_led(self.FRONT_LEFT)
elif self.IS_RIGHT:
self.on_dir_led(self.FRONT_RIGHT)
else:
self.on_dir_led(self.FRONT)
self.IS_FRONT = True
self.IS_BACK = False
elif "back" == cmd:
if self.IS_LEFT:
self.on_dir_led(self.BACK_LEFT)
elif self.IS_RIGHT:
self.on_dir_led(self.BACK_RIGHT)
else:
self.on_dir_led(self.BACK)
self.IS_FRONT = False
self.IS_BACK = True
elif "stop" == cmd:
self.IS_FRONT = False
self.IS_BACK = False
if self.IS_LEFT:
self.on_dir_led(self.LEFT)
elif self.IS_RIGHT:
self.on_dir_led(self.RIGHT)
else:
self.on_break_led()
elif "left" in cmd:
if self.IS_FRONT:
self.on_dir_led(self.FRONT_LEFT)
elif self.IS_BACK:
self.on_dir_led(self.BACK_LEFT)
else:
self.on_dir_led(self.LEFT)
self.IS_LEFT = True
self.IS_RIGHT = False
elif "right" in cmd:
if self.IS_FRONT:
self.on_dir_led(self.FRONT_RIGHT)
elif self.IS_BACK:
self.on_dir_led(self.BACK_RIGHT)
else:
self.on_dir_led(self.RIGHT)
self.IS_LEFT = False
self.IS_RIGHT = True
elif "mid" == cmd:
self.IS_LEFT = False
self.IS_RIGHT = False
if self.IS_FRONT:
self.on_dir_led(self.FRONT)
elif self.IS_BACK:
self.on_dir_led(self.BACK)
else:
self.on_break_led()
def on_dir_led(self, arg):
for pos in arg:
self.sense.set_pixel(pos[0], pos[1], self.YELLOW)
def on_break_led(self):
self.sense.set_pixel(7, 7, self.RED)
self.sense.set_pixel(7, 0, self.RED)
def run(self):
self.sense.clear()
self.on_break_led()
self.client.loop_forever()
main app.py
import camera_thread
import cmd_thread
import etc_thread
import oled_thread
import sensehat_thread
if __name__ == '__main__':
camera_th = camera_thread.CameraThread()
camera_th.start()
sense_th = sensehat_thread.SenseHatThread()
sense_th.start()
cmd_th = cmd_thread.CmdThread()
cmd_th.start()
etc_th = etc_thread.EtcThread()
etc_th.start()
oled_th = oled_thread.OLEDThread()
oled_th.start()
센스햇 코드 동작 시,
OSError: Cannot detect RPi-Sense FB device
같은 에러 메시지가 뜬다?
sudo vi /boot/config.txt
# 문서 가장 아래에 다음 내용 추가 후
dtoverlay=rpi-sense
# 재시작
sudo reboot