Laporan Akhir 1 M2


1. Prosedur [Kembali]

Untuk menjalankan dan memvalidasi simulasi rangkaian pada platform seperti Wokwi, prosedur berikut harus dilakukan secara berurutan:

  1. Persiapan Alat: 

    • Siapkan STM32 Nucleo G474RE
    • LDR sensor
    • Push button
    • Motor servo
    • Breadboard & kabel

  2. Perakitan (Wiring) :

    • LDR → pin ADC (PA1)
    • Push button → PA1/EXTI (sesuai program)
    • Servo → pin PWM (TIM3 CH1)
    • VCC & GND sesuai rangkaian
  3. Konfigurasi STM32CubeIDE :

    • Aktifkan:
      • ADC1 (Channel 1)
      • TIM3 PWM
      • GPIO Interrupt (EXTI)
    • Generate code
  4. Upload Program : Compile dan upload ke board

  5. Pengujian

    • Tutup LDR → servo masuk
    • Sorot cahaya → servo keluar
    • Tekan tombol → mode manual aktif

2. Hardware dan Diagram Blok [Kembali]





A. Hardware

Rangkaian ini terdiri dari beberapa komponen esensial yang saling terintegrasi:
  • Mikrokontroler STM32 Nucleo G474RE: Merupakan unit pemroses utama (otak sistem) yang bertugas mengeksekusi instruksi program, membaca sinyal analog dari sensor LDR melalui ADC, serta mengendalikan output berupa motor servo menggunakan sinyal PWM sesuai algoritma yang telah diprogram.
  • Push Button (Saklar Utama): Komponen input yang digunakan untuk mengaktifkan mode manual. Saat tombol ditekan, sistem akan berpindah dari mode otomatis ke mode manual melalui interrupt, sehingga pengguna dapat mengontrol posisi servo secara langsung.
  • Sensor LDR (Light Dependent Resistor): Komponen sensor cahaya yang berfungsi mendeteksi intensitas cahaya lingkungan. Sensor ini menghasilkan sinyal analog yang nilainya berubah sesuai kondisi pencahayaan (nilai tinggi saat terang dan rendah saat gelap), kemudian dibaca oleh mikrokontroler untuk menentukan kondisi jemuran.
  • Motor Servo: Aktuator mekanik yang berfungsi sebagai penggerak jemuran (membuka dan menutup). Motor ini dikendalikan oleh mikrokontroler menggunakan sinyal PWM, dimana lebar pulsa menentukan posisi sudut servo (misalnya posisi masuk atau keluar).
  • Breadboard: Media perakitan rangkaian sementara tanpa solder yang digunakan untuk menghubungkan seluruh komponen seperti sensor, tombol, dan servo ke mikrokontroler dengan mudah dan fleksibel.
  • Resistor: Komponen pasif yang berfungsi membatasi arus listrik. Dalam rangkaian ini, resistor digunakan untuk melindungi LED dari kerusakan akibat arus berlebih dan menstabilkan sinyal input (konfigurasi pull-down/pull-up).
  • Adaptor / Catu Daya : Berfungsi sebagai sumber tegangan untuk menyuplai energi ke seluruh rangkaian. Tegangan yang digunakan umumnya 3.3V atau 5V sesuai kebutuhan komponen, dengan ground yang terhubung bersama untuk menjaga kestabilan sistem.

B. Diagram Blok (Sistem Loop Tertutup)

Dalam konteks kontrol otomatis, sistem jemuran ini diimplementasikan sebagai siklus pemantauan kontinu (direpresentasikan oleh fungsi while(1)). Kondisi intensitas cahaya lingkungan secara terus-menerus memberikan umpan balik (feedback) kepada sistem untuk menentukan posisi jemuran (buka atau tutup).


  • Input (Referensi/Setpoint):
    Push Button (PA1) bertindak sebagai sinyal kontrol manual (enable manual mode). Saat tombol ditekan, sistem beralih dari mode otomatis ke mode manual, sehingga pengguna dapat langsung menentukan posisi jemuran.
  • Feedback Element (Sensor):
    Sensor LDR (PA1/ADC Channel) secara terus-menerus membaca intensitas cahaya lingkungan dan mengirimkan data analog ke mikrokontroler. Nilai ini merepresentasikan kondisi terang atau gelap.
  • Controller (Mikrokontroler STM32):
    Mikrokontroler STM32 membaca data dari sensor LDR melalui ADC, kemudian membandingkannya dengan nilai ambang (threshold). Berdasarkan hasil perbandingan tersebut, sistem menentukan apakah kondisi lingkungan tergolong terang atau gelap dan mengambil keputusan kontrol.
  • Actuator (Plant):
    Motor servo sebagai aktuator menerima sinyal PWM dari mikrokontroler untuk menggerakkan jemuran. Servo akan bergerak ke posisi tertentu (masuk atau keluar) sesuai dengan hasil keputusan kontrol.
  • Alur Loop Tertutup (Closed Loop System):
    Sistem bekerja dalam loop tertutup, dimana perubahan kondisi lingkungan (perubahan cahaya) akan terus dipantau oleh sensor LDR. Mikrokontroler secara periodik (setiap ±100 ms sesuai HAL_Delay) membaca feedback dan menyesuaikan posisi servo secara real-time. Dengan demikian, sistem mampu merespons perubahan kondisi secara otomatis tanpa intervensi pengguna.


3. Rangkaian Simulasi dan Prinsip Kerja [Kembali]

Prinsip kerja sistem jemuran otomatis ini bekerja dengan memanfaatkan sensor LDR untuk mendeteksi intensitas cahaya lingkungan. LDR memiliki karakteristik resistansi yang berubah sesuai dengan cahaya yang diterima. Pada kondisi terang, resistansi LDR menurun sehingga tegangan output menjadi lebih kecil dan menghasilkan nilai ADC yang rendah. Sebaliknya, pada kondisi gelap, resistansi LDR meningkat sehingga tegangan output menjadi lebih besar dan menghasilkan nilai ADC yang tinggi.

Nilai ADC tersebut dibandingkan dengan nilai ambang (threshold) yang telah ditentukan dalam program. Jika intensitas cahaya rendah (kondisi gelap), sistem menginterpretasikan bahwa jemuran harus ditutup sehingga mikrokontroler mengirimkan sinyal PWM ke motor servo untuk menggerakkan jemuran ke posisi masuk. Sebaliknya, jika intensitas cahaya tinggi (kondisi terang), servo akan digerakkan ke posisi keluar untuk membuka jemuran. Proses ini berlangsung secara terus-menerus dalam loop utama program sehingga sistem dapat merespons perubahan kondisi lingkungan secara real-time.

Selain mode otomatis, sistem juga dilengkapi dengan mode manual yang diaktifkan melalui push button berbasis interrupt. Ketika tombol ditekan, mikrokontroler akan mengubah mode operasi dan langsung mengontrol posisi servo tanpa memperhatikan data dari sensor LDR. Hal ini memungkinkan pengguna untuk mengambil alih kendali sistem kapan pun diperlukan. Dengan kombinasi antara pembacaan sensor, pengolahan data oleh mikrokontroler, serta penggerakan aktuator menggunakan PWM, sistem ini mampu bekerja secara efisien, responsif, dan fleksibel dalam menyesuaikan kondisi jemuran terhadap lingkungan sekitar.




Listing Program :

#include "main.h"

/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
TIM_HandleTypeDef htim3;

/* USER CODE BEGIN PV */
#define LDR_THRESHOLD 2000

uint8_t manual_mode = 0;
uint8_t posisi_servo = 0;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
static void MX_TIM3_Init(void);

/* USER CODE BEGIN 0 */

// ================= SERVO =================
void set_servo(uint8_t state)
{
  if (state == 0)
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 1000);
  else
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 2000);
}

// ================= ADC =================
uint16_t read_LDR(void)
{
  HAL_ADC_Start(&hadc1);
  HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
  return HAL_ADC_GetValue(&hadc1);
}

/* USER CODE END 0 */

int main(void)
{
  HAL_Init();
  SystemClock_Config();

  MX_GPIO_Init();
  MX_ADC1_Init();
  MX_TIM3_Init();

  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);

  while (1)
  {
    /* MODE OTOMATIS */
    if (!manual_mode)
    {
      uint16_t ldr = read_LDR();

      if (ldr < LDR_THRESHOLD)
        posisi_servo = 0; // gelap ? masuk
      else
        posisi_servo = 1; // terang ? keluar

      set_servo(posisi_servo);
    }

    HAL_Delay(100);
  }
}

/* ================= CALLBACK INTERRUPT ================= */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if (GPIO_Pin == GPIO_PIN_1)
  {
    HAL_Delay(50); // debounce

    manual_mode = !manual_mode;
    posisi_servo = !posisi_servo;

    set_servo(posisi_servo);
  }
}

/* ================= CLOCK ================= */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST);

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV4;
  RCC_OscInitStruct.PLL.PLLN = 85;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;

  HAL_RCC_OscConfig(&RCC_OscInitStruct);

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
                              | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4);
}

/* ================= ADC ================= */
static void MX_ADC1_Init(void)
{
  ADC_ChannelConfTypeDef sConfig = {0};

  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.ContinuousConvMode = DISABLE;

  HAL_ADC_Init(&hadc1);

  sConfig.Channel = ADC_CHANNEL_1;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;

  HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}

/* ================= PWM ================= */
static void MX_TIM3_Init(void)
{
  TIM_OC_InitTypeDef sConfigOC = {0};

  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 169;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 19999;

  HAL_TIM_PWM_Init(&htim3);

  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 1500;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

  HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1);

  HAL_TIM_MspPostInit(&htim3);
}

/* ================= GPIO ================= */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  __HAL_RCC_GPIOA_CLK_ENABLE();

  GPIO_InitStruct.Pin = GPIO_PIN_1;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  HAL_NVIC_SetPriority(EXTI1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI1_IRQn);
}

/* ================= ERROR ================= */
void Error_Handler(void)
{
  __disable_irq();
  while (1) {}
}


5. Video Demo [Kembali]



6. Soal Analisa [Kembali]





7. Video Simulasi [Kembali]


8. Download File [Kembali]

Download rangkaian STM32 Nucleo G474RE klik disini

Tidak ada komentar:

Posting Komentar

  BAHAN PRESENTASI UNTUK MATAKULIAH ELEKTRONIKA 2024 Oleh : MUHAMMAD FADLI NIM. 2310952007   Dosen Pengampu : Dr. Darwison, S. T., M. T. NID...