1. Prosedur[Kembali]
Hardware :
3. Rangkaian Simulasi[Kembali]
Prinsip kerjanya ialah:
Sensor Soil Moisture bekerja dengan mendeteksi tingkat resistansi pada tanah. Saat tanah dalam kondisi basah, resistansinya turun, menyebabkan tegangan output sensor meningkat dalam mode analog. Tegangan ini kemudian dikirim ke pin analog STM32, misalnya PA0, untuk dibaca sebagai nilai ADC.
Nilai ADC yang diterima kemudian diproses oleh mikrokontroler dan dibandingkan dengan nilai ambang tertentu (threshold). Contohnya:
-
Jika nilai ADC melebihi threshold, maka tanah dianggap basah.
-
Jika nilai ADC berada di bawah threshold, maka tanah dinilai kering.
Ketika tanah terdeteksi basah, STM32 akan mengeluarkan sinyal logika LOW ke pin warna biru pada LED RGB, sehingga LED menyala biru. Sebaliknya, jika tanah tidak basah, maka LED bisa dibiarkan mati atau dikonfigurasi menyala warna lain, misalnya merah untuk menandakan tanah kering
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 LED\_RED\_PIN GPIO\_PIN\_12
\#define LED\_GREEN\_PIN GPIO\_PIN\_13
\#define LED\_BLUE\_PIN GPIO\_PIN\_14
\#define LED\_PORT GPIOB
// Mode Stepper
const uint16\_t STEP\_SEQ\_CW\[4] = {GPIO\_PIN\_8, GPIO\_PIN\_9, GPIO\_PIN\_11, GPIO\_PIN\_10}; // Clockwise (sesuaikan dengan wiring)
const uint16\_t STEP\_SEQ\_CCW\[4] = {GPIO\_PIN\_10, GPIO\_PIN\_11, GPIO\_PIN\_9, GPIO\_PIN\_8}; // Counter-Clockwise (sesuaikan dengan wiring)
ADC\_HandleTypeDef hadc1;
uint8\_t current\_mode = 0; // 0=Idle, 1=CCW
uint16\_t moisture\_threshold = 2000; // Sesuaikan nilai threshold ini
void SystemClock\_Config(void);
void MX\_GPIO\_Init(void);
void MX\_ADC1\_Init(void);
void RunStepper(const uint16\_t \*sequence, uint8\_t speed);
void Error\_Handler(void);
int main(void) {
HAL\_Init();
SystemClock\_Config();
MX\_GPIO\_Init();
MX\_ADC1\_Init();
```
while (1) {
// Baca sensor kelembapan tanah
HAL_ADC_Start(&hadc1);
if (HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK) {
uint16_t adc_val = HAL_ADC_GetValue(&hadc1);
// Tentukan mode berdasarkan kelembapan
if (adc_val > moisture_threshold) { // Tanah kering (nilai ADC tinggi)
current_mode = 0; // Idle
HAL_GPIO_WritePin(LED_PORT, LED_RED_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(LED_PORT, LED_GREEN_PIN | LED_BLUE_PIN, GPIO_PIN_RESET);
} else { // Tanah basah (nilai ADC rendah)
current_mode = 1; // CCW
HAL_GPIO_WritePin(LED_PORT, LED_GREEN_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(LED_PORT, LED_RED_PIN | LED_BLUE_PIN, GPIO_PIN_RESET);
}
}
// Eksekusi mode
switch (current_mode) {
case 1: // CCW saat tanah basah
RunStepper(STEP_SEQ_CCW, 10);
break;
default: // Idle saat tanah kering
HAL_Delay(100); // Beri sedikit jeda saat tidak bergerak
break;
}
}
```
}
void RunStepper(const uint16\_t \*sequence, uint8\_t speed) {
static uint8\_t step = 0;
HAL\_GPIO\_WritePin(STEPPER\_PORT, IN1\_PIN | IN2\_PIN | IN3\_PIN | IN4\_PIN, GPIO\_PIN\_RESET); // Reset semua pin
HAL\_GPIO\_WritePin(STEPPER\_PORT, sequence\[step], GPIO\_PIN\_SET);
step = (step + 1) % 4;
HAL\_Delay(speed);
}
void SystemClock\_Config(void) {
RCC\_OscInitTypeDef RCC\_OscInitStruct = {0};
RCC\_ClkInitTypeDef RCC\_ClkInitStruct = {0};
RCC\_PeriphCLKInitTypeDef PeriphClkInit = {0};
```
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
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_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
Error_Handler();
}
```
}
/\*\*
* @brief ADC1 Initialization Function
* @param None
* @retval None
\*/
void MX\_ADC1\_Init(void) {
ADC\_ChannelConfTypeDef sConfig = {0};
/\*\* Common config
\*/
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();
}
/\*\* Configure Regular Channel
\*/
sConfig.Channel = ADC\_CHANNEL\_1; // Gunakan PA1 (ADC\_IN1) untuk sensor
sConfig.Rank = ADC\_REGULAR\_RANK\_1;
sConfig.SamplingTime = ADC\_SAMPLETIME\_1CYCLE\_5;
if (HAL\_ADC\_ConfigChannel(\&hadc1, \&sConfig) != HAL\_OK) {
Error\_Handler();
}
}
/\*\*
* @brief GPIO Initialization Function
* @param None
* @retval None
\*/
void MX\_GPIO\_Init(void) {
GPIO\_InitTypeDef GPIO\_InitStruct = {0};
/\* 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, GPIO\_PIN\_10 | GPIO\_PIN\_11 | GPIO\_PIN\_12 | GPIO\_PIN\_13 | GPIO\_PIN\_14 | GPIO\_PIN\_8 | GPIO\_PIN\_9, GPIO\_PIN\_RESET);
/\*Configure GPIO pins : PB10 PB11 PB12 PB13
PB14 PB8 PB9 \*/
GPIO\_InitStruct.Pin = GPIO\_PIN\_10 | GPIO\_PIN\_11 | GPIO\_PIN\_12 | GPIO\_PIN\_13 | GPIO\_PIN\_14 | GPIO\_PIN\_8 | GPIO\_PIN\_9;
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);
/\*Configure GPIO pin : PA1 \*/
GPIO\_InitStruct.Pin = GPIO\_PIN\_1;
GPIO\_InitStruct.Mode = GPIO\_MODE\_ANALOG;
HAL\_GPIO\_Init(GPIOA, \&GPIO\_InitStruct);
}
void Error\_Handler(void) {
/\* User can add his own implementation to report the HAL error return state \*/
\_\_disable\_irq();
while (1) {
}
}
\#ifdef USE\_FULL\_ASSERT
void assert\_failed(uint8\_t *file, uint32\_t line) {
/* 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) */
}
\#endif /* USE\_FULL\_ASSERT \*/
5. Kondisi[Kembali]
6. Video Simulasi[Kembali]
Tidak ada komentar:
Posting Komentar