조도센서로 값을 잘 받아온다.


https://github.com/pimylifeup/Light_Sensor에서 받아온 코드를 기반으로

내가 필요한 기능들을 추가한다.

참고로 redis에 대한 설정은 구글링하면 금방 찾아볼 수 있다.

서버는 내가 사용하는 노트북이다.


우선 redis key로 사용할 ID가 필요해서 라즈베리파이 cpu의 시리얼 정보를 사용했고,

매일 누적하다보니 년, 월에 대한 정보까지 포함시켰다.

그리고 redis-collections의 List를 이용해서 

redis에 저장되는 정보를 마치 List처럼 사용하였다.

써보니 엄청 편하다.


라즈베리파이에서 구동할 파이썬 코드의 설명이다.

1초 sleep을 주고 계속 루프를 돌면서 체크한다.
동작방식은 0.1초간 라즈베리파이에 전원이 인가되고

이 전원이 LDR(조도센서)를 지나가는데

이때의 조도센서는 어두울수록 저항값이 커지기때문에

GPIO.HIGH가 되기까지 더 오래걸려서 측정 값이 커진다.


라즈베리파이3에서 python2로 구동되는 코드


#!/usr/local/bin/python
from __future__ import print_function
from redislite import StrictRedis
from redis_collections import List

import RPi.GPIO as GPIO
import os
import time
from datetime import datetime

__author__ = 'Byungwoo Jeon'
__license__ = "GPL"
__maintainer__ = "byngwoo"

GPIO.setmode(GPIO.BOARD)

# define the pin that goes to the circuit
pin_to_circuit = 7


def get_rp_serial():
    try:
        f = open('/proc/cpuinfo', 'r')
        for line in f:
            if line[0:6] == 'Serial':
                cpu_serial = line[10:26]
        f.close()
    except:
        cpu_serial = None

    return cpu_serial

def rc_time(pin_to_circuit):
    count = 0

    # Output on the pin for
    GPIO.setup(pin_to_circuit, GPIO.OUT)
    GPIO.output(pin_to_circuit, GPIO.LOW)
    time.sleep(0.1)  # sec

    # Change the pin back to input
    GPIO.setup(pin_to_circuit, GPIO.IN)

    # Light-dependent resistor
    # When light hits the LDR, its resistance is very low,
    # but when it's in the dark its resistance is very high.
    # -> Count until the pin goes high
    while (GPIO.input(pin_to_circuit) == GPIO.LOW):
        count += 1
    return count


def redis_init():
    serial_number = get_rp_serial()  # get cpu serial number
    if serial_number is None:
        serial_number = '00000001'  # temp number

    ip = os.environ.get('RS_HOST')  # RS: raspberry pi
    port = os.environ.get('RS_PORT')
    pw = os.environ.get('RS_PASSWORD')
    now = datetime.now()
    time_str = '%4d%02d%02d' % (now.year, now.month, now.day)

    redis_connection = StrictRedis(host=ip, port=port, db=0, password=pw)
    r = List(redis=redis_connection, key='rp3:'+serial_number+time_str)
    return r


# Catch when script is interupted, cleanup correctly
try:
    r = redis_init()
    # Main loop
    while True:
        current_light = rc_time(pin_to_circuit)
        try:
            r.append(current_light)
            print(current_light)
        except Exception as e:
            print("error: ", e)
            pass
        time.sleep(1)  # sec
except KeyboardInterrupt:
    pass
finally:
    GPIO.cleanup()



이 자체만으로 제대로 측정하려면 라즈베리파이에서 딱 이 스크립트만 돌려야한다.

만약 라즈베리파이에서 웹브라우저 실행과 같이 라즈베리파이의 자원을 많이 필요로 하는 작업을 하면

위의 측정 값은 신뢰할 수 없게 된다.



서버에서 수집한 정보를 조회하는 코드

라즈베리파이가 DB에 List형태로 저장하므로 이를 받아와서 

그래프로 보여주기에 매우 수월하다.


서버는 python3를 사용


#!/usr/local/bin/python3
from redis import StrictRedis
from redis_collections import List

import matplotlib.pyplot as plt
import os


def redis_init():
    ip = os.environ.get('RS_HOST')  # RS: raspberry pi
    port = os.environ.get('RS_PORT')
    pw = os.environ.get('RS_PASSWORD')

    redis_connection = StrictRedis(host=ip, port=port, db=0, password=pw)
    # TODO: support multi keys
    r = List(redis=redis_connection, key='rp3:00000000448f542820170421')
    return r


def main():
    r = redis_init()

    plt.xlabel('Run time(sec)')
    plt.ylabel('LDR resister')
    plt.plot(r)
    plt.show()


if __name__ == '__main__':
    main()


수행한 결과 화면




아직 제대로 조건을 못 찾았지만

아래처럼 조건을 정해서 그래프에 표시할 수도 있다.




def main():
    r = redis_init()
    plt.xlabel('Run time(sec)')
    plt.ylabel('LDR resister')
    for i in range(1, len(r)):
        if r[i-1] - r[i] > 1000 and r[i] < 1000:
            plt.annotate('turn on', xy=(i, 600), xytext=(i, 1200),
                         arrowprops=dict(facecolor='black', shrink=0.05),)
    plt.plot(r)
    plt.show()


아래처럼 형광등이 켜졌다고 판단하는 시점을

아래처럼 알아서 표시해줄수도 있는데

아직 저 값에 대해서는 시험이 좀 더 필요하다.




이것에 대해 최종적으로는

Django를 이용해서 웹에서 보여준다. (개인적으로 Django 공부중)

물론 flask, bottle같이 다른 프레임웍을 사용해도 상관은 없다.


웹쪽은 아는게 너무 없어서 적당히 기본만 구현해뒀는데 

아직 바꿔야 할 곳이 너무 많아서 소스는 못 올리겠다.


이렇게까지 구현하는데 파이썬 라이브러리에서 다 해줘서 내가 한 건 별로 없다.

물론 회의실이 여러개가 되고, 모듈의 개수를 늘리고, 

앞으로 해야할 것과 고려할 것은 훨씬 많이 남아있다.



..








반응형


redis-cli

 -h : host ip address

 -p : port number

 -a : password


redis-cli -h 127.0.0.1 -p 6379 -a mysupersecretpassword


참고로 비밀번호에 $가 있으면 에러가 발생하므로 사용하지 않는다.

반응형

#######################################################

# 원본: http://highthroughput.org/wp/    (Hyeshik Chang 장혜식님) 

# 원본참고: http://pinkwink.kr/1005

#######################################################


2곳의 원본을 참고하여 대한민국 지도에

인구 분포도를 그려주는 코드를 한줄한줄 따라가면서 

numpy, pandas, matplotlib에 대한 사용법을 익혀보았다.

필요한 csv 파일과 소스코드는 핑크윙크에 가면 있다.


각 라인별로 주석을 달아두었다.

drawKorea 함수만 이해해도 왠만한건 할 수 있을것 같다.



#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd


BORDER_LINES = [
    [(3, 2), (5, 2), (5, 3), (9, 3), (9, 1)],  # 인천
    [(2, 5), (3, 5), (3, 4), (8, 4), (8, 7), (7, 7), (7, 9), (4, 9), (4, 7), (1, 7)],  # 서울
    [(1, 6), (1, 9), (3, 9), (3, 10), (8, 10), (8, 9),
     (9, 9), (9, 8), (10, 8), (10, 5), (9, 5), (9, 3)],  # 경기도
    [(9, 12), (9, 10), (8, 10)],  # 강원도
    [(10, 5), (11, 5), (11, 4), (12, 4), (12, 5), (13, 5),
     (13, 4), (14, 4), (14, 2)],  # 충청남도
    [(11, 5), (12, 5), (12, 6), (15, 6), (15, 7), (13, 7),
     (13, 8), (11, 8), (11, 9), (10, 9), (10, 8)],  # 충청북도
    [(14, 4), (15, 4), (15, 6)],  # 대전시
    [(14, 7), (14, 9), (13, 9), (13, 11), (13, 13)],  # 경상북도
    [(14, 8), (16, 8), (16, 10), (15, 10),
     (15, 11), (14, 11), (14, 12), (13, 12)],  # 대구시
    [(15, 11), (16, 11), (16, 13)],  # 울산시
    [(17, 1), (17, 3), (18, 3), (18, 6), (15, 6)],  # 전라북도
    [(19, 2), (19, 4), (21, 4), (21, 3), (22, 3), (22, 2), (19, 2)],  # 광주시
    [(18, 5), (20, 5), (20, 6)],  # 전라남도
    [(16, 9), (18, 9), (18, 8), (19, 8), (19, 9), (20, 9), (20, 10)],  # 부산시
]
"""
# ziped BORDER_LINES 확인
>>>    for path in BORDER_LINES:
>>>        ys, xs = zip(*path)

(3, 5, 5, 9, 9) (2, 2, 3, 3, 1)
(2, 3, 3, 8, 8, 7, 7, 4, 4, 1) (5, 5, 4, 4, 7, 7, 9, 9, 7, 7)
(1, 1, 3, 3, 8, 8, 9, 9, 10, 10, 9, 9) (6, 9, 9, 10, 10, 9, 9, 8, 8, 5, 5, 3)
(9, 9, 8) (12, 10, 10)
(10, 11, 11, 12, 12, 13, 13, 14, 14) (5, 5, 4, 4, 5, 5, 4, 4, 2)
(11, 12, 12, 15, 15, 13, 13, 11, 11, 10, 10) (5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 8)
(14, 15, 15) (4, 4, 6)
(14, 14, 13, 13, 13) (7, 9, 9, 11, 13)
(14, 16, 16, 15, 15, 14, 14, 13) (8, 8, 10, 10, 11, 11, 12, 12)
(15, 16, 16) (11, 11, 13)
(17, 17, 18, 18, 15) (1, 3, 3, 6, 6)
(19, 19, 21, 21, 22, 22, 19) (2, 4, 4, 3, 3, 2, 2)
(18, 20, 20) (5, 5, 6)
(16, 18, 18, 19, 19, 20, 20) (9, 9, 8, 8, 9, 9, 10)

# 읽어들였던 data_draw_korea.csv 엑셀 파일의 일부
,인구수,shortName,x,y,면적,광역시도,행정구역
0,202520,강릉,11,4,1040.07,강원도,강릉시
1,25589,고성(강원),9,0,664.19,강원도,고성군
2,86747,동해,11,5,180.01,강원도,동해시
3,63986,삼척,11,8,1185.8,강원도,삼척시
4,76733,속초,9,1,105.25,강원도,속초시

... 후략...

"""


def drawKorea(target_data, blocked_map, d1, d2, cmapname):

    vmin = min(blocked_map[target_data])  # target_data의 최소값 (인구수가 가장 적은 값)
    vmax = max(blocked_map[target_data])  # target_data의 최대값 (인구수가 가장 많은 값)
    white_label_min = (vmax - vmin) * 0.25 + vmin

    # .csv에서 받아온 정보에서 사용하기 좋게 pivot
    map_data = blocked_map.pivot(index='y', columns='x', values=target_data)

    # np.isnan(map_data)는 Nan이면 True, 나머지는 False 리턴해주고
    # 이것을 바탕으로 마스킹 배열 생성
    masked_mapdata = np.ma.masked_where(condition=np.isnan(map_data), a=map_data, copy=True)  # numpy masked array

    plt.figure(figsize=(8, 13))  # width, height tuple in inches

    # create a pseudocolor plot of a 2-D array.
    # plt.pcolor 대신에 pcolormesh 사용함.
    plt.pcolormesh(masked_mapdata, vmin=vmin, vmax=vmax, cmap=cmapname, edgecolor='#aaaaaa', linewidth=0.5)

    for idx, row in blocked_map.iterrows():  # rows에 대한 반복 처리
        # 인구수: row[target_data]
        annocolor = 'white' if row[target_data] > white_label_min else 'black'

        # 광역시도: row[d1]
        # 행정구역: row[d2]

        # 광역시는 구 이름이 겹치는 경우가 많아서 시단위 이름도 같이 표시한다. (중구, 서구)
        # XX시로 끝나지만 세종시가 아닌 것들만 예외처리
        if row[d1].endswith('시') and not row[d1].startswith('세종'):
            # row[d1] : 서울특별시, 부산광역시...  row[d1][:2] : 서울, 부산...
            # row[d2] : 서대문구, 서초구, 중구 ... row[d2][:-1] : 서대문, 서초, 중 ...
            dispname = '{}\n{}'.format(row[d1][:2], row[d2][:-1])
            if len(row[d2]) <= 2:
                # 중, 서, ... -> 중구, 서구, ...
                dispname += row[d2][-1]
        else:
            # 제주특별자치도, 전라남도, 경상북도, ...
            dispname = row[d2][:-1]

        # 서대문구, 서귀포시 같이 이름이 3자 이상인 경우에 작은 글자로 표시한다.
        if len(dispname.splitlines()[-1]) >= 3:
            fontsize, linespacing = 9.5, 1.5
        else:
            fontsize, linespacing = 11, 1.2

        # dispname '서울/n강남'에 대한 annotating
        plt.annotate(s=dispname,
                     xy=(row['x'] + 0.5, row['y'] + 0.5),
                     fontweight='bold', fontsize=fontsize,
                     horizontalalignment='center',
                     verticalalignment='center',
                     color=annocolor,
                     linespacing=linespacing)

    for path in BORDER_LINES:
        ys, xs = zip(*path)
        # plot xs, ys
        plt.plot(xs, ys, color='black', linewidth=4)

    plt.gca().invert_yaxis()  # x, y 뒤집어야 함
    plt.gca().set_aspect(aspect='equal')

    plt.axis('off')

    # 우측에 컬러바를 통해서 색상에 따라 수치를 파악할 수 있음
    # shirink: 컬러바의 전반적인 크기 조절
    # aspect: 컬러바의 폭 조절
    cb = plt.colorbar(shrink=0.1, aspect=10)
    cb.set_label(label=target_data)

    plt.tight_layout()
    plt.show()

def main():
    plt.rcParams["font.family"] = "AppleGothic"  # font setting

    # http://en.wikipedia.org/wiki/Plus_and_minus_signs#Character_codes
    plt.rcParams['axes.unicode_minus'] = False  # use hypen '-' (True: use unicode minus)

    data_draw_korea = pd.read_csv('./data_draw_korea.csv', index_col=0, encoding='UTF-8')
    data_draw_korea.head()  # return first row

    drawKorea('인구수', data_draw_korea, '광역시도', '행정구역', 'Blues')


if __name__ == '__main__':
    main()

...












...

반응형

라즈베리파이3에 USB로 키보드 마우스를 연결해서

사용하다보니 너무 불편하다.


그래서 블루투스 키보드를 사용하기로 했다. 

사용하다보니 편리하다.


찾아보니 Ctrl+Alt+T는 기본 터미널을 여는 단축키라서

마우스는 구지 없어도 될것 같다.


그런데 부팅할때마다 블루투스 연결을 새로 해줘야한다.

아.. 불편하다.


역시 불편한건 찾아보면 해결방안이 있다.


1. 현재 연결된 블루투스 키보드의 MAC 주소를 확인한다.



pi@byungwoo:~ $ hcitool con
Connections:
  > ACL D0:13:1E:15:XX:YY handle 11 state 1 lm MASTER AUTH ENCRYPT

pi@byungwoo:~ $ hcitool name D0:13:1E:15:XX:YY
i-rocks Bluetooth Keyboard


2. /etc/rc.local 파일에 부팅할때 실행할 명령어를 등록한다.

사용하는 블루투스 키보드의 MAC주소를 등록한다.



$ sudo vi /etc/rc.local

echo -e "connect D0:13:1E:15:XX:YY \nquit" | bluetoothctl

:x



3. 라즈베리파이3를 껐다가 다시 부팅해보면

블루투스 키보드가 자동으로 연결되어 사용할 수 있다.


반응형
조도 센서로 데이터를 가져오기 시작했다.

이제 이 데이터를 모아서 의미있는 처리를 해야겠다.


우선은 redis를 사용해서 마이크로 SDcard 말고 메모리를 사용하도록 해야겠다.

redis는 lite 버전을 사용한다.





$ sudo pip install redislite
$ sudo pip install redis-collections

redis 사용을 위해서 redislite 설치하고

이를 파이썬의 리스트처럼 사용하기 위해서 redis-collections도 설치해서

편리하게 사용하고자 한다.












..

반응형

코드는 가져다가 잘 실행을 했는데

각각의 의미가 궁금해졌다.


사진 : https://pimylifeup.com/raspberry-pi-light-sensor/




소스코드 : https://github.com/pimylifeup/Light_Sensor



#!/usr/local/bin/python

import RPi.GPIO as GPIO 
import time . # sleep 용도

GPIO.setmode(GPIO.BOARD)
# GPIO.BOARD 보드 상의 핀 번호 사용
# GPIO.BCM .  핀번호가 아니라 Broadcom SOC channel을 사용 GPIOXX의 XX 번호를 사용

# 7번 핀을 사용함
pin_to_circuit = 7

def rc_time (pin_to_circuit):
    count = 0

    #Output on the pin for
    GPIO.setup(pin_to_circuit, GPIO.OUT)   # 7번 핀을 입력으로 설정
    GPIO.output(pin_to_circuit, GPIO.LOW)  # 7번 핀의 디지털 출력 설정
    # 셋중에 아무거나 골라서 사용
    # 1, GPIO.HIGH, True
    # 0, GPIO.LOW, False
                                                      
    time.sleep(0.1)  # 0.1 sec sleep

    # 7번 핀을 input으로 변경
    GPIO.setup(pin_to_circuit, GPIO.IN)

    # 7번 핀으로부터 읽은 값이 HIGH가 될 때까지 count 수행
    # 그래서 실행해보면 센서 주변이 어두울 수록 카운트 값이 크다. 
    while (GPIO.input(pin_to_circuit) == GPIO.LOW):
        count += 1

    return count


# 스크립트가 인터럽트 될때 catch하고, 올바르게 cleanp
try:
    # 메인 루프
    while True:
        print rc_time(pin_to_circuit) . # 조도 센서의 값 출력
except KeyboardInterrupt:
    pass
finally:
    GPIO.cleanup() . # 사용했던 모든 포트에 대해서 정리


라즈베리파이3에 구성했던 회로를 연결하고

위의 스크립트를 실행시키면 ($ python light_sensor.py)

값을 가져온다.

실제 실행할때는 sleep을 0.1 -> 1초로 늦춰서 했다.


아직 점퍼를 구입하지 못해서

유선랜 케이블 조금 잘라서 임시로 사용했다.

GPIO에는 묶어서 연결했는데 쇼트날까봐 아슬아슬하다.

아무래도 MF (male, female)로 구성된 점퍼선을 사서 해야겠다.


아래는 정상동작하는 모습을 촬영한 화면이다.





반응형

기본 동작이므로 자료가 많아서 

맘에 드는 링크를 찾아서 시작했다.

https://pimylifeup.com/raspberry-pi-light-sensor/


재료는 아래와 같고 실제 구매는 엘레파츠에서 했다.

국내가 아무래도 배송이 빠르니까

- 조도 센서 : GL5537

- 캐패시터 : 1uF 50V 


빨간선: +

검정선: 접지(GND)

노란선: data


회로를 위와 같이 구성한 다음에

기본 코드를 가지고 조도 센서의 값을 가져온다.


본 작업에서는 git clone으로 코드를 받아서 아래와 같이 실행했다.


$ git clone https://github.com/pimylifeup/Light_Sensor/
$ cd Light_Sensor
$ sudo python light_sensor.py



실행해보면 매우 잘된다.

코드에 대한 이해 없이 돌리고나니 뭔가 부족하다.


코드에 대한 분석을 해봐야겠다.


반응형

Windows 7에서 작업함


RASPBIAN 이미지를 다운 받아서

Win32DiskManager를 이용해서 설치하는 방법이 있으나


Beginners should start with NOOBS라고

명시되어 있으니 시작하는 입장에서 NOOBS (New Out Of the Box)를 사용함


NOOBS zip파일을 받아서  

압축을 풀고 

마이크로 SDcard에 복사해주면 끝난다.

MICROSD-ADAPTER 사용함


마이크로 SDCard안에 따로 폴터를 만들어서 복사해주면 안된다.

아래의 파일 목록들이 SDcard에서 root 경로에 존재해야 한다.



복사한 후 마이크로 SDcard를 라즈베리파이에 꽂아서 전원을 연결한다.

알아서 실행된다. 8GB짜리를 사용했는데

32GB보다 큰것을 사용한다면 formatting 확인이 필요하다.


Micro SDcard adapter는 이전단계에서 사용했고,

이후 단계에 필요한 준비물은 아래와 같다.

https://www.raspberrypi.org/learning/software-guide/quickstart/



참고로 마우스와 키보드도 연결

우측 상단에 Wifi 확인 후 비밀번호 입력해서 

인터넷 연결이 되도록 한다.

안 보이면 좀 기다려야한다. 




그런 다음에 OS를 선택하고 좌측 상단의 'Install'을 클릭하면 나머지는

알아서 다운로드하여 설치가 진행된다.




부팅하면 아래같은 화면이 뜬다.

Wifi의 비밀번호는 다시 한번 입력해서 연결이 되도록 한다.


그림 : http://www.multibootpi.com/builds/quad-boot-raspbian-pixel-retropie-rasplex-kodi/





터미널을 열고

sudo apt-get update 명령을 수행해서 최신 버전 패키지 리스트를 갱신하고


sudo apt-get upgrade 명령을 수행해서 최신 버전으로 패키지 업그레이드를 수행한다.


생각보다 오래걸린다. 1시간은 더 걸린 것 같다.



반응형

+ Recent posts