π Written at 2025-01-03 09:44:20
- μ μ μ μ΄: μ νκΈ° μ μμ μΌκ±°λ λ μ μμ.
- ν¬ μλ μ‘°μ : μ μ, μ€μ, κ³ μμΌλ‘ ν¬ μλλ₯Ό λ³κ²½ κ°λ₯.
- λͺ¨λ μ ν: μλ λͺ¨λμ μλ λͺ¨λ κ° μ ν κ°λ₯.
- νμ΄λ¨Έ μ€μ : 3, 5, 7λΆ νμ΄λ¨Έ μ€μ μΌλ‘ μλ μ’ λ£.
- μν νμ: LCD λ° FNDλ‘ νμ¬ λͺ¨λ, μλ, νμ΄λ¨Έ μν νμ.
-
C μΈμ΄ μ½λ λͺ¨λν λ° κ΅¬μ‘°ν
- λͺ
νν λλ ν°λ¦¬ ꡬ쑰 μ€κ³ (
app
->peripheral
(device) ->driver
) - ꡬ쑰체μ ν¨μ ν¬μΈν°λ₯Ό νμ©νμ¬ κ°μ²΄μ§ν₯μ μ€κ³ ꡬν
- μ½λ μΌκ΄μ±μ μν λͺ λͺ κ·μΉ(Naming Convention) μ€μ
- μ¬μ¬μ©μ±μ κ³ λ €ν Utility λΌμ΄λΈλ¬λ¦¬ μ μ
- λͺ
νν λλ ν°λ¦¬ ꡬ쑰 μ€κ³ (
-
λμμΈ ν¨ν΄ νμ΅ λ° νμ©
- πͺ± Model-View-Presenter (MVP) + Service ν¨ν΄μ μ μ©νμ¬ μμ€ν μ λͺ¨λνμ μ μ§λ³΄μμ±μ κ°ν
- ꡬ쑰μ μ€κ³λ₯Ό ν΅ν΄ μ½λ μ¬μ¬μ©μ± λ° νμ₯μ± μ¦λ
-
μΈλΆ μ₯μΉ μ μ΄ κΈ°μ μλ ¨
- LCD, Buzzer, FND, Motor λ± λ€μν μ₯μΉλ₯Ό μ μ΄νλ©° νλμ¨μ΄μ μννΈμ¨μ΄ ν΅ν© κΈ°μ ν₯μ
- UART ν΅μ νλ‘ν μ½ μ΄ν΄ λ° κ΅¬νμ ν΅ν μ₯μΉ κ° λ°μ΄ν° κ΅ν νμ΅
- FND λμ€νλ μ΄λ₯Ό ν΅ν΄ μΆλ ₯ λ°μ΄ν°λ₯Ό μκ°μ μΌλ‘ νννλ κΈ°μ νμ΅
-
λ°μ΄ν° ꡬ쑰μ μκ³ λ¦¬μ¦ νμ΅
- UART μμ λ°μ΄ν° μ²λ¦¬μμ πͺ± μν ν(Circular Queue)λ₯Ό νμ©νμ¬ λ©λͺ¨λ¦¬ ν¨μ¨μ±, λ°μ΄ν° νλ¦ κ΄λ¦¬ ν₯μ λ° λ°μ΄ν° μμ€ λ°©μ§
-
λ°μ΄ν°μνΈ λΆμ λ₯λ ₯ ν₯μ
- λ°μ΄ν°μνΈλ₯Ό κΈ°λ°μΌλ‘ μ₯μΉ νΉμ±μ νμ νκ³ μ΄λ₯Ό ꡬνμ λ°μνλ κΈ°μ κ°ν
Click on the image above to watch the full demo on YouTube.
π μ°Έκ³ : λͺ μμ μΈ μ νμ΄ μ μλμ§ μλ ν μνλ λ³κ²½λμ§ μμ.
λ²νΌ | κΈ°λ₯ |
---|---|
B1 | μμ€ν μ μ ν κΈ (μΌκΈ°/λκΈ°) |
B2 | ν¬ μλ μ‘°μ (μλ λλ μλ λͺ¨λ) |
B3 | μλ λͺ¨λμ μλ λͺ¨λ κ° ν κΈ (μ§μ μ§μ ) |
B4 | μ’ λ£ νμ΄λ¨Έ μ€μ (μμ, 3λΆ, 5λΆ, 7λΆ) |
stateDiagram-v2
[*] --> Off
state "On" as On {
[*] --> On_Manual
state "Manual" as On_Manual {
state "Speed" as On_Manual_Speed {
direction LR
[*] --> Low
Low: Low
Medium: Medium
High: High
Low --> Medium: B2 | USART
Medium --> High: B2 | USART
High --> Low: B2 | USART
}
}
state "Auto" as On_Auto {
direction LR
[*] --> Type1
Type1: Type1
Type2: Type2
Type1 --> Type2: B2 | USART
Type2 --> Type1: B2 | USART
}
On_Manual --> On_Auto: B3 | UART
On_Auto --> On_Manual: B3 | UART
}
On --> Off: B1 | B4 | USART
Off --> On: B1 | USART
- IDE: Microchip Studio
- Programming Language: C
- Processor: AVR Atmega128/A (RISC) (1 EM)
- LCD Module: TC1602A-01T (1 EM)
- Button (Pull-up Circuit): CL5642AH30 (4 EM)
- FND (Common-Cathode Type): - (1 EM)
- Buzzer: - (1 EM)
- Motor: - (1 EM)
βββ π app
βΒ Β Β Β βββ π fanMachine
βΒ Β Β Β Β Β Β Β βββ fanMachinApp.c
βΒ Β Β Β Β Β Β Β βββ π listener
βΒ Β Β Β Β Β Β Β βΒ Β Β Β βββ fanListener.c
βΒ Β Β Β Β Β Β Β βββ π model
βΒ Β Β Β Β Β Β Β βΒ Β Β Β βββ fanModel.c
βΒ Β Β Β Β Β Β Β βββ π presenter
βΒ Β Β Β Β Β Β Β βΒ Β Β Β βββ fanPresenter.c
βΒ Β Β Β Β Β Β Β βββ π service
βΒ Β Β Β Β Β Β Β Β Β Β Β βββ fanService.c
βββ π driver
βΒ Β Β Β βββ π gpio
βΒ Β Β Β βββ π pwm
βΒ Β Β Β βββ π timer
βΒ Β Β Β βββ π uart
βββ main.c
βββ π peripheral
βΒ Β Β Β βββ π button
βΒ Β Β Β βββ π buzzer
βΒ Β Β Β βββ π fnd
βΒ Β Β Β βββ π lcd
βΒ Β Β Β βββ π motor
βββ π resource
βΒ Β Β Β βββ fan_machine-breadboard_setup.jpg
βββ π utility
Β Β Β Β βββ bitmask.h
Β Β Β Β βββ boolean.h
Β Β Β Β βββ clockTimer.h
Layer | Description | Matching Directory |
---|---|---|
Application Layer | μ¬μ©μ μ΄ν리μΌμ΄μ λ‘μ§. μ₯μΉμ μμ€ν νλ¦ μ μ΄ | app/ |
OS/RTOS | μ΄μ 체μ λλ μ€μκ° OS (Optional). | <None> |
Devices Layer | μΈλΆ μ₯μΉ κ΄λ¦¬ (λͺ¨ν°, λ²μ , λ²νΌ, LCD, FND) | peripheral/ (motor, buzzer, button, lcd, fnd) |
HAL/Drivers | νλμ¨μ΄ μ΄κΈ°ν λ° MCU μ£Όλ³ μ₯μΉ μ μ΄ (GPIO, νμ΄λ¨Έ, UART λ±) | driver/ (gpio, timer, uart, pwm) |
Hardware | 물리μ νλμ¨μ΄ (MCU, μΌμ λ±) | AVR Atmega128/A, TC1602A-01T, etc. |
app/fanMachine
λλ ν°λ¦¬μμ λͺ¨λΈ-λ·°-νλ μ ν°(MVP) + μλΉμ€ ν¨ν΄μ μ¬μ©νμ¬ μ ν리μΌμ΄μ
λ‘μ§μ ꡬ쑰ννκ³ μ‘°μ§ν.
-
λͺ¨λΈ (
model/
):- ν¬μ μνμ λ°μ΄ν°(μ: μλ, μ μ΄ λͺ¨λ, μ’ λ£ νμ΄λ¨Έ)λ₯Ό μΊ‘μν.
- λ΄λΆ μνλ₯Ό κ΄λ¦¬νκΈ° μν getter λ° setter λ©μλλ₯Ό μ 곡.
- μ:
uint8_t getFanSpeedState() { return _fanSpeedState; } void setFanSpeedState(uint8_t fanSpeedState) { _fanSpeedState = fanSpeedState; }
- μ± μ: μ€μ μ§μ€μ μν κ΄λ¦¬.
-
λ·° (
listener/
):- μ¬μ©μ μ
λ ₯(μ: λ²νΌ λλ¦, UART λͺ
λ Ή)μ λͺ¨λν°λ§νκ³
Presenter
μ λ³κ²½ μ¬νμ μλ¦Ό. - μΈλΆ μνΈμμ©μ μν μ΄λ²€νΈ 리μ€λ μν .
- μ:
static void _fanListener_checkButtonEvent() { switch (releasedBtnPinNum) { case BUTTON_FAN_SPEED_PIN_NUM: setFanSpeedStateToNext(); break; case BUTTON_FAN_CONTROL_MODE_PIN_NUM: setFanControlModeStateNext(); break; } }
- μ± μ: μ¬μ©μ μ λ ₯μ κ°μ§νκ³ λͺ¨λΈμ μνκ°μ μ λ°μ΄νΈ.
- μ¬μ©μ μ
λ ₯(μ: λ²νΌ λλ¦, UART λͺ
λ Ή)μ λͺ¨λν°λ§νκ³
-
νλ μ ν° (
presenter/
):λͺ¨λΈ
κ³Όλ·°
κ°μ ν΅μ μ μ‘°μ .- μ¬μ©μ μ
λ ₯ λλ μμ€ν
μ΄λ²€νΈμ λ°λΌ
λͺ¨λΈ
μ μ λ°μ΄νΈνκ³ νμν λ°μ΄ν°λ₯Ό μ€λΉ. - μ:
void fanPresenter_displaytoLcd(uint8_t minute, uint8_t second) { char buff[30]; sprintf(buff, "%02d:%02d", minute, second); lcd.writeLcdStringToXy(&lcd, buff, 1, 2); }
- μ± μ: μλΉμ€λ‘λΆν° λ°μ λ°μ΄ν°λ₯Ό λ·°μ μ λ¬νμ¬ μ¬μ©μμκ² νμ.
-
μλΉμ€ (
service/
):- νμ΄λ¨Έ κ΄λ¦¬, λͺ¨ν° μλ μ μ΄, UART ν΅μ λ±μ μ¬μ¬μ© κ°λ₯ν λ‘μ§μ μΊ‘μν.
- μλ λͺ¨λ μν λ° μ’ λ£ νμ΄λ¨Έ μ²λ¦¬μ κ°μ κ³ κΈ κΈ°λ₯μ μ 곡.
- μ:
void _fanService_updateByCurrentState() { if (fanControlModeState == FAN_CONTROL_MODE_AUTO && fanControlAutoModeTimer.second >= fanControlModeAutoCycleSecond) { uint16_t randomDutyCycle = (rand() % 10 + 1) * 10; motor.setFanSpeed(&motor, randomDutyCycle); } }
- μ± μ: ν΅μ¬ μ¬μ¬μ© λ‘μ§ λ° κ³ κΈ κΈ°λ₯. λͺ¨λΈμ μνκ°μ μ£ΌκΈ°μ μΌλ‘ νμΈνκ³ λ‘μ§μ μ²λ¦¬νμ¬ νλ μ ν°λ‘ μ λ¬
-
κ΄μ¬μ¬μ λΆλ¦¬:
- κ° κ΅¬μ± μμ(λͺ¨λΈ, λ·°, νλ μ ν°, μλΉμ€)λ λͺ νν μ± μμ κ°μ§λ©° 볡μ‘μ±μ μ€μ.
-
λͺ¨λμ±:
- λ 립μ μΈ κ΅¬μ± μμλ μλ‘μ΄ κΈ°λ₯ μΆκ° λλ κ°λ³ κ³μΈ΅ κ΅μ²΄λ₯Ό μ½κ² λ§λ¦.
-
ν μ€νΈ κ°λ₯μ±:
μλΉμ€
κ³μΈ΅μ ν΅μ¬ λ‘μ§κ³Όλͺ¨λΈ
κ³μΈ΅μ μν κ΄λ¦¬λ λ 립μ μΌλ‘ ν μ€νΈ κ°λ₯.
-
μ¬μ¬μ©μ±:
fanService
μ κ°μ μλΉμ€λ μ μ¬ν μ ν리μΌμ΄μ λλ κΈ°κ³μμ μ¬μ¬μ© κ°λ₯.
-
νμ₯μ±:
- μΆκ° ν¬ λͺ¨λ λλ κ³ κΈ νμ΄λ¨Έμ κ°μ μλ‘μ΄ κΈ°λ₯ μΆκ°κ° κ³μΈ΅ν μν€ν μ² λλΆμ κ°λ¨.
-
νλμ¨μ΄ λ¬Έμν
β‘οΈ νλμ¨μ΄ λͺ¨λΈμ λν ν¬κ΄μ μΈ λ¬Έμ μμ±, λ°μ΄ν°μνΈ λ§ν¬ ν¬ν¨, νμ μ κ·Όμ±κ³Ό μ΄ν΄λ₯Ό ν₯μμν€λ μμ .
- νλμ¨μ΄ λͺ¨λΈκ³Ό κ·Έ μ¬μμ΄ μ λ¬Έμνλμ΄ μλμ§ νμΈνλ μμ .
-
λλ ν°λ¦¬ λͺ λͺ κ·μΉ
β‘οΈ ν₯ν νλ‘μ νΈμμ μΌκ΄μ μ΄κ³ νμ€νλ μ©μ΄ μ¬μ©μΌλ‘ λͺ νμ±μ κ°μ νλ μμ .
- μ΄ νλ‘μ νΈμμ "peripheral"μ΄λΌλ λλ ν°λ¦¬ μ΄λ¦μ΄ μ¬μ©λμμΌλ, μλ² λλ μμ€ν μμ μ’ μ’ νλμ¨μ΄ λ μ§μ€ν°λ₯Ό μλ―ΈνκΈ° λλ¬Έμ νΌλμ μ΄λν¨.
- ν₯ν νλ‘μ νΈμμλ β **"device"**μ κ°μ λ νμ€μ μ΄κ³ λ리 μ¬μ©λλ μ©μ΄λ₯Ό μ±νν΄μΌ ν¨.
- μμ (Wiktionary μ°Έμ‘°):
- Device: μ£Όλ³ μ₯μΉ; νλμ¨μ΄ νλͺ©.
- Peripheral Device: μ»΄ν¨ν°μμ μ¬μ©νλ μΈλΆ μ μ μ₯μΉ.
- μμ (Wiktionary μ°Έμ‘°):
-
Cμμμ OOP κ°λ μ μν λͺ λͺ κ·μΉ
β‘οΈ μλ² λλ μμ€ν μμ μ°μ νμ€ λͺ λͺ κ·μΉμ μ‘°μ¬νμ¬ λͺ¨λ² μ¬λ‘λ₯Ό ν보νλ μμ .
- Cμμ OOP μμΉμ λ°λ₯΄λ €λ μλλ νΉν ꡬ쑰체μ μΊ‘μν λΆμ‘±μΌλ‘ μΈν΄ μ΄λ €μμ΄ μμμ.
- π£ λͺ¨λ μ΄λ¦(PascalCase)μ ν¨μ μ΄λ¦(camelCase)μ μ λμ΄λ‘ λΆμ¬ OOP ꡬ쑰λ₯Ό λͺ¨λ°©νλ λͺ λͺ κ·μΉ μ±ν.
- μμ:
static void _Fnd_setFndNum(fnd_t* fnd, uint16_t value) { fnd->value = value; }
-
FSM μ€κ³ κ³Όμ
β‘οΈ κΈ°λ₯μ μ μ§νλ©΄μ FSM μ€κ³λ₯Ό λμ± κ°λ¨νκ² λ§λ€ λμμ νμνλ μμ .
- μ΄κΈ° FSM μ€κ³λ μ§λμΉκ² 볡μ‘νκ³ κ΄λ¦¬νκΈ° μ΄λ €μ μ(μ°Έμ‘°: μ΄μ FSM λ€μ΄μ΄κ·Έλ¨).
- μ€κ³λ₯Ό μ¬νκ°ν ν, λ μ§κ΄μ μ΄κ³ λ¨μν κ΅¬μ‘°κ° κ°λ₯ν¨μ΄ λλ¬λ¨.
- κ΅ν: ꡬν μ μ λ λ§μ μκ°μ λ€μ¬ μ μ€νκ² μ€κ³νλ μμ . κ°μ λκ³ κ°κ²°ν FSMμ π "[FSM (Finite State Machine)]"μμ μ°Έμ‘° κ°λ₯.
-
μΈν°λ½νΈ μ²λ¦¬μ λμ€νλ μ΄ ν¨μ¨ κ°μ
- FND λμ€νλ μ΄ ν¨μ¨μ±κ³Ό κ΄λ ¨νμ¬ μμμ± λ¬Έμ λ° λΆνμν κ³μ°κ³Ό κ°μ μ΄μκ° λ°μν¨.
- π‘ μΈν°λ½νΈ λ΄λΆμμμ κ³μ° μ΅μν λ° λ³΅μ‘ν κ³μ°μ΄ νμν κ²½μ° κ°κ²©μ λλ € λ€λ₯Έ μκ°μ λ―Όκ°ν μμ κ³Όμ κ°μμ λ°©μ§νλ μμ .