LAPORAN AKHIR MODUL 3 PERCOBAAN 2
LAPORAN AKHIR MODUL 3 PERCOBAAN 2
1. Prosedur (kembali)
2. Hardware (kembali)
• STM NUCLEO G474RE (x2)
|
Microcontroller |
STM32G474RE (ARM Cortex-M4F) |
|
Operating Voltage |
3.3 V |
|
Input Voltage (recommended) |
5 V via USB (ST-LINK) atau 7–12 V via VIN |
|
Input Voltage (limit) |
4.5 – 15 V (VIN board Nucleo) |
|
Digital I/O Pins |
±51 GPIO pins (tergantung konfigurasi fungsi) |
|
PWM Digital I/O Pins |
Hingga 24 channel PWM (advanced, general-purpose, dan high-resolution timers) |
|
Analog Input Pins |
Hingga 24 channel ADC (12-bit / 16-bit dengan oversampling) |
|
DC Current per I/O Pin |
Maks. 20 mA per pin (disarankan ≤ 8 mA) |
|
DC Current for 3.3V Pin |
Hingga ±500 mA (tergantung regulator & sumber daya) |
|
Flash Memory |
512 KB internal Flash |
|
SRAM |
128 KB SRAM (termasuk CCM RAM) |
|
Clock Speed |
Hingga 170 MHz |
• OLED
• Push button
Push button merupakan saklar sederhana yang digunakan
sebagai perangkat input digital. Tombol ini digunakan untuk memberikan perintah
tertentu pada sistem, seperti menjalankan aksi lompat pada game atau memberikan
trigger pada sistem komunikasi.
• LED
LED (Light Emitting Diode) digunakan sebagai indikator visual output sistem. LED akan menyala atau mati sesuai data yang diterima mikrokontroler sehingga dapat digunakan untuk mengetahui kondisi komunikasi atau status sistem secara langsung.
• Jumper
Kabel jumper
digunakan untuk menghubungkan antar komponen pada breadboard maupun antara
sensor dengan mikrokontroler. Kabel ini menjadi media penghantar sinyal dan
daya pada rangkaian praktikum.
• Breadboard
Breadboard digunakan sebagai media perakitan rangkaian elektronik tanpa proses solder. Komponen dapat dipasang dan dilepas dengan mudah sehingga memudahkan proses praktikum dan pengujian rangkaian.
• Buzzer
Buzzer 5V adalah komponen elektronik yang mengubah sinyal listrik menjadi suara (bunyi), dirancang khusus untuk bekerja optimal pada tegangan 5 volt. Ada dua jenis utama: *buzzer pasif* yang membutuhkan sinyal frekuensi dari mikrokontroler (seperti Arduino) untuk menghasilkan nada bervariasi, dan *buzzer aktif* yang sudah memiliki osilator internal sehingga cukup diberi tegangan 5V langsung untuk berbunyi dengan frekuensi tetap. Cara kerjanya sederhana: saat pin positif dihubungkan ke 5V dan negatif ke GND, komponen di dalamnya bergetar menghasilkan gelombang suara. Dalam proyek elektronika, buzzer 5V sering digunakan sebagai indikator peringatan, alarm, atau notifikasi sederhana (misalnya bunyi "beep" saat tombol ditekan atau sensor mendeteksi sesuatu).
3. Rangkaian Simulasi dan Prinsip Kerja (kembali)
Pada percobaan ini, dua board STM NUCLEO G474RE dihubungkan menggunakan komunikasi I2C sebagai master dan slave untuk menjalankan permainan Geometry Jump. Board master membaca input dari tombol menggunakan pin GPIO input untuk mengontrol gerakan karakter pada permainan. Ketika tombol ditekan, data dikirim melalui pin SDA sebagai jalur data dan pin SCL sebagai jalur clock menuju board slave. Board slave menerima data tersebut kemudian menampilkan gerakan karakter, obstacle, dan skor pada OLED SSD1306 secara real-time. Pin VCC digunakan untuk memberikan suplai tegangan pada rangkaian dan OLED, sedangkan pin GND berfungsi sebagai ground atau referensi tegangan bersama agar komunikasi antar perangkat dapat berjalan dengan stabil.
4. Flowchart dan Listing Program (kembali)
#include "ssd1306.h"
#include <stdio.h>
/* ================= SPI ================= */
SPI_HandleTypeDef hspi1;
/* ================= OLED I2C ================= */
I2C_HandleTypeDef hi2c1;
/* ================= COMMAND ================= */
#define CMD_GAME_RUN 0x01
#define CMD_GAME_OVER 0x02
#define CMD_JUMP_SOUND 0x03
#define CMD_HIT_SOUND 0x04
/* ================= CS PIN ================= */
#define CS_PORT GPIOA
#define CS_PIN GPIO_PIN_4
/* ================= GAME ================= */
int dinoY, velocityY, cactusX;
uint32_t score, highScore;
uint8_t isJumping, gameOver;
#define GRAVITY 2
#define FRAME_DELAY 30
#define GROUND_Y 48
Main.h
char buf[20];
/* ================= SEND SPI ================= */
void Send_To_Slave(uint8_t cmd)
{
HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_RESET);
HAL_SPI_Transmit(&hspi1, &cmd, 1, 100);
HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_SET);
HAL_Delay(1); // penting untuk sync slave
}
/* ================= MAIN ================= */
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_SPI1_Init();
MX_I2C1_Init();
ssd1306_Init();
HAL_GPIO_WritePin(GPIOA, CS_PIN, GPIO_PIN_SET);
ResetGame()
{
if (!gameOver)
{
UpdateGame();
DrawGame();
Send_To_Slave(CMD_GAME_RUN);
}
else
{
DrawGameOver();
if (score > highScore)
highScore = score;
Send_To_Slave(CMD_GAME_OVER);
if (HAL_GPIO_ReadPin(JUMP_BTN_GPIO_Port, JUMP_BTN_Pin) ==
GPIO_PIN_RESET)
{
ResetGame();
HAL_Delay(300);
}
}
HAL_Delay(FRAME_DELAY);
}
}
/* ================= GAME LOGIC ================= */
{
if (HAL_GPIO_ReadPin(JUMP_BTN_GPIO_Port, JUMP_BTN_Pin) ==
GPIO_PIN_RESET && !isJumping)
{
velocityY = -12;
isJumping = 1;
Send_To_Slave(CMD_JUMP_SOUND);
}
dinoY += velocityY;
velocityY += GRAVITY;
if (dinoY >= GROUND_Y)
{
dinoY = GROUND_Y;
velocityY = 0;
isJumping = 0;
}
cactusX -= (6 + score / 15);
if (cactusX < -10)
{
cactusX = 128;
score++;
}
if (cactusX < 25 && cactusX > 5 && (dinoY + DINO_HEIGHT) > 48)
{
Send_To_Slave(CMD_HIT_SOUND);
}
}
/* ================= DRAW ================= */
void DrawGame(void)
{
ssd1306_Fill(Black);
ssd1306_DrawRectangle(10, dinoY, 20, dinoY + DINO_HEIGHT,
White);
ssd1306_FillRectangle(cactusX, 48, cactusX + 8, 60, White);
ssd1306_Line(0, 61, 127, 61, White);
sprintf(buf, "Sc:%lu", score);
ssd1306_SetCursor(0, 0);
ssd1306_WriteString(buf, Font_7x10, White);
sprintf(buf, "Hsc:%lu", highScore);
ssd1306_SetCursor(80, 0);
ssd1306_WriteString(buf, Font_7x10, White);
ssd1306_UpdateScreen();
}
void DrawGameOver(void)
{
ssd1306_Fill(Black);
ssd1306_WriteString("GAME OVER", Font_7x10, White);
sprintf(buf, "HighScore:%lu", highScore);
ssd1306_SetCursor(25, 35);
ssd1306_WriteString(buf, Font_7x10, White);
ssd1306_UpdateScreen();
}
/* ================= RESET ================= */
void ResetGame(void)
{
dinoY = GROUND_Y;
velocityY = 0;
cactusX = 128;
score = 0;
isJumping = 0;
gameOver = 0;
}
/* ================= SPI INIT ================= */
void MX_SPI1_Init(void)
{
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
HAL_SPI_Init(&hspi1);
}
/* ================= GPIO ================= */
void MX_GPIO_Init(void)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* CS */
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* BUTTON */
GPIO_InitStruct.Pin = JUMP_BTN_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(JUMP_BTN_GPIO_Port, &GPIO_InitStruct)
#define __MAIN_H
extern "C" {
#endif
#include "stm32g4xx_hal.h"
#include "ssd1306.h"
#include "ssd1306_fonts.h"
#include <stdio.h>
/* Definisi Pin Hardware */
#define JUMP_BTN_Pin GPIO_PIN_0
#define JUMP_BTN_GPIO_Port GPIOA
/* Konstanta Permainan */
#define GROUND_Y 44
#define DINO_WIDTH 15
#define DINO_HEIGHT 15
/* Prototipe Fungsi */
void SystemClock_Config(void);
void MX_GPIO_Init(void);
void MX_I2C1_Init(void);
void Error_Handler(void);
#ifdef __cplusplus
}
#endif
#endif /* __MAIN_H */
/* ================= SPI ================= */
SPI_HandleTypeDef hspi1;
/* ================= COMMAND ================= */
#define CMD_GAME_RUN 0x01
#define CMD_GAME_OVER 0x02
#define CMD_JUMP_SOUND 0x03
#define CMD_HIT_SOUND 0x04
/* ================= PROTOTYPE ================= */
void SystemClock_Config(void);
void MX_GPIO_Init(void);
void MX_SPI1_Init(void);
void Send(uint8_t data);
/* ================= MAIN ================= */
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_SPI1_Init();
while (1)
{
Send(CMD_GAME_RUN);
HAL_Delay(500);
Send(CMD_JUMP_SOUND);
HAL_Delay(500);
Send(CMD_GAME_OVER);
}
}
/* ================= SEND SPI ================= */
void Send(uint8_t data)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // CS LOW
HAL_SPI_Transmit(&hspi1, &data, 1, 100);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); // CS HIGH
}
/* ================= SPI INIT ================= */
void MX_SPI1_Init(void)
{
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
HAL_SPI_Init(&hspi1);
}
/* GPIO CS */
void MX_GPIO_Init(void)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW
5. Video Demo (kembali)
6. Kondisi (kembali)
Pada percobaan 2, digunakan dua board STM NUCLEO G474RE yang terhubung menggunakan komunikasi I2C sebagai master dan slave. Board master membaca input tombol untuk mengontrol permainan Geometry Jump, sedangkan board slave menerima data dan menampilkan tampilan game pada OLED SSD1306. Saat tombol ditekan, karakter pada game akan melompat untuk menghindari obstacle. Data permainan dikirim secara real-time melalui jalur SDA dan SCL sehingga tampilan pada OLED dapat berubah sesuai input yang diberikan pengguna.7. Video Simulasi (kembali)
8. Download File (kembali)

Komentar
Posting Komentar