.. note::

    Hola, ¡bienvenido a la comunidad de entusiastas de SunFounder Raspberry Pi & Arduino & 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.
    - **Aprende y comparte**: Intercambia consejos y tutoriales para mejorar tus habilidades.
    - **Preestrenos exclusivos**: Obtén acceso anticipado a nuevos anuncios de productos y adelantos.
    - **Descuentos especiales**: Disfruta de descuentos exclusivos en nuestros productos más nuevos.
    - **Promociones y sorteos festivos**: Participa en sorteos y promociones de temporada.

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

.. _4.1.1_py_pi5:

4.1.1 Cámara
=====================

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

Aquí haremos una cámara con un obturador, cuando presiones el botón, la cámara tomará una foto mientras el LED parpadea.

Componentes necesarios
----------------------------

En este proyecto, necesitamos los siguientes componentes. 

.. image:: ../python_pi5/img/4.1.1_camera_list.png
  :width: 800
  :align: center

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

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

    *   - Nombre	
        - ELEMENTOS EN ESTE KIT
        - ENLACE
    *   - Raphael Kit
        - 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_led`
        - |link_led_buy|
    *   - :ref:`cpn_button`
        - |link_button_buy|
    *   - :ref:`cpn_camera_module`
        - |link_camera_buy|

Diagrama esquemático
--------------------------

============== ====== ======== ===
Nombre T-Board físico wiringPi BCM
GPIO17         Pin 11 0        17
GPIO18         Pin 12 1        18
============== ====== ======== ===

.. image:: ../python_pi5/img/4.1.1_camera_schematic.png
   :align: center

Procedimientos experimentales
----------------------------------

**Paso 1:** Construye el circuito.

.. image:: ../python_pi5/img/4.1.1_camera_circuit.png
  :width: 800
  :align: center

**Paso 2:** Ingresa al escritorio de Raspberry Pi. Puede que necesites una pantalla para una mejor experiencia, consulta: `Connect your Raspberry Pi <https://projects.raspberrypi.org/en/projects/raspberry-pi-setting-up/3>`_. O accede al escritorio de Raspberry Pi de forma remota, para un tutorial detallado consulta :ref:`remote_desktop`.

**Paso 3:** Abre una Terminal y entra en la carpeta del código.

.. raw:: html

   <run></run>

.. code-block::

    cd ~/raphael-kit/python-pi5

**Paso 4:** Ejecuta.

.. raw:: html

   <run></run>

.. code-block::

    sudo python3 4.1.1_Camera_zero.py

Después de que el código se ejecute, presiona el botón, el Raspberry Pi hará parpadear el LED y tomará una foto. La foto se llamará ``my_photo.jpg`` y se guardará en el directorio ``~``.

.. note::

    También puedes abrir ``4.1.1_Camera_zero.py`` en la ruta ``~/raphael-kit/python/`` con un IDE de Python, hacer clic en el botón de Ejecutar para ejecutarlo y detener el código con el botón de Detener.

Si deseas descargar la foto a tu PC, consulta :ref:`filezilla`.
.. warning::

    Si recibe el mensaje de error ``RuntimeError: Cannot determine SOC peripheral base address``, consulte :ref:`faq_soc`

**Código**

.. note::
    Puedes **Modificar/Restablecer/Copiar/Ejecutar/Detener** el código a continuación. Pero antes de eso, debes 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

   #!/usr/bin/env python3
   from picamera2 import Picamera2, Preview
   from gpiozero import LED, Button
   import time
   import os

   # Obtener el nombre de usuario actual y el directorio de inicio
   user = os.getlogin()
   user_home = os.path.expanduser(f'~{user}')

   # Inicializar la cámara
   camera = Picamera2()
   camera.start()

   # Inicializar una variable para rastrear el estado de la cámara
   global status
   status = False

   # Configurar el LED y el botón con sus números de pin GPIO
   led = LED(17)
   button = Button(18)

   def takePhotos(pin):
       """Function to set the camera's status to True when the button is pressed."""
       global status
       status = True

   try:
       # Asignar la función a ser llamada cuando se presione el botón
       button.when_pressed = takePhotos
       
       # Bucle principal
       while True:
           # Verificar si el botón ha sido presionado
           if status:
               # Hacer parpadear el LED cinco veces
               for i in range(5):
                   led.on()
                   time.sleep(0.1)
                   led.off()
                   time.sleep(0.1)
               # Capturar y guardar una foto
               camera.capture_file(f'{user_home}/my_photo.jpg')
               print('Take a photo!')          
               # Reset the status
               status = False
           else:
               # Apagar el LED si no se está capturando
               led.off()
           
           # Esperar un corto período antes de verificar el estado del botón nuevamente
           time.sleep(1)

   except KeyboardInterrupt:
       # Detener la cámara y apagar el LED si ocurre una interrupción de teclado
       camera.stop_preview()
       led.off()
       pass


**Explicación del Código**

#. Importa las librerías necesarias para el manejo del tiempo, control de la cámara y control de componentes GPIO.

   .. code-block:: python

       #!/usr/bin/env python3
       from picamera2 import Picamera2, Preview
       from gpiozero import LED, Button
       import time
       import os

#. Obtiene el nombre de usuario actual y el directorio de inicio para guardar las fotos.

   .. code-block:: python

       # Obtener el nombre de usuario actual y el directorio de inicio
       user = os.getlogin()
       user_home = os.path.expanduser(f'~{user}')

#. Inicializa la cámara y la pone en marcha.

   .. code-block:: python

       # Inicializar la cámara
       camera = Picamera2()
       camera.start()

#. Declara ``status`` como una variable global y la inicializa a ``False``.

   .. code-block:: python

       # Inicializar una variable para rastrear el estado de la cámara
       global status
       status = False

#. Inicializa un LED conectado al pin GPIO 17 y un botón conectado al pin GPIO 18.

   .. code-block:: python

       # Configurar el LED y el botón con sus números de pin GPIO
       led = LED(17)
       button = Button(18)

#. Define una función ``takePhotos`` que establece la variable global ``status`` en ``True`` cuando se presiona el botón.

   .. code-block:: python

       def takePhotos(pin):
           """Function to set the camera's status to True when the button is pressed."""
           global status
           status = True

#. Asigna la función ``takePhotos`` para ser llamada cuando se presione el botón.

   .. code-block:: python

       try:
           # Asignar la función a ser llamada cuando se presione el botón
           button.when_pressed = takePhotos
           
           ...
           
#. Verifica continuamente si ``status`` es ``True``. Si es así, hace parpadear el LED cinco veces, captura una foto y restablece ``status``. Si no, el LED permanece apagado. Hay un retraso de 1 segundo entre cada iteración del bucle.

   .. code-block:: python

       try:        
           ...
           
           # Bucle principal
           while True:
               # Verificar si el botón ha sido presionado
               if status:
                   # Hacer parpadear el LED cinco veces
                   for i in range(5):
                       led.on()
                       time.sleep(0.1)
                       led.off()
                       time.sleep(0.1)
                   # Capturar y guardar una foto
                   camera.capture_file(f'{user_home}/my_photo.jpg')
                   print('Take a photo!')          
                   # Reset the status
                   status = False
               else:
                   # Apagar el LED si no se está capturando
                   led.off()
               
               # Esperar un corto período antes de verificar el estado del botón nuevamente
               time.sleep(1)

#. Captura una interrupción de teclado (como Ctrl+C) y detiene la vista previa de la cámara y apaga el LED antes de salir.

   .. code-block:: python

       except KeyboardInterrupt:
           # Detener la cámara y apagar el LED si ocurre una interrupción de teclado
           camera.stop_preview()
           led.off()
           pass

