Created
July 6, 2025 14:06
-
-
Save fajarlabs/c785acf3596944f81b157813fefba787 to your computer and use it in GitHub Desktop.
Pembalik plat berbasis servo L298n
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include "driver/gpio.h" | |
#include "driver/ledc.h" | |
#include "freertos/FreeRTOS.h" | |
#include "freertos/task.h" | |
#include "esp_timer.h" | |
// === Pin Mapping === | |
// Tombol | |
#define BUTTON_PIN GPIO_NUM_32 | |
// Motor Depan | |
#define ENA_DEPAN GPIO_NUM_4 | |
#define ENB_DEPAN GPIO_NUM_16 | |
#define IN1_DEPAN GPIO_NUM_17 | |
#define IN2_DEPAN GPIO_NUM_18 | |
#define IN3_DEPAN GPIO_NUM_19 | |
#define IN4_DEPAN GPIO_NUM_21 | |
#define HALL1_DEPAN GPIO_NUM_24 | |
#define HALL2_DEPAN GPIO_NUM_35 | |
// Motor Belakang | |
#define ENA_BELAKANG GPIO_NUM_22 | |
#define ENB_BELAKANG GPIO_NUM_25 | |
#define IN1_BELAKANG GPIO_NUM_26 | |
#define IN2_BELAKANG GPIO_NUM_27 | |
#define IN3_BELAKANG GPIO_NUM_13 | |
#define IN4_BELAKANG GPIO_NUM_23 | |
#define HALL1_BELAKANG GPIO_NUM_39 | |
#define HALL2_BELAKANG GPIO_NUM_36 | |
// PWM Konfigurasi | |
#define LEDC_TIMER LEDC_TIMER_0 | |
#define LEDC_MODE LEDC_HIGH_SPEED_MODE | |
#define LEDC_FREQ_HZ 1000 | |
#define LEDC_DUTY_RES LEDC_TIMER_10_BIT | |
#define DUTY_MAX ((1 << LEDC_DUTY_RES) - 1) | |
void set_motor_pwm(gpio_num_t en_pin, ledc_channel_t channel, uint8_t duty_percent) | |
{ | |
ledc_channel_config_t ledc_channel = { | |
.channel = channel, | |
.duty = (duty_percent * DUTY_MAX) / 100, | |
.gpio_num = en_pin, | |
.speed_mode = LEDC_MODE, | |
.hpoint = 0, | |
.timer_sel = LEDC_TIMER | |
}; | |
ledc_channel_config(&ledc_channel); | |
ledc_set_duty(LEDC_MODE, channel, (duty_percent * DUTY_MAX) / 100); | |
ledc_update_duty(LEDC_MODE, channel); | |
} | |
void motor_forward(gpio_num_t in1, gpio_num_t in2) | |
{ | |
gpio_set_level(in1, 1); | |
gpio_set_level(in2, 0); | |
} | |
void motor_stop(gpio_num_t in1, gpio_num_t in2) | |
{ | |
gpio_set_level(in1, 0); | |
gpio_set_level(in2, 0); | |
} | |
bool hall_triggered(gpio_num_t hall_pin) | |
{ | |
return gpio_get_level(hall_pin) == 1; // aktif HIGH karena pull-down | |
} | |
void wait_for_hall(gpio_num_t hall1, gpio_num_t hall2) | |
{ | |
while (!(hall_triggered(hall1) && hall_triggered(hall2))) { | |
vTaskDelay(pdMS_TO_TICKS(10)); | |
} | |
} | |
void setup_gpio() | |
{ | |
// Output pin | |
gpio_config_t io_out = { | |
.pin_bit_mask = | |
(1ULL << IN1_DEPAN) | (1ULL << IN2_DEPAN) | | |
(1ULL << IN3_DEPAN) | (1ULL << IN4_DEPAN) | | |
(1ULL << IN1_BELAKANG) | (1ULL << IN2_BELAKANG) | | |
(1ULL << IN3_BELAKANG) | (1ULL << IN4_BELAKANG), | |
.mode = GPIO_MODE_OUTPUT, | |
.pull_up_en = 0, | |
.pull_down_en = 0, | |
.intr_type = GPIO_INTR_DISABLE | |
}; | |
gpio_config(&io_out); | |
// Input pin (button dan hall sensor) | |
gpio_config_t io_in = { | |
.pin_bit_mask = | |
(1ULL << BUTTON_PIN) | | |
(1ULL << HALL1_DEPAN) | (1ULL << HALL2_DEPAN) | | |
(1ULL << HALL1_BELAKANG) | (1ULL << HALL2_BELAKANG), | |
.mode = GPIO_MODE_INPUT, | |
.pull_up_en = 0, | |
.pull_down_en = 1, // Semua pull-down | |
.intr_type = GPIO_INTR_DISABLE | |
}; | |
gpio_config(&io_in); | |
// PWM Timer | |
ledc_timer_config_t ledc_timer = { | |
.speed_mode = LEDC_MODE, | |
.timer_num = LEDC_TIMER, | |
.duty_resolution = LEDC_DUTY_RES, | |
.freq_hz = LEDC_FREQ_HZ, | |
.clk_cfg = LEDC_AUTO_CLK | |
}; | |
ledc_timer_config(&ledc_timer); | |
} | |
bool button_held_1s() | |
{ | |
if (gpio_get_level(BUTTON_PIN) == 1) { | |
int64_t start = esp_timer_get_time(); | |
while (gpio_get_level(BUTTON_PIN) == 1) { | |
if ((esp_timer_get_time() - start) >= 1000000) { | |
return true; | |
} | |
vTaskDelay(pdMS_TO_TICKS(10)); | |
} | |
} | |
return false; | |
} | |
void app_main() | |
{ | |
setup_gpio(); | |
while (1) { | |
if (button_held_1s()) { | |
printf("Tombol ditekan >1 detik, mulai menjalankan motor\n"); | |
// ===== MOTOR DEPAN ===== | |
motor_forward(IN1_DEPAN, IN2_DEPAN); | |
motor_forward(IN3_DEPAN, IN4_DEPAN); | |
set_motor_pwm(ENA_DEPAN, LEDC_CHANNEL_0, 80); | |
set_motor_pwm(ENB_DEPAN, LEDC_CHANNEL_1, 80); | |
wait_for_hall(HALL1_DEPAN, HALL2_DEPAN); | |
motor_stop(IN1_DEPAN, IN2_DEPAN); | |
motor_stop(IN3_DEPAN, IN4_DEPAN); | |
set_motor_pwm(ENA_DEPAN, LEDC_CHANNEL_0, 0); | |
set_motor_pwm(ENB_DEPAN, LEDC_CHANNEL_1, 0); | |
printf("Motor depan selesai.\n"); | |
// ===== MOTOR BELAKANG ===== | |
motor_forward(IN1_BELAKANG, IN2_BELAKANG); | |
motor_forward(IN3_BELAKANG, IN4_BELAKANG); | |
set_motor_pwm(ENA_BELAKANG, LEDC_CHANNEL_2, 80); | |
set_motor_pwm(ENB_BELAKANG, LEDC_CHANNEL_3, 80); | |
wait_for_hall(HALL1_BELAKANG, HALL2_BELAKANG); | |
motor_stop(IN1_BELAKANG, IN2_BELAKANG); | |
motor_stop(IN3_BELAKANG, IN4_BELAKANG); | |
set_motor_pwm(ENA_BELAKANG, LEDC_CHANNEL_2, 0); | |
set_motor_pwm(ENB_BELAKANG, LEDC_CHANNEL_3, 0); | |
printf("Motor belakang selesai.\n"); | |
} | |
vTaskDelay(pdMS_TO_TICKS(100)); // polling delay | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment