Personal BLOG Adnan Kasogi

SELAMAT DATANG DI BLOG ADNAN KASOGI

ELEKTRO UNAND ANGKATAN 23

2310952044--BLOG KULIAH

This is default featured slide 3 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions.

This is default featured slide 4 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions.

This is default featured slide 5 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions.

Jumat, 08 Mei 2026

Percobaan 1 Kondisi 9

[menuju akhir]


Langkah-langkah percobaan :

  1. Pahami terlebih dahulu kondisi yang akan digunakan
  2. Buka software Proteus 8.17
  3. Persiapkan alat dan bahan
  4. Buat rangkaian sesuai dengan kondisi dan modul
  5. Buka software STM32Cube IDE 
  6. Setelah membuka software, pilih perangkat STM32F103C8T6 
  7. Sesuaikan konfigurasi pin sesuai dengan rangkaian proteus 
  8. Buat kode program untuk mengoperasikan rangkaian tersebut sesuai dengan kondisi 
  9. Konfigurasi kan program dengan software Proteus
  10. Jalankan simulasi rangkaian.  
  11. Proses selesai

2. Hardware dan Diagram Blok [Kembali]
a. Hardware
1. STM32F103C8
TM32F103C8 adalah mikrokontroler berbasis ARM Cortex-M3 yang  dikembangkan oleh STMicroelectronics. Mikrokontroler ini sering digunakan dalam pengembangan sistem tertanam karena kinerjanya yang baik, konsumsi daya yang rendah, dan kompatibilitas dengan berbagai protokol komunikasi. Pada praktikum ini, kita menggunakan STM32F103C8 yang dapat diprogram menggunakan berbagai  metode, termasuk komunikasi serial (USART), SWD (Serial Wire Debug), atau JTAG untuk berhubungan dengan komputer maupun perangkat lain.

2. HeartBeat Sensor


HeartBeat sensor atau sensor detak jantung merupakan perangkat input analog yang berfungsi untuk mendeteksi denyut nadi manusia dengan prinsip fotopletismografi (PPG). Sensor ini biasanya bekerja menggunakan infra merah dan fototransistor untuk mengukur perubahan volume darah di dalam pembuluh darah kecil di ujung jari atau telinga. Sinyal yang dihasilkan bersifat analog, sehingga memerlukan fitur ADC (Analog to Digital Converter) pada mikrokontroler agar data detak jantung dapat diproses dan dikonversi menjadi nilai Beats Per Minute (BPM).

3. Push Button


Push button adalah komponen sakelar sederhana yang berfungsi untuk menghubungkan atau memutuskan aliran arus listrik dalam suatu rangkaian dengan cara menekan tombolnya. Pada penggunaan mikrokontroler, komponen ini berperan sebagai perangkat input digital yang bekerja berdasarkan prinsip logika high atau low, di mana status penekanannya dapat dibaca oleh pin GPIO atau digunakan untuk memicu mekanisme interrupt eksternal. Agar pembacaan sinyal tetap stabil dan terhindar dari kondisi floating, push button biasanya dikonfigurasi menggunakan resistor pull-up atau pull-down yang memastikan level tegangan input tetap berada pada kondisi logika yang jelas saat tombol tidak sedang ditekan.


4. LED

LED adalah dioda semikonduktor yang dapat memancarkan cahaya ketika dialiri arus listrik. LED digunakan dalam berbagai aplikasi seperti indikator elektronik, pencahayaan, dan display. LED hanya bekerja pada arah bias maju dan memiliki berbagai warna yang ditentukan oleh material semikonduktornya.

5. Buzzer
Buzzer adalah suatu komponen elektronika yang berfungsi untuk mengubah energi listrik menjadi energi suara (bunyi) melalui mekanisme getaran. Komponen ini termasuk dalam kategori output device karena digunakan untuk memberikan respon berupa suara terhadap suatu kondisi atau perintah dalam rangkaian elektronik.

6. Resistor 

Resistor adalah komponen elektronik pasif yang berfungsi untuk membatasi arus listrik dalam suatu rangkaian. Resistor bekerja berdasarkan hukum Ohm, yang menyatakan bahwa tegangan (V) = arus (I) × resistansi (R). Resistor memiliki satuan Ohm (Ω) dan digunakan dalam berbagai aplikasi seperti pembagian tegangan, kontrol arus, dan proteksi rangkaian elektronik.

b. Diagram Blok




3. Rangkaian Simulasi dan Prinsip Kerja [Kembali]




Prinsip Kerja :

Rangkaian ini bekerja dengan menggunakan mikrokontroler STM32F103C8 sebagai unit pemrosesan utama yang mengolah input dari Sensor Heartbeat untuk mengendalikan output berupa LED dan buzzer. Sensor Heartbeat mendeteksi data detak jantung dalam satuan BPM (Beat Per Minute). Ketika hasil pembacaan menunjukkan nilai BPM kurang dari 60, mikrokontroler akan memberikan logika low pada LED sehingga LED tetap mati. Pada saat yang sama, mikrokontroler akan mengaktifkan buzzer dengan pola bunyi yang mengikuti irama detak jantung yang terdeteksi oleh sensor.

1. Tahap Pembacaan (Input)

Sistem menggunakan Sensor Heartbeat sebagai sumber input utama.

  • Sensor Heartbeat
    Sensor ini mendeteksi perubahan volume darah pada pembuluh kapiler menggunakan cahaya inframerah. Data hasil pembacaan dikirim ke mikrokontroler STM32 dalam bentuk sinyal analog atau pulsa digital yang merepresentasikan jumlah detak jantung per menit (BPM). Selain membaca nilai BPM, sensor juga menghasilkan pola denyut yang dapat digunakan untuk mengatur ritme bunyi buzzer.

2. Tahap Pemrosesan (Logic)

Mikrokontroler STM32F103C8 bertindak sebagai pusat pengendali sistem. Program pada mikrokontroler akan terus memantau nilai BPM yang diterima dari sensor heartbeat.

  • Logika Kondisional
    Program mengevaluasi hasil pembacaan sensor. Jika nilai BPM kurang dari 60, maka:

    • Pin output LED diberikan logika low sehingga LED tetap mati.

    • Mikrokontroler mengaktifkan buzzer dengan pola bunyi yang mengikuti interval detak jantung yang terbaca dari sensor.

Sebaliknya, apabila nilai BPM berada di atas atau sama dengan 60, buzzer tidak aktif dan sistem berada pada kondisi normal.

3. Tahap Eksekusi (Output)

  • LED & Resistor
    LED digunakan sebagai indikator visual. Karena pada kondisi BPM < 60 pin output berada pada logika low, arus tidak mengalir ke LED sehingga LED tetap mati. Resistor pada rangkaian berfungsi membatasi arus agar LED tidak mengalami kerusakan.

  • Buzzer
    Buzzer mengubah energi listrik menjadi suara. Mikrokontroler mengatur pola aktif-mati buzzer berdasarkan interval detak jantung yang terdeteksi, sehingga bunyi buzzer menyerupai ritme denyut jantung pengguna.

4. Flowchart dan Listing Program [Kembali]
a. Flowchart


b. Listing Program [Kembali]


/* USER CODE BEGIN Header */

/**

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

* @file : main.c

* @brief : Main program body

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

*/

/* USER CODE END Header */


#include "main.h"


/* Private variables ---------------------------------------------------------*/

ADC_HandleTypeDef hadc1;


/* USER CODE BEGIN PV */

uint32_t adcValue = 0;

uint32_t filteredValue = 0;


uint8_t beatDetected = 0;

uint32_t BPM = 0;


uint32_t lastBeatTime = 0;

uint32_t interval = 0;


uint8_t buzzerOff = 0;


#define FILTER_SIZE 10

uint16_t buffer[FILTER_SIZE] = {0};

uint8_t indexBuf = 0;

uint32_t buzzerTime = 0;

/* USER CODE END PV */


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

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_ADC1_Init(void);


/* USER CODE BEGIN 0 */


/* ================= FILTER ================= */

uint16_t moving_average(uint16_t val)

{

buffer[indexBuf++] = val;

if(indexBuf >= FILTER_SIZE) indexBuf = 0;


uint32_t sum = 0;

for(int i=0;i<FILTER_SIZE;i++) sum += buffer[i];


return sum / FILTER_SIZE;

}


/* ================= LED RGB ================= */

void LED_RGB(uint8_t r, uint8_t g, uint8_t b)

{

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, r ? GPIO_PIN_SET : GPIO_PIN_RESET);

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, g ? GPIO_PIN_SET : GPIO_PIN_RESET);

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, b ? GPIO_PIN_SET : GPIO_PIN_RESET);

}


void LED_Hijau() { LED_RGB(0,1,0); }

void LED_Kuning() { LED_RGB(1,0,0); }

void LED_Merah() { LED_RGB(0,0,1); }

void LED_Mati() { LED_RGB(0,0,0); }


/* ================= BUZZER ================= */

void Buzzer_On() { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_SET); }

void Buzzer_Off() { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_RESET); }


/* USER CODE END 0 */


int main(void)

{

HAL_Init();

SystemClock_Config();

MX_GPIO_Init();

MX_ADC1_Init();


/* USER CODE BEGIN 2 */

uint32_t baseline = 0;

/* USER CODE END 2 */


while (1)

{

/* USER CODE BEGIN 3 */


/* ==== BACA ADC ==== */

HAL_ADC_Start(&hadc1);

HAL_ADC_PollForConversion(&hadc1, 10);

adcValue = HAL_ADC_GetValue(&hadc1);


/* ==== FILTER ==== */

filteredValue = moving_average(adcValue);


/* ==== BASELINE ==== */

baseline = (baseline * 9 + filteredValue) / 10;

uint32_t threshold = baseline + 50;


/* ==== DETEKSI DETAK ==== */

if(filteredValue > threshold && beatDetected == 0)

{

beatDetected = 1;


uint32_t now = HAL_GetTick();


if(lastBeatTime != 0)

{

interval = now - lastBeatTime;

if(interval > 0)

BPM = 60000 / interval;

}

if(BPM > 0 && BPM < 60)

{

Buzzer_On();

buzzerTime = now;

}

lastBeatTime = now;

}


if(BPM > 0 && BPM < 60)

{

if(HAL_GetTick() - buzzerTime > 80)

{

Buzzer_Off();

}

}


if(filteredValue < threshold)

{

beatDetected = 0;

}


/* ==== TIMEOUT ==== */

if(HAL_GetTick() - lastBeatTime > 2000)

{

BPM = 0;

}


/* ==== OUTPUT ==== */

if(BPM > 60)

{

LED_RGB(1,1,1);

if(!buzzerOff)

Buzzer_On();

else

Buzzer_Off();

}

else

{

LED_Mati();

}


HAL_Delay(5);


/* USER CODE END 3 */

}

}


/* ================= CLOCK ================= */

void SystemClock_Config(void)

{

RCC_OscInitTypeDef RCC_OscInitStruct = {0};

RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};


RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;

RCC_OscInitStruct.HSIState = RCC_HSI_ON;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;

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

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_0);


PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;

PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV2;

HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);

}


/* ================= ADC ================= */

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.ExternalTrigConv = ADC_SOFTWARE_START;

hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;

hadc1.Init.NbrOfConversion = 1;

HAL_ADC_Init(&hadc1);


sConfig.Channel = ADC_CHANNEL_0;

sConfig.Rank = ADC_REGULAR_RANK_1;

sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5; // IMPORTANT

HAL_ADC_ConfigChannel(&hadc1, &sConfig);

}


/* ================= GPIO ================= */

static void MX_GPIO_Init(void)

{

GPIO_InitTypeDef GPIO_InitStruct = {0};


__HAL_RCC_GPIOA_CLK_ENABLE();

__HAL_RCC_GPIOB_CLK_ENABLE();


HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_10|GPIO_PIN_11, GPIO_PIN_RESET);


/* BUTTON */

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


/* LED RGB + BUZZER */

GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_10|GPIO_PIN_11;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}


/* ================= INTERRUPT ================= */

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

{

if(GPIO_Pin == GPIO_PIN_1)

{

buzzerOff = !buzzerOff;

}

}


/* ================= ERROR ================= */

void Error_Handler(void)

{

__disable_irq();

while (1) {}

}


5. Video Demo [Kembali]


6. Kondisi [Kembali]

Buatlah rangkaian seperti pada gambar percobaan 1 dengan kondisi Sensor Heartbeat membaca BPM < 60 LED mati dan buzzer ber bunyi dengan pola yang sama dengan detak jantung.

7. Video Simulasi [Kembali]




8. Download File [Kembali]


percobaan 2 kondisi 9

[menuju akhir]


Langkah-langkah percobaan :

  • Buka web WOKWI.COM dan cari STM 32 NUCLEO C031C6
  • Rangkai komponen sesuai dengan gambar rangkaian di modul
  • Klik pada Library Manager untuk membuat file baru yang bernama main.h dan main.c
  • Masukan program yang telah di buat sesuai kondisi pada kedua file tersebut
  • Simulasikan

2. Hardware dan Diagram Blok [Kembali]
a. Hardware
1. STM32 NUCLEO-G474RE

STM32 NUCLEO-G474RE adalah papan pengembangan (development board) berbasis mikrokontroler STM32 yang dirancang oleh STMicroelectronics untuk memudahkan proses pembelajaran, prototyping, dan pengembangan sistem embedded.

Secara spesifik, board ini menggunakan mikrokontroler STM32G474RE, yang termasuk dalam keluarga STM32 seri G4. Mikrokontroler ini berbasis inti ARM Cortex-M4 dengan kemampuan pemrosesan yang cukup tinggi serta dilengkapi dengan fitur DSP (Digital Signal Processing) dan FPU (Floating Point Unit), sehingga sangat cocok untuk aplikasi yang membutuhkan perhitungan matematis cepat seperti kontrol motor, sistem tenaga, dan pengolahan sinyal.


2. 
LDR Sensor

 

LDR atau Light Dependent Resistor adalah jenis resistor yang nilai hambatannya berubah-ubah sesuai dengan intensitas cahaya yang mengenai permukaannya, di mana prinsip kerjanya didasarkan pada fotokonduktivitas yang menyebabkan resistansi menurun saat terkena cahaya terang dan meningkat saat kondisi gelap. Dalam implementasinya pada mikrokontroler, LDR biasanya disusun menggunakan rangkaian pembagi tegangan agar perubahan intensitas cahaya dapat terbaca sebagai sinyal tegangan analog melalui fitur ADC. Sinyal digital hasil konversi tersebut kemudian digunakan oleh sistem untuk mengambil keputusan otomatis, seperti mengatur tingkat kecerahan lampu melalui PWM atau mendeteksi kondisi siang dan malam pada sistem penerangan pintar.

3. Push Button


Push button adalah komponen sakelar sederhana yang berfungsi untuk menghubungkan atau memutuskan aliran arus listrik dalam suatu rangkaian dengan cara menekan tombolnya. Pada penggunaan mikrokontroler, komponen ini berperan sebagai perangkat input digital yang bekerja berdasarkan prinsip logika high atau low, di mana status penekanannya dapat dibaca oleh pin GPIO atau digunakan untuk memicu mekanisme interrupt eksternal. Agar pembacaan sinyal tetap stabil dan terhindar dari kondisi floating, push button biasanya dikonfigurasi menggunakan resistor pull-up atau pull-down yang memastikan level tegangan input tetap berada pada kondisi logika yang jelas saat tombol tidak sedang ditekan.


4. LED

LED adalah dioda semikonduktor yang dapat memancarkan cahaya ketika dialiri arus listrik. LED digunakan dalam berbagai aplikasi seperti indikator elektronik, pencahayaan, dan display. LED hanya bekerja pada arah bias maju dan memiliki berbagai warna yang ditentukan oleh material semikonduktornya.

5. Buzzer
Buzzer adalah suatu komponen elektronika yang berfungsi untuk mengubah energi listrik menjadi energi suara (bunyi) melalui mekanisme getaran. Komponen ini termasuk dalam kategori output device karena digunakan untuk memberikan respon berupa suara terhadap suatu kondisi atau perintah dalam rangkaian elektronik.

6. Resistor 

Resistor adalah komponen elektronik pasif yang berfungsi untuk membatasi arus listrik dalam suatu rangkaian. Resistor bekerja berdasarkan hukum Ohm, yang menyatakan bahwa tegangan (V) = arus (I) × resistansi (R). Resistor memiliki satuan Ohm (Ω) dan digunakan dalam berbagai aplikasi seperti pembagian tegangan, kontrol arus, dan proteksi rangkaian elektronik.

7. Motor Servo


Motor servo adalah perangkat aktuator yang dirancang dengan sistem umpan balik tertutup (closed loop) untuk mengendalikan posisi sudut, kecepatan, dan akselerasi poros secara presisi. Komponen ini bekerja berdasarkan sinyal kontrol PWM (Pulse Width Modulation), di mana lebar pulsa yang diberikan ke pin kontrol akan menentukan posisi derajat putaran porosnya, seperti pulsa 1 ms untuk posisi 0 derajat dan 2 ms untuk 180 derajat. Di dalam motor servo terdapat potensiometer internal yang berfungsi mendeteksi posisi poros saat ini dan mengirimkan informasi tersebut ke rangkaian kontrol untuk memastikan poros berhenti tepat pada sudut yang diinginkan, sehingga sangat ideal digunakan pada sistem robotika, kendali kemudi, maupun penggerak mekanik yang membutuhkan akurasi tinggi.


b. Diagram Blok


3. Rangkaian Simulasi dan Prinsip Kerja [Kembali]


Prinsip Kerja :
Sistem jemuran otomatis ini bekerja dengan memanfaatkan sensor LDR untuk membaca intensitas cahaya lingkungan yang datanya kemudian diproses oleh mikrokontroler STM32 Nucleo-C031C6. Saat cahaya terdeteksi tinggi (kondisi cerah), mikrokontroler akan mengirim sinyal PWM agar servo motor berputar menggerakkan lengan jemuran ke area terbuka di luar atap. Sebaliknya, jika cahaya meredup karena mendung atau malam hari, sistem secara otomatis memerintahkan servo untuk menarik jemuran kembali ke bawah atap guna memberikan perlindungan. Selain itu, terdapat push button yang berfungsi sebagai kendali manual, sehingga pengguna tetap bisa mengatur posisi jemuran secara instan tanpa harus menunggu perubahan sensor cahaya.
4. Flowchart dan Listing Program [Kembali]
a. Flowchart




b. Listing Program [Kembali]

1. main.c

#include "main.h"
// HANDLE
ADC_HandleTypeDef hadc1;
TIM_HandleTypeDef htim3;
uint8_t last_button = 1;
uint8_t manual_mode = 0;
uint8_t posisi_servo = 0;
// ================= CLOCK =================
void SystemClock_Config(void)
{
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    HAL_RCC_OscConfig(&RCC_OscInitStruct);
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);
}
// ================= GPIO =================
void MX_GPIO_Init(void)
{
    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    // LDR PA0
    GPIO_InitStruct.Pin = LDR_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    HAL_GPIO_Init(LDR_PORT, &GPIO_InitStruct);
    // SERVO PA6 = TIM3_CH1
    GPIO_InitStruct.Pin = SERVO_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Alternate = GPIO_AF1_TIM3;
    HAL_GPIO_Init(SERVO_PORT, &GPIO_InitStruct);
}
// ================= ADC =================
void MX_ADC1_Init(void)
{
    __HAL_RCC_ADC_CLK_ENABLE();
    hadc1.Instance = ADC1;
    hadc1.Init.Resolution = ADC_RESOLUTION_12B;
    hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
    hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
    HAL_ADC_Init(&hadc1);
}
// ================= PWM =================
void MX_TIM3_Init(void)
{
    __HAL_RCC_TIM3_CLK_ENABLE();
    htim3.Instance = TIM3;
    // 48MHz / 48 = 1MHz
    // 1 tick = 1us
    htim3.Init.Prescaler = 48 - 1;
    htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim3.Init.Period = 20000 - 1; // 20ms = 50Hz
    htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
    HAL_TIM_PWM_Init(&htim3);
    TIM_OC_InitTypeDef sConfigOC = {0};
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 1500;
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
    // PA6 = TIM3_CH1
    HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1);
}
// ================= SERVO =================
void set_servo(uint8_t state)
{
    if(state == 0)
    {
        // posisi kiri
        __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 1000);
    }
    else
    {
        // posisi kanan
        __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 2000);
    }
}
// ================= ADC READ =================
uint16_t read_LDR(void)
{
    ADC_ChannelConfTypeDef sConfig = {0};
    sConfig.Channel = ADC_CHANNEL_0;
    sConfig.Rank = ADC_REGULAR_RANK_1;
    HAL_ADC_ConfigChannel(&hadc1, &sConfig);
    HAL_ADC_Start(&hadc1);
    HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
    return HAL_ADC_GetValue(&hadc1);
}
// ================= MAIN =================
int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_ADC1_Init();
    MX_TIM3_Init();
    // start PWM PA6 TIM3_CH1
    HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
  while (1)
  {
    // ===== BUTTON TOGGLE =====
    uint8_t button = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1);
 
    if (last_button == 1 && button == 0)
    {
      manual_mode = !manual_mode;
      posisi_servo = !posisi_servo;
      set_servo(posisi_servo);
      HAL_Delay(0);
    }
 
    last_button = button;
 
    // ===== MODE OTOMATIS =====
    if (!manual_mode)
    {
      uint16_t ldr = read_LDR();
      if (ldr < LDR_THRESHOLD)
      {
        posisi_servo = 0;; // mendung → masuk
      }
      else
      {
        posisi_servo = 1; // terang → keluar
      }
      set_servo(posisi_servo);
    }
 
    HAL_Delay(100);
  }
}

2. main.h

#ifndef __MAIN_H
#define __MAIN_H
#include "stm32c0xx_hal.h"
// ================= HANDLE =================
extern ADC_HandleTypeDef hadc1;
extern TIM_HandleTypeDef htim3;
// ================= PIN =================
// LDR PA0
#define LDR_PIN        GPIO_PIN_0
#define LDR_PORT       GPIOA
// SERVO PA6 = TIM3_CH1
#define SERVO_PIN      GPIO_PIN_6
#define SERVO_PORT     GPIOA
// ================= THRESHOLD =================
#define LDR_THRESHOLD  1500
// ================= FUNCTION =================
void SystemClock_Config(void);
void MX_GPIO_Init(void);
void MX_ADC1_Init(void);
void MX_TIM3_Init(void);
uint16_t read_LDR(void);
void set_servo(uint8_t state);
#endif


5. Video Demo [Kembali]


6. Kondisi [Kembali]

Buatlah rangkaian dengan kondisi ketika sensor cahaya (LDR) mendeteksi cahaya di bawah ambang batas tertentu, maka jemuran akan masuk ke dalam atap secara otomatis. Jika berada di atas ambang batas tersebut, jemuran akan keluar ke luar atap tanpa kondisi perantara.

7. Video Simulasi [Kembali]




8. Download File [Kembali]