1. Buat dua project baru menggunakan board STM32 NUCLEO-G474RE, yaitu Nucleo 1 dan Nucleo 2.
2. Pada
Nucleo 1, konfigurasi pin dan peripheral dengan mengaktifkan TIM2 CH1
pada PA0 sebagai PWM Generation CH1 menggunakan Internal Clock, aktifkan
I2C1 pada PA15 dan PB5, aktifkan USART1 mode Asynchronous pada PA9 dan
PA10, serta aktifkan pin PA1 dan PA4 sebagai GPIO Input.
3. Pada
Nucleo 2, konfigurasi TIM2 CH1 pada PA0 sebagai PWM Generation CH1,
aktifkan USART1 mode Asynchronous pada PA9 dan PA10, lalu aktifkan pin
PA1 dan PA4 sebagai GPIO Input.
4. Generate code untuk kedua project setelah seluruh konfigurasi selesai dilakukan.
5. Pada project Nucleo 1, buat file header baru pada folder Inc berupa main.h, ssd1306_conf.h, ssd1306_fonts.h, dan ssd1306.h.
6. Pada project Nucleo 1, buat file source baru pada folder Src berupa main.c, ssd1306_fonts.c, dan ssd1306.c.
Sistem
kontrol parkir otomatis dua pintu ini bekerja menggunakan dua buah
mikrokontroler STM32 Nucleo G474RE yang berfungsi sebagai pengendali
pintu masuk dan pintu keluar. Pada pintu masuk, sensor IR mendeteksi
keberadaan kendaraan yang datang, kemudian data dibaca oleh Nucleo 1
untuk memeriksa ketersediaan slot parkir. Jika slot masih tersedia,
servo akan membuka palang pintu masuk dan jumlah slot kosong pada OLED
akan diperbarui menjadi berkurang. Namun apabila slot parkir penuh, OLED
akan menampilkan informasi “parkir penuh” dan servo tetap dalam kondisi
tertutup sehingga kendaraan tidak dapat masuk.
Pada
pintu keluar, sensor IR kedua mendeteksi kendaraan yang keluar area
parkir dan sinyal diproses oleh Nucleo 2. Setelah kendaraan terdeteksi,
servo pintu keluar akan membuka palang agar kendaraan dapat keluar,
kemudian sistem menambahkan kembali jumlah slot kosong dan memperbarui
tampilan OLED. Kedua mikrokontroler saling berkomunikasi menggunakan
UART untuk sinkronisasi data jumlah slot parkir sehingga informasi
kapasitas parkir tetap sesuai kondisi aktual secara real-time.
/* USER CODE BEGIN Header */
/**
************************************************************
******************
* @file : main.c
* @brief : Master Parking System - STM32G474RE
************************************************************
******************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------
------------------*/
#include "main.h"
/* Private includes ----------------------------------------
------------------*/
/* USER CODE BEGIN Includes */
#define SSD1306_INCLUDE_FONT_7x10
#include "ssd1306.h"
#include "ssd1306_fonts.h"
#include
#include
/* USER CODE END Includes */
/* Private typedef -----------------------------------------
------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------
------------------*/
/* USER CODE BEGIN PD */
#define MAX_PARKIR 10
/* USER CODE END PD */
/* Private macro -------------------------------------------
------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------
------------------*/
COM_InitTypeDef BspCOMInit;
I2C_HandleTypeDef hi2c1;
TIM_HandleTypeDef htim2;
UART_HandleTypeDef huart1; // komunikasi ke slave (PC4/PC5)
UART_HandleTypeDef huart2; // serial monitor via BSP COM1
(PA2/PA3)
/* USER CODE BEGIN PV */
uint8_t sisa_parkir = MAX_PARKIR;
uint8_t kendaraan_masuk = 0;
uint8_t uart_rx_buffer[1];
/* USER CODE END PV */
/* Private function prototypes -----------------------------
------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MX_TIM2_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */
void Update_Display(void);
void Servo_Buka(void);
void Servo_Tutup(void);
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
MX_GPIO_Init();
MX_I2C1_Init();
MX_TIM2_Init();
MX_USART1_UART_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
BSP_LED_Init(LED_GREEN);
BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);
// Serial monitor via BSP COM1 (USART2 PA2/PA3)
BspCOMInit.BaudRate = 115200;
BspCOMInit.WordLength = COM_WORDLENGTH_8B;
BspCOMInit.StopBits = COM_STOPBITS_1;
BspCOMInit.Parity = COM_PARITY_NONE;
BspCOMInit.HwFlowCtl = COM_HWCONTROL_NONE;
if (BSP_COM_Init(COM1, &BspCOMInit) != BSP_ERROR_NONE) {
Error_Handler();
}
ssd1306_Init();
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
htim2.Instance->CCR1 = 1000;
// USART1 untuk komunikasi ke slave (PC4=TX, PC5=RX)
HAL_UART_Receive_IT(&huart1, uart_rx_buffer, 1);
printf("=== MASTER PARKING READY ===\r\n");
printf("Slot tersedia: %d/%d\r\n", sisa_parkir,
MAX_PARKIR);
Update_Display();
/* USER CODE END 2 */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
uint8_t ir =
!HAL_GPIO_ReadPin(MASTER_IR_SENSOR_GPIO_Port,
MASTER_IR_SENSOR_Pin);
printf("IR: %d | Sisa: %d\r\n", ir, sisa_parkir);
// DETEKSI MASUK
if (ir && sisa_parkir > 0 && !kendaraan_masuk) {
HAL_Delay(50);
ir = !HAL_GPIO_ReadPin(MASTER_IR_SENSOR_GPIO_Port,
MASTER_IR_SENSOR_Pin);
if (ir) {
Servo_Buka();
sisa_parkir--;
kendaraan_masuk = 1;
Update_Display();
printf(">> MASUK! Sisa: %d/%d\r\n", sisa_parkir,
MAX_PARKIR);
HAL_UART_Transmit(&huart1, (uint8_t*)"M", 1, 100);
}
}
// PARKIR PENUH
if (ir && sisa_parkir == 0 && !kendaraan_masuk) {
printf(">> PARKIR PENUH!\r\n");
BSP_LED_Toggle(LED_GREEN);
HAL_Delay(200);
}
// KENDARAAN SUDAH LEWAT
if (!ir && kendaraan_masuk) {
HAL_Delay(50);
ir = !HAL_GPIO_ReadPin(MASTER_IR_SENSOR_GPIO_Port,
MASTER_IR_SENSOR_Pin);
if (!ir) {
Servo_Tutup();
kendaraan_masuk = 0;
printf(">> Palang ditutup\r\n");
}
}
HAL_Delay(100);
}
/* USER CODE END 3 */
}
/* USER CODE BEGIN 4 */
void Update_Display(void) {
char buf[25];
ssd1306_Fill(Black);
/* USER CODE BEGIN Header */
/**
**************************************************************
****************
* @file : main.c
* @brief : Slave Parking System - STM32G474RE
(Pintu Keluar)
**************************************************************
****************
*/
/* USER CODE END Header */
/* Includes --------------------------------------------------
----------------*/
#include "main.h"
/* Private includes ------------------------------------------
----------------*/
/* USER CODE BEGIN Includes */
#include
#include
/* USER CODE END Includes */
/* Private typedef -------------------------------------------
----------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define --------------------------------------------
----------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro ---------------------------------------------
----------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables -----------------------------------------
----------------*/
COM_InitTypeDef BspCOMInit;
TIM_HandleTypeDef htim2;
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
/* USER CODE BEGIN PV */
uint8_t kendaraan_keluar = 0;
uint8_t uart_rx_buffer[1];
/* USER CODE END PV */
/* Private function prototypes -------------------------------
----------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM2_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */
void Servo_Buka(void);
void Servo_Tutup(void);
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
MX_GPIO_Init();
MX_TIM2_Init();
MX_USART1_UART_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
BSP_LED_Init(LED_GREEN);
BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);
BspCOMInit.BaudRate = 115200;
BspCOMInit.WordLength = COM_WORDLENGTH_8B;
BspCOMInit.StopBits = COM_STOPBITS_1;
BspCOMInit.Parity = COM_PARITY_NONE;
BspCOMInit.HwFlowCtl = COM_HWCONTROL_NONE;
if (BSP_COM_Init(COM1, &BspCOMInit) != BSP_ERROR_NONE) {
Error_Handler();
}
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
htim2.Instance->CCR1 = 1000;
// USART2 RX interrupt - terima dari master
HAL_UART_Receive_IT(&huart1, uart_rx_buffer, 1);
HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin,
GPIO_PIN_RESET);
printf("=== SLAVE READY - Pintu Keluar ===\r\n");
/* USER CODE END 2 */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
uint8_t ir = !HAL_GPIO_ReadPin(SLAVE_IR_SENSOR_GPIO_Port,
SLAVE_IR_SENSOR_Pin);
printf("IR: %d\r\n", ir);
// === DETEKSI KENDARAAN KELUAR ===
if (ir && !kendaraan_keluar) {
HAL_Delay(50);
ir = !HAL_GPIO_ReadPin(SLAVE_IR_SENSOR_GPIO_Port,
SLAVE_IR_SENSOR_Pin);
if (ir) {
Servo_Buka();
// 1. buka palang
kendaraan_keluar = 1;
// 2. set flag
HAL_UART_Transmit(&huart1, (uint8_t*)"K", 1, 100); //
3. kirim ke master
HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin,
GPIO_PIN_SET);
printf(">> KELUAR! Kuota +1 dikirim ke master\r\n");
}
}
// === KENDARAAN SUDAH LEWAT ===
if (!ir && kendaraan_keluar) {
HAL_Delay(50);
ir = !HAL_GPIO_ReadPin(SLAVE_IR_SENSOR_GPIO_Port,
SLAVE_IR_SENSOR_Pin);
if (!ir) {
Servo_Tutup();
kendaraan_keluar = 0;
HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin,
GPIO_PIN_RESET);
printf(">> Palang ditutup, siap kendaraan
berikutnya\r\n");
}
}
HAL_Delay(100);
}
/* USER CODE END 3 */
}
/* USER CODE BEGIN 4 */
void Servo_Buka(void) {
htim2.Instance->CCR1 = 2000;
HAL_Delay(600);
}
void Servo_Tutup(void) {
htim2.Instance->CCR1 = 1000;
HAL_Delay(600);
}
// Terima info dari master via USART2
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1)
{
if (uart_rx_buffer[0] == 'M')
{
printf(">> INFO: KENDARAAN MASUK (MASTER)\r\n");
}
Tidak ada komentar:
Posting Komentar