.. note:: Hello, welcome to the SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts Community on Facebook! Dive deeper into Raspberry Pi, Arduino, and ESP32 with fellow enthusiasts. **Why Join?** - **Expert Support**: Solve post-sale issues and technical challenges with help from our community and team. - **Learn & Share**: Exchange tips and tutorials to enhance your skills. - **Exclusive Previews**: Get early access to new product announcements and sneak peeks. - **Special Discounts**: Enjoy exclusive discounts on our newest products. - **Festive Promotions and Giveaways**: Take part in giveaways and holiday promotions. 👉 Ready to explore and create with us? Click [|link_sf_facebook|] and join today! .. _3.1.4_c: 3.1.4 Smart Fan ====================== .. note:: .. image:: ../img/mcp3008_and_adc0834.jpg :width: 25% :align: left Depending on your kit version, please identify whether you have **ADC0834** or **MCP3008** and proceed with the matching section. Introduction ----------------- In this project, we will use motors, buttons and thermistors to make a manual + automatic smart fan whose wind speed is adjustable. Required Components ------------------------------ In this project, we need the following components. .. image:: ../img/list_Smart_Fan.png :align: center It's definitely convenient to buy a whole kit, here's the link: .. list-table:: :widths: 20 20 20 :header-rows: 1 * - Name - ITEMS IN THIS KIT - LINK * - Raphael Kit - 337 - |link_Raphael_kit| You can also buy them separately from the links below. .. list-table:: :widths: 30 20 :header-rows: 1 * - COMPONENT INTRODUCTION - PURCHASE LINK * - :ref:`cpn_gpio_board` - |link_gpio_board_buy| * - :ref:`cpn_breadboard` - |link_breadboard_buy| * - :ref:`cpn_wires` - |link_wires_buy| * - :ref:`cpn_resistor` - |link_resistor_buy| * - :ref:`cpn_power_module` - \- * - :ref:`cpn_thermistor` - |link_thermistor_buy| * - :ref:`cpn_l293d` - \- * - :ref:`cpn_adc0834` - \- * - :ref:`cpn_button` - |link_button_buy| * - :ref:`cpn_motor` - |link_motor_buy| Schematic Diagram ------------------------ ============ ======== ======== === T-Board Name physical wiringPi BCM GPIO17 Pin 11 0 17 GPIO18 Pin 12 1 18 GPIO27 Pin 13 2 27 GPIO22 Pin 15 3 22 GPIO5 Pin 29 21 5 GPIO6 Pin 31 22 6 GPIO13 Pin 33 23 13 ============ ======== ======== === .. image:: ../img/Schematic_three_one4.png :align: center Experimental Procedures ----------------------------- **Step 1:** Build the circuit. .. image:: ../img/image245.png :align: center .. note:: The power module can apply a 9V battery with the 9V Battery Buckle in the kit. Insert the jumper cap of the power module into the 5V bus strips of the breadboard. .. image:: ../img/image118.jpeg :align: center **Step 2**: Get into the folder of the code. .. raw:: html .. code-block:: cd ~/raphael-kit/c/3.1.4/ **Step 3**: Compile. .. raw:: html .. code-block:: gcc 3.1.4_SmartFan.c -lwiringPi -lm **Step 4**: Run the executable file above. .. raw:: html .. code-block:: sudo ./a.out As the code runs, start the fan by pressing the button. Every time you press, 1 speed grade is adjusted up or down. There are **5** kinds of speed grades: **0~4**. When set to the 4\ :sup:`th` speed grade and you press the button, the fan stops working with a **0** wind speed. Once the temperature goes up or down for more than 2℃, the speed automatically gets 1-grade faster or slower. .. note:: If it does not work after running, or there is an error prompt: \"wiringPi.h: No such file or directory\", please refer to :ref:`install_wiringpi`. Code -------- .. code-block:: c #include #include #include #include typedef unsigned char uchar; typedef unsigned int uint; #define ADC_CS 0 #define ADC_CLK 1 #define ADC_DIO 2 #define MotorPin1 21 #define MotorPin2 22 #define MotorEnable 23 #define BtnPin 3 uchar get_ADC_Result(uint channel) { uchar i; uchar dat1=0, dat2=0; int sel = channel > 1 & 1; int odd = channel & 1; digitalWrite(ADC_CLK, 1); delayMicroseconds(2); digitalWrite(ADC_CLK, 0); delayMicroseconds(2); pinMode(ADC_DIO, OUTPUT); digitalWrite(ADC_CS, 0); // Start bit digitalWrite(ADC_CLK,0); digitalWrite(ADC_DIO,1); delayMicroseconds(2); digitalWrite(ADC_CLK,1); delayMicroseconds(2); //Single End mode digitalWrite(ADC_CLK,0); digitalWrite(ADC_DIO,1); delayMicroseconds(2); digitalWrite(ADC_CLK,1); delayMicroseconds(2); // ODD digitalWrite(ADC_CLK,0); digitalWrite(ADC_DIO,odd); delayMicroseconds(2); digitalWrite(ADC_CLK,1); delayMicroseconds(2); //Select digitalWrite(ADC_CLK,0); digitalWrite(ADC_DIO,sel); delayMicroseconds(2); digitalWrite(ADC_CLK,1); digitalWrite(ADC_DIO,1); delayMicroseconds(2); digitalWrite(ADC_CLK,0); digitalWrite(ADC_DIO,1); delayMicroseconds(2); for(i=0;i<8;i++) { digitalWrite(ADC_CLK,1); delayMicroseconds(2); digitalWrite(ADC_CLK,0); delayMicroseconds(2); pinMode(ADC_DIO, INPUT); dat1=dat1<<1 | digitalRead(ADC_DIO); } for(i=0;i<8;i++) { dat2 = dat2 | ((uchar)(digitalRead(ADC_DIO))<=4){ level =4; } digitalWrite(MotorEnable,HIGH); softPwmWrite(MotorPin1, level*25); return level; } void setup(){ if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen printf("setup wiringPi failed !"); return; } softPwmCreate(MotorPin1, 0, 100); softPwmCreate(MotorPin2, 0, 100); pinMode(MotorEnable,OUTPUT); pinMode(BtnPin,INPUT); pinMode(ADC_CS, OUTPUT); pinMode(ADC_CLK, OUTPUT); } int main(void) { setup(); int currentState,lastState=0; int level = 0; int currentTemp,markTemp=0; while(1){ currentState=digitalRead(BtnPin); currentTemp=temperture(); if (currentTemp<=0){continue;} if (currentState==1&&lastState==0){ level=(level+1)%5; markTemp=currentTemp; delay(500); } lastState=currentState; if (level!=0){ if (currentTemp-markTemp<=-2){ level=level-1; markTemp=currentTemp; } if (currentTemp-markTemp>=2){ level=level+1; markTemp=currentTemp; } } level=motor(level); } return 0; } Code Explanation ---------------------- .. code-block:: c int temperture(){     unsigned char analogVal;     double Vr, Rt, temp, cel, Fah;     analogVal = get_ADC_Result(0);     Vr = 5 * (double)(analogVal) / 255;     Rt = 10000 * (double)(Vr) / (5 - (double)(Vr));     temp = 1 / (((log(Rt/10000)) / 3950)+(1 / (273.15 + 25)));     cel = temp - 273.15;     Fah = cel * 1.8 +32;     int t=cel;     return t; } Temperture() works by converting thermistor values read by ADC0834 into temperature values. Refer to :ref:`2.2.2_c` for more details. .. code-block:: c int motor(int level){     if(level==0){         digitalWrite(MotorEnable,LOW);         return 0;     }     if (level>=4){         level =4;     }     digitalWrite(MotorEnable,HIGH);     softPwmWrite(MotorPin1, level*25);     return level;     } This function controls the rotating speed of the motor. The range of the **Level**: **0-4** (level **0** stops the working motor). One level adjustment stands for a **25%** change of the wind speed. .. code-block:: c int main(void) {     setup();     int currentState,lastState=0;     int level = 0;     int currentTemp,markTemp=0;     while(1){         currentState=digitalRead(BtnPin);         currentTemp=temperture();         if (currentTemp<=0){continue;}         if (currentState==1&&lastState==0){             level=(level+1)%5;             markTemp=currentTemp;             delay(500);         }         lastState=currentState;         if (level!=0){             if (currentTemp-markTemp<=-2){                 level=level-1;                 markTemp=currentTemp;             }             if (currentTemp-markTemp>=2){                 level=level+1;                 markTemp=currentTemp;             }         }         level=motor(level);     }     return 0; } The function **main()** contains the whole program process as shown: 1) Constantly read the button state and the current temperature. 2) Every press makes level\ **+1** and at the same time, the temperature is updated. The **Level** ranges **1~4**. 3) As the fan works ( the level is **not 0**), the temperature is under detection. A **2℃\ +** change causes the up and down of the level. 4) The motor changes the rotating speed with the **Level**.