목표
RFID 카드를 태그하면 카드의 요금을 1000원씩 차감하고 “결제가 완료되었습니다.” 음성을 재생합니다. 만약 카드의 잔액이 1000원 보다 작으면 “잔액이 부족합니다. 충전해주세요” 음성을 재생합니다.
푸시버튼을 누르면 충전모드로 진입하고 “충전모드입니다. 카드를 태그해주세요” 음성을 재생합니다. 충전모드에서 카드를 태그하면 5000원을 충전하고 “충전이 완료되었습니다.” 음성을 재생후 충전모드에서 빠져나옵니다.
카드의 잔액은 대시보드에 텍스트 위젯으로 표시합니다.
하드웨어
부품
부품 | 갯수 |
---|---|
MFRC522 RFID 리더 | 1 |
RFID 카드 또는 태그 | 1 |
푸시버튼 | 1 |
연결
아래의 핀을 가로 방향으로 서로 연결합니다.
MFRC522 | 푸시버튼 | GPIO |
---|---|---|
VIN(3.3V) | | 3.3V |
GND | | GND |
SCK ¹ | | 11 (SPI0 SCLK) |
MISO ¹ | | 9 (SPI0 MISO) |
MOSI ¹ | | 10 (SPI0 MOSI) |
SDA ¹ | | 8 (SPI0 CE0) |
RST | | 3.3V |
| 푸시버튼 핀1 ² | 3.3V |
| 푸시버튼 핀2 ³ | 16 |
³ 임의의 GPIO핀에 연결할 수 있습니다.
I/O장치
RFID 리더와 푸시버튼을 I/O장치에 추가합니다.
변수
카드 태그여부, 푸시버튼 누름 여부, 카드 잔액 등 필요한 변수를 추가합니다.
- “카드 태그됨” (디지털)
- “버튼 누름” (디지털)
- “모드” (숫자)
- “잔액 데이터” (바이트 배열)
- “잔액” (숫자)
로직
컨트롤러는 사용자가 언제 푸시버튼을 누르거나 또는 카드를 태그할 지 모르기 때문에 항상 체크해야 합니다.
사용자가 푸시버튼을 누르면 충전모드로 변경하고 “충전모드입니다. 카드를 태그해주세요” 음성을 재생합니다.
사용자가 카드를 태그할 경우에는 아래와 같이 동작합니다.
- 현재모드가 충전모드 일때
- 카드의 잔액에 5000원을 더하여 카드에 다시 쓴다
- “충전이 완료되었습니다.” 음성 재생
- 일반모드로 변경
- 현재모드가 일반모드 일때
- 잔액이 1000원 이상이면
- 잔액에서 1000원을 뺀 뒤에 다시 카드에 쓴다
- “결제가 완료되었습니다.” 음성 재생
- 잔액이 1000원 미만이면
- “잔액이 부족합니다. 충전해주세요” 음성재생
- 잔액이 1000원 이상이면
위의 내용을 알고리즘 블록으로 나타내면 아래와 같습니다.
[로직]
로직을 추가합니다.
[제어] 항상 푸시버튼의 값 및 카드의 태그여부를 체크한다.
제어를 추가합니다.
[조건] 항상
항상 만족하는 조건을 추가합니다.
타입: 항상 유효
[동작] 푸시버튼의 값을 읽어온다
푸시버튼의 누름여부를 “버튼 누름”이라는 변수에 저장하는 동작을 추가합니다.
- 타입: I/O장치
- 장치: 푸시버튼
- 명령: READ_PIN
- 값: “버튼 누름” 선택
[동작] RFID카드의 태그여부를 체크한다
카드의 태그여부를 “카드 태그됨” 이라는 변수에 저장하는 동작을 추가합니다.
- 타입: I/O장치
- 장치: RFID 카드 리더
- 명령: IS_NEW_CARD
- 값: “카드 태그됨” 선택
[제어] 푸시버튼을 눌렀을때 충전모드로 진입한다.
제어를 추가합니다.
[조건] 푸시버튼을 눌렀다면
앞서 푸시버튼의 누름여부를 “버튼 누름”이라는 변수에 저장했으므로 이 변수의 값을 비교하는 조건을 추가합니다.
- 타입: 비교
- 변수: “버튼 누름”
- 연산자: = (같다)
- 값: true
- 조건옵션: 참인 순간
[동작] 현재모드를 충전모드로 설정한다
충전모드 (“모드” 변수의 값이 1)로 설정하는 동작을 추가합니다.
- 타입: 쓰기
- 변수: “모드” 선택
- 값: 1
[동작] 음성을 재생한다.
“충전모드입니다. 카드를 태그해주세요” 음성을 재생하는 동작을 추가합니다.
- 타입: 미디어재생
- 경로: mp3 파일의 라즈베리파이 경로
[제어] 카드를 태그하면 모드에 따라서 요금을 충전하거나 차감한다.
제어를 추가합니다.
[조건] 카드를 태그했다면
앞서, 카드의 태그여부를 “카드 태그됨”이라는 변수에 저장하였으므로, 이 변수의 값을 비교하는 조건을 추가합니다.
- 타입: 비교
- 변수: “카드 태그됨”
- 연산자: = (같다)
- 값: true
[동작] 카드에서 잔액 데이터를 읽는다
카드에서 잔액을 읽어서 바이트 배열 타입의 변수에 저장하는 동작을 추가합니다. Mifare class 카드에서 데이터를 읽고 쓰는 단위를 블럭이라고 하며 1 블럭은 16 바이트로 구성되어 있습니다. 본 예제에서는 블럭 주소 1을 사용합니다. 좀 더 자세한 내용은 여기를 참고합니다.
- 타입: I/O장치
- 장치: RFID 카드리더
- 명령: READ_DATA
- 값
- 블럭주소: 1
- 데이터: “잔액 데이터” 선택
[동작] 바이트 배열 잔액 데이터를 정수로 변환한다.
카드에서 읽은 데이터는 16바이트 크기의 바이트 배열이며 데이터는 배열의 가장 첫번째 위치부터 순서대로 표시 또는 저장됩니다. 그러므로 앞에서 부터 4개의 바이트만 읽어서 정수로 변환 후, 숫자변수 “잔액”에 저장하는 동작을 추가합니다. 4바이트의 정수는 최대 65535원의 금액까지 표시 또는 저장할 수 있습니다.
- 타입: 사용자입력
- 블록작성
- “잔액 데이터”에서 4바이트 추출
- 바이트 배열을 정수로 변환후 “잔액”에 저장
[제어] 충전모드일 때의 동작
제어를 추가합니다.
[조건] 충전모드 라면
변수 “모드”의 값이 1 (충전모드)인지 비교하는 조건을 추가합니다.
- 타입: 비교
- 변수: “모드”
- 연산자: = (같다)
- 값: 1
[동작] 잔액에 5000원을 더한 후 카드에 저장
잔액에 5000원을 더한 뒤, 바이트 배열로 변환하여 카드에 저장하는 동작을 추가합니다. 데이터는 1블록 (16바이트) 단위로 카드에 쓸 수 있으며, 바이트 배열로 변환된 크기가 16바이트보다 작을 경우 나머지 공간은 0x00 으로 채워집니다.
- 타입: I/O장치
- 장치: RFID 카드리더
- 명령: WRITE_DATA
- 값
- 블럭주소: 1
- 데이터: “잔액”에 5000원을 더한 뒤 바이트 배열로 변환
[동작] “충전이 완료되었습니다.” 음성 재생
mp3파일을 재생하는 동작을 추가합니다.
- 타입: 미디어재생
- 파일경로: mp3파일의 라즈베리파이 경로
[동작] 일반모드로 변경
“모드”를 0 (일반모드) 으로 변경하는 동작을 추가합니다.
- 타입: 쓰기
- 변수: “모드”
- 값: 0
[제어] 일반모드일 때의 동작
제어를 추가합니다.
[조건] 일반모드 라면
“모드” 의 값이 0 (일반모드) 인지 비교하는 조건을 추가합니다.
- 타입: 비교
- 변수: “모드”
- 연산자: = (같다)
- 값: 0
[제어] 잔액이 1000원 이상일 때의 동작
제어를 추가합니다.
[조건] 잔액이 1000원 이상이라면
“잔액”의 값을 비교하는 조건을 추가합니다.
- 타입: 비교
- 변수: “잔액”
- 연산자: >= (크거나 같다)
- 값: 1000
[동작] 잔액에서 1000원 뺀 뒤에 다시 카드에 저장한다
잔액에서 1000원 뺀 뒤에 바이트 배열로 변환하여 카드에 저장하는 동작을 추가합니다. 데이터는 1블록 (16바이트) 단위로 카드에 쓸 수 있으며, 바이트 배열로 변환된 크기가 16바이트보다 작을 경우 나머지 공간은 0x00 으로 채워집니다.
- 타입: I/O장치
- 장치: RFID 카드리더
- 명령: WRITE_DATA
- 값
- 블럭주소: 1
- 데이터: “잔액”에 1000원을 뺀 뒤, 바이트 배열로 변환
[동작] “결제가 완료되었습니다.” 음성 재생
mp3파일 재생하는 동작을 추가합니다.
- 타입: 미디어재생
- 파일경로: mp3파일의 라즈베리파이 경로
[제어] 잔액이 1000원 미만일 때의 동작
제어를 추가합니다.
[조건] 잔액이 1000원 미만이라면
“잔액”의 값을 비교하는 조건을 추가합니다.
- 타입: 비교
- 변수: “잔액”
- 연산자: < (작다)
- 값: 1000
[동작] “잔액이 부족합니다. 충전해주세요” 음성 재생
mp3 파일을 재생하는 동작을 추가합니다.
- 타입: 미디어재생
- 파일경로: mp3파일의 라즈베리파이 경로
[동작] 태그된 카드 종료
태그된 카드와 관련된 작업을 종료하는 동작을 추가합니다. 태그된 카드를 종료하지 않으면 동일하거나 다른 카드가 다음에 태그되었을때 제대로 동작하지 않습니다.
- 타입: I/O장치
- 장치: RFID 카드리더
- 명령: STOP
대시보드
대시보드를 추가합니다.
카드의 잔액을 표시하는 위젯을 추가합니다.
- 구분: 읽기
- 변수: “잔액”
- 타입: 텍스트
실행
버튼을 눌러서 RUN모드로 진입합니다.