M3 - Laporan Akhir

a. Prosedur

- Siapkan seluruh komponen yang digunakan, yaitu dua board STM32 Blue Pill STM32F103C8T6 sebagai master dan slave, sensor LDR, push button, LED, modul relay, fan DC, breadboard, resistor, kabel jumper, dan modul programmer ST-LINK.
- Hubungkan kedua board STM32 dengan sumber tegangan 3.3V dan GND pada breadboard 
- Hubungkan sensor LDR pada sisi master dengan konfigurasi pembagi tegangan, kemudian sambungkan output sensor ke salah satu pin ADC pada STM32 master.
- Hubungkan push button ke salah satu pin input digital STM32 master 
- Pasang LED pada salah satu pin output STM32 master dengan resistor 220Ω secara seri sebagai indikator kondisi sistem atau indikator proses pengiriman data komunikasi SPI.
- Hubungkan kedua STM32 menggunakan jalur komunikasi SPI, yaitu pin MOSI master ke MOSI slave, pin MISO master ke MISO slave, pin SCK master ke SCK slave, serta pin SS/CS master ke pin SS/CS slave.
- Hubungkan modul relay ke salah satu pin output digital STM32 slave. Modul relay berfungsi sebagai saklar elektronik untuk mengontrol fan DC berdasarkan data yang diterima dari master.
- Hubungkan fan DC ke terminal output relay dan sumber tegangan yang sesuai sehingga fan dapat menyala ketika relay aktif. Fan digunakan sebagai aktuator pendingin pada sistem greenhouse
- Hubungkan board STM32 ke komputer menggunakan ST-LINK, kemudian upload program master dan slave menggunakan software STM32CubeIDE. 
- Setelah program berhasil di-upload, nyalakan sistem dan lakukan pengujian dengan memberikan perubahan cahaya pada sensor LDR. Amati proses pengiriman data dari master ke slave serta respon relay

b. Hardware dan Diagram Blok

A. Hardware
1. STM32F103C8


2. Sensor LDR

3. Breadboard


4. LED

5. Buzzer

6. Jumper

7. Push Button


B. Diagram Blok

c. Rangkaian Simulasi dan Prinsip Kerja



Prinsip Kerja:

Prinsip kerja sistem kontrol greenhouse pada rangkaian tersebut dimulai dari sensor LDR yang berfungsi untuk mendeteksi intensitas cahaya di lingkungan sekitar greenhouse. Sensor LDR terhubung pada mikrokontroler STM32F103C8T6 yang berperan sebagai master. Ketika kondisi lingkungan berubah dari terang menjadi gelap atau sebaliknya, nilai resistansi pada LDR akan berubah. Perubahan resistansi ini menghasilkan perubahan tegangan yang kemudian dibaca oleh pin ADC (Analog to Digital Converter) pada STM32 master. Nilai analog yang diperoleh akan diproses menjadi data digital sehingga mikrokontroler dapat menentukan kondisi lingkungan berdasarkan batas nilai tertentu yang telah diprogram sebelumnya. Selain sensor LDR, terdapat push button yang digunakan sebagai kontrol manual untuk mengaktifkan atau menonaktifkan sistem. LED pada sisi master digunakan sebagai indikator bahwa sistem aktif dan proses pembacaan maupun pengiriman data sedang berlangsung.

Setelah data sensor diproses oleh STM32 master, data tersebut dikirimkan ke STM32 slave menggunakan komunikasi SPI (Serial Peripheral Interface). Pada komunikasi SPI ini terdapat beberapa jalur utama yaitu MOSI (Master Out Slave In), MISO (Master In Slave Out), SCK (Serial Clock), dan SS/CS (Slave Select). Master bertugas menghasilkan sinyal clock pada jalur SCK untuk mengatur sinkronisasi pengiriman data. Data hasil pembacaan sensor dikirim melalui jalur MOSI menuju slave secara serial dan sinkron mengikuti clock yang diberikan master. Dengan metode SPI, proses komunikasi antar mikrokontroler dapat berlangsung lebih cepat dan stabil karena data dikirim secara langsung antar perangkat tanpa membutuhkan banyak delay.

STM32 slave yang menerima data dari master kemudian memproses data tersebut untuk mengendalikan modul relay yang terhubung dengan fan DC. Relay berfungsi sebagai saklar elektronik yang dapat menghubungkan atau memutus arus ke fan. Ketika data yang diterima menunjukkan kondisi tertentu, misalnya intensitas cahaya tinggi atau kondisi greenhouse memerlukan pendinginan dan sirkulasi udara, maka STM32 slave akan memberikan sinyal output untuk mengaktifkan relay. Saat relay aktif, arus listrik mengalir menuju fan sehingga fan menyala dan membantu sirkulasi udara di dalam greenhouse. Sebaliknya, apabila kondisi lingkungan kembali normal atau tidak memerlukan pendinginan, maka relay akan dimatikan sehingga fan berhenti bekerja.

d. Flowchart dan Listing Program

- Flowchart Master
- Flowchart Slave
Listing Program:
- Master

/*=========================================================

MASTER main.c (ANTI ERROR)

STM32F103C8T6 / Bluepill

PB0 = Push Button

PB1 = LDR (ADC)

SPI1 = MASTER

=========================================================*/


#include "main.h"


/* HANDLE */

ADC_HandleTypeDef hadc1;

SPI_HandleTypeDef hspi1;


/* DATA */

uint8_t txData[2];

uint32_t ldrValue;


/* PROTOTYPE */

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_ADC1_Init(void);

static void MX_SPI1_Init(void);


/*=========================================================*/

uint32_t Read_LDR(void)

{

HAL_ADC_Start(&hadc1);

HAL_ADC_PollForConversion(&hadc1,100);

return HAL_ADC_GetValue(&hadc1);

}


/*=========================================================*/

int main(void)

{

HAL_Init();


SystemClock_Config();


MX_GPIO_Init();

MX_ADC1_Init();

MX_SPI1_Init();


while (1)

{

ldrValue = Read_LDR();


/* PUSH BUTTON -> FAN */

if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==GPIO_PIN_RESET)

txData[0] = 1; // tombol ditekan

else

txData[0] = 0;


/* LDR -> LED */

if(ldrValue < 1500)

txData[1] = 1; // gelap

else

txData[1] = 0; // terang


HAL_SPI_Transmit(&hspi1, txData, 2, 100);


HAL_Delay(200);

}

}


/*=========================================================*/

void SystemClock_Config(void)

{

}


/*=========================================================*/

static void MX_GPIO_Init(void)

{

GPIO_InitTypeDef GPIO_InitStruct = {0};


__HAL_RCC_GPIOA_CLK_ENABLE();

__HAL_RCC_GPIOB_CLK_ENABLE();


/* PB0 = Push Button Input Pullup */

GPIO_InitStruct.Pin = GPIO_PIN_0;

GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

GPIO_InitStruct.Pull = GPIO_PULLUP;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}


/*=========================================================*/

static void MX_ADC1_Init(void)

{

ADC_ChannelConfTypeDef sConfig = {0};


hadc1.Instance = ADC1;

hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;

hadc1.Init.ContinuousConvMode = DISABLE;

hadc1.Init.DiscontinuousConvMode = DISABLE;

hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;

hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;

hadc1.Init.NbrOfConversion = 1;

HAL_ADC_Init(&hadc1);


sConfig.Channel = ADC_CHANNEL_9; // PB1

sConfig.Rank = ADC_REGULAR_RANK_1;

sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;


HAL_ADC_ConfigChannel(&hadc1, &sConfig);

}


/*=========================================================*/

static 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_HARD_OUTPUT;

hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;

hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;

hspi1.Init.TIMode = SPI_TIMODE_DISABLE;

hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

hspi1.Init.CRCPolynomial = 7;


HAL_SPI_Init(&hspi1);

}


- Slave

/* USER CODE BEGIN Header */

/**

******************************************************************************

* @file : main.c

* @brief : Main program body

******************************************************************************

* @attention

*

* Copyright (c) 2026 STMicroelectronics.

* All rights reserved.

*

* This software is licensed under terms that can be found in the LICENSE file

* in the root directory of this software component.

* If no LICENSE file comes with this software, it is provided AS-IS.

*

******************************************************************************

*/

/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/

#include "main.h"


/* Private includes ----------------------------------------------------------*/

/* USER CODE BEGIN Includes */


/* 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 ---------------------------------------------------------*/

SPI_HandleTypeDef hspi1;


/* USER CODE BEGIN PV */


/* USER CODE END PV */


/* Private function prototypes -----------------------------------------------*/

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_SPI1_Init(void);

/* USER CODE BEGIN PFP */


/* USER CODE END PFP */


/* Private user code ---------------------------------------------------------*/

/* USER CODE BEGIN 0 */


/* USER CODE END 0 */


/**

* @brief The application entry point.

* @retval int

*/

int main(void)

{


/* USER CODE BEGIN 1 */


/* USER CODE END 1 */


/* MCU Configuration--------------------------------------------------------*/


/* Reset of all peripherals, Initializes the Flash interface and the Systick. */

HAL_Init();


/* USER CODE BEGIN Init */


/* USER CODE END Init */


/* Configure the system clock */

SystemClock_Config();


/* USER CODE BEGIN SysInit */


/* USER CODE END SysInit */


/* Initialize all configured peripherals */

MX_GPIO_Init();

MX_SPI1_Init();

/* USER CODE BEGIN 2 */


/* USER CODE END 2 */


/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

{

/* USER CODE END WHILE */


/* USER CODE BEGIN 3 */

}

/* USER CODE END 3 */

}


/**

* @brief System Clock Configuration

* @retval None

*/

void SystemClock_Config(void)

{

RCC_OscInitTypeDef RCC_OscInitStruct = {0};

RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};


/** Initializes the RCC Oscillators according to the specified parameters

* in the RCC_OscInitTypeDef structure.

*/

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;

RCC_OscInitStruct.HSIState = RCC_HSI_ON;

RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

{

Error_Handler();

}


/** Initializes the CPU, AHB and APB buses clocks

*/

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;

RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;

RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;


if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)

{

Error_Handler();

}

}


/**

* @brief SPI1 Initialization Function

* @param None

* @retval None

*/

static void MX_SPI1_Init(void)

{


/* USER CODE BEGIN SPI1_Init 0 */


/* USER CODE END SPI1_Init 0 */


/* USER CODE BEGIN SPI1_Init 1 */


/* USER CODE END SPI1_Init 1 */

/* SPI1 parameter configuration*/

hspi1.Instance = SPI1;

hspi1.Init.Mode = SPI_MODE_SLAVE;

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_HARD_INPUT;

hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;

hspi1.Init.TIMode = SPI_TIMODE_DISABLE;

hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

hspi1.Init.CRCPolynomial = 10;

if (HAL_SPI_Init(&hspi1) != HAL_OK)

{

Error_Handler();

}

/* USER CODE BEGIN SPI1_Init 2 */


/* USER CODE END SPI1_Init 2 */


}


/**

* @brief GPIO Initialization Function

* @param None

* @retval None

*/

static void MX_GPIO_Init(void)

{

GPIO_InitTypeDef GPIO_InitStruct = {0};

/* USER CODE BEGIN MX_GPIO_Init_1 */


/* USER CODE END MX_GPIO_Init_1 */


/* GPIO Ports Clock Enable */

__HAL_RCC_GPIOD_CLK_ENABLE();

__HAL_RCC_GPIOA_CLK_ENABLE();

__HAL_RCC_GPIOB_CLK_ENABLE();


/*Configure GPIO pin Output Level */

HAL_GPIO_WritePin(GPIOB, Fan_Pin|LED_Pin, GPIO_PIN_SET);


/*Configure GPIO pins : FAN_Pin LED_Pin */

GPIO_InitStruct.Pin = Fan_Pin|LED_Pin;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);


/* USER CODE BEGIN MX_GPIO_Init_2 */


/* USER CODE END MX_GPIO_Init_2 */

}


/* USER CODE BEGIN 4 */


/* USER CODE END 4 */


/**

* @brief This function is executed in case of error occurrence.

* @retval None

*/

void Error_Handler(void)

{

/* USER CODE BEGIN Error_Handler_Debug */

/* User can add his own implementation to report the HAL error return state */

__disable_irq();

while (1)

{

}

/* USER CODE END Error_Handler_Debug */

}

#ifdef USE_FULL_ASSERT

/**

* @brief Reports the name of the source file and the source line number

* where the assert_param error has occurred.

* @param file: pointer to the source file name

* @param line: assert_param error line source number

* @retval None

*/

void assert_failed(uint8_t *file, uint32_t line)

{

/* USER CODE BEGIN 6 */

/* User can add his own implementation to report the file name and line number,

ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

/* USER CODE END 6 */

}

#endif /* USE_FULL_ASSERT */

g. Download File


Comments

Popular posts from this blog