1. 쉘 Shell 이란?!

- 리눅스의 쉘은 명령어와 프로그램을 실행할 때 사용하는 인터페이스이다.

쉘은 커널(Kernel)과 사용자간의 다리역할을 하는 것이다.

사용자로부터 명령을 받아 그것을 해석하고 프로그램을 실행하는 역할을 한다. 

2. 쉘의 종류와 특징 

쉘은 커널에서 분리된 별도의 프로그램이어서 다양한 종류의 쉘이 존재하고 지금도 발전하고 있다.

* 쉘마다 제공하는 기능이 살짝 다르다. 특정 단축키를 누르면 제공되는 기능 등등 

1) Bourne Shell (sh)

- Bourne Shell(sh)은 유닉스 쉘의 오리지날이다. 이 오리지날 쉘을 통해 더 좋은 쉘들이 발전하였다.

* 프롬포트 - 일반 유저는 $ 프롬포트를 사용하고 root 유저는 # 프롬포트를 사용한다. 

 

2) bash (배쉬)

- 현재 리눅스의 표준 쉘이다. 우분투와 페도라도 배쉬 쉘을 사용한다. bash 쉘은 sh 쉘을 기반으로 만들어졌다. GNU 프로젝트를 위해 개발한 bash 쉘이다. GNU는 자유로운 소프트웨어를 희망하는 프로젝트이다. 

 

C 쉘 Korn 쉘 등등은 생략하고 이제 zsh 쉘에 대해서 알아보자.

 

3) zsh (Z쉘)

- bash와 마찬가지로 sh의 확장 된 버전이다. 

- 장점

1) 자동 CD : 디렉토리 이름을 입력하세요.

2) 재귀 경로 확장 : "/u /lo /b"는 "/usr /local /bin"으로 확장된다.

3) 철자 교정 및 대략적인 완성 : 디렉토리 이름을 입력하는 데, 약간의 실수가 있으면 ZSH 가이를 수정한다.

4) 플러그인 및 테마 지원 : ZSH에는 다양한 플러그인 프레임 워크가 포함되어 있다. 

 

* 맥에서는 카탈리나부터 기본 쉘이 zsh로 바뀌었다.

* Oh-My-Zsh라는 플러그인과 프레임워크가 가장 널리 사용된다고 한다.

 

참고 사이트 : 

https://jhnyang.tistory.com/57

 

[리눅스]셸(Shell)이란? 셸의 변경, 쉘 개념, 기능, 종류와 특징(sh, bash, csh, tcsh, ksh)

리눅스 완전 정복 : 리눅스 목차 셸 스크립트 프로그래밍을 하려면 셸이 무엇인지 먼저 알아야겠죠! 셸(Shell)이란? 리눅스의 셸은 명령어와 프로그램을 실행할 때 사용하는 인터페이스입니다. 좀

jhnyang.tistory.com

 

현재 라즈베리파이에 많은 설치환경을 구성해놓아서 백업을 해놓아야겠다고 생각했다.

참고링크

https://ko.gadget-info.com/19657-how-to-clone-raspberry-pi-sd-card-on-windows-linux-and-macos

 

Windows, Linux 및 MacOS에서 Raspberry Pi SD 카드를 복제하는 방법

Raspberry Pi 설치를 백업 한 다음 복원 하시겠습니까? 다음은 Windows, Linux 및 MacOS에서 Raspberry Pi SD 카드를 복제하는 단계입니다.

ko.gadget-info.com

라즈베리파이 백업에 대해서 잘 정리되어 있는 사이트인데 이 글을 참고해서 정리를 해보겠다.

 

1. 준비물 

1) 백업 할 sd카드

2) sd카드 리더기

3) 맥북

4) balenaEtcher

 

2. 진행순서

1) 터미널에 다음과 같이 입력

 

마운트를 해제한다.

** Mount와 Unmount

마운트란 어떤 파일 시스템을 디렉토리 일부에 넣어서 이용가능하게 하는 작업. 파티션을 하부디렉토리처럼 쓰는 것을 마운트라고 한다.

unmount 마운트명령으로 인해 장착된 장치를 해제한다.

diskutil unmountDisk /dev/disk3

입력하면 아래와 같이 디스크 정보가 나온다.

/dev/disk3 이 라즈베리파이 정보인데, 이 녀석을 백업할 것이다.

 

2) dd 명령을 사용하여 이미지를 하드디스크에 쓴다.

sudo dd if=/dev/disk3 of=~/raspbian_backup.img

# 맥에서 sudo 를 사용할 경우 ~ (홈 디렉토리)를 못 사용한다고 하니 아래와 같이 고쳐쓰자.
sudo dd if=/dev/disk3 of=/Users/jwoh/raspbian_backup.img

와.. 16GB 이미지를 복사하는데 정확히 2시간 5분 정도가 걸렸다...!!

위의 그림과 같이 7327초가 걸렸다고 정확하게 출력하여준다.

brew install pv
sudo pv /dev/disk3 > /Users/jwoh/raspibian_backup.img

위와 같이 입력하면 정확하게 걸리는 시간을 보여준다고 한다. 

터미널 2개를 켜고 같이 돌렷는데 시간이 똑같이 나왔다. 하지만 별 의미는 없는 듯...

미리 완료되는 시간을 알고 싶어서 pv 명령어를 입력했는데 똑같이 2시간 지나서야 완료 시간을 알려주었다..

 

지금보니 img파일이 2개가 만들어 졌는데 pv명령어는 시간만 알려주는게 아니라 복제까지 해주는가 보다...!

두 pv랑 dd 명령어를 같이 돌려서 2시간 오래걸린 것 같기도 하다....?!

 

3) 이제 img로 구운 파일을 내 외장하드에 옮긴다.

- 이 과정은 5분이 채 걸리지 않았다..!!

 

4) 라즈베리파이 SD 카드 복원

이제 라즈베리파이 SD카드를 복원할 것이다.

diskutil unmountDisk /dev/disk3

마운트를 해제한다. 

sudo dd if = ~ / raspbian_backup.img of / dev / disk3

# 아까 말했듯이 ~(홈디렉토리)는 sudo명령어에서 인식을 못하므로 아래와 같이 변경해서 사용.
sudo dd if=/Users/jwoh/raspbian_backup.img of=/dev/disk3

아까 위에서 했던 명령어의 목적어를 뒤집는다. 이미지를 디스크3에 복제한다.

이렇게 하면 총 5시간 쯤 걸리는 듯 하다.


반대로 아주 쉽게하는 방법도 있다.

balenaEtcher라는 앱을 이용하는 것이다.

파일을 복제하거나 URL을 복제하거나 드라이버를 복제할 수 있다.

원하는 방식으로 선택한 뒤 -> Select target (복제할 위치) -> Flash를 누르면 끝!

 

생각해보니.. 이 방법이 훨씬 쉽자나....?

AWSIoTCore

Python으로 aws-iot 진행하였습니다.

준비과정 (AWSIoTCore 세팅방법)

1. AWS IoT Core -> 온보딩 -> 시작하기 1

2. 시작하기 클릭 2

3. 본인은 라즈베리파이에서 하기 때문에, Linux/OSX, Python 클릭 3

4. 사물등록, 이름은 아무거나 4

5. 연결키트 다운로드, Linux/OSX -> 다음 단계 5

6. 1단계부터 3단계까지 순차적으로 진행 -> 완료 클릭 6

7. 보안 -> 정책 클릭 후 새로운 정책을 만든다. Action과 Resource ARN을 아래 그림과 같이 수정
7

8. 보안 -> 인증서 -> 정책연결과 사물연결을 해준다. 8

9. 이제 cognito로 이동,

- cognito는 연동자격 증명에 대한 소비자 자격 증명 관리 및 AWS 자격 증명이다. 9

10. 자격 증명 풀 관리 클릭 10

11.새 자격 증명 풀 만들기 클릭 11

12. 자격 증명 풀 이름을 정하고, 빨간 네모 박스에 체크하고 -> 풀 생성 클릭 12

13. 편집 클릭 -> Resource 아래 "" 사이에 ARN을 입력한다. 13

14. ARN은 AWS IoT -> 관리-> 사물 클릭 [ (+추가) thing까지만 복사 붙여넣기 한다.] 14

15. ENDPOINT는 아래의 사진과 같이 iot core -> settings에 가면 확인할 수 있다. 스크린샷 2021-07-30 오후 12 32 01

AWSIoTCore MQTT Test

이제 awsiotcoreSubTest.py와 awsiotcorePubTest.py로 먼저 MQTT테스트를 진행한다.

코드는 아래와 같다.

awsiotcoreSubTest.py

import time
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient

# subsciber에서 hellowrtd 함수의 내용을 출력하게 된다.
def helloworld(self, params,packet):
    print('Recieved Message from AWS IoT Core')
    print('Topic: '+ packet.topic)
    print("Payload: ", (packet.payload))

# For certificate based connection
myMQTTClient = AWSIoTMQTTClient("clientid")

# For TLS mutual authentication
# "" 사이에 본인의 ENDPOINT를 입력한다.
myMQTTClient.configureEndpoint("ai628r69tqiu1-ats.iot.ap-northeast-2.amazonaws.com", 8883) #Provide your AWS IoT Core endpoint (Example: "abcdef12345-ats.iot.us-east-1.amazonaws.com")

# root-CA.crt, cert.pem, private.key의 경로를 입력한다.
myMQTTClient.configureCredentials("/home/pi/Downloads/aws-iot/root-CA.crt", "/home/pi/Downloads/aws-iot/aws-iot.private.key", "/home/pi/Downloads/aws-iot/aws-iot.cert.pem") #Set path for Root CA and unique device credentials (use the private key and certificate retrieved from the logs in Step 1)
myMQTTClient.configureOfflinePublishQueueing(-1)
myMQTTClient.configureDrainingFrequency(2)
myMQTTClient.configureConnectDisconnectTimeout(10)
myMQTTClient.configureMQTTOperationTimeout(5)
print("Initiating IoT Core Topic ...")

# aws/iot 토픽에 입장하여 helloworld 함수의 내용을 받게 된다.
myMQTTClient.subscribe("aws/iot",1,helloworld)
myMQTTClient.connect()

while True:
    time.sleep(5)

awsiotcorePubTest.py

import time
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient


# For certificate based connection
myMQTTClient = AWSIoTMQTTClient("clientid")
# For TLS mutual authentication
myMQTTClient.configureEndpoint("ai628r69tqiu1-ats.iot.ap-northeast-2.amazonaws.com", 8883) #Provide your AWS IoT Core endpoint (Example: "abcdef12345-ats.iot.us-east-1.amazonaws.com")
myMQTTClient.configureCredentials("/home/pi/Downloads/aws-iot/root-CA.crt", "/home/pi/Downloads/aws-iot/aws-iot.private.key", "/home/pi/Downloads/aws-iot/aws-iot.cert.pem") #Set path for Root CA and unique device credentials (use the private key and certificate retrieved from the logs in Step 1)
myMQTTClient.configureOfflinePublishQueueing(-1)
myMQTTClient.configureDrainingFrequency(2)
myMQTTClient.configureConnectDisconnectTimeout(10)
myMQTTClient.configureMQTTOperationTimeout(5)
print("Initiating IoT Core Topic ...")
# myMQTTClient.subscribe("aws/iot")
myMQTTClient.connect()

print("Publishing Message from RPI")
myMQTTClient.publish(
    topic="aws/iot",
    QoS=1,
    payload="{'Message' : 'Message By RPI'}"
)

미니프로젝트 소개

1. 시나리오

1)스마트홈 구축

  • 문 앞에 접근하면 LED 등이 켜지면서 얼굴 인식이 시작된다. 얼굴 인식에 성공 할 시 “얼굴 인식 성공!” 이라는 단어가 뜨면서 문이 열리게 된다. (얼굴 인식 성공은 “나(Me)”만 얼굴 인식에 성공할 수 있다.)
  • Subscriber(구독자)는 LED 소등 여부와 얼굴인식 성공여부를 보고 받는다.
  • Publisher(발행자)는 LED소등 여부와 얼굴인식 성공여부를 보고한다.
  • 초음파 거리센서와 가까워 질 때, LED가 켜지면서 얼굴인식이 시작된다.
  • 반대로 초음파와 거리가 멀어지면 LED는 꺼지고, "얼굴인식 객체가 없습니다"라는 메세지를 보낸다.

2. 준비물

1)라즈베리파이4(풀세트, 센서포함)

3. 진행과정

1)문 앞, 초음파 거리 센서(sensor) 30cm 이내 위치할 시에
LED 전구가 켜진다.

IMG_6932 copy

2)전구가 켜지면서 얼굴인식이 진행된다.

IMG_6931 copy 2

3)얼굴 인식이 완료되면 “얼굴 인식 성공 !!” 이라는 메세지를 출력하게 되고, MQTT에서도 똑같이 메세지가 도착하게 된다.

** Sub.py에 출력된 내용

image
Subscriber는
LED 전구의 ON / OFF 여부,
얼굴 인식 성공 / 실패 여부를 보고 받는다.

** Pub.py에 출력된 내용
image

** 휴대폰 MQTT 앱에 도착한 내용
image

4. awsiotcore.py (코드내용)

# python3 -m venv venv
# source venv/bin/activate
# pip3 install opencv-python
# pip3 install dlib
# pip3 install face_recognition
# pip3 install RPi.GPIO
# pip3 install picamera
# pip3 install paho-mqtt
# pip3 install AWSIoTPythonSDK

from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
import face_recognition
import picamera
import numpy as np
import paho.mqtt.client as mqtt
import RPi.GPIO as GPIO
import time

# For certificate based connection
myMQTTClient = AWSIoTMQTTClient("clientid")
# For TLS mutual authentication
myMQTTClient.configureEndpoint("ai628r69tqiu1-ats.iot.ap-northeast-2.amazonaws.com", 8883) #Provide your AWS IoT Core endpoint (Example: "abcdef12345-ats.iot.us-east-1.amazonaws.com")
myMQTTClient.configureCredentials("/home/pi/Downloads/aws-iot/root-CA.crt", "/home/pi/Downloads/aws-iot/aws-iot.private.key", "/home/pi/Downloads/aws-iot/aws-iot.cert.pem") #Set path for Root CA and unique device credentials (use the private key and certificate retrieved from the logs in Step 1)
myMQTTClient.configureOfflinePublishQueueing(-1)
myMQTTClient.configureDrainingFrequency(2)
myMQTTClient.configureConnectDisconnectTimeout(10)
myMQTTClient.configureMQTTOperationTimeout(5)
print("Initiating IoT Core Topic ...")

# GPIO ultra sonic Setting
trig=17
echo=18
ledpin=14

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(trig,GPIO.OUT)
GPIO.setup(echo,GPIO.IN)
####################

# Camera Setting
camera = picamera.PiCamera()
camera.resolution = (320, 240)
output = np.empty((240, 320, 3), dtype=np.uint8)
# Load a sample picture and learn how to recognize it.
print("Loading known face image(s)")
me_image = face_recognition.load_image_file("me.jpg")
me_face_encoding = face_recognition.face_encodings(me_image)[0]
# Initialize some variables
face_locations = []
face_encodings = []
#########################

while True:
    myMQTTClient.connect()
    GPIO.output(trig,False)
    time.sleep(15)

    GPIO.output(trig,True)
    time.sleep(0.00001)
    GPIO.output(trig,False)

    while GPIO.input(echo)==0:
        pulse_start=time.time()

    while GPIO.input(echo)==1:
        pulse_end=time.time()

    pulse_duration=pulse_end - pulse_start
    distance=pulse_duration*17000
    distance=round(distance,2)
    print("Distane: ",distance, "cm")

    if distance<30:
        GPIO.setwarnings(False)
        GPIO.setup(ledpin,GPIO.OUT)
        GPIO.output(ledpin,True)
        print("distance is lower than 30")
        print("LED ON")
        print("Publishing Message from RPI")
        myMQTTClient.publish(
            topic="aws/iot",
            QoS=1,
            payload="{'Message' : LED ON'}"
        )

        print("Capturing image.")
        # Grab a single frame of video from the RPi camera as a numpy array
        camera.capture(output, format="rgb")
        # Find all the faces and face encodings in the current frame of video
        face_locations = face_recognition.face_locations(output)
        print("Found {} faces in image.".format(len(face_locations)))
        print("Face Recognition Failed !!")
        myMQTTClient.publish(
            topic="aws/iot",
            QoS=1,
            payload="{'Message' : Face Recognition Failed !!'}"
        )
        face_encodings = face_recognition.face_encodings(output, face_locations)
        # Loop over each face found in the frame to see if it's someone we know.
        for face_encoding in face_encodings:
        # See if the face is a match for the known face(s)
            match = face_recognition.compare_faces([me_face_encoding], face_encoding)
            name = "<Unknown Person>"
            if match[0]:
                name = "Me"
            if(name=="Me"):
                print("Face Recognition PASS !!")
                myMQTTClient.publish(
                topic="aws/iot",
                QoS=1,
                payload="{'Message' : Face Recognition Success !!'}"
            )
            print("This image includes in our data {}!".format(name))

    if distance>30:
        GPIO.setwarnings(False)
        GPIO.setup(ledpin,GPIO.OUT)
        GPIO.cleanup(ledpin)
        print("distance is higher than 30")
        print("LED OFF")
        print("please come to sensor closer")
        myMQTTClient.publish(
            topic="aws/iot",
            QoS=1,
            payload="{'Message' : LED OFF'}"
        )
        myMQTTClient.publish(
            topic="aws/iot",
            QoS=1,
            payload="{'Message' : There is nothing to Recognize'}"
        )

5. AWS 결과 사진

결과1 결과2 결과3

6. 참고 사이트

1)Ultrasonic (초음파거리센서)

2)LED전구

3)MQTT

4)Face Recognition (얼굴인식)

5)AWSIoTCore

7. 오류 해결 내역

1)Subscribe 채널에서 문장 앞에 b”LED ON”과 같이 b가 같이 출력되었음.

--> decode(“utf-8”)로 해결

2)기존의 face_recog.py 코드를 이용했을 경우, 코드가 동작은 했지만, 얼굴 인식 프로그램이 늦게 동작하여 랙이 상당히 많이 걸림.

--> 프레임 수 조절 및 코드를 단순 촬영하는 코드로 바꾸어서 문제 해결.
(기존의 코드는 실시간으로 webcam 프로그램이 실행되면서, 얼굴인식이 진행 되었다.)

3)AWS IoT Core 내의 MQTT 과정을 이해하기 위해서 유튜브링크를 참고하였다. 메세지 부분의 코드를 찾기 시작하였고 앞에서의 awsiotcoreSubTest.py, awsiotcorePubTest.py를 통해 코드의 이해에 큰 도움이 되었다.

'Tech Blog > AWS' 카테고리의 다른 글

AWS (Amazon Web Service) 활용 기초  (0) 2021.07.15

+ Recent posts