.. note::

    Ciao, benvenuto nella Community di appassionati di Raspberry Pi, Arduino e ESP32 di SunFounder su Facebook! Approfondisci il tuo viaggio con Raspberry Pi, Arduino ed ESP32 insieme ad altri appassionati.

    **Perché unirti a noi?**

    - **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 consigli e tutorial per migliorare le tue competenze.
    - **Anteprime esclusive**: Ottieni accesso anticipato a nuovi annunci di prodotti e anteprime.
    - **Sconti speciali**: Godi di sconti esclusivi sui nostri prodotti più recenti.
    - **Promozioni e concorsi festivi**: Partecipa a concorsi e promozioni durante le festività.

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

.. _1.1.6_js:

1.1.6 Modulo LED Matrice a punti
=====================================

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

In questo progetto imparerai a conoscere il Modulo LED Matrice a punti. Il modulo utilizza il driver MAX7219 per controllare la matrice LED 8 x 8.

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

In questo progetto, abbiamo bisogno dei seguenti componenti.

.. image:: ../img/list_dot.png

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

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

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

Puoi anche acquistarli separatamente dai link sottostanti.

.. 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_dot_matrix`
        - |link_led_matrix_buy|

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

============ ======== ======== ====
T-Board Name physical wiringPi BCM
SPIMOSI      Pin 19   12       MOSI
SPICE0       pin 24   10       CE0
SPISCLK      Pin 23   14       SCLK
============ ======== ======== ====

.. image:: ../img/schematic_dot.png

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

**Passo 1:** Costruisci il circuito.

.. image:: ../img/1.1.6fritzing.png

.. note::

    Attiva l'SPI prima di iniziare l'esperimento, consulta :ref:`spi_configuration` per i dettagli.

**Passo 2:** Vai alla cartella del codice.

.. raw:: html

   <run></run>

.. code-block::

    cd ~/raphael-kit/nodejs/

**Passo 3:** Installa le dipendenze.

.. raw:: html

   <run></run>

.. code-block::

    sudo npm install spi-device

**Passo 4:** Esegui il codice.

.. raw:: html

   <run></run>

.. code-block::

    sudo node max7219_led_matrix.js

Dopo l'esecuzione del codice, la matrice a punti LED visualizzerà da 0 a 9 e da A a Z in sequenza.

**Codice**

.. code-block:: js

    const Gpio = require('pigpio').Gpio;
    const spi = require('spi-device');

    class MAX7219_LED_MATRIX {
        constructor(bus, device) {
            this.bus = bus;
            this.device = device;
        }
        delay(ms) {
            return new Promise((resolve, reject) => {setTimeout(resolve, ms)});
        }

        async write(addr, data) {
            return new Promise((resolve, reject)=>{
                const max7219 = spi.open(this.bus, this.device, (err)=>{
                    if (err) reject(err);
            
                    const message = [{                        
                    sendBuffer: Buffer.from([addr, data]),
                        receiveBuffer: Buffer.alloc(2),
                        byteLength: 2,
                        speedHz: 20000
                    }];
        
                    max7219.transfer(message, (err, message)=>{
                        if (err) reject(err);
                        else resolve();
                    })
                })
            })
        }
        async init() {
            await this.write(0x09, 0x00);
            await this.write(0x0a, 0x03);
            await this.write(0x0b, 0x07);
            await this.write(0x0c, 0x01);
            await this.write(0x0f, 0x00);
        }
    }

    const DISP=[        
        [0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x3C],//0
        [0x08,0x18,0x28,0x08,0x08,0x08,0x08,0x08],//1
        [0x7E,0x2,0x2,0x7E,0x40,0x40,0x40,0x7E],//2
        [0x3E,0x2,0x2,0x3E,0x2,0x2,0x3E,0x0],//3
        [0x8,0x18,0x28,0x48,0xFE,0x8,0x8,0x8],//4
        [0x3C,0x20,0x20,0x3C,0x4,0x4,0x3C,0x0],//5
        [0x3C,0x20,0x20,0x3C,0x24,0x24,0x3C,0x0],//6
        [0x3E,0x22,0x4,0x8,0x8,0x8,0x8,0x8],//7
        [0x0,0x3E,0x22,0x22,0x3E,0x22,0x22,0x3E],//8
        [0x3E,0x22,0x22,0x3E,0x2,0x2,0x2,0x3E],//9
        [0x8,0x14,0x22,0x3E,0x22,0x22,0x22,0x22],//A
        [0x3C,0x22,0x22,0x3E,0x22,0x22,0x3C,0x0],//B
        [0x3C,0x40,0x40,0x40,0x40,0x40,0x3C,0x0],//C
        [0x7C,0x42,0x42,0x42,0x42,0x42,0x7C,0x0],//D
        [0x7C,0x40,0x40,0x7C,0x40,0x40,0x40,0x7C],//E
        [0x7C,0x40,0x40,0x7C,0x40,0x40,0x40,0x40],//F
        [0x3C,0x40,0x40,0x40,0x40,0x44,0x44,0x3C],//G
        [0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44],//H
        [0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x7C],//I
        [0x3C,0x8,0x8,0x8,0x8,0x8,0x48,0x30],//J
        [0x0,0x24,0x28,0x30,0x20,0x30,0x28,0x24],//K
        [0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C],//L
        [0x81,0xC3,0xA5,0x99,0x81,0x81,0x81,0x81],//M
        [0x0,0x42,0x62,0x52,0x4A,0x46,0x42,0x0],//N
        [0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x3C],//O
        [0x3C,0x22,0x22,0x22,0x3C,0x20,0x20,0x20],//P
        [0x1C,0x22,0x22,0x22,0x22,0x26,0x22,0x1D],//Q
        [0x3C,0x22,0x22,0x22,0x3C,0x24,0x22,0x21],//R
        [0x0,0x1E,0x20,0x20,0x3E,0x2,0x2,0x3C],//S
        [0x0,0x3E,0x8,0x8,0x8,0x8,0x8,0x8],//T
        [0x42,0x42,0x42,0x42,0x42,0x42,0x22,0x1C],//U
        [0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18],//V
        [0x0,0x49,0x49,0x49,0x49,0x2A,0x1C,0x0],//W
        [0x0,0x41,0x22,0x14,0x8,0x14,0x22,0x41],//X
        [0x41,0x22,0x14,0x8,0x8,0x8,0x8,0x8],//Y
        [0x0,0x7F,0x2,0x4,0x8,0x10,0x20,0x7F],//Z
    ];

    lm = new MAX7219_LED_MATRIX(0, 0);

    async function main(){
        lm.init();
        while(1){
            for(let j=0;j<36;j++){
                for(let i=1;i<9;i++){
                    lm.write(i, DISP[j][i-1]);
                }
                await lm.delay(1000);
            }
        }
    }
    main();

**Spiegazione del codice**

.. code-block:: js

    const spi = require('spi-device');

Importa i moduli necessari per la comunicazione spi.

.. note::
    Quando hai più dispositivi che richiedono comunicazione spi, collega semplicemente i pin cs a diversi pin.

.. code-block:: js

    class MAX7219_LED_MATRIX {
        constructor(bus, device) {
            this.bus = bus;
            this.device è il dispositivo.
        }
        delay(ms) {
            return new Promise((resolve, reject) => {setTimeout(resolve, ms)});
        }

        async write(addr, data) {
            return new Promise((resolve, reject)=>{
                const max7219 = spi.open(this.bus, this.device, (err)=>{
                    if (err) reject(err);

                    const message = [{                        
                    sendBuffer: Buffer.from([addr, data]),
                        receiveBuffer: Buffer.alloc(2),
                        byteLength: 2,
                        speedHz: 20000
                    }];

                    max7219.transfer(message, (err, message)=>{
                        if (err) reject(err);
                        else resolve();
                    })
                })
            })
        }

Implementa una classe ``MAX7219_LED_MATRIX``, e la funzione ``write()`` incapsulata in essa può accendere la matrice.

.. note::
    La parola chiave ``async`` viene utilizzata per modificare la funzione ed è solitamente abbinata alla parola chiave ``await``. L'istruzione modificata da ``await`` deve attendere che il codice precedente termini l'esecuzione prima di proseguire, ottenendo l'effetto del blocco sincrono.

* `Async Function <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function>`_

.. code-block:: js

    lm = new MAX7219_LED_MATRIX(0, 0);

Istanzia un oggetto ``lm`` della classe ``MAX7219_LED_MATRIX``, in modo da poter chiamare la funzione ``write()`` incapsulata.

.. code-block:: js

    while(1){
        for(let j=0;j<36;j++){
            for(let i=0;i<8;i++){
                lm.write(i, DISP[j][i]);
            }
            await lm.delay(1000);
        }
    }

La funzione ``write(row,date)`` ti consente di visualizzare caratteri specifici sulla matrice a punti LED.
Il primo parametro seleziona la riga della matrice LED (in totale 8 righe),
Il secondo parametro inserisce un numero binario a 8 bit per controllare gli 8 LED della riga (0 significa spento, 1 significa acceso).

La variabile ``j`` viene utilizzata per selezionare il glifo, che è ``DISP[]``. Ci sono un totale di 35 glifi, da 0 a 9 e da A a Z.

Ad esempio, quando j=1, la matrice LED dovrebbe visualizzare l'immagine **1**.

La variabile ``i`` viene utilizzata per scrivere i 8 dati nel glifo ``DISP[]`` nella matrice LED in ordine. Dopo il completamento del ciclo, può essere generata una grafica 8x8.

Ad esempio, quando j=1, i=1, qui verranno scritti i dati di ``DISP[1][1]``, cioè ``0x18``,
Questo farà sì che la seconda riga della matrice LED mostri l'immagine ``00011000``.

.. image:: ../img/led_not.png
    :width: 400

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

.. image:: ../img/1.1.6led_dot_matrix.JPG
