.. note::

    Ciao, benvenuto nella community di SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts su Facebook! Immergiti più a fondo in Raspberry Pi, Arduino ed ESP32 con altri appassionati.

    **Perché unirti?**

    - **Supporto esperto**: Risolvi i problemi post-vendita e le sfide tecniche con l'aiuto della nostra community e del nostro team.
    - **Impara e Condividi**: Scambia suggerimenti e tutorial per migliorare le tue competenze.
    - **Anteprime esclusive**: Ottieni accesso anticipato a nuovi annunci di prodotti e anteprime.
    - **Sconti speciali**: Goditi sconti esclusivi sui nostri prodotti più recenti.
    - **Promozioni festive e omaggi**: Partecipa a omaggi e promozioni festive.

    👉 Pronto a esplorare e creare con noi? Clicca su [|link_sf_facebook|] e unisciti oggi stesso!

.. _2.1.6_c_pi5:

2.1.6 Modulo Encoder Rotativo
==================================

Introduzione
---------------

In questo progetto, imparerai a conoscere l'encoder rotativo. Un encoder 
rotativo è un interruttore elettronico con una serie di impulsi regolari 
in una sequenza temporale precisa. Quando viene utilizzato con un IC, può 
gestire operazioni come incremento, decremento, cambio pagina e altre funzioni 
come lo scorrimento del mouse o la selezione dei menu.

Componenti necessari
-----------------------

In questo progetto abbiamo bisogno dei seguenti componenti.

.. image:: ../img/Part_two_25.png

È sicuramente conveniente acquistare un kit completo, ecco il link:

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

    *   - Nome	
        - ELEMENTI IN QUESTO KIT
        - LINK
    *   - Kit Raphael
        - 337
        - |link_Raphael_kit|

Puoi anche acquistarli separatamente dai link sottostanti.

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

    *   - INTRODUZIONE COMPONENTE
        - LINK PER L'ACQUISTO

    *   - :ref:`cpn_gpio_extension_board`
        - |link_gpio_board_buy|
    *   - :ref:`cpn_breadboard`
        - |link_breadboard_buy|
    *   - :ref:`cpn_wires`
        - |link_wires_buy|
    *   - :ref:`cpn_rotary_encoder`
        - |link_rotary_encoder_buy|

Schema elettrico
-------------------

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

Procedure sperimentali
--------------------------

**Passo 1:** Costruisci il circuito.

.. image:: ../img/2.1.6_fritzing.png
   :align: center

**Passo 2:** Apri il file del codice.

.. raw:: html

   <run></run>

.. code-block::

    cd ~/raphael-kit/c/2.1.6/

**Passo 3:** Compila il codice.

.. raw:: html

   <run></run>

.. code-block::

    gcc 2.1.6_RotaryEncoder.c -lwiringPi

**Passo 4:** Esegui.

.. raw:: html

   <run></run>

.. code-block::

    sudo ./a.out

Vedrai il conteggio sul terminale. Quando giri l'encoder rotativo in senso orario, il conteggio aumenta; quando lo giri in senso antiorario, il conteggio diminuisce. Se premi l'interruttore sull'encoder rotativo, le letture torneranno a zero.

.. note::

   Se non funziona dopo l'esecuzione o compare un messaggio di errore: \"wiringPi.h: No such file or directory\", consulta :ref:`install_wiringpi`.

Codice
---------

.. code-block:: c

   #include <stdio.h>
   #include <string.h>
   #include <errno.h>
   #include <stdlib.h>
   #include <wiringPi.h>

   #define  clkPin    0
   #define  dtPin    1
   #define  swPin     2

   static volatile int globalCounter = 0 ;

   unsigned char flag;
   unsigned char Last_dtPin_Status;
   unsigned char Current_dtPin_Status;

   void btnISR(void)
   {
      globalCounter = 0;
   }

   void rotaryDeal(void)
   {
      Last_dtPin_Status = digitalRead(dtPin);

      while(!digitalRead(clkPin)){
         Current_dtPin_Status = digitalRead(dtPin);
         flag = 1;
      }

      if(flag == 1){
         flag = 0;
         if((Last_dtPin_Status == 0)&&(Current_dtPin_Status == 1)){
            globalCounter --;	
         }
         if((Last_dtPin_Status == 1)&&(Current_dtPin_Status == 0)){
            globalCounter ++;
         }
      }
   }

   int main(void)
   {
      if(wiringPiSetup() < 0){
         fprintf(stderr, "Unable to setup wiringPi:%s\n",strerror(errno));
         return 1;
      }

      pinMode(swPin, INPUT);
      pinMode(clkPin, INPUT);
      pinMode(dtPin, INPUT);

      pullUpDnControl(swPin, PUD_UP);

      if(wiringPiISR(swPin, INT_EDGE_FALLING, &btnISR) < 0){
         fprintf(stderr, "Unable to init ISR\n",strerror(errno));	
         return 1;
      }
      
      int tmp = 0;

      while(1){
         rotaryDeal();
         if (tmp != globalCounter){
            printf("%d\n", globalCounter);
            tmp = globalCounter;
         }
      }

      return 0;
   }

Analisi del Codice
------------------------

* Leggi il valore di dtPin quando clkPin è basso.
* Quando clkPin è alto, se dtPin passa da basso ad alto, il conteggio diminuisce, altrimenti il conteggio aumenta.
* swPin emetterà un valore basso quando l'asse viene premuto.

Da questo, il flusso del programma è mostrato di seguito:


.. image:: ../img/2.1.6_flow.png
   :align: center

Immagine del fenomeno
------------------------

.. image:: ../img/2.1.6rotary_ecoder.JPG
   :align: center