.. note::

    ¡Hola! Bienvenido a la comunidad de entusiastas de SunFounder Raspberry Pi, Arduino y ESP32 en Facebook. Sumérgete en el mundo de Raspberry Pi, Arduino y ESP32 con otros entusiastas.

    **¿Por qué unirse?**

    - **Soporte experto**: Resuelve problemas postventa y desafíos técnicos con la ayuda de nuestra comunidad y equipo.
    - **Aprender y compartir**: Intercambia consejos y tutoriales para mejorar tus habilidades.
    - **Avances exclusivos**: Accede anticipadamente a nuevos anuncios de productos y adelantos exclusivos.
    - **Descuentos especiales**: Disfruta de descuentos exclusivos en nuestros productos más recientes.
    - **Promociones y sorteos festivos**: Participa en sorteos y promociones navideñas.

    👉 ¿Listo para explorar y crear con nosotros? Haz clic en [|link_sf_facebook|] y únete hoy mismo.

.. _4.1.10_py:

4.1.10 Ventilador Inteligente
==================================

Introducción
---------------

En este proyecto, utilizaremos motores, botones y termistores para crear un ventilador inteligente manual y automático, cuya velocidad del viento es ajustable.

Componentes Necesarios
-------------------------

En este proyecto, necesitamos los siguientes componentes.

.. image:: ../img/list_Smart_Fan.png
    :align: center

Es muy conveniente comprar un kit completo, aquí está el enlace:

.. list-table::
    :widths: 20 20 20
    :header-rows: 1

    *   - Nombre
        - ELEMENTOS EN ESTE KIT
        - ENLACE
    *   - Kit Raphael
        - 337
        - |link_Raphael_kit|

También puedes comprarlos por separado en los enlaces a continuación.

.. list-table::
    :widths: 30 20
    :header-rows: 1

    *   - INTRODUCCIÓN DEL COMPONENTE
        - ENLACE DE COMPRA

    *   - :ref:`cpn_gpio_extension_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|

Diagrama Esquemático
------------------------

============== =============== ======== ===
Nombre T-Board cableado físico 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

Procedimientos Experimentales
-------------------------------

**Paso 1:** Construye el circuito.

.. image:: ../img/image245.png

.. note::
    El módulo de energía puede aplicar una batería de 9V con el broche de batería 
    de 9V incluido en el kit. Inserta el capuchón del módulo de energía en las tiras 
    de bus de 5V de la placa de pruebas.

.. image:: ../img/image118.jpeg
   :align: center

**Paso 2**: Accede a la carpeta del código.

.. raw:: html

   <run></run>

.. code-block:: 

    cd ~/raphael-kit/python

**Paso 3**: Ejecuta.

.. raw:: html

   <run></run>

.. code-block:: 

    sudo python3 4.1.10_SmartFan.py

Cuando el código se ejecute, inicia el ventilador presionando el botón. 
Cada vez que presiones, se ajusta una velocidad hacia arriba o hacia abajo. 
Hay **5** tipos de velocidades: **0~4**. Cuando se ajusta a la 4\ :sup:`a` velocidad 
y presionas el botón, el ventilador deja de funcionar con una velocidad de viento **0**.

Una vez que la temperatura sube o baja más de 2℃, la velocidad aumenta o disminuye 
automáticamente un grado.

Código
--------

.. note::
    Puedes **Modificar/Restablecer/Copiar/Ejecutar/Detener** el código a continuación. Pero antes de eso, necesitas ir a la ruta del código fuente como ``raphael-kit/python``. Después de modificar el código, puedes ejecutarlo directamente para ver el efecto.

.. raw:: html

    <run></run>

.. code-block:: python

    import RPi.GPIO as GPIO
    import time
    import ADC0834
    import math

    # Set up pins
    MotorPin1   = 5
    MotorPin2   = 6
    MotorEnable = 13
    BtnPin  = 22


    def setup():
        global p_M1,p_M2
        ADC0834.setup()
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(MotorPin1, GPIO.OUT)
        GPIO.setup(MotorPin2, GPIO.OUT)
        p_M1=GPIO.PWM(MotorPin1,2000)
        p_M2=GPIO.PWM(MotorPin2,2000)
        p_M1.start(0)
        p_M2.start(0)
        GPIO.setup(MotorEnable, GPIO.OUT, initial=GPIO.LOW)
        GPIO.setup(BtnPin, GPIO.IN)

    def temperature():
        analogVal = ADC0834.getResult()
        Vr = 5 * float(analogVal) / 255
        Rt = 10000 * Vr / (5 - Vr)
        temp = 1/(((math.log(Rt / 10000)) / 3950) + (1 / (273.15+25)))
        Cel = temp - 273.15
        Fah = Cel * 1.8 + 32
        return Cel

    def motor(level):
        if level == 0:
            GPIO.output(MotorEnable, GPIO.LOW)
            return 0
        if level>=4:
            level = 4
        GPIO.output(MotorEnable, GPIO.HIGH)
        p_M1.ChangeDutyCycle(level*25)
        return level

    def main():
        lastState=0
        level=0
        markTemp = temperature()
        while True:
            currentState =GPIO.input(BtnPin)
            currentTemp=temperature()
            if currentState == 1 and lastState == 0:
                level=(level+1)%5
                markTemp = currentTemp
                time.sleep(0.5)
            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)
            

    def destroy():
        GPIO.output(MotorEnable, GPIO.LOW)
        p_M1.stop()
        p_M2.stop()
        GPIO.cleanup()    

    if __name__ == '__main__':
        setup()
        try:
            main()
        except KeyboardInterrupt:
            destroy()


Explicación del Código
----------------------------
.. code-block:: python

    def temperature():
        analogVal = ADC0834.getResult()
        Vr = 5 * float(analogVal) / 255
        Rt = 10000 * Vr / (5 - Vr)
        temp = 1/(((math.log(Rt / 10000)) / 3950) + (1 / (273.15+25)))
        Cel = temp - 273.15
        Fah = Cel * 1.8 + 32
        return Cel

``temperture()`` funciona convirtiendo los valores del termistor leídos por **ADC0834** en valores de temperatura. Consulta :ref:`2.2.2_py` para más detalles.

.. code-block:: python

    def motor(level):
        if level == 0:
            GPIO.output(MotorEnable, GPIO.LOW)
            return 0
        if level>=4:
            level = 4
        GPIO.output(MotorEnable, GPIO.HIGH)
        p_M1.ChangeDutyCycle(level*25)
        return level

Esta función controla la velocidad de rotación del motor. El rango del **Nivel**: **0-4**
 (el nivel **0** detiene el motor en funcionamiento). Un ajuste de nivel representa un cambio 
 del **25%** en la velocidad del viento.

.. code-block:: python

    def main():
        lastState=0
        level=0
        markTemp = temperature()
        while True:
            currentState =GPIO.input(BtnPin)
            currentTemp=temperature()
            if currentState == 1 and lastState == 0:
                level=(level+1)%5
                markTemp = currentTemp
                time.sleep(0.5)
            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)

La función **main()** contiene todo el proceso del programa como se muestra:

1) Lee constantemente el estado del botón y la temperatura actual.

2) Cada vez que se presiona, el nivel **+1** y al mismo tiempo se actualiza la temperatura. El **Nivel** varía de **1 a 4**.

3) A medida que el ventilador funciona (el nivel no es **0**), la temperatura está bajo detección. Un cambio de **+2℃** causa el aumento y disminución del nivel.

4) El motor cambia la velocidad de rotación con el **Nivel**.

Imagen del Fenómeno
------------------------

.. image:: ../img/image246.png
   :align: center