Selasa, 30 April 2019

Laporan Akhir 2 Modul 2

 




1. Prosedur
[Kembali]

- Rangkaian



- Prosedur

  1. Inisialisasi Komponen
    Raspberry Pi Pico menginisialisasi semua komponen yang terhubung: ADC untuk potensiometer, PWM untuk servo motor dan buzzer, serta komunikasi digital untuk sensor DHT22.

  2. Pembacaan Potensiometer
    Potensiometer menghasilkan sinyal analog yang dibaca oleh ADC pada GPIO 26. Nilai analog ini dikonversi menjadi nilai digital 16-bit.

  3. Kontrol Servo Motor
    Nilai digital dari potensiometer dipetakan (mapping) ke sudut antara 0 hingga 180 derajat, lalu dikonversi lagi ke nilai PWM yang sesuai untuk mengatur posisi servo motor pada GPIO 15.

  4. Pembacaan Sensor Suhu dan Kelembapan
    Sensor DHT22 yang terhubung ke GPIO 16 akan mengukur suhu dan kelembapan. Data ini dibaca secara periodik dan ditampilkan melalui serial monitor.

  5. Pengambilan Keputusan Berdasarkan Data Sensor

    • Jika suhu > 35°C dan kelembapan > 50%, maka buzzer memainkan melodi peringatan kombinasi.

    • Jika hanya suhu > 35°C, maka buzzer memainkan melodi suhu tinggi.

    • Jika hanya kelembapan > 50%, maka buzzer memainkan melodi kelembapan tinggi.

    • Jika kondisi normal, buzzer akan dimatikan.

  6. Loop Berkelanjutan
    Semua proses di atas berjalan terus-menerus dalam loop utama program, sehingga sistem dapat terus memantau dan merespons perubahan suhu, kelembapan, dan input dari potensiometer secara real-time.


2. Hardware dan Diagram Blok [Kembali]

- Raspberry PI Pico sebagai mikrokontroler utama yang mengendalikan semua komponen input dan output



- DHT 22 sebagai sensor untuk mengukur suhu dan kelembapan lingkungan, lalu mengirim datanya ke Pico.




- Potensiometer untuk mengubah nilai resistansi untuk menghasilkan tegangan analog sebagai input ke ADC Pico; digunakan untuk mengatur sudut servo.



Buzzer sebagai output suara yang berbunyi sesuai kondisi suhu dan kelembapan (normal atau tinggi).




- Motor Servo sebagai motor yang dikendalikan sudutnya berdasarkan nilai dari potensiometer.



3. Rangkaian Simulasi dan Prinsip Kerja [Kembali]

- Rangkaian




- Prinsip kerja

Rangkaian ini bekerja dengan menggunakan Raspberry Pi Pico sebagai pusat kendali untuk membaca data dari sensor dan mengontrol aktuator berdasarkan data tersebut. Sensor DHT22 digunakan untuk mengukur suhu dan kelembapan di lingkungan sekitar. Nilai suhu dan kelembapan tersebut kemudian diproses oleh Raspberry Pi Pico. Jika suhu melebihi 35°C atau kelembapan melebihi 50%, maka buzzer akan membunyikan nada tertentu sebagai alarm. Jika keduanya tinggi, buzzer akan membunyikan nada kombinasi sebagai peringatan tambahan.

Sementara itu, potensiometer berfungsi sebagai input analog yang dibaca oleh ADC (Analog to Digital Converter) di Raspberry Pi Pico. Nilai dari potensiometer ini digunakan untuk mengatur sudut servo motor. Nilai ADC dari potensiometer akan dipetakan menjadi rentang sudut antara 0 hingga 180 derajat, kemudian dikonversi ke sinyal PWM yang sesuai untuk mengatur posisi servo.

Dengan kata lain, sistem ini memantau suhu dan kelembapan sekaligus memungkinkan pengguna mengatur posisi servo melalui potensiometer, dan memberikan peringatan suara melalui buzzer jika kondisi lingkungan melebihi ambang batas tertentu. Seluruh proses berjalan secara berulang dalam sebuah loop, memungkinkan pembacaan dan respons sistem secara terus-menerus.


4. Flowchart dan Listing Program [Kembali]

Flowchart :




Listing Program :

from machine import Pin, ADC, PWM

import time

import dht

# Inisialisasi potensiometer pada GPIO 26 (ADC0)

pot = ADC(26)

# Inisialisasi motor servo pada GPIO 15 (PWM)

servo = PWM(Pin(15))

servo.freq(50)  # Frekuensi PWM untuk servo

# Inisialisasi buzzer sebagai PWM pada GPIO 14

buzzer = PWM(Pin(14))

buzzer.duty_u16(0)  # Tidak ada suara saat awal

# Inisialisasi sensor DHT22 pada GPIO 16

dht_sensor = dht.DHT22(Pin(16))

# Fungsi mapping nilai

def map_value(value, in_min, in_max, out_min, out_max):

return int((value - in_min) * (out_max - out_min) / (in_max - in_min) + out_min)

# Fungsi untuk membunyikan buzzer dengan nada tertentu

def play_buzzer_note(frequency, duration_ms):

buzzer.freq(frequency)

buzzer.duty_u16(32768)  # Volume setengah

time.sleep_ms(duration_ms)

buzzer.duty_u16(0)

time.sleep_ms(50)  # Jeda antar nada

# Fungsi melodi untuk suhu tinggi

def play_high_temp_melody():

play_buzzer_note(880, 200)   # A5

play_buzzer_note(988, 200)   # B5

play_buzzer_note(1047, 200)  # C6

# Fungsi melodi untuk kelembapan tinggi

def play_high_humidity_melody():

play_buzzer_note(659, 200)   # E5

play_buzzer_note(698, 200)   # F5

play_buzzer_note(784, 200)   # G5

# Fungsi melodi kombinasi suhu dan kelembapan tinggi

def play_combined_alert_melody():

play_buzzer_note(1047, 200)  # C6

play_buzzer_note(1175, 200)  # D6

play_buzzer_note(1319, 200)  # E6

while True:

# Baca potensiometer

pot_value = pot.read_u16()

servo_angle = map_value(pot_value, 0, 65535, 0, 180)

   servo_duty = map_value(servo_angle, 0, 180, 1638, 8192)

    servo.duty_u16(servo_duty)

 

    # Baca suhu dan kelembapan dari DHT22

    try:

        dht_sensor.measure()

        temperature = dht_sensor.temperature()

        humidity = dht_sensor.humidity()

 

        print(f"Suhu: {temperature}°C | Kelembapan: {humidity:.1f}%")

 

        # Cek kondisi dan mainkan melodi sesuai kondisi

        if temperature > 35 and humidity > 50:

            print("🔥💧 Buzzer ON: Suhu & Kelembapan tinggi!")

            play_combined_alert_melody()

        elif temperature > 35:

            print("🔥 Buzzer ON: Suhu tinggi!")

            play_high_temp_melody()

        elif humidity > 50:

            print("💧 Buzzer ON: Kelembapan tinggi!")

            play_high_humidity_melody()

        else:

            buzzer.duty_u16(0)  # Matikan suara jika normal

 

    except OSError:

        print("⚠️ Gagal membaca sensor DHT22.")

 

    time.sleep(0.5)


5. Video Demo [Kembali]




6. Kondisi [Kembali]




7. Video Simulasi [Kembali]





8. Download File[Kembali]

File HTML [disini]
Listing Program [disini]
Video [disini]
Datasheet Raspberry Pi Pico [disini]

Datasheet DHT22 Sensor [disini]


Laporan Akhir 1 Modul 2

 




1. Prosedur
[Kembali]

- Rangkaian


- Prosedur

  1. Inisialisasi Sistem:

    • STM32F103C8T6 melakukan inisialisasi semua pin GPIO yang terhubung ke stepper motor, motor DC, potensiometer (via ADC), dan touch sensor.

    • Clock sistem dikonfigurasi menggunakan internal oscillator HSI.

  2. Konfigurasi ADC:

    • ADC1 dikonfigurasi untuk membaca nilai analog dari potensiometer.

    • Channel ADC yang digunakan adalah ADC_CHANNEL_0.

  3. Konfigurasi Interrupt:

    • Touch sensor dikonfigurasi pada pin PB0 sebagai input dengan interrupt eksternal (EXTI0) yang aktif pada perubahan naik dan turun (rising & falling).

    • Handler EXTI0_IRQHandler akan memanggil fungsi callback HAL_GPIO_EXTI_Callback() saat interrupt terjadi.

  4. Loop Utama Program:

    • Program utama berjalan dalam loop tak hingga (while(1)).

    • Jika touch sensor tidak aktif (tidak disentuh), sistem akan membaca nilai potensiometer menggunakan ADC.

  5. Pengaturan Arah Motor Stepper:

    • Jika nilai ADC < 2048 → motor stepper berputar searah jarum jam (CW).

    • Jika nilai ADC ≥ 2048 → motor stepper berputar berlawanan arah jarum jam (CCW).

    • Motor stepper dijalankan menggunakan fungsi RunStepper() dengan kecepatan tertentu.

  6. Respon terhadap Sentuhan (Interrupt):

    • Saat touch sensor disentuh:

      • Interrupt aktif dan masuk ke callback HAL_GPIO_EXTI_Callback().

      • Motor DC (pada pin PB7) dinyalakan (GPIO_PIN_SET).

      • Semua output stepper motor dimatikan untuk menghentikan pergerakannya.

    • Saat touch sensor dilepas:

      • Motor DC dimatikan (GPIO_PIN_RESET).

  7. Fungsi RunStepper():

    • Fungsi ini mengatur logika langkah (step) pada stepper motor sesuai urutan CW atau CCW.

    • Mengatur sinyal pada pin PB8–PB11 (IN1–IN4) dan memberikan delay sesuai kecepatan yang ditentukan.

  8. Error Handler:

    • Jika terjadi kesalahan saat inisialisasi periferal (ADC, GPIO, dll.), program masuk ke loop while(1) dalam Error_Handler().

Dengan prosedur ini, sistem mampu bekerja secara otomatis mengendalikan motor stepper berdasarkan nilai potensiometer, dan memprioritaskan kontrol ke motor DC saat sensor disentuh, dengan mekanisme interrupt yang efisien.


2. Hardware dan Diagram Blok [Kembali]

STM32F103C8 sebagai mikrokontroler utama untuk mengontrol input dari sensor dan output ke LED.



- Touch Sensor, Sensor sentuh yang menghasilkan sinyal digital saat disentuh, digunakan untuk mengaktifkan/mematikan motor DC melalui interrupt.



- Potensiometer, komponen variabel yang digunakan sebagai input analog untuk menentukan arah putaran stepper motor melalui ADC.



Resistor, Pull-down resistor pada jalur touch sensor untuk memastikan sinyal stabil saat tidak disentuh.


- ULN2003A (U2), Driver motor stepper yang memperkuat arus dari mikrokontroler agar dapat menggerakkan motor stepper.


- Motor Stepper,  motor yang dikontrol secara bertahap (step-by-step) untuk bergerak CW atau CCW sesuai nilai potensiometer.


- Motor DC, motor searah yang diaktifkan saat touch sensor disentuh sebagai respon interrupt.




3. Rangkaian Simulasi dan Prinsip Kerja [Kembali]

- Rangkaian


- Prinsip kerja

Rangkaian ini bekerja dengan prinsip utama pemilihan dan pengendalian dua jenis motor—motor DC dan motor stepper—berdasarkan masukan dari sensor sentuh dan potensiometer. Saat sistem pertama kali dijalankan, mikrokontroler STM32 akan melakukan inisialisasi terhadap berbagai periferal seperti HAL, clock sistem, GPIO, dan ADC. Setelah inisialisasi selesai, program masuk ke dalam loop utama yang akan terus berjalan selama sistem aktif.

Di dalam loop utama, sistem akan mengecek kondisi dari touch sensor. Jika sensor disentuh, maka terjadi interupsi yang mengaktifkan motor DC dan secara bersamaan mematikan motor stepper untuk mencegah keduanya berjalan secara bersamaan. Hal ini bertujuan agar hanya satu motor yang aktif pada satu waktu berdasarkan input yang diterima.

Namun, jika sensor tidak disentuh, maka sistem akan membaca nilai analog dari potensiometer menggunakan ADC (Analog to Digital Converter). Nilai ini kemudian digunakan untuk menentukan arah putaran motor stepper. Jika nilai ADC kurang dari 2048, maka motor stepper akan berputar searah jarum jam. Sebaliknya, jika nilai ADC lebih besar atau sama dengan 2048, motor stepper akan berputar berlawanan arah jarum jam. Setiap langkah putaran motor diberikan delay selama 1ms untuk mengatur kecepatan rotasi dan menjaga kestabilan.


4. Flowchart dan Listing Program [Kembali]

Flowchart :




Listing Program :

#include "stm32f1xx_hal.h"

// Konfigurasi Hardware

#define STEPPER_PORT GPIOB

#define IN1_PIN GPIO_PIN_8

#define IN2_PIN GPIO_PIN_9

#define IN3_PIN GPIO_PIN_10

#define IN4_PIN GPIO_PIN_11

#define TOUCH_SENSOR_PORT GPIOB

#define TOUCH_SENSOR_PIN GPIO_PIN_0

#define MOTOR_DC_PORT GPIOB

#define MOTOR_DC_PIN GPIO_PIN_7

// Mode Stepper

const uint8_t STEP_SEQ_CW[4] = {

(1<<0),  // IN1

(1<<1),  // IN2

(1<<2),  // IN3

(1<<3)   // IN4

};

const uint8_t STEP_SEQ_CCW[4] = {

(1<<3),  // IN4

(1<<2),  // IN3

(1<<1),  // IN2

(1<<0)   // IN1

};

ADC_HandleTypeDef hadc1;

uint8_t current_mode = 0; // 0=CW, 1=CCW

volatile uint8_t touch_state = 0;

void SystemClock_Config(void);

void MX_GPIO_Init(void);

void MX_ADC1_Init(void);

void RunStepper(const uint8_t *sequence, uint8_t speed);

void Error_Handler(void);

int main(void) {

HAL_Init();

SystemClock_Config();

MX_GPIO_Init();

MX_ADC1_Init();

while (1) {

// Saat tidak disentuh, jalankan stepper seperti biasa

if (HAL_GPIO_ReadPin(TOUCH_SENSOR_PORT, TOUCH_SENSOR_PIN) ==

GPIO_PIN_RESET) {

HAL_ADC_Start(&hadc1);

if (HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK) {

uint16_t adc_val = HAL_ADC_GetValue(&hadc1);

current_mode = (adc_val < 2048) ? 0 : 1; // 0 = CW, 1 = CCW

}

if (current_mode == 0) {

RunStepper(STEP_SEQ_CW, 5);

} else {

RunStepper(STEP_SEQ_CCW, 5);

}

}

HAL_Delay(1);

}

}

void RunStepper(const uint8_t *sequence, uint8_t speed) {

static uint8_t step = 0;

HAL_GPIO_WritePin(STEPPER_PORT, IN1_PIN, (sequence[step] & (1<<0)) ?

GPIO_PIN_SET : GPIO_PIN_RESET);

HAL_GPIO_WritePin(STEPPER_PORT, IN2_PIN, (sequence[step] & (1<<1)) ?

GPIO_PIN_SET : GPIO_PIN_RESET);

HAL_GPIO_WritePin(STEPPER_PORT, IN3_PIN, (sequence[step] & (1<<2)) ?

GPIO_PIN_SET : GPIO_PIN_RESET);

HAL_GPIO_WritePin(STEPPER_PORT, IN4_PIN, (sequence[step] & (1<<3)) ?

GPIO_PIN_SET : GPIO_PIN_RESET);

step = (step + 1) % 4;

HAL_Delay(speed);

}

void MX_GPIO_Init(void) {

GPIO_InitTypeDef GPIO_InitStruct = {0};

__HAL_RCC_GPIOB_CLK_ENABLE();

__HAL_AFIO_REMAP_SWJ_NOJTAG(); // Optional: disable JTAG to free PB3-PB4 if

needed

// Konfigurasi Touch Sensor sebagai input dengan EXTI (interrupt)

GPIO_InitStruct.Pin = TOUCH_SENSOR_PIN;

GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;

GPIO_InitStruct.Pull = GPIO_NOPULL;

HAL_GPIO_Init(TOUCH_SENSOR_PORT, &GPIO_InitStruct);

// Aktifkan NVIC untuk EXTI0

HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);

HAL_NVIC_EnableIRQ(EXTI0_IRQn);

// Konfigurasi Motor DC (PB7)

GPIO_InitStruct.Pin = MOTOR_DC_PIN;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(MOTOR_DC_PORT, &GPIO_InitStruct);

// Konfigurasi Stepper Motor (PB8-PB11)

GPIO_InitStruct.Pin = IN1_PIN | IN2_PIN | IN3_PIN | IN4_PIN;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(STEPPER_PORT, &GPIO_InitStruct);

}

void MX_ADC1_Init(void) {

ADC_ChannelConfTypeDef sConfig = {0};

hadc1.Instance = ADC1;

hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;

hadc1.Init.ContinuousConvMode = DISABLE;

hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;

hadc1.Init.NbrOfConversion = 1;

if (HAL_ADC_Init(&hadc1) != HAL_OK) {

Error_Handler();

}

sConfig.Channel = ADC_CHANNEL_0;

sConfig.Rank = ADC_REGULAR_RANK_1;

sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;

if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {

Error_Handler();

}

}

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;

RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {

Error_Handler();

}

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

}

}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {

if (GPIO_Pin == TOUCH_SENSOR_PIN) {

GPIO_PinState pinState = HAL_GPIO_ReadPin(TOUCH_SENSOR_PORT,

TOUCH_SENSOR_PIN);

if (pinState == GPIO_PIN_SET) {

// Touch sensor ditekan - nyalakan motor DC, matikan stepper

HAL_GPIO_WritePin(MOTOR_DC_PORT, MOTOR_DC_PIN, GPIO_PIN_SET);

HAL_GPIO_WritePin(STEPPER_PORT, IN1_PIN|IN2_PIN|IN3_PIN|IN4_PIN,

GPIO_PIN_RESET);

} else {

// Touch sensor dilepas - matikan motor DC

HAL_GPIO_WritePin(MOTOR_DC_PORT, MOTOR_DC_PIN,

GPIO_PIN_RESET);

}

}

}

// IRQ Handler untuk EXTI0

void EXTI0_IRQHandler(void) {

HAL_GPIO_EXTI_IRQHandler(TOUCH_SENSOR_PIN);

}

void Error_Handler(void) {

while(1) {}

}


5. Video Demo [Kembali]




6. Kondisi [Kembali]




7. Video Simulasi [Kembali]





8. Download File[Kembali]

File HTML [disini]
Listing Program [disini]
Video [disini]
Datasheet STM32F103C8 [disini]

Datasheet Touch Sensor [disini]

Datasheet ULN2003A [disini]

TP 2 M2 Praktikum Mikroprosesor Mikrokontroler 2025

 




1. Prosedur
[Kembali]

- Rangkaian


    Rangkaian ini merupakan sistem otomatis berbasis mikrokontroler STM32F103C8T6 yang menggunakan sensor cahaya LDR untuk mengendalikan buzzer dan motor DC. LDR dan resistor 10kΩ membentuk pembagi tegangan yang terhubung ke pin ADC mikrokontroler (PA1) untuk mendeteksi intensitas cahaya di lingkungan. Jika cahaya terdeteksi redup atau gelap, mikrokontroler akan mengaktifkan buzzer melalui pin PA5 dan mengaktifkan motor DC dengan memberi sinyal ke basis transistor BD139 melalui pin PA6. Transistor ini berfungsi sebagai saklar elektronik untuk mengalirkan arus ke motor dari sumber 5V. Sebuah dioda disematkan sejajar dengan motor untuk melindungi rangkaian dari lonjakan tegangan balik yang ditimbulkan oleh induktansi motor saat dimatikan. Rangkaian ini menunjukkan aplikasi kontrol otomatis berbasis cahaya dengan output suara dan gerak mekanik.

    Rangkaian ini juga merupakan penerapan dari  interrupt eksternal agar mikrokontroler  dimana bisa merespons perubahan kondisi cahaya atau masukan tombol secara efisien tanpa harus terus memantau input. Penggunaan EXTI pada pin seperti PA0 (untuk tombol) memungkinkan sistem segera melakukan aksi saat pemicu tertentu terjadi, lalu memproses pembacaan ADC untuk menentukan apakah buzzer dan motor perlu diaktifkan.

2. Hardware dan Diagram Blok [Kembali]

STM32F103C8T6 (U1) sebagai Mikrokontroler utama yang mengontrol seluruh sistem, termasuk pembacaan sensor dan pengaktifan aktuator seperti buzzer dan motor.


- Buzzer berfungsi sebagai output suara. Saat kondisi tertentu terpenuhi (misalnya cahaya terlalu redup atau terlalu terang), buzzer akan aktif dan mengeluarkan bunyi sebagai peringatan atau notifikasi.





 
- LED merah digunakan sebagai indikator visual yang menyala ketika menerima sinyal dari mikrokontroler. 


- Resistor dipasang seri dengan LED untuk membatasi arus dan mencegah kerusakan. Koneksi daya menggunakan pin VCC (3.3V)


Push Button berfungsi sebagai Saklar manual untuk memberikan input digital ke mikrokontroler, biasanya digunakan sebagai pemicu melalui interrupt eksternal.


 - Motor DC sebagai Aktuator mekanik yang dikendalikan oleh transistor untuk bergerak saat kondisi tertentu terpenuhi.



Q1 (BD139) Transistor NPN yang berfungsi sebagai saklar elektronik untuk mengendalikan arus ke motor.


D1 (Dioda Flyback) Dioda pelindung dari tegangan balik motor DC agar tidak merusak transistor saat motor dimatikan.



3. Rangkaian Simulasi dan Prinsip Kerja [Kembali]

- Rangkaian 



- Prinsip kerja

    Rangkaian ini merupakan sistem kendali berbasis mikrokontroler STM32F103C8T6 yang memanfaatkan sensor LDR untuk mendeteksi intensitas cahaya dan menghasilkan sinyal analog yang dibaca melalui ADC. Nilai tersebut dijadikan acuan dalam bentuk persentase (threshold) untuk mengatur kecepatan motor DC menggunakan PWM serta mengaktifkan buzzer dalam kondisi tertentu. Berdasarkan flowchart, sistem akan mulai dengan inisialisasi semua pin yang terhubung ke LDR, buzzer, tombol, dan motor. Setelah membaca nilai sensor, sistem menentukan zona terang (kurang dari 33%, antara 33–66%, dan lebih dari 66%) dan memberikan respon berupa pengaturan kecepatan motor melalui PWM serta status buzzer. Jika intensitas cahaya tinggi (threshold > 66%), maka kondisi tombol akan diperiksa melalui interrupt eksternal. Bila tombol ditekan, buzzer diaktifkan dan motor tetap berjalan pada kecepatan maksimum, namun jika tidak, hanya motor yang aktif. Sistem terus bekerja dalam loop untuk merespons perubahan cahaya dan input tombol secara dinamis.

4. Flowchart dan Listing Program [Kembali]

Flowchart : 



Listing Program :

#include "main.h"

 

ADC_HandleTypeDef hadc1;

TIM_HandleTypeDef htim1;

TIM_HandleTypeDef htim2;

 

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_ADC1_Init(void);

static void MX_TIM1_Init(void);

static void MX_TIM2_Init(void);

 

int main(void)

{

  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();

  MX_ADC1_Init();

  MX_TIM1_Init();

  MX_TIM2_Init();

 

  HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); // Motor PWM

  HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3); // Buzzer PWM

  HAL_ADC_Start(&hadc1);

 

  uint8_t buzzer_enabled = 1;

  uint32_t last_buzzer_change = 0;

  uint8_t buzzer_freq_index = 0;

 

  const uint32_t buzzer_periods[] = {143999, 71999, 47999}; // Frekuensi berbeda

 

  // Threshold (dari rendah → sedang → tinggi)

  const uint16_t THRESH_LOW = 1500;

  const uint16_t THRESH_MID = 3000;

while (1)

{

HAL_ADC_Start(&hadc1);

HAL_ADC_PollForConversion(&hadc1, 10);

uint32_t adc_val = HAL_ADC_GetValue(&hadc1);

// --- Motor Control ---

if (adc_val < THRESH_LOW)

{

__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 200); // Lambat

}

else if (adc_val < THRESH_MID)

{

__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 600); // Sedang

}

else

{

__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 1000); // Cepat

}

// --- Buzzer Logic ---

if (adc_val < THRESH_LOW && buzzer_enabled)

{

// Ubah frekuensi buzzer setiap 500ms

if (HAL_GetTick() - last_buzzer_change >= 500)

{

last_buzzer_change = HAL_GetTick();

buzzer_freq_index = (buzzer_freq_index + 1) % 3;

uint32_t period = buzzer_periods[buzzer_freq_index];

__HAL_TIM_SET_AUTORELOAD(&htim2, period);

__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, period / 2); // 50% duty

}

}

else

{

}

__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, 0); // Matikan buzzer

// --- Button Logic (PB0 ditekan = nonaktifkan buzzer) ---

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

{

buzzer_enabled = 0;

__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, 0); // Paksa matikan

buzzer

}

HAL_Delay(10);

}

}

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.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

{

Error_Handler();

}

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

}

PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;

PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV2;

if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)

{

Error_Handler();

}

}

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;

if (HAL_ADC_Init(&hadc1) != HAL_OK)

{

Error_Handler();

}

sConfig.Channel = ADC_CHANNEL_0;

sConfig.Rank = ADC_REGULAR_RANK_1;

sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;

if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

{

Error_Handler();

}

}

static void MX_TIM1_Init(void)

{

TIM_MasterConfigTypeDef sMasterConfig = {0};

TIM_OC_InitTypeDef sConfigOC = {0};

TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

htim1.Instance = TIM1;

htim1.Init.Prescaler = 0;

htim1.Init.CounterMode = TIM_COUNTERMODE_UP;

htim1.Init.Period = 65535;

htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

htim1.Init.RepetitionCounter = 0;

htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)

{

Error_Handler();

}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) !=

HAL_OK)

{

Error_Handler();

}

sConfigOC.OCMode = TIM_OCMODE_PWM1;

sConfigOC.Pulse = 0;

sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;

sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;

sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;

if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) !=

HAL_OK)

{

Error_Handler();

}

sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;

sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;

sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;

sBreakDeadTimeConfig.DeadTime = 0;

sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;

sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;

sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;

if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) !=

HAL_OK)

{

Error_Handler();

}

HAL_TIM_MspPostInit(&htim1);

}

static void MX_TIM2_Init(void)

{

TIM_MasterConfigTypeDef sMasterConfig = {0};

TIM_OC_InitTypeDef sConfigOC = {0};

htim2.Instance = TIM2;

htim2.Init.Prescaler = 0;

htim2.Init.CounterMode = TIM_COUNTERMODE_UP;

htim2.Init.Period = 65535;

htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)

{

Error_Handler();

}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) !=

HAL_OK)

{

Error_Handler();

}

sConfigOC.OCMode = TIM_OCMODE_PWM1;

sConfigOC.Pulse = 0;

sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) !=

HAL_OK)

{

Error_Handler();

}

HAL_TIM_MspPostInit(&htim2);

}

static void MX_GPIO_Init(void)

{

GPIO_InitTypeDef GPIO_InitStruct = {0};

__HAL_RCC_GPIOD_CLK_ENABLE();

__HAL_RCC_GPIOA_CLK_ENABLE();

__HAL_RCC_GPIOB_CLK_ENABLE();

/*Configure GPIO pin : PB0 */

GPIO_InitStruct.Pin = GPIO_PIN_0;

GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

GPIO_InitStruct.Pull = GPIO_PULLUP;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

void Error_Handler(void)

{

__disable_irq();

while (1)

{

}

}

#ifdef  USE_FULL_ASSERT

void assert_failed(uint8_t *file, uint32_t line)

{

}

#endif /* USE_FULL_ASSERT */


5. Video Demo [Kembali]




6. Kondisi [Kembali]

Kondisi 5
Buatlah rangkaian seperti gambar  pada percobaan 3, jika nilai potensiometer dibawah threshold 1500 maka motor DC berputar dengan duty cycle 20%  dan buzzer berbunyi dengan frekuensi sedang; jika nilai diatas threshold 3000 maka motor DC berputar dengan duty cycle 100% dan buzzer berbunyi dengan frekuensi rendah. 


7. Video Simulasi [Kembali]




8. Download File[Kembali]

File HTML [disini]
Rangkaian [disini]
Listing Program [disini]
Video [disini]
Datasheet STM32F103C8 [disini]

Datasheet  LDR [disini]

Datasheet Transistor BD139 [disini]