STM32 Device에서 Rpi4(라즈베리파이 4)를 거쳐 AWSIOT까지 무사히 전송해보는것을 소개하고자 합니다.
우선 본문에 사용되는 STM32 Device는 STM32L475VGT6칩을 사용하는 B-L475E-IOT01A1입니다.
STM32 Project 생성
STM32CUBEIDE를 통해 Project를 생성하면 다음과 같은 창이 나오게 되는데 Board Selector를 클릭해준뒤 보드 모델을 검색해줍니다. 해당 보드를 찾았다면 Next 버튼을 눌러줍니다.
원하는 Project명을 정한뒤 Finish를 누르면 다음과 같은 창이 나오게 되는데 Yes를 눌러줍니다.
그러면 모든 핀들이 활성화된 상태로 설정이 됩니다.
이어서 라즈베리파이와 uart 통신을 하기 위해서 uart4를 활성화 시켜주고 Baud Rate를 9600으로 맞춰줍니다. 핀을 활성화 시켰다면 PA0과 PA1이 초록색으로 변합니다. 이어서 똑같이 ST-Link가 연결되어있는 usart1핀의 Boud Rate 또한 9600으로 맞춰줍니다.
그 다음 상단 카테고리 중 Project Manager 탭에 들어가 Code Generator를 클릭 후 다음과 같이 Generate peripheral initialization as a pair of './c/h' files per peripheral에 체크해줍니다. 이렇게 해줘야 GPIO, Timer, UART 등 각각의 peripheral 마다 별도로 c 파일과 h 파일을 생성해 줍니다. 이 설정을 하지 않으면 모든 설정 파일들이 main.c 에 생성이 됩니다.
이제 저장하고 Code를 Generator 합니다. 그러면 프로젝트안에 파일들이 생성됩니다.
printf 설정
printf 출력을 USART와 연결하여 사용합니다. 그러기 위해서 main.c 파일에 다음의 함수를 추가. 이때 uart의 인스턴스를 설정해야 하는데, 사용중인 보드에선 USART1번이 ST-Link의 Virtual Com Port와 연결되어 있음. 따라서 huart1를 선택.
/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */
/* USER CODE BEGIN 4 */
int __io_putchar(int ch)
{
HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, 100);
return ch;
}
/* USER CODE END 4 */
함수를 작성한 뒤 이제는 printf를 통해 데이터를 출력해봅니다.
while (1)
{
printf("test\r\n");
HAL_Delay(2000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
다음과 같이 while문 안에 코드를 작성 후 디버그를 하면 USART 통신을 통해 데이터를 계속 받고 있습니다. 이를 확인하기 위해서는 터미널 프로그램이 필요한데 본문에서는 Tera Term을 통해 확인해보겠습니다.
만약 데이터가 제대로 출력이 안된다면 설정에 들어가 포트 속도 등을 제대로 설정했는지 확인합니다.
다음은 USB - UART 모듈을 통해 데이터 통신을 해보겠습니다. 모듈을 다음과 같이 연결해줍니다.
보드 회로도를 보면 D1과 D0이 각각 TX, RX 역할을 하고 있습니다. 모듈에 핀을 연결하여 보드와 연결해줍니다.
연결에 성공했다면 다시 코드를 수정해줍니다. 기존 HAL_UART_Transmit 밑에 uart의 인스턴스 설정을 huart4로 변경해서 작성해줍니다.
/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */
/* USER CODE BEGIN 4 */
int __io_putchar(int ch)
{
HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, 100);
HAL_UART_Transmit(&huart4, (uint8_t*)&ch, 1, 100);
return ch;
}
/* USER CODE END 4 */
코드를 작성하고 실행시켜줍니다. 그 다음 다시 Tera Term을 실행시켜 이번에는 모듈을 통해 생성된 COM5에 연결해줍니다. 데이터가 무사히 전송되었다면 연결에 성공한것입니다.
AWS 설정
AWS Management Console에서 IoT core (MQTT 용도) 선택
IoT core - Overview - 디바이스 연결 - 시작하기 선택
시작하기 후 Linux platform - Python (라즈베리파이에서 python 환경용, 사전 설치 조건: git 8883 output port open)
AWS IoT 설정
1단계: 사물 이름 지정 (Client ID로 사용됨): stm_rpi_test
2단계: 연결 키트 다운로드 : 다운로드하여 라즈베리파이에 복사
3단계: Configure and test your device
./start.sh을 열게 되면 pushc, popd가 있는데 현재 해당명령어는 사용되지 않기 때문에 각 cd, cd..으로 변경해줍니다.
그리고 python으로 되있는 부분은 python3로 변경하여 수정해줍니다.
$ vi ./start.sh
다음 내용 수정: pushd->cd, popd->cd, python->python3 (라즈베리파이에서 사용하지 않는 명령)
$ chmod +x start.sh
$ sudo ./start.sh
- rpi에서 Hello world를 cloud에 보내는 것을 볼 수 있음
AWS IoT 초기 정책 설정
- AWS IoT - 관리 - 사물에 "stm_rpi_test"가 등록된 것 확인 가능
- AWS IoT - 보안 - 정책 - stm_rpi_test-Policy에서 아래와 같이 허용된 자원을 볼 수 있음
AWS IoT 정책 변경
- AWS IoT - 보안 - 정책 - 정책생성에서 Name에 allow_all_Policy를 쓰고 Action: *, Resource ARN: *, Allow로 선택
- allow-all_Policy를 보면 아래와 같이 모든 행위를 허용하고 있음
- AWS IoT - 관리 - 사물 에 "stm-rpi_test" 선택
- stm_rpi_test를 선택한 후 인증서에 들어가서 정책 연결메뉴를 클릭하고 만들어둔 allow_all_Pocity 정책 선택
1. 사용자 프로그램에서 MQTT 통신
- 기본적으로 ./start.sh를 실행하면 AWSIoTPythonSDK 모듈이 설치됨.
- AWS IoT - 설정 카테고리에 들어가면 endpoint 볼 수 있음
그 end point를 python 코드에 넣음
mqtt_client = AWSIoTMQTTClient(client_id)
mqtt_client.configureEndpoint("endpoint",8883) # 찾은 endpoint 써줌
mqtt_client.configureCredentials("/home/pi/certs/root-CA.crt", "/home/pi/certs/stm_rpi_test.private.key", "/home/pi/certs/stm_rpi_test.cert.pem") # 인증서 경로 확인
mqtt_client.configureOfflinePublishQueueing(-1) # 연결되지 않을 때 얼마나쌓을것인가 무한대일경우 -1
# mqtt_client.configureDrainingFrequency(2) # 1초에 몇개 데이터 전송할 것인지
mqtt_client.configureConnectDisconnectTimeout(10) # 연결 끊어질때 타임아웃
mqtt_client.configureMQTTOperationTimeout(5)
mqtt_client.connect()
mqtt_client.publish("rpi/status", '{"status":"connect"}',0) #토픽, 데이터(페이로드), 방식
-rpi에서 python3 mqtt_test.py 실행
- AWS IoT - 테스트에서 MQTT 테스트 클라이언트- 주제 구독- 주제 필터에 rpi/count라고 적고 구독 버튼 누르면 좌측에 rpi/status가 나오고 rpi/status를 선택하면 받아지는 내용을 볼 수 있음.
2. 사용자 프로그램에서 MQTT 통신
- 아래 내용 추가
import json, time
for i in range(5):
payloads = { "count": i}
mqtt_client.publish("rpi/count", json.dumps(payloads),0)
time.sleep(1)
- rpi에서 python3 mqtt_test.py 실행
- AWS IoT - 테스트에서 MQTT 테스트 클라이언트- 주제 구독- 주제 필터에 rpi/count라고 적고 구독 버튼 누르면 좌측에 rpi/count가 나오고 rpi/count를 선택하면 받아지는 내용을 볼수 있음.
3. 사용자 프로그램에서 MQTT 통신
- 아래 내용으로 변경
import serial
while True:
if ser.in_waiting:
r = ser.readline()
payloads = {
"value" : r.decode('utf-8')
}
mqtt_client.publish("rpi/serial", json.dumps(payloads),0)
else :
mqtt_client.publish("rpi/status", '{"status":"disconnect"}', 0)
ser.close()
break
- AWS IoT - 테스트에서 MQTT 테스트 클라이언트- 주제 구독- 주제 필터에 rpi/serial라고 적고 구독 버튼 누르면 좌측에 rpi/serial가 나오고 rpi/serial를 선택하면 받아지는 내용을 볼수 있음.
출처 : https://www.youtube.com/watch?v=nkf8rvARfAA&t=1992s
'STM32 > STM32L475VGT6' 카테고리의 다른 글
B-L475E-IOT01A (0) | 2022.02.15 |
---|---|
STM32_RPI4_thingspark (0) | 2022.01.29 |