.. nota::

    Ciao, benvenuto nella community di SunFounder Raspberry Pi & Arduino & ESP32 su Facebook! Approfondisci le tue conoscenze su Raspberry Pi, Arduino ed ESP32 insieme ad altri appassionati.

    **Perché unirti a noi?**

    - **Supporto Esperto**: Risolvi problemi post-vendita e sfide tecniche con l'aiuto della nostra comunità 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**: Approfitta di sconti esclusivi sui nostri prodotti più recenti.
    - **Promozioni Festive e Giveaway**: Partecipa a concorsi e promozioni festive.

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

.. _2.1.6_c:

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

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

In questo progetto imparerai a utilizzare l'encoder rotativo. Un encoder 
rotativo è un interruttore elettronico che genera una sequenza regolare 
di impulsi in stretta sequenza temporale. Se utilizzato con un IC, può 
eseguire operazioni come incremento, decremento, cambio di pagina e altre 
funzioni simili allo scorrimento del mouse o alla 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	
        - COMPONENTI IN QUESTO KIT
        - LINK
    *   - Raphael Kit
        - 337
        - |link_Raphael_kit|

Puoi anche acquistarli separatamente dai link seguenti.

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

    *   - INTRODUZIONE AI COMPONENTI
        - 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 sulla shell. Quando giri l'encoder rotativo in senso orario, il conteggio aumenta; se lo giri in senso antiorario, il conteggio diminuisce. Se premi l'interruttore sull'encoder rotativo, i valori torneranno a zero.

.. note::

   Se non funziona dopo l'esecuzione o appare un errore come: \"wiringPi.h: No such file or directory\", fai riferimento a :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 a alto, il conteggio diminuisce, altrimenti il conteggio aumenta.
* swPin emetterà un valore basso quando l'albero viene premuto.

Da qui, 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
