ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ESP-IDF 쿨링팬 FG센서, PWM제어(vscode)
    소프트웨어 2023. 4. 11. 11:35

    #esp32 윈도우 vscode 환경
    #선행(필수) ESP-IDF 윈도우 개발환경 세팅(vscode)
    #선행(필수) ESP-IDF 외부 폴더에서 예제 파일 실행(vscode)

    #선행(필수) ESP-IDF .c .h 참조 cMakeLists (vscode)

    #선행(필수) ESP-IDF components 참조 cMakeLists (vscode)

    #선행(필수) ESP-IDF GPIO 인풋, 아웃풋 (VSCODE)
    #선행(필수) ESP-IDF PULSE COUNTER(vscode) (예정)

    #선행(필수) PWM(vscode) (예정)

    #선행(필수) FreeRTOS - Create Task(vscode) (예정)
    #선행(필수) ESP-IDF I2C OLED(vscode) (예정)

    #선행(필수) ESP-IDF ADC , DAC(vscode) (예정)
    #선행(필수) ESP-IDF USB-C로 전원 인가 (예정)


    1) 최종 결과

     

    2) 결선

    FAN : 24V / GND / FG 23 / PWM 12
    포텐셜미터 : 3.3V / GND / 15
    OLED : 3.3V / GND / SDA 21 / SCL 22

    EasyEDA - 회로

    SCH_FG_PWM_2023-05-06.json
    0.03MB

    EasyEDA - 아트웍

    PCB_PCB_FG_PWM_9_2023-05-06.json
    0.24MB

     

    3) 코드

    components.zip
    0.01MB

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "freertos/FreeRTOS.h"
    #include "freertos/task.h"
    #include "esp_log.h"
    #include "ssd1306.h"
    #include "esp_timer.h"
    #include "driver/gpio.h"
    #include "driver/ledc.h"
    #include "esp_system.h"
    #include "driver/adc.h"
    #include "driver/pcnt.h"
    
    #define tag "SSD1306"
    #define V_REF 1100
    
    const int pwmPin = 12;
    const gpio_num_t fgPin = GPIO_NUM_23;
    const gpio_num_t potPin = GPIO_NUM_15;
    
    #define POT_CHANNEL ADC1_CHANNEL_6
    #define ADC_WIDTH ADC_WIDTH_BIT_12
    #define ADC_ATTEN ADC_ATTEN_DB_11
    
    #define PCNT_UNIT PCNT_UNIT_0
    #define PCNT_CHANNEL PCNT_CHANNEL_0
    #define PCNT_H_LIM_VAL 10000
    #define PCNT_L_LIM_VAL 0
    
    
    volatile int16_t pulseCount = 0;
    uint32_t lastMillis = 0;
    int16_t prevPulseCount = -1;
    
    
    const int frequency = 25000;
    const int resolution = 8;
    const int channel = 0;
    
    long fanRPM = 0;
    long prevRPM = -1;
    
    SSD1306_t dev;
    
    // Forward declaration for the tasks
    void rpmTask(void *pvParameters);
    void mainTask(void *pvParameters);
    
    void init_pulse_counter() {
        pcnt_config_t pcnt_config = {
            .pulse_gpio_num = fgPin,
            .ctrl_gpio_num = PCNT_PIN_NOT_USED,
            .channel = PCNT_CHANNEL_0,
            .unit = PCNT_UNIT,
            .pos_mode = PCNT_COUNT_INC,
            .neg_mode = PCNT_COUNT_DIS,
            .lctrl_mode = PCNT_MODE_KEEP,
            .hctrl_mode = PCNT_MODE_KEEP,
            .counter_h_lim = PCNT_H_LIM_VAL,
            .counter_l_lim = PCNT_L_LIM_VAL,
        };
        pcnt_unit_config(&pcnt_config);
    
        // Set the GPIO filter value for the pulse counter
        pcnt_set_filter_value(PCNT_UNIT, 1000); // Increase filter value
        pcnt_filter_enable(PCNT_UNIT);
        pcnt_counter_pause(PCNT_UNIT);
        pcnt_counter_clear(PCNT_UNIT);
        pcnt_counter_resume(PCNT_UNIT);
    }
    
    void app_main(void)
    {
        gpio_set_direction(pwmPin, GPIO_MODE_OUTPUT);
        gpio_pulldown_dis(fgPin);
        gpio_pullup_en(fgPin);
        gpio_set_direction(fgPin, GPIO_MODE_INPUT);
        gpio_set_direction(potPin, GPIO_MODE_INPUT);
    
        init_pulse_counter();
    
        ledc_timer_config_t ledc_timer = {
            .duty_resolution = LEDC_TIMER_8_BIT,
            .freq_hz = frequency,
            .speed_mode = LEDC_HIGH_SPEED_MODE,
            .timer_num = LEDC_TIMER_0,
            .clk_cfg = LEDC_AUTO_CLK
        };
        ledc_timer_config(&ledc_timer);
    
        ledc_channel_config_t ledc_channel = {
            .channel = LEDC_CHANNEL_0,
            .duty = 0,
            .gpio_num = pwmPin,
            .speed_mode = LEDC_HIGH_SPEED_MODE,
            .hpoint = 0,
            .timer_sel = LEDC_TIMER_0
        };
        ledc_channel_config(&ledc_channel);
    
    
    
        i2c_master_init(&dev, CONFIG_SDA_GPIO, CONFIG_SCL_GPIO, false);
    
        ssd1306_init(&dev, 128, 64);
        ssd1306_clear_screen(&dev, false);
    
        adc1_config_width(ADC_WIDTH);
        adc1_config_channel_atten(POT_CHANNEL, ADC_ATTEN);
    
        // Create the tasks
        xTaskCreatePinnedToCore(&rpmTask, "RPM Task", 4096, NULL, 20, NULL, 1);
        xTaskCreatePinnedToCore(&mainTask, "Main Task", 4096, (void *)&dev, 1, NULL, 0);
    }
    
    void rpmTask(void *pvParameters)
    {
        while (1)
        {
            uint32_t currentMillis = esp_timer_get_time() / 1000; // Convert to milliseconds
            if (currentMillis - lastMillis >= 1000)
            {
                lastMillis = currentMillis;
                pcnt_get_counter_value(PCNT_UNIT, (int16_t *)&pulseCount);
    
                fanRPM = (pulseCount*60)/2;
                pcnt_counter_clear(PCNT_UNIT);
    
                if (fanRPM != prevPulseCount)
                {
                    prevPulseCount = fanRPM;
                }
            }
            vTaskDelay(pdMS_TO_TICKS(10)); // Slight delay to reduce CPU usage
        }
    }
    
    
    void mainTask(void *pvParameters)
    {
        // SSD1306_t *dev = (SSD1306_t *)pvParameters;
        char rpmText[22];
        char dutyRateText[25];
        ssd1306_clear_screen(&dev, false);
        ssd1306_display_text(&dev, 1, "   <FG , PWM>", strlen("   <FG , PWM>"), false);
        while (1)
        {
            int potValue = adc1_get_raw(POT_CHANNEL);
            uint32_t dutyCycle = (potValue * 255) / 4095;
            int dutyRate = (100 * dutyCycle) / 255;
            snprintf(dutyRateText, sizeof(dutyRateText), "Duty Rate: %d%%  ", dutyRate);
            ledc_set_duty(LEDC_HIGH_SPEED_MODE, channel, dutyCycle);
            ledc_update_duty(LEDC_HIGH_SPEED_MODE, channel);
    
            snprintf(rpmText, sizeof(rpmText), "Speed: %ldRPM     ", fanRPM);
            ssd1306_display_text(&dev, 3, rpmText, strlen(rpmText), false);
            ssd1306_display_text(&dev, 5, dutyRateText, strlen(dutyRateText), false);
    		printf("rpmText: %s \n ", rpmText);
            vTaskDelay(pdMS_TO_TICKS(1000)); // Refresh display every 100ms
        }
    }

     

    팬.com
    YeHAUS


    ESP-IDF 윈도우 개발환경 세팅 (VSCODE)
    ESP-IDF 외부 폴더에서 예제 파일 실행 (VSCODE)
    ESP-IDF GPIO 인풋, 아웃풋 (VSCODE)
    ESP-IDF 인터럽트 (VSCODE)

    ESP-IDF 디바운싱 (esp32, vscode)
    ESP-IDF .c .h 참조 cMakeLists (vscode)

    ESP-IDF components 참조 cMakeLists (vscode)
    ESP-IDF LCD 출력(vscode)
    ESP-IDF 메모리 - Flash (vscode)
    ESP-IDF 메모리 - SRAM (vscode)
    ESP-IDF FreeRTOS - buffer (vscode)
    ESP-IDF 쿨링팬 FG센서, PWM제어(vscode)



    <포스트 예정>
    *ESP-IDF 메모리 - ROM

    *ESP32용 핀헤더 PCB 제작(easyEDA)

    *LCD - 메뉴 만들고 버튼으로 메뉴 이동(터미널로 작업)
    *LCD - 2차원 배열로 메뉴 진입, 뒤로가기(터미널로 작업)
    *LCD - 메뉴 만든 것 LCD 출력
    *LCD - 메뉴 UI 제작.  연두색 블럭은 메인 메뉴 회색 블럭은 서브 메뉴
            (1.팬  1-1.ON  1-2.OFF  1-3.BACK   2.LED  2-1.밝기 약  2-2.밝기 중  2-3.밝기 강   2-4.BACK   3.빛 밝기 출력 lux(+PPFD 변환)
    *Easy EDA툴 활용하여 커스텀 ESP32 보드 제작
    *LCD - LCD , 팬 , 펌프 ,  ESP32 연결 가능한 PCB 제작 주문.
    *LCD - 간이 스마트팜 제작
    *ESP32 JTAG 디버그
    *FreeRTOS - Create Task
    *FreeRTOS - QUEUE
    *FreeRTOS - timer
    *FreeRTOS - Semaphore , mutex
    *FreeRTOS - event group , notification

    *ESP-IDF ADC , DAC

    *ESP-IDF PWM
    *ESP-IDF I2C SPI UART
    *ESP-IDF wifi
    *ESP-IDF MQTT
    *ESP-IDF Server (XAMPP 로컬 서버 연결)
    *DIY 컨테이너 / 유리온실 스마트팜 제작

    *ESP-IDF USB-C로 전원 인가 (예정)

    *ESP-IDF CAM

     

     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     

    '소프트웨어' 카테고리의 다른 글

    ESP-IDF RTC DS3231(vscode)  (0) 2023.08.05
    ESP32 PIN-OUT  (0) 2023.04.12
    ESP-IDF FreeRTOS - Buffer (vscode)  (0) 2023.03.30
    ESP-IDF 메모리 - SRAM (vscode)  (0) 2023.03.28
    ESP-IDF 메모리 - Flash (vscode)  (0) 2023.03.25
Designed by PixelSpace